chirp-20240224/0000755000175000017500000000000014566340177012051 5ustar hibbyhibbychirp-20240224/tests/0000755000175000017500000000000014566340177013213 5ustar hibbyhibbychirp-20240224/tests/images/0000755000175000017500000000000014566340177014460 5ustar hibbyhibbychirp-20240224/tests/images/Yaesu_FT-25R.img0000644000175000017500000002076114411666130017176 0ustar hibbyhibby4123џџџџџџџџџџџџ@ dQ%9•bUQ%229•Q% %hh % bUQ%9•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ dp  P @  @ d P @  @ dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ---------..------------------------------------------------------------------------------------------------------------------------------------------------------P P  P џchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQtMjVSIiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIllhZXN1RlQyNVJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Icom_IC-V82.img0000644000175000017500000001473114411666130016770 0ustar hibbyhibbyrш @џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHq„ @џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ш P@џџџџџ zzJzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџа5€ ЊD  @€r ЊD  @ Jџџџџџџџџџџџџџџџџ џџџџ џџџџ џџџџ џџџџ џџџџ џџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ Шџ 28260001џchirpюimgeyJyY2xhc3MiOiAiSUNWODJSYWRpbyIsICJ2ZW5kb3IiOiAiSWNvbSIsICJtb2RlbCI6ICJJQy1WODIiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Retevis_RT29_UHF.img0000644000175000017500000000225514411666130020052 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%D%DЉ Љ 0џї%'D%'D  0џї%D%D  0џї%ID%ID  0џї%QD%QD  0џї%bD%bD  0џї%sD%sD  0џї%„D%„D  0џї%•D%•D  0џїuDuD  0џїuXCuXC9 9 0џїu•Cu•C: : 0џїu„Cu„CM M 0џїusCusCR R 0џїubCubCU U 0џїuQCuQC“ “ 0џї  џџџ000џџџџџџџџџ12345џџџџџџџџџџџџџџџџџџџџџџџџџџџџ3џџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP3207јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџррррррррр€€€€€€€іѕѕѕѕѕѕїїїїїїїїѕŽŽ““““’ŒŽ“››KKKKKKKKKUUUXZXbџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџdFH  џџџџџџЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDI5X1VIRiIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwNzAzIiwgInJjbGFzcyI6ICJSVDI5VUhGUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Yaesu_FT-817.img0000644000175000017500000001455514411666130017151 0ustar hibbyhibbyјП€€ @$T–BYхFNВ…€2222В2 bHП 'џџџџџџџџ`HW0'џџџџџџџџaH В('џџџџџџџџbHB@'џџџџџџџџaЮ'џџџџџџџџaHw@'џџџџџџџџaH 'џџџџџџџџaH%bP'џџџџџџџџeH+X'џџџџџџџџEHL]Ы† џџџџџџџџEO њ№џџџџџџџџDKЄЫ€џџџџџџџџEHпš0ъ`џџџџџџџџENЈ€ќЁ џџџџџџџџdH\­'џџџџџџџџbHП 'џџџџџџџџ`HW0'џџџџџџџџ`H Ў`'џџџџџџџџbHB@'џџџџџџџџaH\Р'џџџџџџџџaHw@'џџџџџџџџaH 'џџџџџџџџaH%bP'џџџџџџџџaH*Й€'џџџџџџџџAHLK@† џџџџџџџџEO†GџџџџџџџџDKЄЫ€џџџџџџџџAHлКъ`џџџџџџџџAN РЁ џџџџџџџџdHу`'џџџџџџџџeH-*€'џџџџџџџџEHP%”† џџџџџџџџEHп’`ъ`џџџџџџџџENЈŠРЁ џџџџџџџџ`H Ў`'CH-001 E$Hоъ`џџџџџџџџ`H Џ\'CH-001 ъ @LK@ReР…Hп’`ъ`NATSIMPX…NЈŠРЁ UHFSIMPXEdHпЕˆъ`џџџџџџџџEЅN І…,Ё џџџџџџџџEЅNЂ\ИЁ џџџџџџџџEЄAрvфъ`џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„ K€ ){$CB-19 @K-: ' B€K€LnhCW Call K€Lv8DX Call A€K€L| A€K€L…иSSB CAllE K€(N™ EK€(P%”6m Simp EA K( P3@†  EA K(Pу†  EA K( Pъи†  EA K( PюР†  EA KQH†  EA K( Q†  EA K(QИ†  EA K( Q1(†  Ea H(Q<р†  EA K( QL€† Tucson EA K( QoЈ†  EA K(QH†  EA K( QІX†  EA K( QЕј†  EA K(QНШ† KB9KRI EA K(QЭh†  EA K(R†  Aм ъ` AK€м  AK€мЈ edH нЊ'џџџџџџџџEdнБшъ`џџџџџџџџEdнијъ`џџџџџџџџEdн№hъ`џџџџџџџџ…DK( н№hъ` EH( оlъ`KG5EGC EEK оo\ EH€( п’`ъ`2m SimplEDK(пЕˆъ`LaPorte Edпр€ъ`џџџџџџџџEDKпѕќъ`Valpo EdH(пї№ъ`CH-021 Edръ`џџџџџџџџEdръ`џџџџџџџџEDK(р*Иъ`WA9JLN Ed@(р6pъ` EDKрB(ъ`MichCty EDKС(рMръ` EЄH( рt№ъ`KC0LL „Kрvфъ`KB9KRI E„Kр„ъ` EЄH(рŒ`ъ`Ears E„Kрš ъ`Hammond ЄK( рЋ ъ`CH-076 E„K рН4ъ`PlymouthEЄH рк€џџџџџџџџEeNЇГшЁ џџџџџџџџE…KІЂxЁ Hammd E…KІ№˜Ё Portage eNЊдАЁ CH-067 eNЋg,Ё CH-068 EeNЌlЁ џџџџџџџџEeAЌ ИЁ џџџџџџџџeNЌ4@Ё CH-065 EEK Ќ>Ё EEK ЌQŒЁ eN ЌnиЁ CH-060 Ee(­мЁ Cactus Ee@A ­lРЁ џџџџџџџџeNЎW Ё CH-064 Ee( Ў›|Ё KC0LL ENГ`0Ё џџџџџџџџENГ‡@Ё џџџџџџџџEK€ГšШ EK€ГЎP EK€(ГИ EK€Ге` EK€ГђЌ EK€Д#€ EK€Д^ EK€Дq  EK€Л“Ь EK€НёD EK‚О EK€О\А EK€Оft EKР Оp8 EK€Оyќ EK€ОƒР ENО„Ё џџџџџџџџEK€ОЁ EK€ОШ … K€СаzFRS-1 …-I(Ск>Ё FRS-2 …-I(СфЁ FRS-3 …-I(СэЦЁ FRS-4 …-I(СїŠЁ FRS-5 …-I(ТNЁ FRS-6 … K€(Т FRS-7 EK€У м EK€Уј< EK€ХЏА … K€(ЩqšFRS-8 … K€Щ{^FRS-9 … K€Щ…"FRS-10 … K€ЩŽцFRS-11 … K€٘ЊFRS-12 … K€ЩЂnFRS-13 … K€ЩЌ2FRS-14 џџџџџџџџџџџџџџџџџџџџџџџџџџEeN ЎtlЁ џџџџџџџџEeNЎtlЁ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!":'AH-140 a(z'AH-140 a0J'AH-140 a2>'AH-140 a>О'AH-140 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџeПƒћн@ ™™ eПƒћсд€™™ aHтŽ'џџџџџџџџ" $$хaЮ'џџџџeПƒћн@ ™™ eПƒћсд€™™ aHтŽ'џџџџџџџџ" $$хaЮ'џџџџchirp-20240224/tests/images/Retevis_RB19P.img0000644000175000017500000000222514411666130017442 0ustar hibbyhibbyџџџџџџџџџџџџџџџPb%FPb%Fppт€џP‡%FP‡%Fˆˆт€џP&FP&Fssт€џP7&FP7&Fт€џPb&FPb&Feeт€џP‡&FP‡&Fт€џP'FP'Fbbт€џPbuFPbuFC‚C‚ф€џP‡uFP‡uF2€2€ф€џPvFPvFG€G€ф€џP7vFP7vFQ€Q€ф€џPbvFPbvFS€S€ф€џP‡vFP‡vFe€e€ф€џPwFPwFф€џP%FP%F00т€џu%Fu%FCЧCЧт€џ&F&F2У2Утџџџ%&F%&FssтџџџP&FP&FCТCТтџџџu&Fu&F††тџџџ'F'F1Ч1Чтџџџ%'F%'FeeтџџџP%FPuFeeтџu%FuuFeeтџ&FvFeeтџ%&F%vFeeтџP&FPvFeeтџu&FuvFeeтџ'FwFeeтџ%'F%wFeeтџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ›јџџSMџP558џ@GџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjE5UCIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwNjA0IiwgInJjbGFzcyI6ICJSQjE5UFJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Anysecu_WP-9900.img0000644000175000017500000004024114411666130017560 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%CuGџџџџџџџџџџџџџџџџ%v%vЮЮ%T%T%C%C%UC%UCљљ%wC%wC %˜C%˜CввP'GP'Gџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   <џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџModel:WP9900  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ &!#000000&!#))))))&!#))))))&!#))))))-   2KT-WP1WP3094 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000WP3094000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJ2ZW5kb3IiOiAiQW55c2VjdSIsICJtb2RlbCI6ICJXUC05OTAwIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjAyMTkiLCAicmNsYXNzIjogIldQOTkwMCIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Kenwood_TK-3180K2.img0000644000175000017500000015066114411666130017746 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKPG089DV1.02џџџџ089K5363Z001џџџџP3180џџџџџџџџџџџџџџџџџџџџџџџџџџџ1џџџџџџџџџџџџџџџџџџџџџџџџџуџуџуWRDN337 џџџџџ100џџџ1џ0џџџџџџџџџџџџџџџџџџ0џџџџ–Аџџ №џєџˆДѓўўџџџџ0џџџ0џџџџ1ˆџ<0 џџџџџџџџџџџџџџџџџџџџџџџ 67.0žž 69.3ЕЕ 71.9ЯЯ 74.4шш 77.0 79.7 82.599 85.4VV 88.5uu 91.5““ 94.8ДД 97.4ЮЮ 100.0шш 103.5   107.200 110.9UU 114.8|| 118.8ЄЄ 123.0ЮЮ 127.3љљ 131.8&& 136.5UU 141.3…… 146.2ЖЖ 151.4ъъ 156.7 162.2VV 167.9 173.8ЪЪ 179.9 186.2FF 192.8ˆˆ 203.5ѓѓ 210.7;; 218.1…… 225.7бб 233.6 241.8r r 250.3Ч Ч џџџџв в в MMMMMMMЃ^Ѓ^Ѓ^Ѓ^@^†ЃР †F”M”M”MMMMMMMMu”u”u”u”u”u”u”И 100џџџџџџџџџїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?џџџџџџџџ(/3аџџ(џџџџџџџџџ-,шџџLџMџшџџ&џџџџџџџџџџџџџџџџџџџџџџџџџ%џшџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0єа0 SCANџџџџџџ§џ,ааџџџџџџџџўџ0Шаџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџ#іџџџjшџџџџџџџџџџ0џџџџрџџџџџџџџ0 џ0џџџџџџџџџџџџџџџџџџџџ0џџџџџџ 8сџ'аєџџўџџџџ1 P0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(ш џ0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљџџџџџџџџџџџџџ3џŒўџџџ2џџџџџџџџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ1џџџџџџцхууџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPPCQC66P@@66P™F™F66PCPC66RCRC66TCTC66џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP@@66PpBvA66PPCQC66P%E&E66P™F™F66џџџџџџџџџџџџџџ —PŸPЇdДZџџџџџџџџџџџџ Раџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ1FRS/GMRSџџ<џџџџџџџџџјџPb%FPb%F66џџџџFRS/GMRS 1џџџџџџџџџџџџџџџџџџџќџP‡%FP‡%F66џџџџFRS/GMRS 2џџџџџџџџџџџџџџџџџџџќџP&FP&F66џџџџFRS/GMRS 3џџџџџџџџџџџџџџџџџџџќџP7&FP7&F66џџџџFRS/GMRS 4џџџџџџџџџџџџџџџџџџџќџPb&FPb&F66џџџџFRS/GMRS 5џџџџџџџџџџџџџџџџџџџќџP‡&FP‡&F66џџџџFRS/GMRS 6џџџџџџџџџџџџџџџџџџџќџP'FP'F66џџџџFRS/GMRS 7џџџџџџџџџџџџџџџџџџџќџPbuFPbuF66џџџџFRS/GMRS 8џџџџџџџџџџџџџџџџџџџќџ P‡uFP‡uF66џџџџFRS/GMRS 9џџџџџџџџџџџџџџџџџџџќџ PvFPvF66џџџџFRS/GMRS 10џџџџџџџџџџџџџџџџџџџќџ P7vFP7vF66џџџџFRS/GMRS 11џџџџџџџџџџџџџџџџџџџќџ PbvFPbvF66џџџџFRS/GMRS 12џџџџџџџџџџџџџџџџџџџќџ P‡vFP‡vF66џџџџFRS/GMRS 13џџџџџџџџџџџџџџџџџџџќџPwFPwF66џџџџFRS/GMRS 14џџџџџџџџџџџџџџџџџџџќџP%FP%F66џџџџFRS/GMRS 15џџџџџџџџџџџџџџџџџџџќџu%Fu%F66џџџџFRS/GMRS 16џџџџџџџџџџџџџџџџџџџќџ&F&F66џџџџFRS/GMRS 17џџџџџџџџџџџџџџџџџџџќџ%&F%&F66џџџџFRS/GMRS 18џџџџџџџџџџџџџџџџџџџќџP&FP&F66џџџџFRS/GMRS 19џџџџџџџџџџџџџџџџџџџќџu&Fu&F66џџџџFRS/GMRS 20џџџџџџџџџџџџџџџџџџџќџ'F'F66џџџџFRS/GMRS 21џџџџџџџџџџџџџџџџџџџќџ%'F%'F66џџџџFRS/GMRS 22џџџџџџџџџџџџџџџџџџџќџP%FPuF66џџџџGMRS RPT 550џџџџџџџџџџџџџџџџџџџќџu%FuuF66џџџџGMRS RPT 575џџџџџџџџџџџџџџџџџџџќџ&FvF66џџџџGMRS RPT 600џџџџџџџџџџџџџџџџџџџќџ%&F%vF66џџџџGMRS RPT 625џџџџџџџџџџџџџџџџџџџќџP&FPvF66џџџџGMRS RPT 650џџџџџџџџџџџџџџџџџџџќџu&FpvF65џџџџGMRS RPT 675џџџџџџџџџџџџџџџџџџџќџ'FwF66џџџџGMRS RPT 700џџџџџџџџџџџџџџџџџџџќџ%'F%wF66џџџџGMRS RPT 725џџџџџџџџџџџџџџџџџџџќџ1Channelsџџ<џџџџџџџџџ§џ'F'F66ЯЯGMRS 21-2џџџџџџџџџџџџџџџџџџџќџ`D`D66џџџџHAM UHF SPXџџџџџџџџџџџџџџџџџџџўџ `D `D55шшHAM LocalџџџџџџџџџџџџџџџџџџџўџPDPdD66  ECX NET-5џџџџџџџџџџџџџџџџџџџўџPDPdD66  N5 PAGE 3260џџџџџџџџџџџџџџџџџџўџ1$GMRS Wideџџ<џџџџџџџџџјџPb%FPb%F66џџџџGMRS 1џџџџџџџџџџџџџџџџџџџўџP‡%FP‡%F66џџџџGMRS 2џџџџџџџџџџџџџџџџџџџўџP&FP&F66џџџџGMRS 3џџџџџџџџџџџџџџџџџџџўџP7&FP7&F66џџџџGMRS 4џџџџџџџџџџџџџџџџџџџўџPb&FPb&F66џџџџGMRS 5џџџџџџџџџџџџџџџџџџџўџP‡&FP‡&F66џџџџGMRS 6џџџџџџџџџџџџџџџџџџџўџP'FP'F66џџџџGMRS 7џџџџџџџџџџџџџџџџџџџўџPbuFPbuF66џџџџFRS/GMRS 8џџџџџџџџџџџџџџџџџџџќџ P‡uFP‡uF66џџџџFRS/GMRS 9џџџџџџџџџџџџџџџџџџџќџ PvFPvF66џџџџFRS/GMRS 10џџџџџџџџџџџџџџџџџџџќџ P7vFP7vF66џџџџFRS/GMRS 11џџџџџџџџџџџџџџџџџџџќџ PbvFPbvF66џџџџFRS/GMRS 12џџџџџџџџџџџџџџџџџџџќџ P‡vFP‡vF66џџџџFRS/GMRS 13џџџџџџџџџџџџџџџџџџџќџPwFPwF66џџџџFRS/GMRS 14џџџџџџџџџџџџџџџџџџџќџP%FP%F66џџџџGMRS 15џџџџџџџџџџџџџџџџџџџўџu%Fu%F66џџџџGMRS 16џџџџџџџџџџџџџџџџџџџўџ&F&F66џџџџGMRS 17џџџџџџџџџџџџџџџџџџџўџ%&F%&F66џџџџGMRS 18џџџџџџџџџџџџџџџџџџџўџP&FP&F66џџџџGMRS 19џџџџџџџџџџџџџџџџџџџўџu&Fu&F66џџџџGMRS 20џџџџџџџџџџџџџџџџџџџўџ'F'F66џџџџGMRS 21џџџџџџџџџџџџџџџџџџџўџ%'F%'F66џџџџGMRS 22џџџџџџџџџџџџџџџџџџџўџP%FPuF66џџџџGMRS RPT 550џџџџџџџџџџџџџџџџџџџўџu%FuuF66џџџџGMRS RPT 575џџџџџџџџџџџџџџџџџџџўџ&FvF66џџџџGMRS RPT 600џџџџџџџџџџџџџџџџџџџўџ%&F%vF66џџџџGMRS RPT 625џџџџџџџџџџџџџџџџџџџўџP&FPvF66џџџџGMRS RPT 650џџџџџџџџџџџџџџџџџџџўџu&FpvF65џџџџGMRS RPT 675џџџџџџџџџџџџџџџџџџџўџ'FwF66џџџџGMRS RPT 700џџџџџџџџџџџџџџџџџџџўџ%'F%wF66џџџџGMRS RPT 725џџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШшИ ˆџџџџўџ‘ ‰ЇƒA$/Ђ-y\I|FжO’Й0џџџџџџџ џџџџџџџсџ‘ ‰ЇƒA$/Ђ-y\I|FжO’Й0џџџџџџџ џџџџџџџсџ‘ ‰ЇƒA$/Ђ-y\I|FжO’Й0џџџџџџџ џџџџџџџсџ‘ ‰ЇƒA$/Ђ-y\I|FжO’Й0џџџџџџџ џџџџџџџсџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 2-TONE 1‘ A$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџДДџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ3џџџ3џџџ3џџџ3џџџ3џџџ3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџќџџџџџџџџџџџџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiS2Vud29vZCIsICJtb2RlbCI6ICJUSy0zMTgwSzIiLCAiY2hpcnBfdmVyc2lvbiI6ICIwLjMuMGRldiIsICJyY2xhc3MiOiAiS2Vud29vZFRLMzE4MEsyUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Wouxun_KG-UV980P.img0000644000175000017500000010031114411666130017736 0ustar hibbyhibbyA9e’X'?E>PP%& "PџџџџџџџџџџџџX9c(Sss„Sџџџџџџџџџџџџ'%(%PPџџџџџџџџ€@G`029p˜P@pBG€0`@џџџџ(3џю3+Žk-Дj1223457јЃрљЃрњЃр€`@`2pp INX_n‚‘ ЊŒ,048<@DHLPTX\`dgџџџџџџџџџџџџџџџџ&-4FKU_n‚‘ ЊЊ,048<@DHLPTX\bmqџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€@G`029p˜P`@@G@`B xxxxxxqqppLLLLLKIHGG7888876544%'&&&&%%$$^^dddbbabdiinnnnCB@??CDEFGHJKMNN1/....../0012345$"!  !"##$‡Š‰‰[[Z[FFEF3334}}|{RRRP>>><,-,+Ѕ˜‘‘“›ЊЏШѕ˜š ЁЂЂЃЃЃЃЃЄІЊЏЅЙУцЙвцњВМЦзPNNNNPVZavLLOOPPPPPPPPPPTTPZnsCFHMXRNNPUZ\fpPPSSTTTTTTTTVVZZм№џџУЬбу +((((##!!!!!!#!!!!!777444422<84544(((&&&$$$"*******###########dnsxZ_dnPZ_dKPZdPU_nPU_nAFFF22772222--//--//-277##!!!!############### KK_dKK_dKZ_dPdinZdinZdin,-//,-//--//-/2225772577ЙЌЅЅЊДУЩсџЌЎБДЕЕЕЖЖЖЖЖЗЙНТДУвсds}Œfkpu876669<=BN55778888888888;;Zdiv-/24<9889>DDџџџџ ‡Œ‘˜ААААААААААААААААААААААџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜Gџџџџr3џџPW;>џџџџџџџџџџџџџџџџ%PF%PP9%X%X2%Xp%XF•p€Ьџџџџ#&ў"џџџшџџџџџџџџ%&   E91>PP!E1>*8?EPP*&"PcdЧШ+,ѓєWXЛМ ƒ„чџџџџџџџџPPPPPPPPPPPPPPPPPPPPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA%A%ZC%C%XџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD1D99иџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџRFЮЮШD0uD€uЮЮякрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPNrthvillPPPPPPPPPPPPPPPPGMARC VGMARC UPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2ZW5kb3IiOiAiV291eHVuIiwgIm1vZGVsIjogIktHLVVWOTgwUCIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzAxMjEifQ==chirp-20240224/tests/images/Icom_IC-T70.img0000644000175000017500000001474014411666130016763 0ustar hibbyhibbyrx  rx  sx  qŠx ! _hx  qшx  џџџџџџџџџџџџџџџџrшx ! €rшx ! €rшx ! €џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp€x €_ш P€p€x €rшx ! €H ш P€_ш P€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџrx €WРш P€pќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџ НР' ! о9@KL џџџџџџџџџџџџџџџџџџџџџџяГР'  џџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ32530001chirp-20240224/tests/images/BTECH_UV-25X2.img0000644000175000017500000004025514560403070017043 0ustar hibbyhibby%f%f%v%v%D%D%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ    џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџ WELCOME UV-25X2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2 UV25X2UC2012  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000UC2012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjI1WDIiLCAidmVuZG9yIjogIkJURUNIIiwgIm1vZGVsIjogIlVWLTI1WDIiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Retevis_RB28B.img0000644000175000017500000000126114411666130017423 0ustar hibbyhibbyPb%FPb%Fžž P‡%FP‡%FЄЄ P&FP&Fљљ NP7&FP7&F&& Pb&FPb&FUU P‡&FP‡&F…… P'FP'FЖЖ PbuFPbuFЃ(Ѓ(P‡uFP‡uF((PvFPvF'('(P7vFP7vF)()(PbvFPbvF+(+(P‡vFP‡vF5(5(PwFPwFN(N(P%FP%FЮЮ u%Fu%FуЉуЉ &F&FкЈкЈ %&F%&Fљљ P&FP&FЃЈЃЈ u&Fu&F†)†) 'F'FйЉйЉ %'F%'FUU џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSQjI4QlJhZGlvIiwgInZlbmRvciI6ICJSZXRldmlzIiwgIm1vZGVsIjogIlJCMjhCIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Retevis_RT9000D_220-260.img0000644000175000017500000004027114411666130020502 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   ` ` 2d ` 2d‘ A$H:3 d ‘$AyOж2d ўџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџ < џџџџџџџџI†‘ A$4P ` џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"фдф#циц$шмш%ъръ&ьфь&юъю&№ђ№&ёљё&ђџђ'єє(її(ћћ* -0  48$;*=0?6@<ABB H C"H"C$H$C&F&C(D(C*B*C,@,D.>.E/</F0:0M181T303Z88`@P@d   f№№№kАААpppppџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@аpаpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ @ рU%еˆXч$Є(а(Їџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@@@@@ @@@@     @@@@ P```====  (0…8888р€2222аррр№p((((ШШШШШp%%%%†„‚€€X%%%%pppppF%%%% ќќˆџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџˆs&ь €І’Œr{z~}‡џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкKџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDkwMDBEXzIyMC0yNjAiLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIxMDgxNCIsICJyY2xhc3MiOiAiUlQ5MDAwRDIyMFJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Wouxun_KG-1000G.img0000644000175000017500000010030114411666130017511 0ustar hibbyhibby†A9e’X'?E>PP%& "PџџџџџџџџџџџџX9c(Sss„S`0`@Pџџџџџџџџ€@G`029p˜P`@@G`0`@џџџџ(3џю3+Žj-Дh1223457јЃрљЃрњЃр€`@`2pp AFP_s‚Œ– Œ(,048<@DHLPTX\`dџџџџџџџџџџџџџџџџ&-4AKU_n‚‘ ЊЊ*.26:>BFJNRVXZbfџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€@G`029p˜P`@@G`0`@B xxxxxxssnnMNOSSMMKII8::<=:8765&'())'&&$$nnssddhilpsx––}}AAAAAAAAAAAA@A<<------------.0--Œ‘‘‘baaaKKKK5555}}}}UUUT9???*+,,Ѕ  ЇБОЭвџџ––––––––––––ЏЏ––ЏОвцЙвцњЊДОвKKKKPZbm}‘FFFFFFFFFFFFFKKKU_is@HNR]j7777777777777777вцџџ ‚‡Œ‘ААААААААААААААААААААААџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”Eџџџџf/џџi\PEџџџџџџџџџџџџџџџџa%XC%Xa%X%X2%Xp%XA%XЬ џџџџ#&"Pџџџшџџџџџџџџ'%(%PPE91>PP!E1>*8?EPP*&"PcdЧШ+,ѓєWXЛМ ƒ„чџџџџџџџџPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF%bPF%bPТF%‡PF%‡PТF&PF&PТF&7PF&7PТF&bPF&bPТF&‡PF&‡PТF'PF'PТFubPџџџџлFu‡PџџџџлFvPџџџџлFv7PџџџџлFvbPџџџџлFv‡PџџџџлFwPџџџџлF%PF%PкF%uF%uкF&F&кF&%F&%кF&PF&PкF&uF&uкF'F'кF'%F'%кF%PFuPšF%uFuušF&FvšF&%Fv%šF&PFvPšF&uFvušF'FwšF'%Fw%šџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS-01 GMRS-02 GMRS-03 GMRS-04 GMRS-05 GMRS-06 GMRS-07 GMRS-08 GMRS-09 GMRS-10 GMRS-11 GMRS-12 GMRS-13 GMRS-14 GMRS-15 GMRS-16 GMRS-17 GMRS-18 GMRS-19 GMRS-20 GMRS-21 GMRS-22 RPT-15 RPT-16 RPT-17 RPT-18 RPT-19 RPT-20 RPT-21 RPT-22 PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@@@@@@@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJLRzEwMDBHUmFkaW8iLCAidmVuZG9yIjogIldvdXh1biIsICJtb2RlbCI6ICJLRy0xMDAwRyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzAxMjEifQ==chirp-20240224/tests/images/KYD_NC-630A.img0000644000175000017500000000147014551723752016574 0ustar hibbyhibbyџџџџџ$@FFџџчЯџџP7sEP7sEџџ чЯџџPwEPwEџџ чЯџџP‡wEP‡wEџџ чЯџџPxEPxEџџ чЯџџP‡xEP‡xEџџ чЯџџ@F@FџџчЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџїЯџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џ00џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP32073№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Retevis_RT95.img0000644000175000017500000003150114411666130017347 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџQP ђCPP ђWELCOMEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ dd–88888 12345 23456 34567 45678 FFFd–d 2F4^ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 123456   QPCP  ђџchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIlJldGV2aXMiLCAibW9kZWwiOiAiUlQ5NSIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Icom_IC-2820H.img0000644000175000017500000012654514565617124017134 0ustar hibbyhibbyЫ–@ 'РCQCQCQ r (DSTAR S1Ъњ 'РCQCQCQ r DSTAR S2С„ 'РCQCQCQ r „W.Co PriШ‰ 'РCQCQCQ r@ рW.Co SecЩ%@ 'РCQCQCQ r €W.Co Sim?50LK@CQCQCQ rlL€KOIN UHFЧьР 'РCQCQCQ r@ р@D1 ARES gЄРLK@CQCQCQ KD7REX BKD7REX GrX €K7HIO `eHLK@CQCQCQ KD7RFI BKD7RFI GrD рWORCALOHЋВ0 'РCQCQCQ KD7REX BKD7REX Gr$ рWORCShrVn шLK@CQCQCQ KD7REX BKD7REX GrD рWORCShrUЉP 'РCQCQCQ WB7DZG BWB7DZG Gr$"0OEM NCS 'РCQCQCQ WB7DZG BWB7DZG Gr € zшdLK@CQCQCQ WB7DZG BWB7DZG Gr@!6WB7DZG BЦf 'РCQCQCQ KD7REX C rD РHEBO 722Ѓ›р 'РCQCQCQ KD7REX C r РWCCCA PKС„ 'РCQCQCQ KD7REX C r €€TEST 1 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅ—А 'Р €CEDAR ЌъА 'Р €HIO ЖеРЖеРп Р]‰6€‰6€ ХH@ ХH@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ;—МРџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџRк|LK@CQCQCQ KD7REX BKD7REX GџР ƒ?KD7REX BBBpLK@CQCQCQ KD7RFI BKD7RFI GџР €?KD7RFI B{ЋДLK@CQCQCQ WB7DZG BWB7DZG GџР ƒ?WB7DZG BН*и 'РCQCQCQ WB7DZG CWB7DZG Gџ  €?WB7DZG Cџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ’$Ф 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 1 ’†l 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 2 ’ш 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 3 “IМ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 4 “Ћd 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 5 ” 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 6 ”nД 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 7 оp 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 8 обЌ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 9 п3T 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 10 п”ќ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 11 піЄ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 12 рXL 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 13 рЙє 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯFRS 14 ‘ѓ№ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 1 ’U˜ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 2 ’З@ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 3 “ш 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 4 “z 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 5 “м8 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 6 ”=р 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 7 ”Ÿˆ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGMRS 8 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ –р 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯMURS1 @ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯMURS2 k  'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯMURS3 6 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯMURS4BLU 7@ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯMURS5GRN ( 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯRED DOT І8 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯPUR DOT Аxp 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯYEL DOT ЏЕ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯBRN DOT с}D 'Р ƒJ DOTт@” 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯK DOT тг 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯSIL STARу4И 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯGLD STARу–` 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯRED STARуј 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯBLU STARџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ,м 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯV-TAC 1 v$\ 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯV-TAC 3 yT 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯU-TAC C Iф 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯU-TAC 1  t 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯU-TAC 2  dd 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ ƒ?џЯU-TAC 3 'Рџџџџџџџџџџџџџџџџџџџџџџџџџ€ €?џЯI-TAC C џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ•D 'РCQCQCQ r € вM 'РCQCQCQ r € ЁG€LK@CQCQCQ r † вt€LK@CQCQCQ r † ЦyЈ 'РCQCQCQ KD7REX C r@ Р џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgЄРLK@CQCQCQ KD7REX BKD7REX GrX!  K7HIO 9оLK@CQCQCQ r † Аџџџџџџџџџџр№Рџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџљ Юџџџџџџџџџр№€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЮџџџџџџџџџр№€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ     џџџџџџџџџџџџџџџџ !"#$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Digital General Public S WC ARES џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ KK7DS K7TAY KK7DS M KE7FTE VK3UR /VK3RWNC/KJ4ACN WA4DOC N7QQU /KJ4ACNB/NI4CE BREF002AL UKD7REX EKD7REX EN9JA CQCQCQ W7GC LW7GC CL U UREF002ALREF002CLREF001ALREF017AL UCQCQCQ REF001CLREF015CLREF015CLREF001CL UW7GC CL KD7REX BKD7REX GKD7REX GKD7REX CWB7DZG BWB7DZG BWB7DZG GKD7REX BKD7REX B W7BVT EOC CQCQCQ ™™™™™™KD7YPY KD7REX GKD7REX BCQCQCQ ™™™™™™KD7REX B KD7REX BKD7REX BK7HIO ™™™™™™N7OGM N7OGM ™™™™™™N7HQR MOB KD7REX GKD7REX BCQCQCQ ™™™™™™KK7DS KD7REX BKD7REX BCQCQCQ ™™™™™™KD7REX G KD7REX GKD7REX BK7HIO ™™™™™™KD7REX G KD7REX GKD7REX BKK7DS ™™™™™™K7TAY KD7REX BKD7REX BCQCQCQ ™™™™™™WX7EM KD7REX GKD7REX BCQCQCQ ™™™™™™ ™™™™™™KB7WUK 2820KD7REX GKD7REX BCQCQCQ ™™™™™™N7HQR KD7REX GKD7REX BCQCQCQ ™™™™™™KK7DS CQCQCQ ™™™™™™K7TAY CQCQCQ ™™™™™™K7HIO CQCQCQ ™™™™™™KD7REX B KD7REX BKD7REX BK7TAY ™™™™™™N7AAM B CQCQCQ ™™™™™™N7ALN KD7REX GKD7REX BCQCQCQ ™™™™™™K7HIO KD7REX BKD7REX BCQCQCQ ™™™™™™   џ kk7ds@danplanet.com џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9оLK@CQCQCQ r † џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'РCQCQCQ r € 9оLK@CQCQCQ r †  € џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'РCQCQCQ r € 9оLK@CQCQCQ r †  € џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'РCQCQCQ r € 9оLK@CQCQCQ r †  € џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЫ–@ 'РCQCQCQ r €DIGITAL Гя 'РCQCQCQ r € Гя 'РCQCQCQ r € 9оLK@CQCQCQ r † 9оLK@CQCQCQ r †џџџџџџџџ9оLK@CQCQCQ r †џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'РCQCQCQ r €џџџџџџџџГя 'РCQCQCQ r €џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘нРCQCQCQ r †€2CQCQCQ r †€Ў#0 'РCQCQCQ KD7REX C r8р˜ОCQCQCQ r †‹8РCQCQCQ r ƒ]XLK@CQCQCQ KD7REX BKD7REX Gr@  /ПCQCQCQ r ƒƒ^аCQCQCQ r †€2CQCQCQ r †€ оА 'РCQCQCQ r0а‹8РCQCQCQ r ƒnф8LK@CQCQCQ KD7REX BKD7REX GrD!аЁ€CQCQCQ r ƒ;R|CQCQCQ r ƒ?50LK@CQCQCQ rlL€KOIN UHFgЄРLK@CQCQCQ KD7REX BKD7REX GrX €K7HIO џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ† џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIkljb20iLCAibW9kZWwiOiAiSUMtMjgyMEgiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Vertex_Standard_VXA-700.img0000644000175000017500000001000014411666130021251 0ustar hibbyhibby='џџџџџџџџџџ7ўџџџџ  @€ @@@@@@@@@@@@@Z       џџ?П? №џ ь Ї6 EЈџ70џќїўќўќ’ЁC6Hf8Ao2€И@џ@@@@@@@@rx Рџ@@@@@@@@IРЅрOџ@@@@@@@@Z  пРџ@@@@@@@@7§р !N@@@e˜§р !N@@@e€§р !N@@@eŒ§р !N@@@e„§р !N@@@eˆ§р !N@@@e§р !N@@@e”§р !N@@@e§р !N @@@e§р !N@@@f ЅрOџ @@@@@@@Z  И`џ qH И`џ @@@@@@@qH И`џ @@@@@@@qH И`Oџ @@@@@@@qH ИdOџ @@@@@@@qH ИdOџ @@@@@@@qH  `Oџ @@@@@@@qH €`Oџ @@@@@@@qH  `Oџ @@@@@@@qH  pOџ @@@@@@@qI €`Oџ @@@@@@@qH  `Oџ @@@@@@@qH ЂрOџ @@@@@@@ZЂ ЅрOџ @@@@@@@Z  ЅрOџ @@@@@@@^x рџ> @Kpрџ>  N0рџ  LИ l@ @@r$rИ`џ Y@@@vu  l@@@sŒs Јl@ @@r$rЈl@@@p”p€Јl@@@sŒs И`џ Y@@@w€ Аl@@@p”p€Аl@@@sŒs Иl@ @@r$rИl@ @@p”p€Иl@@sŒs Иl@@@kp€Иl@ !@@€дs Иlh  @@@rˆrtИlш @@@@@rˆrtр @! Pр @! IРр @!@Uœ§р !N@@@f пР @ @=PпР @ @7пР @@@CpР @!@@@PИl@0(7@r$r§р !@0(7@f пР @0(7=Pр @0(7@PР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРИdoџ x  @rН Иhџ x@rъ И`яџ+ x@r„ Р@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРрџ > T@рџ > Mpрџ > MШрџ > I№рџ >  NАР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРР@@@@@@@@IРРџ@@@@@@@@IР `Oџ @@@@@@@qI Рџ@@@@@@@@IРРџ@@@@@@@@IРрџ N @M(рџ N @R`рџ  @UPрџ  @UTрџ  @UXрџ  @U\рџ  @U`рџ  @Udрџ  @Uhрџ  @Ulрџ  @ Upрџ  @Utрџ  @Uxрџ  @U|рџ  @U€рџ  @U„рџ  @Uˆрџ  @UŒрџ  @Uрџ  @U”рџ  @ U˜рџ  @U”рџ  @U˜рџ  @Uœрџ  @Uрџ  @Uрџ  @Uрџ  @U рџ  @Uрџ  @Uрџ  @Uрџ  @U$рџ  @ U(рџ  @U0рџ  @U4рџ  @U8рџ  @U@рџ  @UDрџ  @UHрџ @@@@@L@рџ@@Lдрџ@@@@@M@рџ @ @Lфрџ@O QАрџ@"@Q0рџ@@Rxрџ@ @Nррџ @@L№рџ @Lарџ @Mрџ @M0рџ @LАрџ @LДрџ @LИрџ @LРрџ @Lирџ @Lррџ @Lшрџ @LьРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРРџ@@@@@@@@IРEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCcџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Retevis_RT16.img0000644000175000017500000000600514411666130017341 0ustar hibbyhibbyPb%FPb%FџџџP‡%FP‡%FџџџP&FP&FџџџP7&FP7&FџџџPb&FPb&FџџџP‡&FP‡&FџџџP'FP'FџџџPbuFPbuF&&џџџP‡uFP‡uFџџџPvFPvFџџџP7vFP7vFџџџPbvFPbvF  џџџP‡vFP‡vF  џџџPwFPwFџџџP%FP%Fџџџu%Fu%Fffџџџ&F&F88џџџ%&F%&FџџџP&FP&F&&џџџu&Fu&FWWџџџ'F'Fccџџџ%'F%'FџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџˆџџџџџџџџџџџџџџџџPb%FPb%FџџџџP‡%FP‡%FџџџџP&FP&FџџџџP7&FP7&FџџџџPb&FPb&FџџџџP‡&FP‡&FџџџџP'FP'FџџџџPbuFPbuFџџџџP‡uFP‡uFџџџџPvFPvFџџџџP7vFP7vFџџџџPbvFPbvFџџџџP‡vFP‡vFџџџџPwFPwFџџџџP%FP%Fџџџџu%Fu%FџџџџvFvFџџџџ%vF%vFџџџџP&FP&Fџџџџu&Fu&Fџџџџ'F'Fџџџџ%'F%'FџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDE2IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMTA1MjAiLCAicmNsYXNzIjogIlJldGV2aXNSVDE2IiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_FT-1802M.img0000644000175000017500000001751314411666130017336 0ustar hibbyhibbyAH023џџџџџџџџџџџџџџџџџџReРџџџџџџReРџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..#7РDˆџџџџџџџџџџџџџџџџџџџџ e џџџџџџ€R€  џџџџ gџџ €e…џ.ѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ e џџџџџџ€R€  џџџџ gџџ €e…џ.ѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $ $ $ $ $ $ $ $e Рџџџџџџ Ruџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@3АГЛ3;333 3333333V@Рџџџџџџ Q`Рœ  QuР„!  a5И џb@Р™ џ 0UС``RР–R Р &R5Р— џџReР &R€Р—  R•Рœ uР– џџU5РЂ  TСœ @UСœ WС•  WUР” b@С–  8Рџџ0UС!U0IeС” $џ9•7UС” $џQuС” $!0V@С™ $ G0IPС™ $0AEР™ ‘eР $  IРœ  HEРœ  QР  bР  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`Р”џџ0Р”џџ`Р”џџР” џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 0ReТœ &џ7@ ReСœ &џ RСœ &џ C…Т Q`С– џџџ Q`С—џџџ ˆ5Т• &  S@СŽ$џ ƒPР›$  0cPС›$iP cPС›$ TuС— џ UeТ• & 0Q0Т• &G 0VpУ• &‘P R5С– $џ!џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџh Сџџџџџџ g@Рџџџџџџ S0Aџџџџџџ!TPAŠ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџchirp-20240224/tests/images/TYT_TH9000_144.img0000644000175000017500000004000014411666130017111 0ustar hibbyhibbyЅЅ0ŠŠТyd=­АPTH-9000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџТџџџџџџџџџџџџџџџџџџџџџџџџџџџџТџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  6t6tGP  2d‘ A$H:3 d ‘$AyOж2d ўџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџ џkk6dfI†‘ A$4^GP`  W6SRR G` W6CX G`  AD6KV E#`  N6NFI E!`  WA6SEK FR2MCALL FAP2S6.415FPP2S6.505GE 2S7.450GUP2S7.555GP`  STOCK1 FqP` )W6SUV F…` WA6EWV G$` NR7A E` N6ICW Q‚MURS1 QˆMURS2 Q”MURS3 TWBLUEDOTT`GRENDOTb@NOAA1 bBPNOAA2 bENOAA3 bGPNOAA4 chirp-20240224/tests/images/Kenwood_HMK.hmk0000644000175000017500000001663514411666130017266 0ustar hibbyhibbyKENWOOD MCP FOR AMATEUR MOBILE TRANSCEIVER [Export Software]=MCP-2A Version 3.02 [Export File Version]=1 [Type]=E [Language]=English // Comments !!Comments= // Memory Channels !!Ch,Rx Freq.,Rx Step,Offset,T/CT/DCS,TO Freq.,CT Freq.,DCS Code,Shift/Split,Rev.,L.Out,Mode,Tx Freq.,Tx Step,M.Name "900","00155,500000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","155,500000","025,00","MVHF L1" "901","00155,525000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","155,525000","025,00","MVHF L2" "902","00155,625000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","155,625000","025,00","MVHF F1" "903","00155,775000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","155,775000","025,00","MVHF F2" "904","00155,825000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","155,825000","025,00","MVHF F3" "905","00156,300000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,300000","025,00","MVHF K06" "906","00156,375000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,375000","025,00","MVHF K67" "907","00156,400000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,400000","025,00","MVHF K08" "908","00156,425000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,425000","025,00","MVHF K68" "909","00156,450000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,450000","025,00","MVHF K09" "910","00156,475000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,475000","025,00","MVHF K69" "911","00156,500000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,500000","025,00","MVHF K10" "912","00156,525000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,525000","025,00","MDSC K70" "913","00156,550000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,550000","025,00","MVHF K11" "914","00156,575000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,575000","025,00","MVHF K71" "915","00156,600000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,600000","025,00","MVHF K12" "916","00156,625000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,625000","025,00","MVHF K72" "917","00156,650000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,650000","025,00","MVHF K13" "918","00156,675000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,675000","025,00","MVHF K73" "919","00156,700000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,700000","025,00","MVHF K14" "920","00156,725000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,725000","025,00","MVHF K74" "921","00156,750000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,750000","025,00","MVHF K15" "922","00156,800000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,800000","025,00","MVHF K16" "923","00156,850000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,850000","025,00","MVHF K17" "924","00156,875000","025,00","00,000000","Off","88,5","88,5","023"," ","Off","Off","FM","156,875000","025,00","MVHF K77" "925","00160,625000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,625000","025,00","MVHF K60" "926","00160,650000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,650000","025,00","MVHF K01" "927","00160,675000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,675000","025,00","MVHF K61" "928","00160,700000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,700000","025,00","MVHF K02" "929","00160,725000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,725000","025,00","MVHF K62" "930","00160,750000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,750000","025,00","MVHF K03" "931","00160,775000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,775000","025,00","MVHF K63" "932","00160,800000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,800000","025,00","MVHF K04" "933","00160,825000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,825000","025,00","MVHF K64" "934","00160,850000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,850000","025,00","MVHF K05" "935","00160,875000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,875000","025,00","MVHF K65" "936","00160,925000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,925000","025,00","MVHF K66" "937","00160,950000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","160,950000","025,00","MVHF K07" "938","00161,500000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,500000","025,00","MVHF K18" "939","00161,525000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,525000","025,00","MVHF K78" "940","00161,550000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,550000","025,00","MVHF K19" "941","00161,575000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,575000","025,00","MVHF K79" "942","00161,600000","025,00","04,600000","Off","88,5","88,5","023","-","Off","Off","FM","161,600000","025,00","MVHF K20" "943","00161,625000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,625000","025,00","MVHF K80" "944","00161,650000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,650000","025,00","MVHF K21" "945","00161,675000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,675000","025,00","MVHF K81" "946","00161,700000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,700000","025,00","MVHF K22" "947","00161,725000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,725000","025,00","MVHF K82" "948","00161,750000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,750000","025,00","MVHF K23" "949","00161,775000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,775000","025,00","MVHF K83" "950","00161,800000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,800000","025,00","MVHF K24" "951","00161,825000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,825000","025,00","MVHF K84" "952","00161,850000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,850000","025,00","MVHF K25" "953","00161,875000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,875000","025,00","MVHF K85" "954","00161,900000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,900000","025,00","MVHF K26" "955","00161,925000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,925000","025,00","MVHF K86" "956","00161,950000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,950000","025,00","MVHF K27" "957","00161,975000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","161,975000","025,00","MAIS K87" "958","00162,000000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","162,000000","025,00","MVHF K28" "959","00162,025000","025,00","04,600000","Off","88,5","88,5","023","-","Off","On","FM","162,025000","025,00","MAIS K88" chirp-20240224/tests/images/Yaesu_FT-4XR.img0000644000175000017500000002076114411666130017243 0ustar hibbyhibby4123џџџџџџџџџџџџC Ш` ` @ P ` p €    bp E Ш     C Ш`  P @ C Ш P X0 C Ш  CHAN1 aAd123 4L C`@Qaq bpEKM6YCR---.0-1234123456------------------------------------------------------------------------------------------------------------------------------------------+Х-GP Ш  P@џchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQtNFhSIiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIllhZXN1RlQ0UmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Wouxun_KG-UV9GX.img0000644000175000017500000010041114430171343017704 0ustar hibbyhibbyІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІ000000џџ000000џџKG-UV9GX 8  Ќ–X&„Ž ФPЬ PЬ8P џџџџџџџ>HR\fpz„Ž˜ЌРдш#-7AKZdnx‚Œ– ЅІІІІІІІІІІІІІІІІcWK=3/-*.1œ—ŒˆŠŠ”šЧХТСІЃІВХЭІІІІІІІІІІІІІІІPG<<62($*+0}wqhb[XXSQSTW_`мммммммммммммммІІІІІІІІІІІІІІІІ8  Ќ–X&„Ž ФP PІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІfpz„Ž˜ЌОд&0:DS]gq{…™ЃІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІqsuwy{}ƒ…‡‰‹‘“•—јјІІІІІІІІІІІІІІІІІІІІп’`шШСۘшШІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІшHишаЈŠРшаРС,€СUАРІІІІІІІІІІІІІІІІџџ  Ъч 8&zP%  №№џџџџџџџџ(<PZBetterSafeRadio ІІІІІІІІІІІІІІІІWOUXUN20220609ИЃНЈЪЁШЊжнЪа000000B4_PX3.0deШЩ ,-‘єѕМН !RSдџџџџџџџџGMRSMUMMS-CGHAMSATRACINGAM-AIRLMRISRSHTFMDCORDLSMARSCAAARAILІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІСаzџџџџHќСк>џџџџHќСфџџџџHќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІGMRS 1GMRS 2GMRS 3ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAќќќAќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќAќAќAAAAAAAAAAAAAAAAAAAAAAAAќќAAAAќќќќќAќќќќќќќќќќAAAAAќќќќќAќAAAAAAAќAAAAќќAAAAAAAAAAAAќќќќќќќќќќќќAAAAќќќќќќќќќќќAAAќAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAќAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAќAAAAAAAќAAAAAAAAAAAAAAAAAAAAAAAAAќAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAќAAAAAAAAAAќќAAAAAAAAAAAAAAќќAAAAAAAAAAAќќќAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAќќќAAAAAAAAAAAAAAAAAќќќAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAќAAAќќAAІІІІІІІІІІІІІІІІІІІІІІІІ  №№  №№  №№  №№  №№  №№  №№  №№ №№ №№ №№ №№ №№ №№ №№ №№ №№ №№ №№ №№U 101џџU 102џџU 103џџU 104џџU 105џџU 106џџU 107џџU 108џџU 109џџU 110џџU 111U 112U 113џџU 114џџU 115џџU 116џџU 117џџU 118џџU 119џџU 120џџ  !"#$%&'()*+,-./0123456789:;<=>?ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІџchirpюimgeyJtZW1fZXh0cmEiOiB7IjAwMDFfY29tbWVudCI6ICIiLCAiMDAwMl9jb21tZW50IjogIiIsICIwMDAzX2NvbW1lbnQiOiAiIn0sICJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIldvdXh1biIsICJtb2RlbCI6ICJLRy1VVjlHWCIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Yaesu_FT-817ND_US.img0000644000175000017500000001477314411666130020004 0ustar hibbyhibbyЮП€Р ,R–ВBˆe2HВ…Й22222%`€ 'џџџџџџџџ`€Кh'џџџџџџџџ`€ шќ'џџџџџџџџbHB@'џџџџџџџџa€z 'џџџџџџџџaHw@'џџџџџџџџa€ YЄ'џџџџџџџџaH%bP'џџџџџџџџa€+G'џџџџџџџџa €QŸP'џџџџџџџџEO†GџџџџџџџџDƒˆ‚( Им8ъ`џџџџџџџџE„ˆ‚( рН4ъ`џџџџџџџџAN РЁ џџџџџџџџa3:'џџџџџџџџbHП 'џџџџџџџџ`HW0'џџџџџџџџ`H Ў`'џџџџџџџџbHB@'џџџџџџџџaH\Р'џџџџџџџџaHw@'џџџџџџџџaH 'џџџџџџџџaH%bP'џџџџџџџџaH*Й€'џџџџџџџџAHLK@† џџџџџџџџEO†GџџџџџџџџDKЄЫ€џџџџџџџџAHлКъ`џџџџџџџџAN РЁ џџџџџџџџdHу`'џџџџџџџџeH-*€'џџџџџџџџEHP%”† џџџџџџџџEHп’`ъ`џџџџџџџџENЈŠРЁ џџџџџџџџE„ˆ‚( рН4ъ` џџџџџџџџџџџџџџџџџџџџџџџџџџ`H Ў]' П  @LK@ReРЫџџ…Єˆ‚( рН4Canton2m…Єˆ‚( рk,ъ`Peoria2m…dˆ€( рB(ъ`146.970 …Ѕˆ( І˜ДЁ Canton70…ˆ€(Іцд444.925 …ˆ€(Јmt445.925 Нˆы мRXAPRSVA …ˆмRXAPRSNONEEHсд€ъ`џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџaHтŽ'џџџџџџџџ" $$yˆ‚( рН4ъ`џџџџaH"а'џџџџџџџџaH)'џџџџџџџџaH0р'џџџџџџџџaH2д'џџџџџџџџaH?T'џџџџџџџџaH"а'џџџџџџџџaH)'џџџџџџџџaH0р'џџџџџџџџaH2д'џџџџџџџџaH?T'џџџџџџџџchirp-20240224/tests/images/Wouxun_KG-935G_Plus.img0000644000175000017500000010031114411666130020455 0ustar hibbyhibbyннннннннннннннннŸЉ<ннннннннннннннннннннннннннннннннннннннннннннџbZмkbZмkЯ… fЯ… f н<šнннннннннннннннн  !bZЯ…ннннннннннннннннннžЂЂЊЌЌЌЌДДДД„МР"/8@;>FLQRei_a"+2Ск>!СфСф!СэЦСэЦ!СїŠСїŠ!ТNТN!Т Т !ЩqšЩqš Щ{^Щ{^ Щ…"Щ…" ЩŽцЩŽц ٘Њ٘Њ ЩЂnЩЂn ЩЌ2ЩЌ2 СۘСۘ!Се\Се\!Сп Сп !СшфСшф!СђЈСђЈ1СќlСќl!Т0Т0!ТєТє!СۘЩlИ!Се\Щv|!Сп Щ€@!СшфЩŠ!СђЈЩ“Ш!СќlЩŒ!Т0ЩЇP!ТєЩБ!џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS-01GMRS-02GMRS-03GMRS-04GMRS-05GMRS-06GMRS-07GMRS-08GMRS-09GMRS-10GMRS-11GMRS-12GMRS-13GMRS-14GMRS-15GMRS-16GMRS-17GMRS-18GMRS-19GMRS-20GMRS-21GMRS-22RPT-15RPT-16RPT-17RPT-18RPT-19RPT-20RPT-21RPT-22џџџџџџџџџџџџџџџџžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJLRzkzNUdQbHVzUmFkaW8iLCAidmVuZG9yIjogIldvdXh1biIsICJtb2RlbCI6ICJLRy05MzVHIFBsdXMiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMwMjA2In0=chirp-20240224/tests/images/Baofeng_UV-17.img0000644000175000017500000011025614531336265017356 0ustar hibbyhibbyч%a`D%2Eџџџџ!%–aD%!E““%`D%`D  !%2Eu`D “!%CE%CEee1%TE%TEA%eE%eE((Q%vE%vE$$a%‡E%‡E%€%€q%˜E%˜E44%F%Ft‚t‚‘%"F%"FFƒFƒЁ%3F%3F……Б%DF%DFsРsРС%UF%UFЧЧб%"@%"@џџџџс%tC%tCџџџџёu™Gu™GџџџџP…P…џџџџPvPvџџџџP'P'џџџџ…C…CџџџџWWџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%!E%!E““џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&џџџџџџџџџџџџџџџџџџџџ@R`@3џџџџџџџџџџџџџџџџџџџџџџџџh џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџUV-17џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjE3IiwgInZlbmRvciI6ICJCYW9mZW5nIiwgIm1vZGVsIjogIlVWLTE3IiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Yaesu_VX-8GE.img0000644000175000017500000017731314411666130017243 0ustar hibbyhibbyAH041џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџ CEPџџџџџџџџџџџџџџџџ џџџџ @€ ˆ4D”%P  F %2832џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ# ЈТŽЈџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€УџџџџџџD€УџџџџџџDџџџџ @џџџџџџџџџџџџџџџџ p@@€ Wџџџџ @џџџџџџџџџџџџџџџџ p@@€ W џџџџ CPџџџџџџџџџџџџџџџџ BGC€ @ џџџџ CPџџџџџџџџџџџџџџџџ BGC€ @Уџџџџџџ@€ ЉУџџџџџџ@€ Љџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ  џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ@@€@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @@€@@€G€Рџџџџџџџџџџџџџџџџ e Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ D`РџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ @@€@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @@€@@€G€Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ CРџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ @@€@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @@€@@€G€Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ CРџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУУУƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒ@Рџџџџџџџџџџџџџџџџ D`Р $ %00џџџџџџџd Р$6)4џџџџџџџџџDd Р $6)4џџџџџџџPCР џџџџџџџџџџџџh Т F 37832џџџџRР  F 37832џџџR0С  F 37832џџџџ D5PТ  F 37832џџџџPSТ  F 37832џџџџ DGТ F 37832џџџџP D5PТ  F 37832џџџџџPDxuТ F%60&3639+,P D"PТF3;)00џџџџPDvuТ  F%8-'/џџџP( DIbТ  F3;)00џџџP!gТ F 960-2+832 D0PТ F %08,%1џџџPgТ F )7832џџџџџDuuТ F 32'36(џџџPQТ F%0)1џџџџџDfuТF%60&3639+,PQ€Р F ,)017*36(џ DAТF368,$ 2(3P sEТ!F)44)6)00џ  D)С!F)44)6)00џP D˜%ТF 3&962џџџџPCРџџџџџџџџџџџџџџџџ Dp%Т   F 960-2+832PD‘%С   F%8-'/џџџџP q Т  F -00)6-'%џџ DguТ  "F 960-2+832P qPС "F6%1-2+,%1џ D€%Т "F34/-2832џџP  s`Т F);832џџџџf@Т F %08,%1џџџDuС F %08,%1џџџPT0Т  F )01328џџџ rpТ  F%60&3639+D™%Т  F%60&3639+P D'Т  F )7832џџџџP p0С #F);832џџџџ DFТ #F);832џџџџP D'PТ F);832џџџP r@С F%60&3639DuТ  F6%1-2+,%PDe%Т F)%(-2+џџP puС F %/)*-)0(iUТ F )78*36(џ@CРџџџџџџџџџџџџџџџџ  D%С F 6%-286))џPgEТ  F %2832џџџџD”%Т  F %2832џџџџPheТ !F,%632џџџџ i…Т  F 633/0-2)џh•СF %0430)џџџ pС F 6)28,%1џџ DDPТ F 6)28,%1џџPD…uС F 6)28,%1џџP pТ  "F3<&3639+ sР F )=1398,џџ DТF)(*-)0(џџPfpТ  F9-2'=џџџџDc%Т   F 633/0-2)џP rТ F36;33(џџџ  p`Р F)(;%=џџџџџD‰uС # F %0430)џџџP Dd7С F %0430)џџP Dd7С F %0430)џџDruСF%:)6,-00џPf%ТF $);&96=џiТF%9+97џџџџRТ  F$ 2(3:)6DcuС F%;6)2')џP SPСF%:)6,-00џџfUТ! F%;6)2')џџ D$ТF=22џџџџџџPTpТ F %2:)67џџџ D(С F %2:)67џџџPh€Т F%0)1џџџџџDf%Т F%0)1џџџџџPh5Р  F 2(3:)6џџџ pТ  F=22џџџџџџ DFPТ  F=22џџџџџџP Q0Т F039')78)6TТ F47;-',џџџS0Т !F=22џџџџџџ D&PТ !F=22џџџџџџP Du%С  F039')78)6P D7Р F039')78)6џP r…Т "F347*-)0(џ  sР  F ):)60=џџ D(PТ  F ):)60=џџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ q•ТF 880)&363џ q5Т F%92832џџџDyuТ F$ 880)&36PDi%Т F%27*-)0(P S Р F;%27)%џџQТ  F);$ )(*36hТ F%00$-:)6џ pТ   F %681398,џTТ  F%-6,%:)2џQPТ   F%00$-:)R€Р F%92832џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ DEPТ " F 6-(+);%8P sТ"F0=1398,џџSТ##F%67,*-)0(f…Т  F0=1398,џџ D6Т F36;)00џџџџPguУ F $ 6-(+;%8)' q€Т F 6-(+);%8 r%Т F ,-81%2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDs%СF$%78,%1џPiUТ F )22-7џџџџfUТF%01398,џџџ suТ"F%01398,џџS`Р F%78,%1џџџџg0Т F %6278%&0)RpТ "F%6;-',џџ rUТ "F6963џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџfТ  F)2(32џџџџџ rUС F<*36(џџџџ rТF %66)2џџџџ D9Т F 9&962џџџџP D%Т F 9&962џџџџP DС F368,&3639P DIТ  F )78$-00P Dy%С F398,&363P sР F<&6-(+)џџD„uР F%6:%6(џџџP D#Т F 0-2832џџџP D3Т#F 36')78)6џP 0d€Т F 36')78)6џI€D˜uТ F 36')78)6џP  sТ F 8,30џџџџџџ fUТ##F 0-2832џџџipТ  F%<832џџџџD•uТ  F398,&3639PQ@Р  F30-7832џџTТ   F%6:%6(џџџRpР  F398,&3639SpТ  F%6(2)6џџџ D!С  F%6(2)6џџџPTPТ #F-8',&96+џџSТ  F 36')78)6џ D%С  F 36')78)6џPDy‡Т !F%<832џџџџPi%Т "F 36')78)6џџ Dh%Т F-0*36(џџP  sТ  F-8',&96+  D)PТ  F-8',&96+PDrТ F -2',)2(32џPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGCr%РџџџџџџџџџџџџџџџџP g`Т  F8$ 7'982)  D@С F 8$:6$'8PD%С  F8$ 7'982)P pС F%60&363џџ  pС !F);*%2)џџ DPС F 8,)27џџџџP DGТ !F);*%2)џџPSТ #F8$59-23 h5РF,%*87&96=џ D@PТ  F8$59-23P h€С  F-00-2+832pEТ  F980%2(џџџ  DDР  F980%2(џџџP DEТ  F980%2(џџP DEPТ  F-00-2+832P DHuС  !F)2(32џџџP D‘uС #F980%2(џџP GCuРџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ppРџџџџџџџџџџD`Р $ %00џџџџџџџD`Р $ %00џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФџџџџџџ4z?BYYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******CQ*******QST******YAESU****џџџџџџџџџBLN******BLN*џџџџџBLN*џџџџџFxx  xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:A?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЄf bЌ`–„b”Ђ‚ђЎbšЄ‚@`Ў’ˆŠd@с№`cH!l+ok/`"5U}147.225MHz T156 +060_" мЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈf ІpАр–†b„žІd–„bЈІž`Ў’ˆŠd@с№`c.PnTi>/"5{}TinyTrak4 Mobile`CL-IN DIGI FALMOUTH MA лщџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЄЈЈjЊрœf˜ŠŠ@~–„bЈІž`Ў’ˆŠd@с№`c9Xl#5>/"4U}/TinyTrak4 чџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœрœbš’Ў@bЎdˆ‚œ@|Ў’ˆŠd@с№@122116z4139.23N/07134.69W_227/001g002t022r000p001P001h59b10180/fWDpartlycloudyNew WX station as of 4-9-2014 - Davis VP2 Т<џџџџџџџЈdЂЈdЈ`œbžД@`ЎbšЄ‚@`Ў’ˆŠd@с№'cN]l -/ѕ„ Alphaь9 AlphaZ•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЊdjœрЎb”Ј@@`Ўb†˜‚@тџџˆŠd@№ ™}Monitoring 146.535 Simplex_" ќшџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЄЂЌ`А`–„b˜žВђЎb†˜‚@bЎ’ˆŠb@р№'c9vl >/]James in Ashland, MA = б%" ŸQџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЎЎb`р–„bЈІž`Ўb†˜‚@тџџ†˜‚@т№@214232h4242.77N/07113.26W#PHG73604 / iGate/Digi Methuen MAСџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„Š‚†žœ`Ўb‚І@bЎb†˜‚@bЎ’ˆŠd@с№!4136.79NS07056.62W# Fill-in/MAn-n APRS Digi Dartmouth MA ЛЁ™џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЎЎb`р–„b†ЊzЎb†˜‚@тџџˆŠd@с№@215053h4204.95N/07041.11WWMarshfield W/X @KB1CHU.COMїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЊdjœрЎ‚b”ІŠbœbЄ†Ў@fЎ’ˆŠd@с№=4138.92N/07023.07W-Wide 1-1 Fill in Digi Paul in Osterville {UIV32} $Bџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„Š‚†žœ`œpЌ’š@`ЎbšЄ‚@`Ў’ˆŠd@с№!4240.85N/07133.99W_PHG72604/ Pepperell, MA. WX. 442.9+ PL100 Yрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœр–bЄЈ‚@b–b†––@dЎ’ˆŠd@с№@122048z4154.23N/06959.62W_000/000g000t024r000p000P000h70b10201 WX STATION AND DIGI {UIV32N} œyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpf`œbœ†’@fЎbšЄ‚@`Ў’ˆŠd@с№!4302.00NN07222.04W#HG5530/CCDX Club Repeater, www.ccdx.org sŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЎЎb`р–bЄ’@@`Ўdˆ‚œ@|Ў’ˆŠd@с№>122141zAPRSISCE/32љ.9.38WrPHG3640 www.K1RI.comр, MA {UIV32N} 9џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЊdjœрœbЄ–@`ЎbšЌ@@bЎ’ˆŠd@с№@122046z4133.95N/07129.60W_248/005g007t024r000P000p000h68b10173wU2100 {UIV32N} џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠ†hЄf рŽbЈŒ’@n–„bЈІž`Ў’ˆŠd@с№`c`@n*,[/`"42}W2/G1TFI_ 1$е_% Еs, NH= к–55.06N 07057.33W н#џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„Š‚†žœ`ЎbšЌ@@bЎb†˜‚@тџџˆŠd@с№!4159.21NS07057.60W# W2 MAn-n Digipeater Bridgewater MA. *tџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpd`Ўdˆ‚œ@|ЎbšЌ@@bЎ’ˆŠd@с№!4150.45NL07140.18W#PHG7560/RIAFMRS DIGI - w2dan@arrl.net жRџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpd`Š–žœ†Ј`Ўbš˜@`Ў’ˆŠd@с№!4139.83NS07150.95W#PHG7560/W3,CTn SECT W1SP Птh42b10183TU2kжїџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЊdjœрœbЄ–@~ЎbšЌ@@bЎ’ˆŠd@с№/'"5!}|!#&D'3|!wQJ!|3mёN Digi/Igate - XASTIR-TNC-PI w7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpf`Ў‚dŽЊŽ~Š–žœ†Ј`Ў’ˆŠd@с№!4234.186N/07403.002W#PHG5360 Green County ARES Cairo,NY wa2gug@arrl.net LvџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЂЄАr `œbŠІ‚@рЎdˆ‚œ@|Ў’ˆŠd@с№`d_wl##-/]"47} Nyg@arrl.net 01060F 14.0V/A=000125rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpf`œbЄ†Ў@hЎb†˜‚@bš‚d@@@с№!4136.68N107036.53W#WIDE1-1 FILL-IN DIGI FALMOUTH MA Я wa2gug@arrl.net ЊIџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœрœbš’Ў@`Ўdˆ‚œ@|Ў’ˆŠd@с№>122116zDX: EKONCT 41.39.83N 71.50.95W 14.0 miles 273ј 16:07 ~~џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЄ`Њ`І`œbДДœ@ђЎbšЌ@@bЎ’ˆŠd@с№`cZymRyk/`"4K}_% ,I#RI Digi/Igate-w2dan@arrl.net UGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈdЄЂlІ`–†b‚”ЈrЎbš˜@`Ў’ˆŠd@с№`c,4p?f>/'"4A}MT-RTG|!6%i'U|!wL>!|3їux +џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœр–†b–š@b–b†––@dЎ’ˆŠd@с№>052346zUI-View32 V2.03 ѓqBeacon From Harwichport, MA {UIV32N} 9џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠ„hЄdІ`Ў‚bЎ††р–b†––@dЎ’ˆŠd@с№'aVrl y/]WCC SPCL EVENT 4/18 CK QRZ FOR DETAILS= ВqџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЂЈВfЄ`–‚b†ЂˆьЎbšЌ@@bЎ’ˆŠd@с№`c1.nRk>/]"4,}= /tV 60.8F X|(c!(-1$e!'|Љkџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpd`Ўbš˜@`Ўb†˜‚@тџџˆŠd@№!4223.32N/07115.23W#PHG3640/Waltham Amateur Radio Association - N1OMJ Digipeater NoW1 мџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЊdjœрЎ‚b”ІŠbœbЄ†Ў@fЎ’ˆŠd@с№;K1PBO-R *121300z4144.03N/07011.00WmBARC Rptr PL 88.5 -Offset у џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈd ЈrІ`–„b†ЊђЎb”Ј@@`Ў’ˆŠd@с№`bE&l u\`"4;}Steves F-150_" uЦџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ‚ŽЎ@`œbДДœ@`Ўb†˜‚@bЎ’ˆŠd@с№@121648z4204.72N/07053.70W_187/000g002t023r000p000P000h51b10159 Hanson, MA WX/Digi9џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈdІЎbВрœbЈ„œ@r–„bЈІž`Ў’ˆŠd@с№`c0<"+#k/]"46}444.100MHz=ВX,Ma. {UIV32N} KGateway. Visit http://smsgte.wix.com/smsgte$яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈdЈЄnЂ`‚„bž†@єЎbšЄ‚@`Ўb†˜‚@т№'c?El -/]PHG7260 iGate in Hollis, NH= ­ICE!!W60!  Н.33W Чllis, NH!W60! Н+џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpd`ЎbšЄ‚@`Ўb†˜‚@тџџˆŠd@с№!4220.74N/07134.04W#PHG2430/MMRA MRW Digipeater NoW1 љџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œА`b`Ў‚b ˜Š~Ўb†˜‚@тџџˆŠd@с№!4205.70N/07116.75W#PHG7550 W2, MAоiury-XASTIR/fedora 22aКџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЄІЄpАр–„bˆˆ†`–„bЈІž`Ў’ˆŠd@с№'c&*l -/]xˆ01.27Wj000/000/A=000018Russ listening 146.955, 147.255 еЋџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈf`рœf˜ŠŠ@шЎbš˜@сџџ№!4224.15N/07147.64W# 13.9V N3LEE W Boylston-Nashoba Valley DigiПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈdЄ rІ`–„b˜œ‚`Ўbš˜@`Ў’ˆŠd@с№`c&onf,v/'"4T}|!(&8';|!w3g!|3`?9!|3KŠџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Јfbb`Ўb”š†@hЎb†˜‚@bš‚d@@@с№$GPRMC,215522,A,4228.2205,N,07128.9908,W,000,000,280696,,*02АЯ5\/Nikki's WX Stn {UIV32N} ЏVџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpf`–b†––@dЎb†˜‚@bš‚d@@@с№!4145.79NS06959.43W# W2,MAn APRS DIGI ORLEANS MA <оџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„Š‚†žœ`Ўb ’ˆ@`Њœ†‚œ@`Ў’ˆŠd@с№w1pid APRS Digipeater ЪJ/001g004t024r000p000P000h24b10170чHnџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p`‚‚‚‚‚‚рЎ’ˆŠb@bџџ№:BBBBBB :1{80 ЈљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p`‚‚‚‚‚‚рЎ’ˆŠb@bџџ№:BBBBBB :1{81 pрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p`‚‚‚‚‚‚рЎ’ˆŠb@bџџ№:BBBBBB :1{57 пKџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџ‘chirp-20240224/tests/images/TIDRADIO_TD-H3.img0000644000175000017500000002026114534315077017211 0ustar hibbyhibbyP31183џџџџџџџџџџџџџџџџџџ%a%aџџџџ%!F%!FџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџТE-…@Bџџџџџџџџџџџџџџџџ`@@Rџџџџџџџџџџџџџџџџџџџџ1111џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP`P`џџџџP@P@џџџџ‰џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Welcome TD-H8 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ-222-9}}x‚‚‚‚x‚‚‚‚‚‚‚‚џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ…XџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJUREgzIiwgInZlbmRvciI6ICJUSURSQURJTyIsICJtb2RlbCI6ICJURC1IMyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Retevis_RB18.img0000644000175000017500000000340114411666130017316 0ustar hibbyhibbyPb%FPb%Fpp џџџP‡%FP‡%Fˆˆ џџџP&FP&Fss џџџP7&FP7&F џџџPb&FPb&Fee џџџP‡&FP‡&F џџџP'FP'Fbb џџџPbuFPbuFC‚C‚џџџP‡uFP‡uF2€2€џџџPvFPvFG€G€џџџP7vFP7vFQ€Q€џџџPbvFPbvFS€S€џџџP‡vFP‡vFe€e€џџџPwFPwFџџџP%FP%F00 џџџu%Fu%FCЧCЧ џџџ&F&F2У2У џџџ%&F%&Fss џџџP&FP&FCТCТ џџџu&Fu&F†† џџџ'F'F1Ч1Ч џџџ%'F%'Fee џџџP%P%џџџџ џџџ$$џџџџ џџџu$u$џџџџ џџџ%$%$џџџџ џџџ™I$™I$џџџџ џџџ%%џџџџ џџџ%%%%џџџџ џџџPPџџџџ џџџuuџџџџ џџџu2u2џџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџї3103PџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjE4IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMTEwMTYiLCAicmNsYXNzIjogIlJCMThSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Retevis_RB23.img0000644000175000017500000000170514411666130017317 0ustar hibbyhibbyPb%FPb%Fžž P‡%FP‡%FЄЄ P&FP&Fљљ P7&FP7&F&& Pb&FPb&FUU P‡&FP‡&F…… P'FP'FЖЖ PbuFPbuFЃ(Ѓ(P‡uFP‡uF((PvFPvF'('(P7vFP7vF)()(PbvFPbvF+(+(P‡vFP‡vF5(5(PwFPwFN(N(P%FP%FЮЮ u%Fu%FуЉуЉ &F&FкЈкЈ %&F%&Fљљ P&FP&FЃЈЃЈ u&Fu&F†)†) u&'F'FйЉйЉ F%'F%'FUU P%FPuFUU u%FuuFUU &FvFUU %&F%vFUU P&FPvFUU u&FuvFUU 'FwFUU %'F%wFUU 0џџџџ282626џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000џchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjIzIiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIkR5bmFtaWNSYWRpb0FsaWFzIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_FT-8800.img0000644000175000017500000005331114411666130017222 0ustar hibbyhibbyAH018$A$G@ Р„Hb@€@ ДA`!":Њџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒ™™џџџџџџџџџџFU Р@ € Y @€@…  Р˜@ €™ „'Q@€@HP† џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD РP@ €P 0P @€@P D РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0џџџџџџџџџџџџџџџџD РP@ €P 0P @€@P D РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0џџџџџџџџџџџџџџџџD РP@ €P 0P @€@P D РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0џџџџџџџџџџџџџџџџD РP@ €P 0P @€@P D РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„8‚DE@€@џџџџџџџџџџџџџџџџ0џџџџџџџџџџџџџџџџD РP@ €P 0P @€@P D РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€E P @€@0џџџџџџџџџџџџџџџџD РP@ €P 0P @€@P D РP@ €P 0P @€@P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€P @€@0џџџџџџџџџџџџџџџџ‚F”Ž€ Ь$€FRР€GUŽ€  ф$€GUŽ€  ф$R$$$$ф$bEŽ€ Ь$€FF $$$$ф$€F $$$$ф$€F $$$$ф$€FF Р‚EŽ€ $ф$€D0X@€@ƒG $$$$ф$F Р‚H%Y @€@‚„IBY@€@‚„IYŒ@€@D РD РD РD РD РD РD РUV РTi РT РTw РUG РT( РT@ РTD РT€ РU РUY РUI РT РT# РT7 РU" РU& РQ РG0X@€@G0X@€@D Р‚Fˆ Р‚FY @€@D РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD Р‚I0RŽ€1V›J1‚IRŽ€ŒJ ‚I@QŽ€N‹]‚„IWQ”€ [P‚GQŽ€ aN‚GQŽ€ J“X$‚IQŽ€ Ud$‚IQ @Š[GPQŽ€ @Š[‚IPQŽ€ UL‚GQŽ€W•P‚G Q”€ [X‚I€QŽ€ _’U$‚G5Q@€@I@Q@€@I0RŽ€1V›J1‚„IBR$$dЄd$‚„IQ $$dЄd$‚H%Q $$dЄd$G@Q@€@„HgQ@€@HuQ @€@„HgQ@€@0P @€@ƒ„BWQ”€ ]ž[€„BWQ”€ ]\€I0Q$$dЄd$I0Q$$dЄd$0P @€@‚G@Q@€@‚„HgQ@€@‚HuQ @€@‚„HbQŽ€MŽW$„HbQ$$dЄd$„HbQ$$dЄd$0P @€@0P @€@0P @€@0P @€@‚GPQ@€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@‚HuQ@€@‚IQ @€@ƒBQ@€@‚HeQ@€@‚„H—Q @€@‚„HbQ@€@‚„HgQ@€@‚IpQ@€@‚„GbQ@€@‚„GbQ@€@ƒ„BQ€?$dЄd$0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@‚F”$$$$ф$0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@D РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD РD Р0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@0P @€@chirp-20240224/tests/images/Wouxun_KG-818.img0000644000175000017500000002000014411666130017337 0ustar hibbyhibby``џџџџ•џџџџџџџ•џџџџџџџ•џџџuuџџџџ•џџџџџџџ•џџџPPџџџџ•џџџ%%џџџџ•џџџP7P7џџџџ•џџџPPџџџџ•џџџPbPbџџџџ•џџџuuџџџџ•џџџP‡P‡џџџџ•џџџџџџџ•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPPџџџџјџџPPџџџџјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ w wwwЅЄЄЄЏЏЏЏЏЏЏwwwwwœЛЕ)/чсцwwwwwюЛюЛюЛюЛюЛюЛwwwwwuЗПs%ЄЇ~~wюpџџџџџџџџџџџџџџџџwюw1wюw1wюw1wюw1ЋЇszsн? !"#$%&'()*+,-./0123456789:џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџ!џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ!џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@џџџџ0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Wouxun_KG-UV6.img0000644000175000017500000002000014411666130017437 0ustar hibbyhibbyџџџџџџџџџџџџџџџџWQџџДxџџCCџџДpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKGUV6DWELCOMKGUV6DџџџџџџџџџџџџџџџџЧWWџџДјџџCCџџДјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™™š——————š™wwwЄЄЏЏЃЃЁЁЁЁЃЏЄwwwyvЏ“Б.чс3їwwwдѓдѓдёдё_ё_ѕ_ѕwwwuЗПs%ЄЇszzžyzžzy'{zžzy'{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЋЇІ­~|zpwywqw^:џџџџџџџџџџџџџџџџЋwwzwwwz•wC}ёwsw p|}Иsy~pwww:џџџџџџџџџWELCOMџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“›š ’’žž‘‘‘‘‘“ ­ЌЈЅЅЄЄЄЄЄЄЄЄt ‘ОЖр5ђ@_ŽРЦiю?ю?ює"є"E"E"X.XODDDDDDDDDPDйy'sџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Anysecu_UV-A37.img0000644000175000017500000013237514437574623017544 0ustar hibbyhibbyPFPFžžџџџџ001џџџџџџџџџP2FP2FЕЕџџџџ002џџџџџџџџџPRFPRFџџџџ003џџџџџџџџџPrFPrFџџџџ004џџџџџџџџџP’FP’Fџџџџ005џџџџџџџџџPBEPBEџџџџ006џџџџџџџџџPbEPbEџџџџ007џџџџџџџџџP‚EP‚Eџџџџ008џџџџџџџџџPRCPRCџџџџ009џџџџџџџџџP’CP’Cžžџџџџ010џџџџџџџџџP‚P‚џџџџ011џџџџџџџџџPRPRџџџџ012џџџџџџџџџP‚P‚џџџџ013џџџџџџџџџPR$PR$џџџџ014џџџџџџџџџPR8PR8џџџџ015џџџџџџџџџP‚P‚џџџџ016џџџџџџџџџEEžžџџџџ017џџџџџџџџџFFџџџџ018џџџџџџџџџGGџџџџ019џџџџџџџџџHHџџџџ020џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџeEeEџџџџЕк256ЙЄзїзщџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@џџџџџџџџ@џџџџџџзк џџџџџџџџџ џџџџџџџџџ(й џџџџџџџџџ џџџџџџџџџ(й џџџџџџџџџ џџџџџџџџџ(й џџџџџџџџџ џџџџџџџџџ(йџџџџџџџџџџџџ@џџџџџџj”џџџџџџџџџџџ@џџџџџџєQџџџџџџџџџџџ@џџџџџџдщџџџџџџџџџџџ@џџџџџџj џџџџџџџџџџџ@џџџџџџєQџџџџџџџџџџџ@џџџџџџ"Жџџџџџџџџџџџ@џџџџџџєQ џџџџџџџџџџџ@џџџџџџ”џџџџџџџџџџџ@џџџџџџєQ џџџџџџџџџџџ@џџџџџџ”џџџџџџџџџџџ@џџџџџџєQџџџ@џџџџџџџџ@џџџџџџD/џџџ@џџџџџџџџ@џџџџџџМHџџџ@џџџџџџџџ@џџџџџџD/џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџTіџ Йџ lџ Йџ N#џ Йџ љbџ ђЩџ TМџ ђЩџ  Z™џ  ќьџ  Z™џ  ќьџ  Z™џ  ќьџ  Z™џ  ќьџ  Z™џ  ќьџ  Z™џ  ќьџ  ЩЩџ  гUџ  u џ  гUџ  u џ  ‚џ  6Нџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      Ж­ЪТГЄзмО­РэзмМрО­Рэ1О­Рэ2О­Рэ3О­Рэ4О­Рэ5О­Рэ6О­Рэ7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџАьЙЋЪвааеўВПУХВЦЮёЪевјШЫСІзЪдДВПНгД§ВПбнвеВПЕМбнВПбндБВПЩЬЮёВПАВБЃВПОЦЕъДѓЬУЧАЬЈВжПтЪлКѓВППЭЗП01ВППЭЗП02ВПВЭвћ01ВПВЭвћ02ВПВЩЙК01ВПВЩЙК02ВПгЊЯњ01ВПгЊЯњ02ВП1КХГЕЖг2КХГЕЖг3КХГЕЖг4КХГЕЖг5КХГЕЖг6КХГЕЖг7КХГЕЖг8КХГЕЖгџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVkEzN1JhZGlvIiwgInZlbmRvciI6ICJBbnlzZWN1IiwgIm1vZGVsIjogIlVWLUEzNyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzA0MTYifQ==chirp-20240224/tests/images/Yaesu_VX-3.img0000644000175000017500000007751314411666130017023 0ustar hibbyhibbyAH028џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ e џџџџџ@џџџџџџ џџџEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8рўнФ§7•  џџџџџџџџџџџ @џџџџџџ џџ џџџџЈТЮџџџџџџџџџџ џџџџЈТŽџџџџџџџџџџџџџџџџџџ џџџџџџ..џџџџџ ЈТŽџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџ..џџџџџ ЈТЮ Јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ @џџџџџџ p@@€џџџџ `џџџџџџ ˜џџџџџџ ˜џџџџ @џџџџџџ p@@€џџџџ `џџџџџџ ˜џџџџџџ ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $ $ $ $ $ $ $ $ $               B@Рџџџџџџ ˜@Рџџџџџџ @Рџџџџџџ ‡`Рџџџџџџ ˜ˆ WPРџџџџџџ ˜F€Рџџџџџџ e Рџџџџџџ ‡@Рџџџџџџ " Рџџџџџџ D`РџџџџџџP ‡GРџџџџџџ †Рџџџџџџ B@Рџџџџџџ ˜@Рџџџџџџ @Рџџџџџџ ‡`Рџџџџџџ ˜ˆ WPРџџџџџџ ˜F€Рџџџџџџ @Рџџџџџџ ‡@Рџџџџџџ " Рџџџџџџ CРџџџџџџP ‡GРџџџџџџ †Рџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333@РŠ $$ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџмchirp-20240224/tests/images/Yaesu_FT-90.img0000644000175000017500000001022414411666130017047 0ustar hibbyhibbyіLK@^ѓРLK@^ѓРЋ?(З@Ћ?(З@#Eg‰ЋЭя#Eg‰ЋЭяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$$$$$$$H$hfа Šп4ъ`Œ€џџџџџџRм/0ъ` VHFhomeЂУ~*Ё ›€џџџџџџrAІгLЁ UHFhomebЈŠРъ`440 Calџџџџџџџџџџџџ@УŠ˜Є˜@RDM A/D@Нја6`@RDM Twr@Л›X “и@Unicom B @ьЕЈ†x@SheriffB @ы˜шhRd FireBРп’`ъ`2M Callb€ЈŠРъ`440 Calz ШСаzЁ FRS 1 z ШСк>Ё FRS 2 z ШСфЁ FRS 3 z ШСэЦЁ FRS 4 z ШСїŠЁ FRS 5 z ШТNЁ FRS 6 z ШТ Ё FRS 7 z ШЩqšЁ FRS 8 z ШЩ{^Ё FRS 9 z ШЩ…"Ё FRS 10 z ШЩŽцЁ FRS 11 z Ш٘ЊЁ FRS 12 z ШЩЂnЁ FRS 13 z ШЩЌ2Ё FRS 14 b РСۘЁ FRS 15 b РСе\Ё FRS 16 b РСп Ё FRS 17 b РСшфЁ FRS 18 b РСђЈЁ FRS 19 b РСќlЁ FRS 20 b РТ0Ё FRS 21 b РТєЁ FRS 22 b РСۘЁ gmrs550b РСе\Ё gmrs575b РСп Ё gmrs600b РСшфЁ gmrs625b РСђЈЁ gmrs650b РСќlЁ gmrs675b РТ0Ё gmrs700b РТєЁ gmrs725BРчЈАъ`MURS 1 BРчР ъ`MURS 2 BРчзъ`MURS 3 BРыкшъ`Blue DtBРыц ъ`Gren DtBРюъ` Mar 1 BРюDъ` Mar 3 BРюk(ъ` Mar 5 BРю~Аъ` Mar 6 BРю’8ъ` Mar 7 BРюЅРъ` Mar 8 BрюЙHъ` Mar 9 BРюЬаъ` Mar 10 BРюрXъ` Mar 11 BРюѓръ` Mar 12 BРяhъ` Mar 13 BРя№ъ` Mar 14 B Ря.xъ` Mar 15 BРяBъ` Mar 16 BРяUˆъ` Mar 17 BРяiъ` Mar 18 Bря|˜ъ` Mar 19 BРі•ъ` Mar 20 BРяЃЈъ` Mar 21 BРяЗ0ъ` Mar 22 BРяЪИъ` Mar 23 Bріу ъ` Mar 24 BРііЈъ` Mar 25 Bрї 0ъ` Mar 26 BрїИъ` Mar 27 Bрї1@ъ` Mar 28 Bрю&Ьъ` Mar 61 BРюMмъ` Mar 63 BРюadъ` Mar 64 BРюtьъ` Mar 65 BРюˆtъ` Mar 66 BРю›ќъ` Mar 67 BРюЏ„ъ` Mar 68 BРюУ ъ` Mar 69 BРюъъ` Mar 71 BРю§Єъ` Mar 72 BРя,ъ` Mar 73 BРя$Дъ` Mar 74 BРя_Lъ` Mar 77 BРяrдъ` Mar 78 BРя†\ъ` Mar 79 BРя™фъ` Mar 80 BРя­lъ` Mar 81 BРяРєъ` Mar 82 BРяд|ъ` Mar 83 BРіьфъ` Mar 84 BРїlъ` Mar 85 BРїєъ` Mar 86 BРї'|ъ` Mar 87 BРї;ъ` Mar 88 B Рј-ЦР WX 1 B РїЭ€-ЦР WX 2 B РїъЬ-ЦР WX 3 B РїзD-ЦР WX 4 B Рїс-ЦР WX 5 B Рїє-ЦР WX 6 B РїўT-ЦР WX 7 @Рю§Єъ` Mar 72 @Ря,ъ` Mar 73 @Ря$Дъ` Mar 74 @Ря_Lъ` Mar 77 @Ряrдъ` Mar 78 @Ря†\ъ` Mar 79 @Ря™фъ` Mar 80 @Ря­lъ` Mar 81 @РяРєъ` Mar 82 @Ряд|ъ` Mar 83 @Ріьфр Mar 84 @Рїlр Mar 85 @Рїєр Mar 86 @Рї'|р Mar 87 @Рї;р Mar 88 @Ріьфр Mar 84 @Рїlр Mar 85 @Рїєр Mar 86 @Рї'|р Mar 87 @Рї;р Mar 88 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџB рј-ЦРL1Wx 550B рїЭ€-ЦРL2Wx 400B рїъЬ-ЦРL3Wx 475B рїзD-ЦРL4Wx 425B рїс-ЦРL5Wx 450B рїє-ЦРL6Wx 500B рїќ`-ЦРL7Wx 520BрпС@ъ`LWx Ham џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ рј-ЦРL1Wx 550@ рїЭ€-ЦРL2Wx 400@ рїъЬ-ЦРL3Wx 475@ рїзD-ЦРL4Wx 425@ рїс-ЦРL5Wx 450@ Рїє-ЦРL6Wx 500@ Рїќ`-ЦРL7Wx 520@РпС@ъ`LWx Ham @ РїзD-ЦРL4Wx 425@ Рїс-ЦРL5Wx 450@ Рїє-ЦРL6Wx 500@ Рїќ`-ЦРL7Wx 520@РпС@ъ`LWx Ham @ Рјъ` WX 550 @ РїЭ€ъ` WX 400@ РїъЬъ` WX 475 €н@ ъ`Ь €н@ ъ`Ь €н@ ъ`Ь €н@ ъ`Ь ’HУ~*Ё ›€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJGVDkwUmFkaW8iLCAidmVuZG9yIjogIllhZXN1IiwgIm1vZGVsIjogIkZULTkwIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDIzMDIxOSJ9chirp-20240224/tests/images/Talkpod_A36plus.img0000644000175000017500000013240114442031345020055 0ustar hibbyhibbyu0Cu0CџџџџLPD-01џџџџџџ1C1CџџџџLPD-02џџџџџџ%1C%1CџџџџLPD-03џџџџџџP1CP1CџџџџLPD-04џџџџџџu1Cu1CџџџџLPD-05џџџџџџ2C2CџџџџLPD-06џџџџџџ%2C%2CџџџџLPD-07џџџџџџP2CP2CџџџџLPD-08џџџџџџu2Cu2CџџџџLPD-09џџџџџџ3C3CџџџџLPD-10џџџџџџ%3C%3CџџџџLPD-11џџџџџџP3CP3CџџџџLPD-12џџџџџџu3Cu3CџџџџLPD-13џџџџџџ4C4CџџџџLPD-14џџџџџџ%4C%4CџџџџLPD-15џџџџџџP4CP4CџџџџLPD-16џџџџџџu4Cu4CџџџџLPD-17џџџџџџ5C5CџџџџLPD-18џџџџџџ%5C%5CџџџџLPD-19џџџџџџP5CP5CџџџџLPD-20џџџџџџu5Cu5CџџџџLPD-21џџџџџџ6C6CџџџџLPD-22џџџџџџ%6C%6CџџџџLPD-23џџџџџџP6CP6CџџџџLPD-24џџџџџџu6Cu6CџџџџLPD-25џџџџџџ7C7CџџџџLPD-26џџџџџџ%7C%7CџџџџLPD-27џџџџџџP7CP7CџџџџLPD-28џџџџџџu7Cu7CџџџџLPD-29џџџџџџ8C8CџџџџLPD-30џџџџџџ%8C%8CџџџџLPD-31џџџџџџP8CP8CџџџџLPD-32џџџџџџu8Cu8CџџџџLPD-33џџџџџџ9C9CџџџџLPD-34џџџџџџ%9C%9CџџџџLPD-35џџџџџџP9CP9CџџџџLPD-36џџџџџџu9Cu9CџџџџLPD-37џџџџџџ@C@CџџџџLPD-38џџџџџџ%@C%@CџџџџLPD-39џџџџџџP@CP@CџџџџLPD-40џџџџџџu@Cu@CџџџџLPD-41џџџџџџACACџџџџLPD-42џџџџџџ%AC%ACџџџџLPD-43џџџџџџPACPACџџџџLPD-44џџџџџџuACuACџџџџLPD-45џџџџџџBCBCџџџџLPD-46џџџџџџ%BC%BCџџџџLPD-47џџџџџџPBCPBCџџџџLPD-48џџџџџџuBCuBCџџџџLPD-49џџџџџџCCCCџџџџLPD-50џџџџџџ%CC%CCџџџџLPD-51џџџџџџPCCPCCџџџџLPD-52џџџџџџuCCuCCџџџџLPD-53џџџџџџDCDCџџџџLPD-54џџџџџџ%DC%DCџџџџLPD-55џџџџџџPDCPDCџџџџLPD-56џџџџџџuDCuDCџџџџLPD-57џџџџџџECECџџџџLPD-58џџџџџџ%EC%ECџџџџLPD-59џџџџџџPECPECџџџџLPD-60џџџџџџuECuECџџџџLPD-61џџџџџџFCFCџџџџLPD-62џџџџџџ%FC%FCџџџџLPD-63џџџџџџPFCPFCџџџџLPD-64џџџџџџuFCuFCџџџџLPD-65џџџџџџGCGCџџџџLPD-66џџџџџџ%GC%GCџџџџLPD-67џџџџџџPGCPGCџџџџLPD-68џџџџџџuGCuGCџџџџLPD-69џџџџџџ%`D%`DџџџџPMR-01џџџџџџu`Du`DџџџџPMR-02џџџџџџ%1`D%1`DџџџџPMR-03џџџџџџuC`DuC`DџџџџPMR-04џџџџџџ%V`D%V`DџџџџPMR-05џџџџџџuh`Duh`DџџџџPMR-06џџџџџџ%`D%`DџџџџPMR-07џџџџџџu“`Du“`DџџџџPMR-08џџџџџџP`P`џџџџMAR-01џџџџџџaaџџџџMAR-02џџџџџџPaPaџџџџMAR-03џџџџџџbbџџџџMAR-04џџџџџџPbPbџџџџMAR-05џџџџџџccџџџџMAR-06џџџџџџPcPcџџџџMAR-07џџџџџџddџџџџMAR-08џџџџџџPdPdџџџџMAR-09џџџџџџeeџџџџMAR-10џџџџџџPePeџџџџMAR-11џџџџџџffџџџџMAR-12џџџџџџPfPfџџџџMAR-13џџџџџџggџџџџMAR-14џџџџџџPgPgџџџџMAR-15џџџџџџhhџџџџMAR-16 NOTџџPhPhџџџџMAR-17џџџџџџiiџџџџMAR-18џџџџџџPiPiџџџџMAR-19џџџџџџppџџџџMAR-20џџџџџџPpPpџџџџMAR-21џџџџџџqqџџџџMAR-22џџџџџџPqPqџџџџMAR-23џџџџџџrrџџџџMAR-24џџџџџџPrPrџџџџMAR-25џџџџџџssџџџџMAR-26џџџџџџPsPsџџџџMAR-27џџџџџџttџџџџMAR-28 NOTџџ%`%`џџџџMAR-60џџџџџџu`u`џџџџMAR-61џџџџџџ%a%aџџџџMAR-62џџџџџџuauaџџџџMAR-63џџџџџџ%b%bџџџџMAR-64џџџџџџububџџџџMAR-65џџџџџџ%c%cџџџџMAR-66џџџџџџucucџџџџMAR-67џџџџџџ%d%dџџџџMAR-68џџџџџџududџџџџMAR-69џџџџџџ%e%eџџџџMAR-70џџџџџџueueџџџџMAR-71џџџџџџ%f%fџџџџMAR-72џџџџџџufufџџџџMAR-73 SSџџџ%g%gџџџџMAR-74џџџџџџugugџџџџMAR-75џџџџџџ%h%hџџџџMAR-76џџџџџџuhuhџџџџMAR-77 SSџџџ%i%iџџџџMAR-78џџџџџџuiuiџџџџMAR-79џџџџџџ%p%pџџџџMAR-80џџџџџџupupџџџџMAR-81џџџџџџ%q%qџџџџMAR-82џџџџџџuquqџџџџMAR-83џџџџџџ%r%rџџџџMAR-84џџџџџџururџџџџMAR-85џџџџџџ%s%sџџџџMAR-86џџџџџџususџџџџMAR-87џџџџџџ%t%tџџџџMAR-88џџџџџџ%%џџџџFree-01џџџџџP7P7џџџџFree-02џџџџџPPџџџџFree-03џџџџџP‡P‡џџџџFree-04џџџџџ‘‘џџџџFree-05џџџџџP‘P‘џџџџFree-06џџџџџuSuSџџџџ2m AnrufџџџџCCџџџџ2m AnrufџџџџRRџџџџISS 2mџџџџџџXPTџџџџISS2 2mџџџџџP‡UP‡Uџџџџ2mџџџџџџџџџџPVPVџџџџ2mџџџџџџџџџџPTPTџџџџ2mџџџџџџџџџџ"C"Cџџџџ70cmџџџџџџџџ5C5Cџџџџ70cm Anrufџџ%a…C%a…Cџџџџ70cmџџџџџџџџ%‰C%‰Cџџџџ70cmџџџџџџџџP‡“CP‡“CџџџџDB0RBB FMџџџ™C™Cџџџџ70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%F%FџџџџOV P24 2mџџџ%&C%&CџџџџOV P24 70cmџP‡RP‡RВЦЮёuVuVuu@џџџџџџџџџџџџPˆCPCu@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџEEџџџџF-NEUFFENџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџuџџџ@џџџџџ@џџџџџ^ џџџџџџџџuџџџ@џџџџџˆџџџџџџџџuџџџ@џџџџџНЙџџџџџџџџuџџџ@џџџџџkАџџџџџџџџuџџџ@џџџџџyџџџџџџџџuџџџ@џџџџџЏџџџџџџџџuџџџ@џџџџџ[Iџџџџџџџџuџџџ@џџџџџ@џџџџџџџџuџџџ@џџџџџŸџџџџџџџџџuџџџ@џџџџџIіџџџџџџџџuџџџ@џџџџџPHџџџџџџџџuџџџ@џџџџџ†Aџџџџџџџџuџџџ@џџџџџ”ўџџџџџџџџuџџџ@џџџџџBїџџџџџџџџuџџџ@џџџџџЖИџџџџџџџџuџџџ@џџџџџ`Бџџџџџџџџuџџџ@џџџџџrџџџџџџџџuџџџ@џџџџџЄџџџџџџџџuџџџ@џџџџџFJџџџџџџџџuџџџ@џџџџџCџџџџџџџџuџџџ@џџџџџ‚ќџџџџџџџџuџџџ@џџџџџTѕџџџџџџџџuџџџ@џџџџџ Кџџџџџџџџuџџџ@џџџџџvГџџџџџџџџuџџџ@џџџџџd џџџџџџџџuџџџ@џџџџџВџџџџџџџџuџџџ@џџџџџЋЛџџџџџџџџuџџџ@џџџџџ}Вџџџџџџџџuџџџ@џџџџџo џџџџџџџџuџџџ@џџџџџЙџџџџџџџџuџџџ@џџџџџMKџџџџџџџџuџџџ@џџџџџ›Bџџџџџџџџuџџџ@џџџџџ‰§џџџџџџџџuџџџ@џџџџџ_єџџџџџџџџ uџџџ@џџџџџНЋџџџџџџџџuџџџ@џџџџџ_єџџџџџџџџ uџџџ@џџџџџНЋџџџџџџџџuџџџ@џџџџџmWџџџџџџџџ uџџџ@џџџџџf8џџџџџџџџuџџџ@џџџџџmWџџџџџџџџ uџџџ@џџџџџf8џџџџџџџџuџџџ@џџџџџф˜џџџџџџџџ uџџџ@џџџџџ#Цџџџџџџџџuџџџ@џџџџџф˜џџџџџџџџuџџџ@џџџџџЙыџџџџџџџџ uџџџ@џџџџџХџџџџџџџџuџџџ@џџџџџќ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџkOџ xаџ kOџ xаџ оЅџ xаџ оЅџ xаџ овџ ЭMџ k8џ ЭMџ k8џ ЭMџ NHџ ш=џ NHџ ш=џ NHџ ш=џ NHџ ш=џ NHџ ш=џ NHџ ш=џ NHџ ш=џ NHџ ]зџ ћЂџ ]зџ ћЂџ ]зџ ћЂџ ]зџ ћЂџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      Ж­ЪТГЄзмО­РэзмМрО­Рэ1О­Рэ2О­Рэ3О­Рэ4О­Рэ5О­Рэ6О­Рэ7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFLUGFUNKMARINEВЦЮёЪевјШЫСІзЪдДВПНгД§ВПбнвеВПЕМбнВПбндБВПЩЬЮёВПАВБЃВПОЦЕъДѓЬУЧАЬЈВжПтЪлКѓВППЭЗП01ВППЭЗП02ВПВЭвћ01ВПВЭвћ02ВПВЩЙК01ВПВЩЙК02ВПгЊЯњ01ВПгЊЯњ02ВП1КХГЕЖг2КХГЕЖг3КХГЕЖг4КХГЕЖг5КХГЕЖг6КХГЕЖг7КХГЕЖг8КХГЕЖгџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJBMzZwbHVzUmFkaW8iLCAidmVuZG9yIjogIlRhbGtwb2QiLCAibW9kZWwiOiAiQTM2cGx1cyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzA0MjcifQ==chirp-20240224/tests/images/Boblov_X3Plus.img0000644000175000017500000000176014411666130017610 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%`D%`D——яџџџ%1`D%1`D  яџџџuQCuQC  ыџџџu‰Bu‰BH H ыџџџPb%FPb%FяџџџP‡%FP‡%F——яџџџP—@P—@яџџџPb—@Pb—@ppяџџџP&FP&F%%яџџџP7&FP7&F%%яџџџPb&FPb&F%%яџџџP‡&FP‡&F%%яџџџP'FP'F%%яџџџPbuFPbuF%%яџџџu`Du`D%%яџџџ%V`D%V`D%%яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:Б№+џџџџP3107єџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Yaesu_FT-1500M.img0000644000175000017500000001005414411666130017322 0ustar hibbyhibbyAH4N0$ $ џџџџџџџџџџџџџџџџџџџџџџџџџџџџ` џџџџџџh%  Qu џџvџџџџџџvџџџџџџvџџџџџџvџџџџџџp% @€pP @€pu #@q%@РqP  @€qP @rP@s%@h% @hP@@p% џџџџџџp% џџџџџџ@pP џџџџџџ@ pu џџџџџџ@ q $$$$$$ rP $$$$$$ ru $$$$$$ s% $$$$$$ sP $$$$$$ x $$$$$$ x% $$$$$$ yP $$$$$$ dP $$$$$$du $$$$$$e $$$$$$e% $$$$$$eP $$$$$$€0%  €6%  $xP $$$$$$ Q $$$$$$ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ $$$$$$ џџџџџџџџџџџџџџџџ@ $$$$$$ џџџџџџџџџџџџџџџџ$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0 h  ,Т[џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0 h  ,Т[џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџаџchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQtMTUwME0iLCAiY2hpcnBfdmVyc2lvbiI6ICIwLjMuMGRldiIsICJyY2xhc3MiOiAiRlQxNTAwUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Retevis_RT20.img0000644000175000017500000000225114477554757017362 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%Fppяb%FP‡%FP‡%Fˆˆя‡%FP&FP&Fssя&FP7&FP7&Fя7&FPb&FPb&Feeяb&F%&F%&Fssя%&F%'F%'Feeя%'FP‡&FP‡&Fя‡&FP'FP'Fbbя'FP%FP%F00яP%Fu%Fu%FCЧCЧяu%F&F&F2У2Уя&FP&FP&FCТCТяP&Fu&Fu&F††яu&F'F'F1Ч1Чя'F%'F%'FbФbФя%'Fџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ†^џџSMP5558џџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSVDIwUmFkaW8iLCAidmVuZG9yIjogIlJldGV2aXMiLCAibW9kZWwiOiAiUlQyMCIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzA5MDUifQ==chirp-20240224/tests/images/Icom_IC-2730A.img0000644000175000017500000005150014411666130017100 0ustar hibbyhibbyrx WРш€ rаx r r r r r r r r r r r r r r r r r r qЊx KIRK1 qЊx  r r r r r r r џџРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ [žшW7EOC WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ WРш€џ rx rx WРш€ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџпџџџџџџџџџџџџџџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљџџџџџџџџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџџџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџŸџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ HAM џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@7P­Аџ p€s џ O№_џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ џ јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџ џџџџџџџ‰__ЈЈ3;џџџџ6G3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘нР""рГя 'Р9оLK@€‘нР""рГя 'Р9оLK@€Гя 'Р 9оLK@€џџџџџџ џџџџџџџџџџџџџџќќџџџџџџџџџџўўўўўўўўўў&џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/TYT_TH-UV88.img0000644000175000017500000002150514411666130016731 0ustar hibbyhibbyИЭЄИЭЄџџ xоxоџџ ффџџ ЈЛbЈЛbžž ЄЫ—ЄЫ—ww „”Ј„”Јэ э  8Э8Э„„  , ,џџ рп’рп’џџ @Ъ“@Ъ“џџ ˜˜џџ HъХHъХџџ $Б‘$Б‘џџ H•H•џџ DМБDМБџџ lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu n†І‡€№‰АeŠрМ@Їл“pў•Аš–№Ї™pрš№‰ž0—Ё0Єџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?€№‰†ЭР!†ЭР'P10blмlмu lмlмu lмlмu lмlмu рС—рС—ш рС—рС—ш lмlмu lмlмu lмlмu dJнdJнџџ`ъђ‰€ђ‰€№‰€`ъф Їф Їџџ`ъdJнdJнџџ`ъ€№‰€№‰џџ`ъф Їф Їџџ`ъ ˜!BррёAё рСUV-88 %‘P– B000000rIѓёAџџёšМо№4Vx'24W˜4P4Vx24W˜4_4VxB4ex4P4VxB4ex4_4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx Уi№ №Vx 4VxšМо№4Vx ˜vT2Мо№4Vx 24W˜4_B4ex4_ рС—рС—rIѓёAё рСVЬ2T-01  VЬyOжP  4Vx 5T-01  4Vx 5T-02  4Xx123456 5T-03  ‡eC!123456 5T-04  5W„123456 5T-05  4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx `а4Vx‡eC!F 4VxšМ5T-01  4V‡ŠМ 5T-02  ‡eC!šМ5T-03  5W„šМ5T-04  4VxšМ 4VxšМ 4VxšМ 4VxšМ …ЯР€ …ЯР€ џџџџџџџџџџџџџџџџZblмZblмџџџџџџџџџ&)"(ZZZZZdddddddddddddddZ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡вввввввввввввввввввввммм<<HR\fpz„Ž˜ЌРдш#-7AKZdnx‚Œ– ЅІІІІІІІІІІІІІІІІMID@=<<<c]YVTSSS–‰‚ƒƒ‚ІІІІІІІІІІІІІІІІSKIFDDCC@=;842/khebaa``]YWSOOL–––––––––––––––ІІІІІІІІІІІІІІІІ8  Ќ–X&„ќ ФPЬ PЬІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІfpz„Ž˜ЌОд&0:DS]gq{…™ЃІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІš§r„јјјјјјјјјјјјјјјјјјІІІІІІІІІІІІІІІІІІІІу•ИаЁчˆаІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІНрfд@Ђp@аbUа-Ÿ>аn?ФаІІІІІІІІІІІІІІІІџџ ч PЬљ  №№џџџџџџџџ(<PxCHIRP ІІІІІІІІІІІІІІІІWOUXUN20190719ИЃНЈЪЁШЊжнЪа000000B4_R1.02cdЧ+-ѕWXЛ‘ѓ ЖЗчџџџџџџџџHAMPMRHamMarAnalogCommerAirbanAir VeriFireRepeatSatellІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІнŽРнŽРуаќџн˜„н˜„уаќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІ145.200145.225ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІ=<><<><><><<>>>>>>>>>>>>>><>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<ќќќќќ<<<<<<<<<<<<<<<<ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ<=>=>>=><<<<<<<<ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ>>>>><><<<<<<<<<<>>>>>>>>>>>>>>>>>><<<<<<<<<<<>>>>>>>>><<ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ}}}>}}<<><<<<ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ==<<<<<<<<<<<<<<<<<<<<<<===<<<<<<<<<<<<<<<<<<<<<<<<<=<<<<<><<<<<<<<<}}}}}}}}}}}}}}}}ќќќќќќќќќќќќќќќќ}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}ќ|ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ}}}}}}}}}}}}}}}}}}}}ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ><>>>>>><<>>>>>>>>>>>><>>>><>>>>>>>>>>><<><>><<><>>>>><>>>><>><<<>><><>>><><>><<><><>>><<><<<>><<>>>>>>><ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ>>===>>=>>}=>>><<<ІІІІІІІІІІІІІІІІІІІІІІІІџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  !"#$%&'()*+,-./0123456789:;<=>?ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІџchirpюimgeyJtZW1fZXh0cmEiOiB7IjAwMDFfY29tbWVudCI6ICIiLCAiMDAwMl9jb21tZW50IjogIiJ9LCAicmNsYXNzIjogIkR5bmFtaWNSYWRpb0FsaWFzIiwgInZlbmRvciI6ICJXb3V4dW4iLCAibW9kZWwiOiAiS0ctVVY5SyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Yaesu_FT-50.img0000644000175000017500000000721314551723752017060 0ustar hibbyhibby $$$$ $€ @$$$$… CP$$$$€ @$$$$€ D`P$$$$Р"Ss0$$$$€Р!BRP €Р"LD%P Р"LD"%P$$$$Р"HD%P$$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€€ FЂџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ F%`џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ U $$$$џџџџџџџџџџџџџџџџ€ GU $€ U  $€ ˆP € U  € BP  Dд џџџџџџ€ Y@ $ € Ш% $џџџџџџџџџџџџџџџџџџџџ F%`Pвџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ $ € $% € $P € $u € % € %% € %P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ U $$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ $ € $% € $P € $u € % € %% € %P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ F%`P$$$$€!R0$$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$$ $™`€ @$$$$‚ " $$$$‚ 8$$$$… CP$$$$‚ €$$$$€ @$$$$‚ " $$$$‚ 8$$$$… CP$$$$‚ €$$$$` @BGџџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $џџџџџџџџџџџџџџџџ $ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџj’гџџ€€џџџџџџџџџџџџџџџџџџџџ'2^? јпB@$$$$L€џ€ 0€•EЂ’ра`$$$$$џџеchirp-20240224/tests/images/Retevis_RB15.img0000644000175000017500000000410114411666130017311 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ7р 'џџџџњ |(џT < < (џP < < 'џP < < &џP < < &џP < < %џP < < $џP < < #џP < < "џP < < "џP < < "џP < < "џP < < "џP < < !џP < < !џP < < !џP < < џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџ7иGFAxџџџСаzžСаzž$џџџСк>ЄСк>Є$џџџСфљСфљ$џџџСэЦ&СэЦ&$џџџСїŠUСїŠU$џџџТN…ТN…$џџџТ ЖТ Ж$џџџЩqš@ЃЩqš@ЃЄџџџЩ{^@Щ{^@ЄџџџЩ…"@'Щ…"@'ЄџџџЩŽц@)ЩŽц@)Єџџџ٘Њ@+٘Њ@+ЄџџџЩЂn@5ЩЂn@5ЄџџџЩЌ2@NЩЌ2@NЄџџџСۘЮСۘЮ$џџџСе\уСе\у$џџџСп €кСп €к$џџџСшфљСшфљ$џџџСђЈ€ЃСђЈ€Ѓ$џџџСќlA†СќlA†$џџџТ0йТ0й$џџџТєUТєU$џџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjE1IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjA3MDMiLCAicmNsYXNzIjogIlJCMTVSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Icom_ID-4100.img0000644000175000017500000052170014411666130016775 0ustar hibbyhibbyrx €ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ џџџџџџџџџџџџџџџџџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџсџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@7P­Аџџ p€s џџ O№_џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџ@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ CALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGN џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№џšџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџŸ__ˆˆ++џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњNWџџџ API410,DSTAR* />/v/k/- \Y NWџџџ \Y NWџџџџ/_ џџџџџџџџџџџџџџџ‘нР"3@ €Гя 'Р@ €I3@ €м“€@ €9оLK@@ €‘нР"3@ €Гя 'Р@ €I3@ €м“€@ €9оLK@@ €CQCQCQ CQCQCQ CQCQCQ CQCQCQ џџ NWџџџџџџџџ REF000ALREF000AL CQCQCQ NWџџџџџ NWџџџџџџџџ REF000ALREF000AL CQCQCQ NWџџџГя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџ9оLK@@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќџџџџџџџџџџўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3chirp-20240224/tests/images/Abbree_AR-730.img0000644000175000017500000013242114467633002017222 0ustar hibbyhibbyPFPFžžџџџџ001џџџџџџџџџP2FP2FЕЕџџџџ002џџџџџџџџџPRFPRFџџџџ003џџџџџџџџџPrFPrFџџџџ004џџџџџџџџџP’FP’Fџџџџ005џџџџџџџџџPBEPBEџџџџ006џџџџџџџџџPbEPbEџџџџ007џџџџџџџџџP‚EP‚Eџџџџ008џџџџџџџџџPRCPRCџџџџ009џџџџџџџџџP’CP’Cžžџџџџ010џџџџџџџџџP‚P‚џџџџ011џџџџџџџџџPRPRџџџџ012џџџџџџџџџP‚P‚џџџџ013џџџџџџџџџPR$PR$џџџџ014џџџџџџџџџPR8PR8џџџџ015џџџџџџџџџP‚P‚џџџџ016џџџџџџџџџEEžžџџџџ017џџџџџџџџџFFџџџџ018џџџџџџџџџGGџџџџ019џџџџџџџџџHHџџџџ020џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџeEeEџџџџЕк256ЙЄзїзщџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@џџџџџџџџџџџџџџџџџџџџџџџџзк џџџџџџџџџ џџџџџџџџџ(йџџџџџџџџџџџџ@џџџџџџj”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ mџ иŸџ г4џ  Žџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      Ж­ЪТГЄзмО­РэзмМрО­Рэ1О­Рэ2О­Рэ3О­Рэ4О­Рэ5О­Рэ6О­Рэ7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџАьЙЋЪвааеўВПУХВЦЮёЪевјШЫСІзЪдДВПНгД§ВПбнвеВПЕМбнВПбндБВПЩЬЮёВПАВБЃВПОЦЕъДѓЬУЧАЬЈВжПтЪлКѓВППЭЗП01ВППЭЗП02ВПВЭвћ01ВПВЭвћ02ВПВЩЙК01ВПВЩЙК02ВПгЊЯњ01ВПгЊЯњ02ВП1КХГЕЖг2КХГЕЖг3КХГЕЖг4КХГЕЖг5КХГЕЖг6КХГЕЖг7КХГЕЖг8КХГЕЖгџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7IjAwMDZfY29tbWVudCI6ICIifSwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2ZW5kb3IiOiAiQWJicmVlIiwgIm1vZGVsIjogIkFSLTczMCIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Baofeng_UV-S9X3.img0000644000175000017500000002030114471346476017634 0ustar hibbyhibbyџ%E џџYXSQ%!E%!EЕЕD%2E%2E““D%CE%CEUUD%TE%TEээD%fE%fE;;D%vE%vEr r D%‡E%‡ED%˜E%˜ED%F%F33D%"F%"F;; D%3F%3FPP D%DF%DFxx D%UF%UFЫЫ D%"@%"@ D%tC%tCDu™Gu™GDP…P…DPvPvDP'P'D% % D%R#%R#D%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ€YYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`?џџџџџџџџ`?џџџџџџџџџџџџџџŠџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ001џџџџџџџџџџџџџ002џџџџџџџџџџџџџ003џџџџџџџџџџџџџ004џџџџџџџџџџџџџ005џџџџџџџџџџџџџ006џџџџџџџџџџџџџ007џџџџџџџџџџџџџ008џџџџџџџџџџџџџ009џџџџџџџџџџџџџ010џџџџџџџџџџџџџ011џџџџџџџџџџџџџ012џџџџџџџџџџџџџ013џџџџџџџџџџџџџ014џџџџџџџџџџџџџ015џџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџАААААААААААААџџџeeeeeeeeeeeeeџџџNNNNOOOOOOPPPџџџџџџџџџџџџџџџџџџџџџџџџ151123HџџџџџџџџџWELCOME џџHN5RV011џџџџџџџџЎЎЎЎЎЏЏЏЏЏЏЏАБББААЏБЏЏ­ЌЌЌЌЌЌџџџeeeeeeeeeeeeeeeeiiiiiiiiiiiiiџџџMNNNOPPPPPQQQQQQQQQQQQQRRRRRRџџџџџџџџ?џџџџџ?0 <џџpsv}‡Ђ1 џ€6t `џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЊ0v нџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVlM5WDMiLCAidmVuZG9yIjogIkJhb2ZlbmciLCAibW9kZWwiOiAiVVYtUzlYMyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzA3MTkifQ==chirp-20240224/tests/images/TYT_TH-9800.img0000644000175000017500000017742014411666130016627 0ustar hibbyhibbyTH9800џџV14xџџџџ@@#РџџџџџџџџџџCC#Рvџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ#Рџџџџџџџџџџ#Рџџџџџџџџџџ#Рџџџџџџџџџџ€€#Рџџџџџџџџџџ@@#Рџџџџџџџџџџ#Рvџџџџџџџџџџ55#РvџџџџџџџџџџCC#Рvџџџџџџџџџџ……#Рvџџџџџџџџџџ@@#РџџџџџџџџџџCC#Рvџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ ф 3#џџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2T-S01џџ 2 џџ‘ A$yжOUџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2T-01џџџ‘ A$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF џџџР]h)P-œ1А6Ф;W{˜VyŠ?W{Šџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0 РРPPџџџџ PаPPР ` 0џџџџџџџџџџџџџџџџџџoE іf-nџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $ $а 0 P 0№P"P   @ @ А           &А%И$Р(( №v€  РаРЋЋ 0˜РvvРРЦРа`аPPааРРра№UU0 0№GGаРРРррј;;0 `ШPP@0 №€Ш33№рррр€ ++рааашЪЪ``ppрЌЌА АрXААР Аж:ІІ0@@@XА:––    @Ј*††€00€00€00€00€00€00€00€00€00€00€00  АА22   ((А 33(  00А33    Аx22 Аh22јјјј 0,,тшшр№((вииашˆ&&ииии№ˆ&&žљ™('№&2x"Љ {*п,G /Э™f™f™f™f™f™f8o$o&= *2!2$%[M7'$k#g0‡5и03h0e4x$?/ЩUв]ЭNбхЏ>f™Ÿ0Ї7{PРџ` №0pА €№џџџџћ!ў % 1"/&9'8&:$p@+l§џsД§w$џrBѕЩўѕж]СIџьџџ Z џ‚‚„ƒ„…‚ˆˆ‚ƒ‚„џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTH980020141120џџџџџџџџџџџџџџџџџџџџџџџџџџTH9800џџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџ`0`0p@p@€•9@@@5•™9@ Q@Hu•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Quansheng_UV-K5_egzumer.img0000644000175000017500000002036514560403070021524 0ustar hibbyhibby0y)т№1Јт№’Јт№ѕ–Јт№з›Јт№Й Јт№›ЅЈт№}ЊЈт№_ЏЈт№AДЈт№#ЙЈт№ОЈт№чТЈт№ЩЧЈт№ЋЬЈт№бЈт№oжЈт№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРјf№ єїhxёY hxёA @wNT ГЧ^б   б  б IР€ ЄbЈВ%cŸ@B˜Ћ` шь……………………………………РСТУФХЦџџџџџџџџџџџџџџџџџџџџџџ}ŒџџЪџџў џџ%.џџџџџџџџџџџџџџџџџџџџ&Щ ЩЯЯ} џџџџџџџџџџџџџ‚Lџџџџџџџџџџџџџџ*#c џџџџџ1027777788888123456џ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{џџџџџџџџCB19 PMR1 PMR2 PMR3 PMR4 PMR5 PMR6 PMR7 PMR8 PMR9 PMR10 PMR11 PMR12 PMR13 PMR14 PMR15 PMR16 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџtesttest MarSycEng MarSycItalџџџџџџџџџџџџџџџџtest џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCALL1101CALL2102CALL3103CALL4104CALL5105џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ KSVY\_bdfџџџџџџFPSVY\_bdџџџџџџZ-)&# џџџџџџd0-)&# џџџџџџZ џџџџџџd џџџџџџ2hknoruwy{џџџџџџ(dgjlnqsvxџџџџџџA2-($!џџџџџџF72-(%"џџџџџџZ џџџџџџd џџџџџџnx‚ŒДОШв222dddŒŒŒџџџџџџџ222dddŒŒŒџџџџџџџ___iiiq‹џџџџџџџ222dddŒŒŒџџџџџџџZZZddd‚‚‚џџџџџџџZZZddd‰{†џџџџџџџ222dddŒŒŒџџџџџџџеЗ7ŽИќџџџџ2FZn‚–ЊШцџџџџ(<PdxŒ ОмџџџџџџџќџFP,џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‰џџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInV2azVfZmlybXdhcmUiOiAiRUdaVU1FUiB2MC4yMSIsICJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIlF1YW5zaGVuZyIsICJtb2RlbCI6ICJVVi1LNSIsICJ2YXJpYW50IjogImVnenVtZXIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Yaesu_FT-65R.img0000644000175000017500000002076514411666130017206 0ustar hibbyhibby4123џџџџџџџџџџџџe  t€  p  f  R0  pE  TP  r@  T  f@  p`  D` dD& dD% dD%u dD) dr@  i@  g`  S0  p  d0  p  TP  De dC5P dC d@    PP  De d P @  C dМ€'p  М€'p  WA6PWW KN6EF N6NFI LARK K6FB W6RGG WA6HAM LPRC W6CX WA6PWWU ACWD K6FBU LPRCU TAHOE BISHOP MAZRKA SANDIA YOSEMITE e t€pfR0pETPr@Tf@p`D`D&D%D%uD)r@i@g`S0pd0pTPDeC5P ..----------------------------------------------------------------------------------------------------------------------------------------------------  C d@  PP  PP  џchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQtNjVSIiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIkR5bmFtaWNSYWRpb0FsaWFzIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_VX-7.img0000644000175000017500000003752314411666130017024 0ustar hibbyhibby  $ј$јџџџџ @  CP  @  CP  @  CP  @  CP  @  CP  @  CP  @  CP  @  CP  @  CP  @  CP ЪЌ„ŠX@ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ -09.32s   1џџџџ CP џџџџџџџџџџs   1џџџџ CP џџџџџџџџџџЌ„ŠX@ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ -09.32,*,/,2+,21џџџ1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ џџџџџџџџС@ Р Ч Ц@ С  Р@  "  ХC P Х€ Т8 Т† С@ Р Ч Ц@ С  Р@  "  хDP PХ€ Т8 Т† С  Р@  ХC P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ333033333333033303303333333333333333333030333333333333333333333333333333333333333333333333333333џџР@0  C0 t0!    s`0!  d@0!  h0!  %D1P0!  PRp0!  %D%0!  PTp0!  %D4%0!  P%D)%0!  PT00!  %DP0 Pg`0   q€0  u 0 #  e 0   s 0  P0 g0    s`0!  `1  1   D00N  P s€0N   t@0N   DP0N  P D)%0N  P D3P0N  P D(%0N  P%DI0 P%DI%0 P p0  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ sU0 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ s 0  i0!  t0!   DP0!   PS00  #R00   q 0   f`0   h€0   r 0   q`0  Du0 P  DP0 Ph@0  r@0   i€0  RP0  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$0!" $%0!" $P0!" $u0!" %0!" %%0!" %P0!" џџџџџџџџџџџџџџџџџџџџџ“1   vP1  1 “1! )P1  P1  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ…0  …0  … 0  …%0  …00  …%0 …‡0 …P0 …u0 …0 …%70!  …%b0!  …%‡0!  …&0!  …&70!  E20  E4b0  E70  E8b0  …470 …70 …P0 …u0 …3‡0 # # WP0  70   DR0   ‡70   ”r0   †70!  †70!  …—70!  …—70!  …‚70!  …r70!  …b70!  …Yb0!  …R70! …I‡0! џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџUP0  C0  UP0N  Pp0N  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF%b0  F%‡0  F&0  F&70  F&b0  F&‡0  F'0  Fub0  Fu‡0 Fv0  Fv70  Fvb0  Fv‡0  Fw0  F%P0  F%u0  F&0  F&%0  F&P0  F&u0  F'0  F'%0   0 €0 @0 Ep0 F0%0  U0  FEP0#  FE0   Fwb0 Fx0  FxP0  Fxu0  Fy0  Fy%0   џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрp  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ p0  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџGchirp-20240224/tests/images/Baofeng_5RM.img0000644000175000017500000010207114565075506017203 0ustar hibbyhibby e eџџџџNCF 2mџџџџџџ5"5"џџџџNCF 1.25mџџџ`D`DџџџџNCF 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџRFЮЮџџџџREN CEN 2mџџu0Du€DЮЮџџџџREN CEN 70cm0S0GшџџџџDET DTE 2mџџ`C"`'"  џџџџDET 1.25mџџџ!DqD00џџџџDET 2mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ1DD99џџџџNRTHVL1 70cmP1DPD00џџџџNRTHVL2 70cm%2D%‚D00џџџџBEV HIL 70cmicшшџџџџPONTIAC 2mџџ@h@bшџџџџCLRKSTN 2mџџ F" 0"шшџџџџHOLLY 1.25mџP#DPsD00џџџџHOLLY 70cmџџHD˜DUUџџџџNOVI 70cmџџџu9Du‰DžџџџџFENTON 70cmџ@p@vUUџџџџS LYON 2mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџqwшџџџџFLINT1 2mџџџ`r`xшџџџџFLINT2 2mџџџ@s@yшџџџџFLINT3 2mџџџ€s€yuuџџџџFLINT4 2mџџџ€D"€("шџџџџFLINT5 1.25m DpDшшџџџџFLINT6 70cmџBD’D0џџџџFLINT7 70cmџFD–DъъџџџџFLINT8 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`@"`$"шџџџџCLIO 1.25mџџRFшшџџџџDURAND 2mџџџ`H"`2"шџџџџDURAND 1.25m%&D%vDшџџџџDURAND 70cmџ p vшџџџџOWOSSO 2mџџџ$DtDшџџџџOWOSSO 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0S0GuџџџџSAGINAW 2mџџ@r@x џџџџSAGINAW 2mџџ"DrD  џџџџBURT 70cmџџџ%@D%DшџџџџFRANKM 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTHVVџџџџHOWELL 2mџџџ%ED%•DшшџџџџHOWELL 70cmџPaDPDшшџџџџDEXTER 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@i@cшшџџџџLANSNG 2mџџ€I"€3"шџџџџLANSNG 1.25mSGшшџџџџPOTRVIL 2mџџ% D%pDЪЪџџџџPOTRVIL 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`s`yшшџџџџJACKSON 2mџџID™D&&џџџџJACKSON 70cm`A"`%"шџџџџGRS LK 1.25mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@i@c џџџџW BRANCH 2mџQE&&DџџџџROSE CTY 2mџPTPH……џџџџROSCMN 2mџџџ1DDЖЖџџџџROSCMN 70cmџ0Q0E0џџџџGRAYLING 2mџ@G"@1"UџџџџGAYLRD 1.25mrx  џџџџHARRISON 2mџ€s€y0џџџџMANCLON 2mџџ(DxDUџџџџMANCLON 70cm€r€x  џџџџE JORDAN 2mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`h`b||џџџџTRAV C 2mџџP‡"DP‡rD||џџџџTRAV C 70cmџQE  џџџџMACKNAW 2mџџuCDu“D00џџџџMACKNAW 70cmPHDP˜DшџџџџCHBOYGN 70cm@g@a џџџџCHBOYGN 2mџџ2D‚DъъџџџџALANSON 70cm`E"`)"шџџџџSTUTSM 1.25mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџga  џџџџMIO 2mџџџџџџuIDu™D џџџџMIO 70cmџџџџ`g`auџџџџALPENA 2mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ h bДџџџџMUSKGN 2mџџџG"1"ДџџџџMUSKGN 1.25mP)DPyDДџџџџMUSKGN 70cmџTHДДџџџџGRD HVN 2mџџu7Du‡DДџџџџGRD HVN 70cm`q`wДДџџџџGRD RPD 2mџџ8DˆDДДџџџџGRD RPD 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@p@vДДџџџџKALMZO 2mџџџuHDu˜DДДDџџџџKALMZO 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџpTpHUџџџџBADAXE 2mџџџP5DP…D|џџџџBADAXE 70cmџ`f``шшџџџџCARO 2mџџџџџP%DPuD  џџџџCARO 70cmџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџga  џџџџSNO DRIFT P`d`dџџџџSNO DRIFT SџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPb%FPb%FџџџџGMRS 1џџџџџџP‡%FP‡%FџџџџGMRS 2џџџџџџP&FP&FџџџџGMRS 3џџџџџџP7&FP7&FџџџџGMRS 4џџџџџџPb&FPb&FџџџџGMRS 5џџџџџџP‡&FP‡&FџџџџGMRS 6џџџџџџP'FP'FџџџџGMRS 7џџџџџџPbuFPbuFDџџџџGMRS 8џџџџџџP‡uFP‡uFDџџџџGMRS 9џџџџџџPvFPvFDџџџџGMRS 10џџџџџP7vFP7vFDџџџџGMRS 11џџџџџPbvFPbvFDџџџџGMRS 12џџџџџP‡vFP‡vFDџџџџGMRS 13џџџџџPwFPwFDџџџџGMRS 14џџџџџP%FP%FџџџџGMRS 15џџџџџu%Fu%FџџџџGMRS 16џџџџџ&F&FџџџџGMRS 17џџџџџ%&F%&FџџџџGMRS 18џџџџџP&FP&FџџџџGMRS 19џџџџџu&Fu&FџџџџGMRS 20џџџџџ'F'FџџџџGMRS 21џџџџџ%'F%'FџџџџGMRS 22џџџџџP%FPuFџџџџREPTR 15џџџџu%FuuFџџџџREPTR 16џџџџ&FvFџџџџREPTR 17џџџџ%&F%vFџџџџREPTR 18џџџџP&FPvFџџџџREPTR 19џџџџu&FuvFџџџџREPTR 20џџџџ'FwFџџџџREPTR 21џџџџ%'F%wFџџџџREPTR 22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPQPQџџџџDTW APPROACHu…u…џџџџDTW APRCH EџP@P@џџџџDTW APRCH WџP”P”џџџџDTW GND NEџџџџџџDTW GND NWџџP’P’џџџџDTW GND SEџџP”P”џџџџDTW GND SWџџ„„џџџџDTW TOWER EџPPџџџџDTW TOWER Wџ``џџџџDTW CLEARNCEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPTK CTAFџџџџџџџџPTK GROUND1џPPџџџџPTK GROUND2џ77џџџџPTK TOWERџџџP‚P‚џџџџPTK CLEARNCEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџccџџџџBISHP CTAFџџџџџџBISHP GROUNDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ((џџџџDALTON CTAFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2ZW5kb3IiOiAiQmFvZmVuZyIsICJtb2RlbCI6ICI1Uk0iLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Retevis_RT26.img0000644000175000017500000000200014411666130017331 0ustar hibbyhibbyџџџџџџџџџџџџџџџџuFEuFE00џџџџ%@E%@Eppџџџџ%7E%7E%%џџџџ%1E%1EџџџџuEEuEEџџџџu6Eu6EHHџџџџ%CE%CE#€#€џџџџ%RC%RCG€G€џџџџu’Du’D““џџџџ%…D%…D""џџџџu)Eu)Ebbџџџџu$Eu$E……џџџџ%fB%fB——џџџџuHEuHE——џџџџ%F%F——џџџџ%E%Eџџџџџџџџџџџџџџџџџџџџэхєџ T1џџџџџџџџџџџџџџџџџџџџџџђџџ№Ъ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPDK80ѓџџџџџџџџс.џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ•›КХсв№24ў€dШԘџ „d џ ,) џKџK џџџџџџџџ7d‚џџџџџ7d‚џџџџџ7d‚џџџџџ7d‚џџџџџ7d‚џџџџџ7d‚џџџџџ7d‚џџџџџ7d‚џџџџџ7d џџџџџ7d џџџџџ8dЊџџџџџ7dЊџџџџџџџџџ7dЊџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Retevis_RA79.img0000644000175000017500000002034514560403070017327 0ustar hibbyhibbyФУл‡мdJнД обоT”п „* $Б‘ Ф7“dО”E–ЄЫ—DR™фиš""„_œ%%$ц((ФlŸ,,џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNTNT(-Ѕ(-ЅHЂнHЂнШ8vШ8vhpЈВ%ˆ#˜ˆ#˜шьшьЯЯЯЯЯФХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЭЭЯЯџџџџџџџџџџџџџџџџџџџџџџџџWELCOME*# џџџџџ1027777788888123456џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCH001CH002CH003CH004CH005CH006CH007CH008CH009CH010CH011CH012CH013CH014CH015CH016CH017џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCALL1101CALL2102CALL3103CALL4104CALL5105џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ KSVY\_bdfџџџџџџFPSVY\_bdџџџџџџZ-)&# џџџџџџd0-)&# џџџџџџZ џџџџџџd џџџџџџ2hknoruwy{џџџџџџ(dgjlnqsvxџџџџџџA2-($!џџџџџџF72-(%"џџџџџџZ џџџџџџd џџџџџџnx‚ŒДОШв222dddŒŒŒџџџџџџџ222dddŒŒŒџџџџџџџKKJbf]|šџџџџџџџ222dddŒŒŒџџџџџџџZZZddd‚‚‚џџџџџџџOIQmcm•“џџџџџџџ222dddŒŒŒџџџџџџџ †Ђќџџџџ2FZn‚–ЊШцџџџџ(<PdxŒ ОмџџџџџџџќџFP,џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInV2azVfZmlybXdhcmUiOiAiYXBwXzIuMDEuMTciLCAicmNsYXNzIjogIkR5bmFtaWNSYWRpb0FsaWFzIiwgInZlbmRvciI6ICJSZXRldmlzIiwgIm1vZGVsIjogIlJBNzkiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Retevis_RT19.img0000644000175000017500000000104514411666130017343 0ustar hibbyhibbyPb%FPb%Fžž џџџP‡%FP‡%FЄЄ џџџP&FP&Fљљ žP7&FP7&F&& Pb&FPb&FUU џџP‡&FP‡&F…… ?P'FP'FЖЖ PbuFPbuFЃ(Ѓ(€P‡uFP‡uF((€PvFPvF'('(€P7vFP7vF)()(€PbvFPbvF+(+(€P‡vFP‡vF5(5(€PwFPwFN(N(€P%FP%FЮЮ u%Fu%FуЉуЉ џ&F&FкЈкЈ %&F%&Fљљ P&FP&FЃЈЃЈ u&Fu&F†)†) 'F'Fй)й) %'F%'FUU џџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDE5IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjA4MjMiLCAicmNsYXNzIjogIlJCVDE5UmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Retevis_RT1.img0000644000175000017500000000200014411666130017242 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%2F%2Fџџџџџџџџ%3F%3F——џџџџ%4F%4F……џџџџ%5F%5F  џџџџ%6F%6F  џџџџ%7F%7Fˆˆџџџџ%8F%8F00џџџџ%8F%8Fџџџџ%RF%RFbbџџџџ%SF%SFggџџџџ%TF%TFyyџџџџ%UF%UF1€1€џџџџe5Fe5FQ€Q€џџџџ%WF%WFe€e€џџџџe7Fe7F%%џџџџ%YF%YFRRџџџџџџџџџџџџџџџџџџџџ­нД џџџџ2оџ†ЪAџџџџџџџџџџџџџџџџџџџ?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPXT8Kѓџџџџџџџџрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ї­Ьлћв)24џџ‘ Xџ „№ џў,- џ.џџџџџџџ!!!!џџ Омџџџџџ›Дмџџџџџ›Кмџџџџџ–Умџџџџџ–Ямџџџџџ‘Кмџџџџџ‘Шмџџџџџ‘мцџџџџџŒЯцџџџџџŒџџџџџџџŒџџџџџџџ џџџџџџџЅтџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Icom_IC-T8A.img0000644000175000017500000000366014411666130017004 0ustar hibbyhibby%P SpTpsp@ r  pg€p $џџџџџџџџe€C P DPP `  %* џџџџџџџџџџџџџџџџџџџџџџџџCP€Q Yz CPzQ Yz CPpQ Yz CPjQ Yz CP`Q Y€ Ch Q XP ChQ XP CgšQ XP CgQ XP CgŠQ XZ DRP DRP " " џџџџџџџџџџџџџџџџ@ @ 6 ˆ  8 D˜P  " x џџџџџџџџ @ @ € DP EP @ € DP 9 Y D™P   џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD˜P DP DRP b " x B x D˜P ‚ 8 @P F˜P џџџџџџџџџџџџџџџџD™`P D™`P @@ @@ 9 € EP џџџџџџџџXP   џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ XP DP џџџџџџџџПџџџ@ @џџ%% џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD((,,,,,,€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€8<џџџџџџџџџџџџџџ%* џџџџџџџ P џџџџџџџAz џџџџџџџE0џџџџџџџ0 џџџџџџџC”X*џџџџџџџ€ џџџџџџџ џџџџџџџџџџџџџџџџџ IcomCloneFormat3chirp-20240224/tests/images/Retevis_RT47V.img0000644000175000017500000000222514411666130017473 0ustar hibbyhibbyџџџџџџџџџџџџьџџ  џџџџ§€€€џџџџ§@@@џџџџ§pEpEpEџџџџљFFFџџџџљџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹џџџџџџџџSMџP558џџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDQ3ViIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwOTE3IiwgInJjbGFzcyI6ICJSVDQ3VlJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Puxing_PX-777.img0000644000175000017500000000614014411666130017347 0ustar hibbyhibby e eџџџџљџџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџџџХўџџџџџџџџџџџя:џџџџРЈФ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХ=—chirp-20240224/tests/images/TYT_TH-UVF1.img0000644000175000017500000001002014411666130016726 0ustar hibbyhibby`@@H59GRџџџџџџџџџџџџџџџџp`v`џџ0FsEyEџџbFD%D1%џџ0Fg0a0џџFf@`@џџgFD„%D4%џџџџFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDAD‘џџyFD‰%D9%џџyFD–uDFuџџyFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD@D@#€#РFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџRPFPџџbFiUcUџџџџD'PDwPџџgFRFџџgFDy%D)%џџџџFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџe e џџџџFD`D`џџџџFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF%bPF%bPџџџџFF%‡PF%‡PџџџџFF&PF&PџџџџFF&7PF&7PџџџџFF&bPF&bPџџџџFF&‡PF&‡PџџџџFF'PF'PџџџџFFubPFubPџџџџFFu‡PFu‡PџџџџFFvPFvPџџџџFFv7PFv7PџџџџFFvbPFvbPџџџџFFv‡PFv‡PџџџџFFwPFwPџџџџFF%PFuPџџџџFF%uFuuџџџџFF&FvџџџџFF&%Fv%џџџџFF&PFvPџџџџFF&uFvuџџFF'FwџџџџFF'%Fw%џџџџFџџџџџџџџџџџџџџџџ  џџџџFџџџџF@@џџџџFEpEpџџџџFFFџџџџF$џџџџџџџџF$%џџџџџџџџF$PџџџџџџџџF$uџџџџџџџџF%џџџџџџџџF%%џџџџџџџџF%PџџџџџџџџFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8E8EџџџџFA`A`џџџџF9P9PџџџџFCg•Cg•џџџџF%P%PџџџџFA^ˆ }P W3SJM џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ5џџџџџџџџK3MAD-2K3MAD-1K3MAD-4W3ICF-VK3ERM-VK3ERM-UџџџџџџџџџџџџџџџџџџџџџN3ST-FRN3ST-PGN3ST-BAџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџN3VNGџџKV3B-VџKV3B-UџK3YGG-VK3YGG-UџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџN4HAJџџN4HAJџџN4HAJџџN4HAJџџKD4KDOџW4EWN-VW4EWN-Uџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2M Call440CallџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGM/FRS1GM/FRS2GM/FRS3GM/FRS4GM/FRS5GM/FRS6GM/FRS7FRS 08џFRS 09џFRS 10џFRS 11џFRS 12џFRS 13џFRS 14џGMRS550GMRS575GMRS600GMRS625GMRS650GMRS675GMRS700GMRS725GMRS725MURS 1џMURS 2џMURS 3џMURS 4џMURS 5џNOAAWX1NOAAWX2NOAAWX3NOAAWX4NOAAWX5NOAAWX6NOAAWX7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFDKFIREMC FIREMC FD7B ‘$Ayџџџџџџџ ‘$Adџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`@@H59GRџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџмџџ–dAA<<ьAёCѓE і G$љ$G&ќ&H''J((L))N**M))M((M'ћ'M&њ&M&љ&L$љ$J"ј"H ї FѕDѓCёAђ>ю<љ:љ:ј9 ї 9"і"8%ѕ%8%ѕ%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџpА@РPА џџџџџџџџџџџџџџџџџџџџџџџџџџџџх 0P'™%ЊS#Лџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ55550Хll`l55500еnnbn55550хppdpeUPP@ѕppfp•e`P@rrhrХ||`Ptthtх`vvjvхЅpxxlxХЅ}}o}ХХЅѓ€€s€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќЪ™‚‡ФЕЕЗЁqv>b‘џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџіnџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ŒџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDkwMDBEXzQwMC00OTAiLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIxMDgxNCIsICJyY2xhc3MiOiAiUlQ5MDAwRFVIRlJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Kenwood_TH-D74_clone_mode.img0000644000175000017500000172165514551723752021716 0ustar hibbyhibbyџџџџџџџџџџџџџ000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp7›Р' CQCQCQDIRECTDIRECTX‚ Р' iCQCQCQDIRECTDIRECTOPџџPџџOMџџџџџџџџџџџџџџџџџџџџџџO џ`?=џџџџџџџџџџџџџџџ§чœы4Т\м5Т{Р\м5ТФ}5Т%РYРtЂ5ТHт5Тœ,AТ?Р<Ђ5ТЃбРp7›Р' CQCQCQDIRECTDIRECTџџџџџџџџрЮ> jwCQCQCQDIRECTDIRECTџџџџџџџџо9@KLˆCQCQCQDIRECTDIRECTџџџџџџџџ`=D!CQCQCQDIRECTDIRECTџџџџџџџџрg55CQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџР2 DCQCQCQDIRECTDIRECTџџџџџџџџ`?=ЛCQCQCQDIRECTDIRECTџџџџџџџџ€‰U!CQCQCQDIRECTDIRECTџџџџџџџџX‚ Р' iCQCQCQDIRECTDIRECTџџџџџџџџАЦ ЊCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџРЕJ jwCQCQCQDIRECTDIRECTџџџџџџџџо9@KLˆCQCQCQDIRECTDIRECTџџџџџџџџp^[ЊCQCQCQDIRECTDIRECTџџџџџџџџиЈЙ@KLq№CQCQCQW1IXU BW1IXU Bџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   џџ2€_ цп I€p€Ёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   "#$000$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKK7DS 5039629401TH-D74џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKK7DS-6џџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/[Fx<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTEMPџџџ*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL,QST,CQ,KWDџџџџџ000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/E/E/Eџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џ џ џ џ џ џ џ џ џ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"џџ"џџ"џџ"џџ"џџ"џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ШГР'  CQCQCQDIRECTDIRECT€ШГР' € CQCQCQDIRECTDIRECT€ШГР' @ CQCQCQDIRECTDIRECT€ШГР'   CQCQCQDIRECTDIRECT€ШГР' ,CQCQCQDIRECTDIRECT€ШГР' €  CQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџ€ШГР' @ CQCQCQDIRECTDIRECT€ШГР'   CQCQCQDIRECTDIRECT€ШГР'  ,CQCQCQDIRECTDIRECT€ШГР' @ CQCQCQDIRECTDIRECT€ШГР' @ CQCQCQјДГР' ` CQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџ€ШГР' pCQCQCQDIRECTDIRECT€ШГР' €џџџџљ/(`"zЈN1SU-2џW7KKE-9 . *Sџџщщџџџџaъџ /vџџџџљ-(#{1\HEBOWXW7SRAџK7TAY-8 ,6џџщщџџџџaъџ „/jџџџџљ-Dzd446.020MHz C100џN7NJO-14 . 13џџщщџџџџaъџ „/uџџџџљ/ Lz,147.080MHz T110 +060 Tacoma to the BayJUPITRW7SRAџLINCON -џABџџџџџџщщџџџџaъџ@џџџџџџџ§џџџџџџџџOregon Coast Repeater Group: WX: Lincoln CIDIOTVџOCNSID -;џABџџџџџџ<.б'\S_џџџџљ-8{:@p000P000h92b10193.U21h HEBOWXIDIOTVџK7JLX-1ABџџщщџџџџaъџ €/-џџџџј- ,z#146.550MHz D031 https://blog.k7jlx.ioџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHamacyoTokyoJP1YIU AJP1YIU Gkф@KLѓ\џџюџџHamacyoTokyoJP1YIU BJP1YIU G §L-1ѓ\џџюEdogawaTokyoJP1YJK AJP1YJK G0­+@KLѓ\џџюџџџџџџџџџџџџџџџџEdogawaTokyoJP1YJK BJP1YJK Gа§L-1ѓ\џџюEbisuTokyoJR1VF AJR1VF GАDњL-1ѓ\џџюSugamoTokyoJR1WN AJR1WN G—,@KLѓ\џџюџџџџџџџџџџџџџџџџTokyoDenkiUnivTokyoJP1YDG AJP1YDG G Hт@KLѓ\џџюChofuTokyoJP1YIX AJP1YIW GpќL-1ѓ\џџюNishitokyoTokyoJP1YIW AJP1YIW GАV/@KLѓ\џџю џџџџџџџџџџџџџџџџNishitokyoTokyoJP1YIW BJP1YIW GPЫћL-1ѓ\џџю KomaeTokyoJP1YJO AJP1YJO G/@KLѓ\џџю HamFair 430-ATokyoJP1YJJ AJP1YJJ GPl.@KLѓ\џџю џџџџџџџџџџџџџџџџHamFair 1200TokyoJP1YJJ BJP1YJJ GАгїL-1ѓ\џџю HamFair 430-CTokyoJP1YJJ CJP1YJJ G0­+@KLѓ\џџю Yokohama-KohokuKanagawaJP1YJY AJP1YJY Gрф@KLѓ\џџю џџџџџџџџџџџџџџџџYokohama-KonanKanagawaJP1YIQ AJP1YIQ Gа-@KLѓ\џџюShonanKoukaDaiKanagawaJP1YJV AJP1YJV G№-@KLѓ\џџюShonanKoukaDaiKanagawaJP1YJV BJP1YJV GpЈљL-1ѓ\џџюџџџџџџџџџџџџџџџџEbinaKanagawaJP1YJX AJP1YJX G_+@KLѓ\џџюEbinaKanagawaJP1YJX BJP1YJX GPZљL-1ѓ\џџюInageChibaJP1YJQ AJP1YJQ GpК.@KLѓ\џџюџџџџџџџџџџџџџџџџFunabashiChibaJP1YFY AJP1YFY G`Uх@KLѓ\џџюKisarazuChibaJP1YEM AJP1YEM GpI,@KLѓ\џџюNagareyamaChibaJP1YJR AJP1YJR GPћ+@KLѓ\џџюџџџџџџџџџџџџџџџџYachimataChibaJP1YJT AJP1YJT G Йф@KLѓ\џџюKatoriChibaJP1YDS AJP1YDS Gа-@KLѓ\џџюChiba-NagaraChibaJP1YKM AJP1YKM GрЋс@KLѓ\џџюџџџџџџџџџџџџџџџџIrumaSaitamaJP1YKG AJP1YKG G`sр@KLѓ\џџюFurukawaIbarakiJP1YIK AJP1YIK G00@KLѓ\џџюTsukubaIbarakiJP1YJZ AJP1YJZ GPн0@KLѓ\џџюџџџџџџџџџџџџџџџџKashimaIbarakiJP1YKH AJP1YKH G/@KLѓ\џџюShizuokaShizuokaJP2YGY AJP2YGY GPн0@KLѓ\џџю Gifu-ImazawaGifuJP2YGR Ap+1@KLѓ\џџю!џџџџџџџџџџџџџџџџGifu-KinkazanGifuJP2YDS AJP2YDS Gа2@KLѓ\џџю "EnaGifuJR2WO AJR2WO GаТ*@KLѓ\џџю!#Ibi-OnoGifuJP2YHR AJP2YHR G žо@KLѓ\џџю"$џџџџџџџџџџџџџџџџKamoGun-YaotsuGifuJP2YGA A№ђ/@KLѓ\џџю#%Nagoya-UnivAichiJP2YGI AJP2YGE GA0@KLѓ\џџю$&JRC-NagoyaDai2HPAichiJP2YGG AJP2YGE G№Q§L-1ѓ\џџю%'џџџџџџџџџџџџџџџџDenpa-GakuenAichiJP2YGE AJP2YGE G §L-1ѓ\џџю&(KasugaiAichiJP2YGK AJP2YGE G00@KLѓ\џџю')NishioAichiJP2YDN AJP2YDN G0.@KLѓ\џџю(*џџџџџџџџџџџџџџџџKotaAichiJP2YDP AJP2YDP GPн0@KLѓ\џџю)+Kyoto-HieizanKyotoJP3YCS AJP3YIJ Gр:п@KLѓ\џџю*,Kyoto-NishikyoKyotoJP3YIV AJP3YIV G€Ср@KLѓ\џџю+-џџџџџџџџџџџџџџџџArashiyamaKyotoJP3YHV AJP3YHV GA0@KLѓ\џџю,.Kyoto-MinamiKyotoJP3YIX AJP3YIX G@–т@KLѓ\џџю-/Shiga-MoriyamaShigaJR3WZ AJR3WZ GАЧ1@KLѓ\џџю.0џџџџџџџџџџџџџџџџNaraNaraJP3YIA AJP3YIA Gа-@KLѓ\џџю/1SakuraiNaraJP3YIW AJP3YIW G€2у@KLѓ\џџю02Nara-IkomaNaraJP3YIE AJP3YIE Gy1@KLѓ\џџю13џџџџџџџџџџџџџџџџNarayamaNaraJP3YHL AJP3YHH Gа2@KLѓ\џџю24WTCOsakaJP3YHF AJP3YHH Gа§L-1ѓ\џџю35HiranoOsakaJP3YHH AJP3YHH G00@KLѓ\џџю46џџџџџџџџџџџџџџџџHiranoOsakaJP3YHH BJP3YHH GАЕќL-1ѓ\џџю57IkomaOsakaJP3YHJ AJP3YHH GаТ*@KLѓ\џџю68IkomaOsakaJP3YHJ BJP3YHH G№Q§L-1ѓ\џџю79џџџџџџџџџџџџџџџџSakaiOsakaJP3YHT AJP3YHT GАV/@KLѓ\џџю8:NeyagawaOsakaJP3YHX AJP3YHX Gp+1@KLѓ\џџю9;Kii-TanabeWakayamaJP3YIC AJP3YIC Gа2@KLѓ\џџю:<џџџџџџџџџџџџџџџџAritaWakayamaJP3YCV AJR3WV GpК.@KLѓ\џџю;=AritaWakayamaJP3YCV BJR3WV G0›іL-1ѓ\џџю<>KoyasanWakayamaJP3YHN AJP3YHN G№+@KLѓ\џџю=?џџџџџџџџџџџџџџџџKoyasanWakayamaJP3YHN BJP3YHN GpќL-1ѓ\џџю>@Wakayama-SusamiWakayamaJP3YIU AJP3YIU G0­+@KLѓ\џџю?ARokko-MinamiHyogoJR3VK AJR3VK GPн0@KLѓ\џџю@BџџџџџџџџџџџџџџџџRokko-MinamiHyogoJR3VK BJR3VK G№ѓL-1ѓ\џџюACNadaHyogoJP3YES A!т@KLѓ\џџюBDKurashikiOkayamaJP4YDV AJP4YDV GаЄ/@KLѓ\џџюCEџџџџџџџџџџџџџџџџSuo-OshimaYamaguchiJP4YDW AJP4YDW GАЧ1@KLѓ\џџюDFHiroshimaHiroshimaJP4YDU AJP4YDU Gа2@KLѓ\џџюEGTakamatsuKagawaJP5YCN AJP5YCN Gp+1@KLѓ\џџюFHџџџџџџџџџџџџџџџџMatsuyamaEhimeJP5YCO AJP5YCO Gy1@KLѓ\џџюGIKochiKochiJP5YCQ AJP5YCQ GАЧ1@KLѓ\џџюHJFukuokaFukuokaJP6YHS AJP6YHS G—,@KLѓ\џџюIKџџџџџџџџџџџџџџџџKumamotoKumamotoJP6YHN AJP6YHN G№+@KLѓ\џџюJLYatsushiroKumamotoJP6YHR AJP6YHR Gy1@KLѓ\џџюKMGinowanOkinawaJR6YZ AJR6YZ Gy1@KLѓ\џџюLNџџџџџџџџџџџџџџџџSendaiMiyagiJP7YEL AJP7YEL Gа2@KLѓ\џџюMOSapporoHokkaidoJP8YDZ AJP8YDZ Gа2@KLѓ\џџюNPChitoseHokkaidoJP8YEB AJP8YEB GАЧ1@KLѓ\џџюOQџџџџџџџџџџџџџџџџHakodateHokkaidoJP8YEA AJP8YEA G№+@KLѓ\џџюPRAsahikawaHokkaidoJP8YEE AJP8YEE Gp+1@KLѓ\џџюQSObihiroHokkaidoJP8YEC AJP8YEC Gy1@KLѓ\џџюRTџџџџџџџџџџџџџџџџKitamiHokkaidoJP8YEF AJP8YEF GPн0@KLѓ\џџюSUTakaokaToyamaJP9YEG AJP9YEG G№+@KLѓ\џџюTVNantoToyamaJP9YEI AJP9YEI GАЧ1@KLѓ\џџюUWџџџџџџџџџџџџџџџџNiigataUnivNiigataJP0YDR AJP0YDR G№-@KLѓ\џџ юVXNagaokaNiigataJP0YDU AJP0YDU Gp+1@KLѓ\џџ юWYUedaNaganoJP0YDP AJP0YDP G№+@KLѓ\џџ юXZџџџџџџџџџџџџџџџџUtsukushigaharaNaganoJP0YCI AJP0YDP G0­+@KLѓ\џџ юY[NaganoNaganoJP0YEC AJP0YEC G№ђ/@KLѓ\џџ юZ\Chiang MaiChiang MaiHS5AC CHS5AC GlŠАŽѓTџџ ю[]џџџџџџџџџџџџџџџџFarm OzondjisseErongoV53DV BV53DV Gр<2€їsѓ<џџ ю\^Farm OzondjisseErongoV53DV CV53DV GЎ­Р' ѓ<џџ ю]_WindhoekKhomasV53W CV53W G 4ЏР' ѓ<џџ ю^`џџџџџџџџџџџџџџџџPort ElizabethEastern CapeZU9KDL AZU9KDL G˜YАР' ѓ@џџ ю_aPort ElizabethEastern CapeZU9KDL BZU9KDL GРf€їsѓ@џџ ю`bPort ElizabethEastern CapeZU9KDL CZU9KDL GXL­Р' ѓ@џџ юacџџџџџџџџџџџџџџџџDurbanKwaZulu-NatalZS0PMB BZS0PMB GРf€їsѓ@џџ юbdDurbanKwaZulu-NatalZS0PMB CZS0PMB GЬЏР' ѓ@џџ юcePietermaritzburgKwaZulu-NatalZU9PKF BZU9PKF G*€їsѓ@џџ юdfџџџџџџџџџџџџџџџџPretoriaGautengZS6PTA CZS6PTA GteЏР' ѓ@џџ юegSandton JNBGautengZS6STN CZS6STN GшБР' ѓ@џџ юfhKeutschachCarinthiaOE8XKK COE8XKK G,}­Р' ѓ<џџ(юgiџџџџџџџџџџџџџџџџGraz - DoblStyriaOE6XDE BOE6XDE G )€їsѓ<џџ(юhjOberer HіhenwegStyriaOE6XDG BOE6XDG G8І%€їsѓ<џџ(юikLinzUpper AustriaOE5XOL BOE5XOL GH\#€їsѓ<џџ(юjlџџџџџџџџџџџџџџџџViennaViennaOE1XDS AOE1XDS GгgM?Ћѓ<џџ(юkmViennaViennaOE1XDS BOE1XDS GH\#€їsѓ<џџ(юlnBoomAntwerpON0DP BON0DP G$h"€їsѓ<џџ)юmoџџџџџџџџџџџџџџџџKluisbergenEast FlandersON0VA BON0VA GhШ€їsѓ<џџ)юnpLokerenEast FlandersON0LOK BON0LOK G`э€їsѓ<џџ)юoqSint-NiklaasEast FlandersON0SNW BON0SNW G@Ж0€їsѓ<џџ)юprџџџџџџџџџџџџџџџџDiestFlemish BrabantON0DST BON0DST Gy1€їsѓ<џџ)юqsGosseliesHainautON0CPS BON0CPS G13€їsѓ<џџ)юrtFlщronLiшgeON0LGE BON0LGE GЌ’3€їsѓ<џџ)юsuџџџџџџџџџџџџџџџџUniv. of LiшgeLiшgeON0ULG BON0ULG Gˆž2€їsѓ<џџ)юtvUniv. of LiшgeLiшgeON0ULG CON0ULG GЈЎР' ѓ<џџ)юuwVrerenLimburgON0LB BON0LB GЄ‚(€їsѓ<џџ)юvxџџџџџџџџџџџџџџџџOostendeWest FlandersON0OS AON0OS G o_M?Ћѓ<џџ)юwyOostendeWest FlandersON0OS BON0OS Gр<2€їsѓ<џџ)юxzOostendeWest FlandersON0OS CON0OS GteЏР' ѓ<џџ)юy{џџџџџџџџџџџџџџџџrayon VitoshaSofiaLZ0DSR BLZ0DSR GАх,@KLѓ<џџ*юz|CelavacLika-Senj9A0DZD B9A0DZD GјЭ.€їsѓ<џџ+ю{}OstravaMoravian-SilesiaOK0DSK BOK0DSK G@$€їsѓ<џџ,ю|~џџџџџџџџџџџџџџџџPraguePragueOK0HCS BOK0HCS Gy1€їsѓ<џџ,ю}BrnoSouth MoraviaOK0BRQ BOK0BRQ Gy1€їsѓ<џџ,ю~€CopenhagenCapitalOZ2REA BOZ2REA Gœžь€„ѓ<џџ-юџџџџџџџџџџџџџџџџCopenhagenCapitalOZ2REA COZ2REA GteЏР' ѓ<џџ-ю€‚MontmaraultAllierF1ZHY BF1ZHY GbЇРnѓ<џџ.юƒHaguenauBas-RhinF1ZDZ BF1ZDZ GXЇРnѓ<џџ.ю‚„џџџџџџџџџџџџџџџџLyonMщtropole deLyonF1ZDI BF1ZDI G№ђ/€їsѓ<џџ.юƒ…ParisParisF1ZPL BF1ZPL GфHЅРnѓ<џџ.ю„†ParisParisF1ZPL CF1ZPL G4XЌР' ѓ<џџ.ю…‡џџџџџџџџџџџџџџџџHAM RADIOFriedrichshafenDB0COM BDB0COM Gиa3€їsѓ<џџ/ю†ˆHAM RADIOFriedrichshafenDB0COM CDB0COM G 4ЏР' ѓ<џџ/ю‡‰GіppingenBadenWќrttembergDB0RIG BDB0RIG GdЊ1€їsѓ<џџ/юˆŠџџџџџџџџџџџџџџџџKarlsbadBadenWќrttembergDB0DJ ADB0DJ G˜ЎfM?Ћѓ<џџ/ю‰‹KarlsbadBadenWќrttembergDB0DJ BDB0DJ Gр<2€їsѓ<џџ/юŠŒKarlsbadBadenWќrttembergDB0DJ CDB0DJ GФ(АР' ѓ<џџ/ю‹џџџџџџџџџџџџџџџџKlippeneckBadenWќrttembergDB0KLI BDB0KLI GЙ8Рnѓ<џџ/юŒŽLudwigsburgBadenWќrttembergDB0LBX BDB0LBX GР›*€їsѓ<џџ/юArbergBavariaDB0AB BDB0AB Gy1€їsѓ<џџ/юސџџџџџџџџџџџџџџџџMuenchenBavariaDB0TVM BDB0TVM Gиa3€їsѓ<џџ/ю‘WќrzburgBavariaDB0WZ ADB0WZ GоbM?Ћѓ<џџ/ю’WќrzburgBavariaDB0WZ BDB0WZ G8л1€їsѓ<џџ/ю‘“џџџџџџџџџџџџџџџџWќrzburgBavariaDB0WZ CDB0WZ GH–ЏР' ѓ<џџ/ю’”BerlinBerlinDB0DF BDB0DF GdЊ1€їsѓ<џџ/ю“•DARC HQ/BaunatalHesseDB0AFZ BDB0AFZ G8л1€їsѓ<џџ/ю”–џџџџџџџџџџџџџџџџBad SodenHesseDB0ICM ADB0ICM GPЦdM?Ћѓ<џџ/ю•—Bad SodenHesseDB0ICM BDB0ICM GX|9Рnѓ<џџ/ю–˜GiessenHesseDB0SIF BDB0SIF G 2€їsѓ<џџ/ю—™џџџџџџџџџџџџџџџџGroпer FeldbergHesseDB0HRF ADB0HRF GPHJ?Ћѓ<џџ/ю˜šGroпer FeldbergHesseDB0HRF BDB0HRF Gy1€їsѓ<џџ/ю™›Hoher MeiпnerHesseDB0HRM BDB0HRM Gˆž2€їsѓ<џџ/юšœџџџџџџџџџџџџџџџџDortmundN.R-WestphaliaDB0DDO CDB0DDO GH–ЏР' ѓ<џџ/ю›HagenN.R-WestphaliaDB0HAA BDB0HAA GЌ’3€їsѓ<џџ/юœžMarlN.R-WestphaliaDB0NG ADB0NG G˜ЎfM?Ћѓ<џџ/юŸџџџџџџџџџџџџџџџџMarlN.R-WestphaliaDB0NG BDB0NG Gиa3€їsѓ<џџ/юž MќlheimN.R-WestphaliaDF0MHR BDF0MHR GdЊ1€їsѓ<џџ/юŸЁMќlheimN.R-WestphaliaDF0MHR CDF0MHR GЎ­Р' ѓ<џџ/ю ЂџџџџџџџџџџџџџџџџOelbergN.R-WestphaliaDB0DBN BDB0DBN GђЖ2€їsѓ<џџ/юЁЃHerxheimRheinland-PfalzDB0WIM BDB0WIM G13€їsѓ<џџ/юЂЄHohenstein-ErnstSaxonyDB0SBX BDB0SBX Gр<2€їsѓ<џџ/юЃЅџџџџџџџџџџџџџџџџHohenstein-ErnstSaxonyDB0SBX CDB0SBX GЬЏР' ѓ<џџ/юЄІMittweidaSaxonyDM0MW BDM0MW G03€їsѓ<џџ/юЅЇAthensAtticaSV1P ASV1P G( ГK?Ћѓ<џџ0юІЈџџџџџџџџџџџџџџџџAthensAtticaSV1P BSV1P Gш1€їsѓ<џџ0юЇЉFlorinaWesternMacedoniaSZ2RLF BSZ2RLF Gt`/€їsѓ<џџ0юЈЊMonte MaiellaAbruzzoIR6UCC BIR6UCC GTxЁ@KLѓ<џџ3юЉЋџџџџџџџџџџџџџџџџMonte MaiellaAbruzzoIR6UCC CIR6UCC GЬЏР' ѓ<џџ3юЊЌBariApuliaIR7UBA BIR7UBA G`лЅjѓ<џџ3юЋ­BariApuliaIR7UBA CIR7UBA Gдо­Р' ѓ<џџ3юЌЎџџџџџџџџџџџџџџџџMonte PierfaoneBasilicataIR8BQ CIR8BQ GјвЎР' ѓ<џџ3ю­ЏAvellinoCampaniaIR8UAF BIR8UAF GœУjѓ<џџ3юЎАBattipagliaCampaniaIR8BT BIR8BT GЈУЇ@KLѓ<џџ3юЏБџџџџџџџџџџџџџџџџNapoliCampaniaIR8AW BIR8AW GЈУЇ@KLѓ<џџ3юАВPordenoneFRIIR3UIB BIR3UIB GˆŒИjѓ<џџ3юБГUdineFRIIR3UBZ BIR3UBZ GшoЯjѓ<џџ3юВДџџџџџџџџџџџџџџџџRomeLazioIR0MA AIR0MA G„UMР;Gѓ<џџ3юГЕRomeLazioIR0MA BIR0MA Gъ_Ё@KLѓ<џџ3юДЖRomeLazioIR0MA CIR0MA GАГи"ѓ<џџ3юЕЗџџџџџџџџџџџџџџџџBernate TicinoLombardyIR2UEZ AIR2UEZ GxиRM€[ѓ<џџ3юЖИBernate TicinoLombardyIR2UEZ BIR2UEZ GTтЙjѓ<џџ3юЗЙBresciaLombardyIR2UBG BIR2UBG GЙjѓ<џџ3юИКџџџџџџџџџџџџџџџџMilanLombardyIR2UDY AIR2UDY G(RMР' ѓ<џџ3юЙЛMilanLombardyIR2UDY BIR2UDY GМ6Зjѓ<џџ3юКМAlbugnanoPiedmontIR1UCB BIR1UCB G ЮЂjѓ<џџ3юЛНџџџџџџџџџџџџџџџџTorinoPiedmontIR1CJ CIR1CJ GlUЄ@Bѓ<џџ3юМОPlermoSiciliyIR9P BIR9P Gp‘Ѓjѓ<џџ3юНПPlermoSiciliyIR9P CIR9P G|@ЎР' ѓ<џџ3юОРџџџџџџџџџџџџџџџџScandicciTuscanyIR5UBN BIR5UBN G=Іjѓ<џџ3юПСTerniUmbriaIR0K BIR0K GмmІjѓ<џџ3юРТTerniUmbriaIR0K CIR0K Gдо­Р' ѓ<џџ3юСУџџџџџџџџџџџџџџџџMonseliceVenetoIR3UEF AIR3UEF G(RM€[ѓ<џџ3юТФMonseliceVenetoIR3UEF BIR3UEF G8ЩЗjѓ<џџ3юУХMonseliceVenetoIR3UEF CIR3UEF GиfГрШѓ<џџ3юФЦџџџџџџџџџџџџџџџџDippechCapellenLX0DRD BLX0DRD G<.+€їsѓ<џџ 4юХЧJunglinsterGrevenmacherLX0DRJ BLX0DRJ G@Ж0€їsѓ<џџ 4юЦШRiesenhaffRedangeLX0DRH BLX0DRH GРf€їsѓ<џџ 4юЧЩџџџџџџџџџџџџџџџџBredaNorth BrabantPI1HWB BPI1HWB G р€їsѓ<џџ!5юШЪDelftSouth HollandPI1HGL BPI1HGL G*€їsѓ<џџ!5юЩЫIJsselsteinUtrechtPI1UTR API1UTR GР*mM?Ћѓ<џџ!5юЪЬџџџџџџџџџџџџџџџџIJsselsteinUtrechtPI1UTR BPI1UTR G0Ы&€їsѓ<џџ!5юЫЭIJsselsteinUtrechtPI1UTR CPI1UTR G˜$Єѓ<џџ!5юЬЮKongsvingerHedmarkLD2KR BLD2KR GФхц€„ѓ<џџ"6юЭЯџџџџџџџџџџџџџџџџKvinesdalVest-AgderLD4LK CLD4LK GЬЏР' ѓ<џџ"6юЮаSandnesRogalandLD4VF BLD4VF G№Дц€„ѓ<џџ"6юЯбTromsјTromsLD9TN BLD9TN G€…ъ€„ѓ<џџ"6юавџџџџџџџџџџџџџџџџLeknesNordlandLD8LK BLD8LK G|Шиѓ<џџ"6юбгRTCN KrakѓwLesser PolandSR9UVM BSR9UVM G@Ж0€їsѓ<џџ#7ювдAѓdzAѓdzSR7UVL BSR7UVL G:*€їsѓ<џџ#7югеџџџџџџџџџџџџџџџџWarsawMasoviaSR5UVA BSR5UVA GМH1€їsѓ<џџ#7юджGdyniaPomeraniaSR2UVG BSR2UVG G з%€їsѓ<џџ#7юезSzczecinWest PomeraniaSR1UVS BSR1UVS Gч0€їsѓ<џџ#7южиџџџџџџџџџџџџџџџџOliveira/AzemщisNorteCQ0DOA BCQ0DOA Gh§*€їsѓ<џџ$8юзйSerra deLeirancoNorteCQ0DCH BCQ0DCH G˜$€їsѓ<џџ$8юикTorres VedrasCentroCQ0DTV BCQ0DTV G8І%€їsѓ<џџ$8юйлџџџџџџџџџџџџџџџџRamadaLisbonCQ0DLX BCQ0DLX G№Н#€їsѓ<џџ$8юкмPortalegreAlentejoCQ0DSM BCQ0DSM Gt+#€їsѓ<џџ$8юлнSan MarinoSan MarinoT79DV BT79DV G њЗjѓ<џџ';юмоџџџџџџџџџџџџџџџџMariborDravaS55DMX BS55DMX GЉ-€їsѓ<џџ*>юнпZaragozaAragonED2ZAA BED2ZAA GАА €їsѓ<џџ+?юорIrunBasque CountryED2ZAB CED2ZAB G˜YАР' ѓ<џџ+?юпсџџџџџџџџџџџџџџџџBarcelonaCataloniaED3YAK CED3YAK GPqЎР' ѓ<џџ+?юртCastellar VallщsCataloniaEA3RCC BEA3RCC Gј˜"€їsѓ<џџ+?юсуVaxjoKronobergSK7HW BSK7HW Gрўш€„ѓ<џџ,@ютфџџџџџџџџџџџџџџџџMinnesbergSkхneSK7RDS CSK7RDS Gю3­Р' ѓ<џџ,@юухTyresoStockholmSK0QO BSK0QO G˜ч€„ѓ<џџ,@юфцFalkenfluhBernHB9BG BHB9BG GO €їsѓ<џџ-AюхчџџџџџџџџџџџџџџџџMenznauLuzernHB9AW BHB9AW G„,€їsѓ<џџ-AюцшMenznauLuzernHB9AW CHB9AW GlŠАР' ѓ<џџ-AючщRigi-ScheideggSchwyzHB9RF BHB9RF GdЊ1€їsѓ<џџ-AюшъџџџџџџџџџџџџџџџџBraunauThurgauHB9HD CHB9HD G,}­Р' ѓ<џџ-AющыMonte TamaroTicinoHB9H BHB9H G03€їsѓ<џџ-AюъьMotto RotondoTicinoHB9DD BHB9DD G@Ж0€їsѓ<џџ-AюыэџџџџџџџџџџџџџџџџLa BarilletteVaudHB9IAC BHB9IAC GЌ’3€їsѓ<џџ-AюьюLa BarilletteVaudHB9IAC CHB9IAC GФ(АР' ѓ<џџ-AюэяWarringtonHaltonGB7WC BGB7WC G 2@T‰ѓ8џџ/Fюю№џџџџџџџџџџџџџџџџSheffieldSouth YorkshireGB7SF BGB7SF Gœм5@T‰ѓ8џџ/FюяёSheffieldSouth YorkshireGB7SF CGB7SF GЧЏР' ѓ8џџ/Fю№ђAmpthillBedfordshireGB7DB BGB7DB GЄЗ4@T‰ѓ8џџ/GюёѓџџџџџџџџџџџџџџџџRoystonHertfordshireGB7PI BGB7PI G4ˆ8@T‰ѓ8џџ/HюђєFolkestoneKentGB7FK BGB7FK Gœм5@T‰ѓ8џџ/HюѓѕFolkestoneKentGB7FK CGB7FK GlŠАР' ѓ8џџ/HюєіџџџџџџџџџџџџџџџџHerne BayKentGB7IC AGB7IC GСэL-1ѓ8џџ/HюѕїHerne BayKentGB7IC BGB7IC Gy1@T‰ѓ8џџ/HюіјHerne BayKentGB7IC CGB7IC G$ЂЎР' ѓ8џџ/HюїљџџџџџџџџџџџџџџџџNorwichNorfolkGB7NB BGB7NB GL5@T‰ѓ8џџ/HюјњBewdleyWorcestershireGB7WF BGB7WF G 2@T‰ѓ8џџ/JюљћUpper LargoFifeGB7DE BGB7DE G€У3@T‰ѓ8џџ/KюњќџџџџџџџџџџџџџџџџUpper LargoFifeGB7DE CGB7DE G|@ЎР' ѓ8џџ/Kюћ§BristolConnecticutW1IXU BW1IXU GиЈЙ@KLѓ$џџ2dюќўBristolConnecticutW1IXU CW1IXU G ЉІР' ѓ$џџ2dю§џџџџџџџџџџџџџџџџџEast HartfordConnecticutW1CDG CW1CDG GАг›ѓ$џџ2dюўEnfieldConnecticutKB1UHR BKB1UHR G mx@KLѓ$џџ2dюџHaddamConnecticutKB1UHS BKB1UHS GpK@KLѓ$џџ2dюџџџџџџџџџџџџџџџџKillinglyConnecticutN1GAU BN1GAU G mx@KLѓ$џџ2dюMeridenConnecticutW1ECV BW1ECV GЗz@KLѓ$џџ2dюMeridenConnecticutW1ECV CW1ECV GPЌР' ѓ$џџ2dюџџџџџџџџџџџџџџџџNewingtonConnecticutW1HQ AW1HQ GH1ŠLЗѓ$џџ2dюNewingtonConnecticutW1HQ BW1HQ G щY@KLѓ$џџ2dюNewingtonConnecticutW1HQ CW1HQ G0ўШР' ѓ$џџ2dюџџџџџџџџџџџџџџџџNorwalkConnecticutW1NLK BW1NLK GHR@KLѓ$џџ2dю SalemConnecticutKD1STR BKD1STR G@Пm@KLѓ$џџ2dю TerryvilleConnecticutWD1STR BWD1STR GPIœ@KLѓ$џџ2dю  џџџџџџџџџџџџџџџџVernonConnecticutAA1HD BAA1HD GpЌZ@KLѓ$џџ2dю  VernonConnecticutAA1HD CAA1HD Gр}ЈР' ѓ$џџ2dю  WestbrookConnecticutW1BCG BW1BCG Gчv@KLѓ$џџ2dю џџџџџџџџџџџџџџџџAuburnMaineW1NPP AW1NPP G`–ЗLЗѓ$џџ2dю AuburnMaineW1NPP BW1NPP G 8l@KLѓ$џџ2dюAuburnMaineW1NPP CW1NPP G0аІР' ѓ$џџ2dюџџџџџџџџџџџџџџџџBiddefordMaineKC1ALA BKC1ALA Ghh@KLѓ$џџ2dюBiddefordMaineKC1ALA CKC1ALA GАTХР' ѓ$џџ2dюBrunswickMaineKS1R BKS1R Gиs­@KLѓ$џџ2dюџџџџџџџџџџџџџџџџCooperMaineW1SCV CW1SCV G(аТР' ѓ$џџ2dюKnoxMaineW1EMA AW1EMA G`=ЗKЗѓ$џџ2dюKnoxMaineW1EMA BW1EMA Gрz{@KLѓ$џџ2dюџџџџџџџџџџџџџџџџKnoxMaineW1EMA CW1EMA GаЧЊР' ѓ$џџ2dюTurnerMaineKB1VFA CKB1VFA G€ЊР' ѓ$џџ2dюBrocktonMassachusettsKB1YAC BKB1YAC GxdЧ@KLѓ$џџ2dюџџџџџџџџџџџџџџџџBrooklineMassachusettsK1MRA CK1MRA G@їІР' ѓ$џџ2dюBrooklineMassachusettsW1MRA BW1MRA Gш^З@KLѓ$џџ2dюDartmouthMassachusettsKC1BJB AKC1BJB G 1M-1ѓ$џџ2dюџџџџџџџџџџџџџџџџDartmouthMassachusettsKC1BJB BKC1BJB GаZe@KLѓ$џџ2dюDartmouthMassachusettsKC1BJB CKC1BJB GѓЈР' ѓ$џџ2dюFall RiverMassachusettsK1RFI AK1RFI G сЇР' ѓ$џџ2dю џџџџџџџџџџџџџџџџFall RiverMassachusettsK1RFI BK1RFI G5Ы@KLѓ$џџ2dю!Fall RiverMassachusettsK1RFI CK1RFI GрюЊР' ѓ$џџ2dю "FalmouthMassachusettsKB1ZEG CKB1ZEG GКЇР' ѓ$џџ2dю!#џџџџџџџџџџџџџџџџFeeding HillsMassachusettsW1KK AW1KK G eqLЗѓ$џџ2dю"$Feeding HillsMassachusettsW1KK BW1KK GинХ@KLѓ$џџ2dю#%Feeding HillsMassachusettsW1KK CW1KK G0аІР' ѓ$џџ2dю$&џџџџџџџџџџџџџџџџFreetownMassachusettsKB1WUW AKB1WUW GШ8Щѓ$џџ2dю%'FreetownMassachusettsKB1WUW BKB1WUW G˜Я@KLѓ$џџ2dю&(FreetownMassachusettsKB1WUW CKB1WUW GиаЫ@Bѓ$џџ2dю')џџџџџџџџџџџџџџџџHollistonMassachusettsW1DSR BW1DSR GИвЅ@KLѓ$џџ2dю(*HollistonMassachusettsW1DSR CW1DSR G ЉІР' ѓ$џџ2dю)+HolyokeMassachusettsAA1KK BAA1KK G˜fЊ@KLѓ$џџ2dю*,џџџџџџџџџџџџџџџџNorth OxfordMassachusettsKC1ACI BKC1ACI GјпЈ@KLѓ$џџ2dю+-SuttonMassachusettsKC1AZZ BKC1AZZ GаZe@KLѓ$џџ2dю,.WalpoleMassachusettsWA1PLE BWA1PLE G|œ@KLѓ$џџ2dю-/џџџџџџџџџџџџџџџџWestfordMassachusettsWB1GOF BWB1GOF GP@_@KLѓ$џџ2dю.0WestfordMassachusettsWB1GOF CWB1GOF GPЉР' ѓ$џџ2dю/1BowNew HampshireNE1DS ANE1DS GpПЎѓ$џџ2dю02џџџџџџџџџџџџџџџџBowNew HampshireNE1DS BNE1DS G˜(a@KLѓ$џџ2dю13BowNew HampshireNE1DS CNE1DS GPІК@Bѓ$џџ2dю24East KingstonNew HampshireK1GHZ AK1GHZ G(RM€УЩѓ$џџ2dю35џџџџџџџџџџџџџџџџEast KingstonNew HampshireK1GHZ BK1GHZ G@UU@KLѓ$џџ2dю46East KingstonNew HampshireK1GHZ CK1GHZ GХР' ѓ$џџ2dю57FremontNew HampshireN1HIT BN1HIT GјIС@KLѓ$џџ2dю68џџџџџџџџџџџџџџџџFremontNew HampshireN1HIT CN1HIT G@hЉР' ѓ$џџ2dю79HamptonNew HampshireK1HBR BK1HBR GИqЪ@KLѓ$џџ2dю8:HamptonNew HampshireK1HBR CK1HBR G=ЋР' ѓ$џџ2dю9;џџџџџџџџџџџџџџџџKensingtonNew HampshireKB1TIX CKB1TIX GР ЊР' ѓ$џџ2dю:<OssipeeNew HampshireN1ATV BN1ATV GMb@KLѓ$џџ2dю;=OssipeeNew HampshireN1ATV CN1ATV GИ/ФР' ѓ$џџ2dю<>џџџџџџџџџџџџџџџџPortsmouthNew HampshireKB1ZDR BKB1ZDR G0ŸW@KLѓ$џџ2dю=?SalemNew HampshireK1HRO AK1HRO G@M-1ѓ$џџ2dю>@SalemNew HampshireK1HRO BK1HRO G0>|@KLѓ$џџ2dю?AџџџџџџџџџџџџџџџџSalemNew HampshireK1HRO CK1HRO G@hЉР' ѓ$џџ2dю@BTwin MountainNew HampshireKB1UVE BKB1UVE G3\@KLѓ$џџ2dюACPortsmouthRhode IslandW1AAD CW1AAD G ЉР' ѓ$џџ2dюBDџџџџџџџџџџџџџџџџW.WarwickRhode IslandW1HDN CW1HDN GˆКУР' ѓ$џџ2dюCEAtlantic CityNew JerseyKC2TGB BKC2TGB Gиs­@KLѓ$џџ2eюDFBridgetonNew JerseyKC2TXB BKC2TXB G^‹@KLѓ$џџ2eюEGџџџџџџџџџџџџџџџџCedar GroveNew JerseyW2DGL AW2DGL G`M-1ѓ$џџ2eюFHCedar GroveNew JerseyW2DGL BW2DGL GШрA@KLѓ$џџ2eюGICedar GroveNew JerseyW2DGL CW2DGL GШ’К@Bѓ$џџ2eюHJџџџџџџџџџџџџџџџџFordsNew JerseyKD2HUY AKD2HUY GpПЎѓ$џџ2eюIKFordsNew JerseyKD2HUY BKD2HUY GшІѓ$џџ2eюJLFordsNew JerseyKD2HUY CKD2HUY G$ЂЎѓ$џџ2eюKMџџџџџџџџџџџџџџџџGlassboroNew JerseyKC2TXX BKC2TXX G };@KLѓ$џџ2eюLNKendall ParkNew JerseyKC2WBJ BKC2WBJ Glј…@KLѓ$џџ2eюMOLake HopatcongNew JerseyNJ2MC BNJ2MC GHR@KLѓ$џџ2eюNPџџџџџџџџџџџџџџџџLake HopatcongNew JerseyNJ2MC CNJ2MC G№ЋР' ѓ$џџ2eюOQLindenwoldNew JerseyK2EOC BK2EOC G&–=@KLѓ$џџ2eюPRMartinsvilleNew JerseyNJ2DG ANJ2DG GIˆLЗѓ$џџ2eюQSџџџџџџџџџџџџџџџџMartinsvilleNew JerseyNJ2DG BNJ2DG GP S@KLѓ$џџ2eюRTMartinsvilleNew JerseyNJ2DG CNJ2DG G ЉІР' ѓ$џџ2eюSUOceanviewNew JerseyNJ2CM BNJ2CM G6L;@KLѓ$џџ2eюTVџџџџџџџџџџџџџџџџVinelandNew JerseyK2GOD BK2GOD Gшєž@KLѓ$џџ2eюUWWoodstownNew JerseyNJ2SC BNJ2SC GRЃ†@KLѓ$џџ2eюVXAlbanyNew YorkWA2UMX BWA2UMX G 8l@KLѓ$џџ2eюWYџџџџџџџџџџџџџџџџBabylonNew YorkW2TOB BW2TOB GЎ=@KLѓ$џџ2eюXZBataviaNew YorkKD2FET AKD2FET GpПЎѓ$џџ2eюY[BataviaNew YorkKD2FET BKD2FET GФ–…@KLѓ$џџ2eюZ\џџџџџџџџџџџџџџџџBataviaNew YorkKD2FET CKD2FET GpПЎѓ$џџ2eю[]BrooklynNew YorkWG2MSK BWG2MSK GИh@KLѓ$џџ2eю\^BuffaloNew YorkKC2ZCE BKC2ZCE G( ѓ$џџ2eю]_џџџџџџџџџџџџџџџџBuffaloNew YorkKC2ZCE CKC2ZCE GˆIСР' ѓ$џџ2eю^`CarmelNew YorkK2PUT BK2PUT G8ƒ“@KLѓ$џџ2eю_aFairportNew YorkKB2VZS BKB2VZS Gƒ@KLѓ$џџ2eю`bџџџџџџџџџџџџџџџџGreene CountyNew YorkKD2HCQ AKD2HCQ GpПЎѓ$џџ2eюacGreene CountyNew YorkKD2HCQ BKD2HCQ GшІѓ$џџ2eюbdGreene CountyNew YorkKD2HCQ CKD2HCQ G@“žѓ$џџ2eюceџџџџџџџџџџџџџџџџHauppaugeNew YorkWD2NY BWD2NY GМ†z@KLѓ$џџ2eюdfHauppaugeNew YorkWD2NY CWD2NY G№УР' ѓ$џџ2eюegHemlockNew YorkK2BWK BK2BWK GрEo@KLѓ$џџ2eюfhџџџџџџџџџџџџџџџџHemlockNew YorkK2BWK CK2BWK G˜УШР' ѓ$џџ2eюgiIthacaNew YorkAF2A BAF2A Gш“У@KLѓ$џџ2eюhjLake GroveNew YorkKD2DIP BKD2DIP G )ѓ$џџ2eюikџџџџџџџџџџџџџџџџNew YorkNew YorkK2DIG AK2DIG G@M-1ѓ$џџ2eюjlNew YorkNew YorkK2DIG BK2DIG Gx[Š@KLѓ$џџ2eюkmOtisvilleNew YorkK9RRD BK9RRD GЖМ@KLѓ$џџ2eюlnџџџџџџџџџџџџџџџџStanleyNew YorkKD2HVC BKD2HVC Gрz{@KLѓ$џџ2eюmoThiellsNew YorkKD2EQY BKD2EQY Gј~Э@KLѓ$џџ2eюnpValhallaNew YorkW2ECA BW2ECA GlЬЖ@KLѓ$џџ2eюoqџџџџџџџџџџџџџџџџWestburyNew YorkNC2EC BNC2EC GЖМ@KLѓ$џџ2eюprWestburyNew YorkNC2EC CNC2EC GАОР' ѓ$џџ2eюqsForest HillMarylandKB3TOG AKB3TOG G`=ЗKЗѓ$џџ2fюrtџџџџџџџџџџџџџџџџForest HillMarylandKB3TOG BKB3TOG G,ПГ@KLѓ$џџ2fюsuForest HillMarylandKB3TOG CKB3TOG G[ІР' ѓ$џџ2fюtvFrederickMarylandKB3YBH BKB3YBH Gƒ@KLѓ$џџ2fюuwџџџџџџџџџџџџџџџџGermantownMarylandKV3B BKV3B G@єy@KLѓ$џџ2fюvxHunt ValleyMarylandKC3BIY AKC3BIY G 1M-1ѓ$џџ2fюwyHunt ValleyMarylandKC3BIY BKC3BIY GДр‡ѓ$џџ2fюxzџџџџџџџџџџџџџџџџHunt ValleyMarylandKC3BIY CKC3BIY Gt0ЃР' ѓ$џџ2fюy{Lexington ParkMarylandN3PX AN3PX GРЖLЗѓ$џџ2fюz|Lexington ParkMarylandN3PX BN3PX G mx@KLѓ$џџ2fю{}џџџџџџџџџџџџџџџџLexington ParkMarylandN3PX CN3PX GxЦР' ѓ$џџ2fю|~SalisburyMarylandW3PRO BW3PRO G@єy@KLѓ$џџ2fю}SalisburyMarylandW3PRO CW3PRO GЬЈР' ѓ$џџ2fю~€џџџџџџџџџџџџџџџџTowsonMarylandW3DHS AW3DHS GрrtLЗѓ$џџ2fюTowsonMarylandW3DHS BW3DHS GєZ@KLѓ$џџ2fю€‚TowsonMarylandW3DHS CW3DHS G ЉІР' ѓ$џџ2fюƒџџџџџџџџџџџџџџџџAllentownPennsylvaniaW3OI BW3OI GшІ@KLѓ$џџ2fю‚„AllentownPennsylvaniaW3OI CW3OI GHХР' ѓ$џџ2fюƒ…AtlanticPennsylvaniaK3AWS CK3AWS GАTХР' ѓ$џџ2fю„†џџџџџџџџџџџџџџџџBradfordPennsylvaniaKC3ESS BKC3ESS GXК‚@KLѓ$џџ2fю…‡EaglevillePennsylvaniaAA3E AAA3E GижJЗѓ$џџ2fю†ˆEaglevillePennsylvaniaAA3E BAA3E G~r†@KLѓ$џџ2fю‡‰џџџџџџџџџџџџџџџџEast StroudsburgPennsylvaniaKB3TEM CKB3TEM G№,МР' ѓ$џџ2fюˆŠGreensburgPennsylvaniaWC3PS AWC3PS G€ЭІLЗѓ$џџ2fю‰‹GreensburgPennsylvaniaWC3PS BWC3PS GpЌZ@KLѓ$џџ2fюŠŒџџџџџџџџџџџџџџџџGreensburgPennsylvaniaWC3PS CWC3PS G=ЋР' ѓ$џџ2fю‹GreenvillePennsylvaniaKB3WNO CKB3WNO G№ЋР' ѓ$џџ2fюŒŽKylertownPennsylvaniaW3PHB CW3PHB GиюЦР' ѓ$џџ2fюџџџџџџџџџџџџџџџџNazarethPennsylvaniaW3OK CW3OK G№3ІР' ѓ$џџ2fюސNew CastlePennsylvaniaKB3YBB BKB3YBB GИЩh@KLѓ$џџ2fю‘PhiladelphiaPennsylvaniaK3PDR BK3PDR GBэˆ@KLѓ$џџ2fю’џџџџџџџџџџџџџџџџPhiladelphiaPennsylvaniaK3PDR CK3PDR GPНР' ѓ$џџ2fю‘“PhilipsburgPennsylvaniaKC3BMB BKC3BMB GАX‚@KLѓ$џџ2fю’”PittsburghPennsylvaniaW3EXW BW3EXW G0>|@KLѓ$џџ2fю“•џџџџџџџџџџџџџџџџPittsburghPennsylvaniaW3EXW CW3EXW G KРР' ѓ$џџ2fю”–PocopsonPennsylvaniaW3EOC AW3EOC GрhеJЗѓ$џџ2fю•—PocopsonPennsylvaniaW3EOC BW3EOC GЮ5‡@KLѓ$џџ2fю–˜џџџџџџџџџџџџџџџџPocopsonPennsylvaniaW3EOC CW3EOC GBЛ@Bѓ$џџ2fю—™University ParkPennsylvaniaK3CR CK3CR G+ЊР' ѓ$џџ2fю˜šAlexander CityAlabamaWA4KIK CWA4KIK G№ЄЈР' ѓ џџ2gю™›џџџџџџџџџџџџџџџџBirminghamAlabamaK4DSO AK4DSO G@!LЗѓ џџ2gюšœBirminghamAlabamaK4DSO BK4DSO GВj@KLѓ џџ2gю›BirminghamAlabamaK4DSO CK4DSO GаЧЊР' ѓ џџ2gюœžџџџџџџџџџџџџџџџџBirminghamAlabamaKI4SBB AKI4SBB G eqLЗѓ џџ2gюŸBirminghamAlabamaKI4SBB BKI4SBB GX…v@KLѓ џџ2gюž BirminghamAlabamaKI4SBB CKI4SBB GъЃ %&ѓ џџ2gюŸЁџџџџџџџџџџџџџџџџBirminghamAlabamaKO4TM BKO4TM Gx‡Y@KLѓ џџ2gю ЂBirminghamAlabamaKO4TM CKO4TM G€PЧР' ѓ џџ2gюЁЃClantonAlabamaW4AEC AW4AEC G eqL МОѓ џџ2gюЂЄџџџџџџџџџџџџџџџџClantonAlabamaW4AEC BW4AEC GиŸ|@KLѓ џџ2gюЃЅClantonAlabamaW4AEC CW4AEC G`EЇР' ѓ џџ2gюЄІFt PayneAlabamaKI4SAY AKI4SAY G eqLЗѓ џџ2gюЅЇџџџџџџџџџџџџџџџџFt PayneAlabamaKI4SAY BKI4SAY GHšl@KLѓ џџ2gюІЈFt PayneAlabamaKI4SAY CKI4SAY G=ЋР' ѓ џџ2gюЇЉGreenvilleAlabamaK4TNS BK4TNS Ghб[@KLѓ џџ2gюЈЊџџџџџџџџџџџџџџџџGreenvilleAlabamaK4TNS CK4TNS GplЇР' ѓ џџ2gюЉЋHuntsvilleAlabamaW4WBC AW4WBC G@‹—LЗѓ џџ2gюЊЌHuntsvilleAlabamaW4WBC BW4WBC Gш n@KLѓ џџ2gюЋ­џџџџџџџџџџџџџџџџHuntsvilleAlabamaW4WBC CW4WBC G€ЊР' ѓ џџ2gюЌЎMagnolia SpringsAlabamaKI4SAZ AKI4SAZ G@‹—LЗѓ џџ2gю­ЏMagnolia SpringsAlabamaKI4SAZ BKI4SAZ Gрz{@KLѓ џџ2gюЎАџџџџџџџџџџџџџџџџMagnolia SpringsAlabamaKI4SAZ CKI4SAZ G0AЉР' ѓ џџ2gюЏБMentoneAlabamaKI4SBC BKI4SBC Gш n@KLѓ џџ2gюАВMentoneAlabamaKI4SBC CKI4SBC G€ЊР' ѓ џџ2gюБГџџџџџџџџџџџџџџџџMobileAlabamaW4IAX BW4IAX G Ђ„@KLѓ џџ2gюВДMobileAlabamaW4IAX CW4IAX GАyЊР' ѓ џџ2gюГЕMontgomeryAlabamaW4AP AW4AP GIˆLЗѓ џџ2gюДЖџџџџџџџџџџџџџџџџMontgomeryAlabamaW4AP BW4AP GX…v@KLѓ џџ2gюЕЗMontgomeryAlabamaW4AP CW4AP G@вСР' ѓ џџ2gюЖИOpelikaAlabamaW4LEE CW4LEE G˜УШР' ѓ џџ2gюЗЙџџџџџџџџџџџџџџџџRoanokeAlabamaKJ4JNX AKJ4JNX GРyLЗѓ џџ2gюИКRoanokeAlabamaKJ4JNX BKJ4JNX G Ђ„@KLѓ џџ2gюЙЛRoanokeAlabamaKJ4JNX CKJ4JNX GР ЊР' ѓ џџ2gюКМџџџџџџџџџџџџџџџџTrussvilleAlabamaKK4YOE BKK4YOE G щY@KLѓ џџ2gюЛНTrussvilleAlabamaKK4YOE CKK4YOE G€"ЅР\ѓ џџ2gюМОTuscaloosaAlabamaW4KCQ AW4KCQ G€cŽLЗѓ џџ2gюНПџџџџџџџџџџџџџџџџTuscaloosaAlabamaW4KCQ BW4KCQ Gј x@KLѓ џџ2gюОРTuscaloosaAlabamaW4KCQ CW4KCQ GШНР' ѓ џџ2gюПСVernonAlabamaKC4UG AKC4UG G 1M-1ѓ џџ2gюРТџџџџџџџџџџџџџџџџVernonAlabamaKC4UG BKC4UG GЗz@KLѓ џџ2gюСУVernonAlabamaKC4UG CKC4UG G[ІР' ѓ џџ2gюТФCocoaFloridaKJ4OXT CKJ4OXT GˆКУР' ѓ$џџ2gюУХџџџџџџџџџџџџџџџџCrestviewFloridaKO4EOC AKO4EOC G ЌїL-1ѓ$џџ2gюФЦCrestviewFloridaKO4EOC BKO4EOC GР€@KLѓ$џџ2gюХЧCrestviewFloridaKO4EOC CKO4EOC G0аІР' ѓ$џџ2gюЦШџџџџџџџџџџџџџџџџDaytona BeachFloridaKJ4RYH CKJ4RYH G RЊР' ѓ$џџ2gюЧЩFort LauderdaleFloridaW4AB BW4AB GP@_@KLѓ$џџ2gюШЪFort PierceFloridaW4AKH BW4AKH G ˆ~@KLѓ$џџ2gюЩЫџџџџџџџџџџџџџџџџFreeportFloridaWF4X BWF4X G`+i@KLѓ$џџ2gюЪЬFreeportFloridaWF4X CWF4X GDxТР' ѓ$џџ2gюЫЭFt LauderdaleFloridaW4BUG AW4BUG G€@ќL-1ѓ$џџ2gюЬЮџџџџџџџџџџџџџџџџFt LauderdaleFloridaW4BUG BW4BUG GРo[@KLѓ$џџ2gюЭЯFt LauderdaleFloridaW4BUG CW4BUG G`ЖЉР' ѓ$џџ2gюЮаInvernessFloridaKK4ZBF BKK4ZBF GZ†ѓ$џџ2gюЯбџџџџџџџџџџџџџџџџJacksonvilleFloridaW4RNG CW4RNG G6СР' ѓ$џџ2gюавJacksonville BCHFloridaKJ4RYG CKJ4RYG G€ЊР' ѓ$џџ2gюбгKissimmeeFloridaN4ARG AN4ARG Gpи)ѓ$џџ2gювдџџџџџџџџџџџџџџџџKissimmeeFloridaN4ARG BN4ARG GаФ}@KLѓ$џџ2gюгеKissimmeeFloridaN4ARG CN4ARG G?ЦР' ѓ$џџ2gюджLakelandFloridaKJ4ACN AKJ4ACN GАM-1ѓ$џџ2gюезџџџџџџџџџџџџџџџџLakelandFloridaKJ4ACN BKJ4ACN GXК‚@KLѓ$џџ2gюжиMelbourneFloridaK4RPT BK4RPT G(ФX@KLѓ$џџ2gюзйMiamiFloridaW4NVU BW4NVU Gј x@KLѓ$џџ2gюикџџџџџџџџџџџџџџџџMiamiFloridaW4NVU CW4NVU GXEУР' ѓ$џџ2gюйлMiltonFloridaKI4WZA BKI4WZA GH…@KLѓ$џџ2gюкмMiltonFloridaKI4WZA CKI4WZA GаШР' ѓ$џџ2gюлнџџџџџџџџџџџџџџџџNaplesFloridaAA4PP AAA4PP G(RM€УЩѓ$џџ2gюмоNaplesFloridaAA4PP BAA4PP G`СP@KLѓ$џџ2gюнпNaplesFloridaAA4PP CAA4PP GPЌР' ѓ$џџ2gюорџџџџџџџџџџџџџџџџNaplesFloridaAB4NP CAB4NP G№ЄЈР' ѓ$џџ2gюпсNaplesFloridaAB4FL BAB4FL G%РР' ѓ$џџ2gюртOcalaFloridaKG4NXO BKG4NXO GИўt@KLѓ$џџ2gюсуџџџџџџџџџџџџџџџџOcalaFloridaKG4NXO CKG4NXO GPЇР' ѓ$џџ2gютфOcalaFloridaKK4DFC CKK4DFC GpжПР' ѓ$џџ2gюухOrlandoFloridaK1XC AK1XC G@‹—LЗѓ$џџ2gюфцџџџџџџџџџџџџџџџџOrlandoFloridaK1XC BK1XC Gјжk@KLѓ$џџ2gюхчOrlandoFloridaK1XC CK1XC G KРР' ѓ$џџ2gюцшOrlandoFloridaW4AES BW4AES G(.q@KLѓ$џџ2gючщџџџџџџџџџџџџџџџџPalm BeachFloridaK4WPB CK4WPB G@hЉР' ѓ$џџ2gюшъPalm CoastFloridaKG4TCC AKG4TCC GРЗM-1ѓ$џџ2gющыPalm CoastFloridaKG4TCC BKG4TCC GX]@KLѓ$џџ2gюъьџџџџџџџџџџџџџџџџPalm HarborFloridaW4AFC AW4AFC G`M-1ѓ$џџ2gюыэPalm HarborFloridaW4AFC BW4AFC GШрA@KLѓ$џџ2gюьюPalm HarborFloridaW4AFC CW4AFC GШ’К@Bѓ$џџ2gюэяџџџџџџџџџџџџџџџџPanama CityFloridaKK4IQW CKK4IQW G(Ѓѓ$џџ2gюю№SanfordFloridaW4PLB BW4PLB G`і\@KLѓ$џџ2gюяёSanfordFloridaW4PLB CW4PLB G@їІР' ѓ$џџ2gю№ђџџџџџџџџџџџџџџџџSt.PetersburgFloridaW4ICY BW4ICY G0дc@KLѓ$џџ2gюёѓSun City CenterFloridaW1SCC BW1SCC GP@_@KLѓ$џџ2gюђєTallahasseeFloridaNF4DG ANF4DG G@M-1ѓ$џџ2gюѓѕџџџџџџџџџџџџџџџџTallahasseeFloridaNF4DG BNF4DG G‚n@KLѓ$џџ2gюєіTallahasseeFloridaNF4DG CNF4DG G8†РР' ѓ$џџ2gюѕїTampaFloridaW4RNT BW4RNT GдLƒ@KLѓ$џџ2gюіјџџџџџџџџџџџџџџџџTavaresFloridaKJ4TJD BKJ4TJD G ˆ~@KLѓ$џџ2gюїљTavaresFloridaKK4KYK BKK4KYK G`+i@KLѓ$џџ2gюјњWesley ChapelFloridaW4SRT BW4SRT GX]@KLѓ$џџ2gюљћџџџџџџџџџџџџџџџџAlbanyGeorgiaKJ4KLD BKJ4KLD G`ŒD@KLѓ$џџ2gюњќAlbanyGeorgiaKJ4KLD CKJ4KLD GъЃ %&ѓ$џџ2gюћ§AlbanyGeorgiaKJ4KLE BKJ4KLE GИ*D@KLѓ$џџ2gюќўџџџџџџџџџџџџџџџџAlbanyGeorgiaKJ4KLE CKJ4KLE GРMЃ %&ѓ$џџ2gю§џAppling/AugustaGeorgiaKJ4PYA BKJ4PYA GЩC@KLѓ$џџ2gюўAppling/AugustaGeorgiaKJ4PYA CKJ4PYA GРОЅР\ѓ$џџ2gюџџџџџџџџџџџџџџџџџAthensJackson CoGeorgiaKJ4PXY BKJ4PXY G<˜C@KLѓ$џџ2gюAthensJackson CoGeorgiaKJ4PXY CKJ4PXY G 8Є %&ѓ$џџ2gюAtlantaGeorgiaW4DOC AW4DOC G@ьrLЗѓ$џџ2gюџџџџџџџџџџџџџџџџAtlantaGeorgiaW4DOC BW4DOC GРC@KLѓ$џџ2gюAtlantaGeorgiaW4DOC CW4DOC GpнЉР' ѓ$џџ2gюBall GroundGeorgiaKK4WIB AKK4WIB GРЖLЗѓ$џџ2gюџџџџџџџџџџџџџџџџBall GroundGeorgiaKK4WIB BKK4WIB GЬв_ѓ$џџ2gюBall GroundGeorgiaKK4WIB CKK4WIB Gш†Щѓ$џџ2gю BraseltonGeorgiaWJ4FD BWJ4FD GьдB@KLѓ$џџ2gю џџџџџџџџџџџџџџџџBufordGeorgiaKJ4BDF BKJ4BDF GюD@KLѓ$џџ2gю  CarrolltonGeorgiaW4FWD BW4FWD Gј x@KLѓ$џџ2gю  ChatsworthGeorgiaKJ4KLF BKJ4KLF GЩC@KLѓ$џџ2gю  џџџџџџџџџџџџџџџџChatsworthGeorgiaKJ4KLF CKJ4KLF GРОЅР\ѓ$џџ2gю ClevelandGeorgiaK4GAR BK4GAR GєЏA@KLѓ$џџ2gю CummingGeorgiaKI4SBA AKI4SBA G€cŽLЗѓ$џџ2gюџџџџџџџџџџџџџџџџCummingGeorgiaKI4SBA BKI4SBA G0>|@KLѓ$џџ2gюCummingGeorgiaKI4SBA CKI4SBA G€“ЇР' ѓ$џџ2gюDaltonGeorgiaKA4RVT BKA4RVT G ˆ~@KLѓ$џџ2gюџџџџџџџџџџџџџџџџDaltonGeorgiaKA4RVT CKA4RVT GPЉР' ѓ$џџ2gюDoravilleGeorgiaWB4HRO AWB4HRO Gа&LЗѓ$џџ2gюDoravilleGeorgiaWB4HRO BWB4HRO G4НD@KLѓ$џџ2gюџџџџџџџџџџџџџџџџDublinGeorgiaKJ4YNR AKJ4YNR GаМvLЗѓ$џџ2gюDublinGeorgiaKJ4YNR BKJ4YNR GШрA@KLѓ$џџ2gюDublinGeorgiaKJ4YNR CKJ4YNR G`EЇР' ѓ$џџ2gюџџџџџџџџџџџџџџџџEllijayGeorgiaW4HHH BW4HHH G,Жv@KLѓ$џџ2gюGainesvilleGeorgiaKJ4ZLL BKJ4ZLL GdIV@KLѓ$џџ2gюGainesvilleGeorgiaKJ4ZLL CKJ4ZLL G[ІР' ѓ$џџ2gюџџџџџџџџџџџџџџџџLawrencevilleGeorgiaWD4STR BWD4STR GpBB@KLѓ$џџ2gюLawrencevilleGeorgiaWD4STR CWD4STR G pЅР\ѓ$џџ2gюMaconGeorgiaWX4EMA BWX4EMA GhgC@KLѓ$џџ2gюџџџџџџџџџџџџџџџџMaconGeorgiaWX4EMA CWX4EMA G`ЖЉР' ѓ$џџ2gю MorgantonGeorgiaKM4MAD CKM4MAD GР ЊР' ѓ$џџ2gю!PembrokeGeorgiaKJ4GGV AKJ4GGV GрrtLЗѓ$џџ2gю "џџџџџџџџџџџџџџџџPembrokeGeorgiaKJ4GGV BKJ4GGV G`ŒD@KLѓ$џџ2gю!#PembrokeGeorgiaKJ4GGV CKJ4GGV GЬЈР' ѓ$џџ2gю"$RockmartGeorgiaWX4PCA BWX4PCA GЄB@KLѓ$џџ2gю#%џџџџџџџџџџџџџџџџRockmartGeorgiaWX4PCA CWX4PCA G`ЖЉР' ѓ$џџ2gю$&SavannahGeorgiaKK4SGC AKK4SGC G €wLЗѓ$џџ2gю%'SavannahGeorgiaKK4SGC BKK4SGC GьдB@KLѓ$џџ2gю&(џџџџџџџџџџџџџџџџSavannahGeorgiaKK4SGC CKK4SGC Gр›Ѓ %&ѓ$џџ2gю')Stone MountainGeorgiaWX4GPB AWX4GPB GрrtLЗѓ$џџ2gю(*Stone MountainGeorgiaWX4GPB BWX4GPB G`ŒD@KLѓ$џџ2gю)+џџџџџџџџџџџџџџџџStone MountainGeorgiaWX4GPB CWX4GPB GъЃ %&ѓ$џџ2gю*,ThomasvilleGeorgiaKJ4PYB BKJ4PYB GЩC@KLѓ$џџ2gю+-ThomasvilleGeorgiaKJ4PYB CKJ4PYB GРОЅР\ѓ$џџ2gю,.џџџџџџџџџџџџџџџџTiftonGeorgiaW4PVW AW4PVW GЏsLЗѓ$џџ2gю-/TiftonGeorgiaW4PVW BW4PVW GD|@KLѓ$џџ2gю.0TiftonGeorgiaW4PVW CW4PVW G[ІР' ѓ$џџ2gю/1џџџџџџџџџџџџџџџџValdostaGeorgiaW4VLD AW4VLD G([vLЗѓ$џџ2gю02ValdostaGeorgiaW4VLD BW4VLD Gєƒr@KLѓ$џџ2gю13ValdostaGeorgiaW4VLD CW4VLD G ЉІР' ѓ$џџ2gю24џџџџџџџџџџџџџџџџHighland HeightsKentuckyK4CO CK4CO GрюЊР' ѓ$џџ2gю35LexingtonKentuckyW4DSI BW4DSI G†U@KLѓ$џџ2gю46LexingtonKentuckyW4DSI CW4DSI G ‹ЋР' ѓ$џџ2gю57џџџџџџџџџџџџџџџџMiddlesboroKentuckyWA4YZY AWA4YZY GпoLЗѓ$џџ2gю68MiddlesboroKentuckyWA4YZY BWA4YZY GdГn@KLѓ$џџ2gю79MiddlesboroKentuckyWA4YZY CWA4YZY G ЉР' ѓ$џџ2gю8:џџџџџџџџџџџџџџџџRichmondKentuckyKE4YVD BKE4YVD GTШd@KLѓ$џџ2gю9;UnionKentuckyWW4KY AWW4KY G@M-1ѓ$џџ2gю:<UnionKentuckyWW4KY BWW4KY G№e…@KLѓ$џџ2gю;=џџџџџџџџџџџџџџџџUnionKentuckyWW4KY CWW4KY G0ўШР' ѓ$џџ2gю<>BurlingtonNorth CarolinaAK4EG AAK4EG G€cŽL-1ѓ$џџ2gю=?BurlingtonNorth CarolinaAK4EG BAK4EG GЬq„@KLѓ$џџ2gю>@џџџџџџџџџџџџџџџџBurlingtonNorth CarolinaAK4EG CAK4EG G@hЉР' ѓ$џџ2gю?ACharlotteNorth CarolinaKI4WXS AKI4WXS G@3љL-1ѓ$џџ2gю@BCharlotteNorth CarolinaKI4WXS BKI4WXS GфЭt@KLѓ$џџ2gюACџџџџџџџџџџџџџџџџCharlotteNorth CarolinaKI4WXS CKI4WXS G ЉІР' ѓ$џџ2gюBDFletcherNorth CarolinaNC4BS BNC4BS GDg@KLѓ$џџ2gюCEGastoniaNorth CarolinaKA4YMZ BKA4YMZ G,Жv@KLѓ$џџ2gюDFџџџџџџџџџџџџџџџџGastoniaNorth CarolinaKA4YMZ CKA4YMZ GРMЃ %&ѓ$џџ2gюEGGastoniaNorth CarolinaKK4JDH AKK4JDH G[M-1ѓ$џџ2gюFHGreensboroNorth CarolinaW4GSO BW4GSO GЄ‹e@KLѓ$џџ2gюGIџџџџџџџџџџџџџџџџHendersonvilleNorth CarolinaKJ4JAL BKJ4JAL G(ФX@KLѓ$џџ2gюHJHendersonvilleNorth CarolinaKJ4JAL CKJ4JAL GиюЦР' ѓ$џџ2gюIKMt. AiryNorth CarolinaKJ4HFV BKJ4HFV GD|@KLѓ$џџ2gюJLџџџџџџџџџџџџџџџџRaleighNorth CarolinaKR4RAL BKR4RAL G” [@KLѓ$џџ2gюKMShelbyNorth CarolinaW4NYR BW4NYR GlУy@KLІћ$џџ2gюLNShelbyNorth CarolinaW4NYR CW4NYR GРОЅР\Іћ$џџ2gюMOџџџџџџџџџџџџџџџџTryonNorth CarolinaKK4LVF BKK4LVF GxМe@KLѓ$џџ2gюNPWingateNorth CarolinaW4FAN BW4FAN G$„@KLѓ$џџ2gюOQAikenSouth CarolinaKR4AIK BKR4AIK G№m@KLѓ$џџ2gюPRџџџџџџџџџџџџџџџџAikenSouth CarolinaKR4AIK CKR4AIK G@їІР' ѓ$џџ2gюQSAwendawSouth CarolinaKR4CHS CKR4CHS G[ІР' ѓ$џџ2gюRTBeaufortSouth CarolinaKJ4LNJ CKJ4LNJ G@йЋР' ѓ$џџ2gюSUџџџџџџџџџџџџџџџџColumbiaSouth CarolinaKJ4BWK AKJ4BWK GшЗ‹LЗѓ$џџ2gюTVColumbiaSouth CarolinaKJ4BWK BKJ4BWK GВj@KLѓ$џџ2gюUWColumbiaSouth CarolinaKJ4BWK CKJ4BWK GР ЊР' ѓ$џџ2gюVXџџџџџџџџџџџџџџџџColumbiaSouth CarolinaKJ4FCS AKJ4FCS GIˆLЗѓ$џџ2gюWYColumbiaSouth CarolinaKJ4FCS BKJ4FCS Gи5d@KLѓ$џџ2gюXZColumbiaSouth CarolinaKJ4FCS CKJ4FCS G RЊР' ѓ$џџ2gюY[џџџџџџџџџџџџџџџџColumbiaSouth CarolinaKJ4MKV BKJ4MKV GHšl@KLѓ$џџ2gюZ\ColumbiaSouth CarolinaKJ4MKV CKJ4MKV GР/ЈР' ѓ$џџ2gю[]DillionSouth CarolinaW4PDE AW4PDE G@KLЗѓ$џџ2gю\^џџџџџџџџџџџџџџџџDillionSouth CarolinaW4PDE BW4PDE GŒ/u@KLѓ$џџ2gю]_DillionSouth CarolinaW4PDE CW4PDE G`ЖЉР' ѓ$џџ2gю^`GreenwoodSouth CarolinaW4GWM CW4GWM GрюЊР' ѓ$џџ2gю_aџџџџџџџџџџџџџџџџLeesvilleSouth CarolinaKC4GYM BKC4GYM GрEo@KLѓ$џџ2gю`bLeesvilleSouth CarolinaKC4GYM CKC4GYM GЧНР' ѓ$џџ2gюacMyrtle BeachSouth CarolinaNE4SC BNE4SC GЌfd@KLѓ$џџ2gюbdџџџџџџџџџџџџџџџџMyrtle BeachSouth CarolinaNE4SC CNE4SC G 8Є %&ѓ$џџ2gюceSummervilleSouth CarolinaKX4DOR BKX4DOR Gќ)e@KLѓ$џџ2gюdfSummervilleSouth CarolinaKX4DOR CKX4DOR GЬЈР' ѓ$џџ2gюegџџџџџџџџџџџџџџџџCarryvilleTennesseeKK4VQG CKK4VQG G`дЄР\ѓ$џџ2gюfhChattanoogaTennesseeW4PL AW4PL GРѓL-1ѓ$џџ2gюgiChattanoogaTennesseeW4PL BW4PL GАюi@KLѓ$џџ2gюhjџџџџџџџџџџџџџџџџChattanoogaTennesseeW4PL CW4PL GѓЈР' ѓ$џџ2gюikClevelandTennesseeKK4BXE BKK4BXE GШрA@KLѓ$џџ2gюjlClevelandTennesseeKK4BXE CKK4BXE G@йЋР' ѓ$џџ2gюkmџџџџџџџџџџџџџџџџKnoxvilleTennesseeKM4JXA CKM4JXA Gр›Ѓ %&ѓ$џџ2gюlnMemphisTennesseeW4LET BW4LET G,Жv@KLѓ$џџ2gюmoMemphisTennesseeW4LET CW4LET G pЅР\ѓ$џџ2gюnpџџџџџџџџџџџџџџџџMemphisTennesseeWB4KOG BWB4KOG GќєX@KLѓ$џџ2gюoqMorristownTennesseeW4LDG BW4LDG Gx&~@KLѓ$џџ2gюprMorristownTennesseeW4LDG CW4LDG GРMЃ %&ѓ$џџ2gюqsџџџџџџџџџџџџџџџџNashvilleTennesseeKI4SDI CKI4SDI GрЩХР' ѓ$џџ2gюrtOneidaTennesseeW4BSF BW4BSF GЌа|@KLѓ$џџ2gюsuRockwoodTennesseeKE4RX BKE4RX G†U@KLѓ$џџ2gюtvџџџџџџџџџџџџџџџџWhitevilleTennesseeKM4GHK BKM4GHK Gќ“}@KLѓ$џџ2gюuwAlexandriaVirginiaW4HFH AW4HFH GРp‘LЗѓ$џџ2gюvxAlexandriaVirginiaW4HFH BW4HFH GрLY@KLѓ$џџ2gюwyџџџџџџџџџџџџџџџџAlexandriaVirginiaW4HFH CW4HFH G RЊР' ѓ$џџ2gюxzHamptonVirginiaW4HPT BW4HPT G%z@KLѓ$џџ2gюy{HamptonVirginiaW4HPT CW4HPT G€“ЇР' ѓ$џџ2gюz|џџџџџџџџџџџџџџџџHaymarketVirginiaW4BRM BW4BRM GhШ@KLѓ$џџ2gю{}HaymarketVirginiaW4BRM CW4BRM GdЋР' ѓ$џџ2gю|~LexingtonVirginiaW4ROC BW4ROC Gрz{@KLѓ$џџ2gю}џџџџџџџџџџџџџџџџNewport NewsVirginiaW4MT BW4MT G†U@KLѓ$џџ2gю~€Newport NewsVirginiaW4MT CW4MT G`\ИР' ѓ$џџ2gюRichmondVirginiaW4FJ AW4FJ GIˆL-1ѓ$џџ2gю€‚џџџџџџџџџџџџџџџџRichmondVirginiaW4FJ BW4FJ Gєƒr@KLѓ$џџ2gюƒRichmondVirginiaW4FJ CW4FJ GиюЦР' ѓ$џџ2gю‚„StaffordVirginiaWS4VA AWS4VA GРбlLЗѓ$џџ2gюƒ…џџџџџџџџџџџџџџџџStaffordVirginiaWS4VA BWS4VA GјпЈ@KLѓ$џџ2gю„†StaffordVirginiaWS4VA CWS4VA G@hЉР' ѓ$џџ2gю…‡Tysons CornerVirginiaNV4FM ANV4FM G€љuLЗѓ$џџ2gю†ˆџџџџџџџџџџџџџџџџTysons CornerVirginiaNV4FM BNV4FM GИxД@KLѓ$џџ2gю‡‰Tysons CornerVirginiaNV4FM CNV4FM G`ЖЉР' ѓ$џџ2gюˆŠWintergreenVirginiaWR4CV BWR4CV G5…@KLѓ$џџ2gю‰‹џџџџџџџџџџџџџџџџLittle RockArkansasN5DSD BN5DSD Gдw@KLѓ џџ2hюŠŒLittle RockArkansasN5DSD CN5DSD GР]Ъ %&ѓ џџ2hю‹AlexandriaLouisianaKF5PIE CKF5PIE G?ЦР' ѓ џџ2hюŒŽџџџџџџџџџџџџџџџџBaton RougeLouisianaKD5CQB CKD5CQB G6СР' ѓ џџ2hюFranklintonLouisianaKF5BSZ AKF5BSZ G@MЗѓ џџ2hюސFranklintonLouisianaKF5BSZ BKF5BSZ Gьн@KLѓ џџ2hю‘џџџџџџџџџџџџџџџџFranklintonLouisianaKF5BSZ CKF5BSZ G€СЩ %&ѓ џџ2hю’LeesvilleLouisianaKE5PFA BKE5PFA Gа%Y@KLѓ џџ2hю‘“LeesvilleLouisianaKE5PFA CKE5PFA GhNШР' ѓ џџ2hю’”џџџџџџџџџџџџџџџџLeesvilleLouisianaKF5QAR AKF5QAR GpПЎѓ џџ2hю“•LeesvilleLouisianaKF5QAR BKF5QAR GŒ[D@KLѓ џџ2hю”–LeesvilleLouisianaKF5QAR CKF5QAR G€§Пѓ џџ2hю•—џџџџџџџџџџџџџџџџManyLouisianaN5MNY CN5MNY GРР' ѓ џџ2hю–˜MindenLouisianaN5MAD BN5MAD Gt4`@KLѓ џџ2hю—™MindenLouisianaN5MAD CN5MAD GРMЃ %&ѓ џџ2hю˜šџџџџџџџџџџџџџџџџNew OrleansLouisianaKF5ZVT AKF5ZVT GMb@KLѓ џџ2hю™›New OrleansLouisianaKF5ZVT BKF5ZVT GРx˜ѓ џџ2hюšœNew OrleansLouisianaKF5ZVT CKF5ZVT Gе­ѓ џџ2hю›џџџџџџџџџџџџџџџџNew OrleansLouisianaW5GAD AW5GAD G@‹—LЗѓ џџ2hюœžNew OrleansLouisianaW5GAD BW5GAD GH…@KLѓ џџ2hюŸNew OrleansLouisianaW5GAD CW5GAD GШхСР' ѓ џџ2hюž џџџџџџџџџџџџџџџџPinevilleLouisianaKC5ZJY CKC5ZJY G0аІР' ѓ џџ2hюŸЁRustonLouisianaN5APB CN5APB G ЉІР' ѓ џџ2hю ЂShreveportLouisianaW5SHV AW5SHV G@M-1ѓ џџ2hюЁЃџџџџџџџџџџџџџџџџShreveportLouisianaW5SHV BW5SHV G€bX@KLѓ џџ2hюЂЄShreveportLouisianaW5SHV CW5SHV G‰ШР' ѓ џџ2hюЃЅSt. MartinvilleLouisianaKF5ZUZ AKF5ZUZ G сM-1ѓ џџ2hюЄІџџџџџџџџџџџџџџџџSt. MartinvilleLouisianaKF5ZUZ BKF5ZUZ Gt@KLѓ џџ2hюЅЇSt. MartinvilleLouisianaKF5ZUZ CKF5ZUZ GР УР' ѓ џџ2hюІЈSulphurLouisianaAF5XP BAF5XP Ghp€@KLѓ џџ2hюЇЉџџџџџџџџџџџџџџџџBrandonMississippiK5RKN BK5RKN GЈ}ƒ@KLѓ$џџ2hюЈЊBrandonMississippiK5RKN CK5RKN GPЇР' ѓ$џџ2hюЉЋClintonMississippiW5DRA BW5DRA G†U@KLѓ$џџ2hюЊЌџџџџџџџџџџџџџџџџClintonMississippiW5DRA CW5DRA G зШР' ѓ$џџ2hюЋ­ColumbusMississippiKC5ULN BKC5ULN GH…@KLѓ$џџ2hюЌЎForestMississippiKF5SEB CKF5SEB GР/ЈР' ѓ$џџ2hю­ЏџџџџџџџџџџџџџџџџMcHenryMississippiKI4TMJ AKI4TMJ GIˆLЗѓ$џџ2hюЎАMcHenryMississippiKI4TMJ BKI4TMJ Gx&~@KLѓ$џџ2hюЏБMcHenryMississippiKI4TMJ CKI4TMJ GPЇР' ѓ$џџ2hюАВџџџџџџџџџџџџџџџџNatchezMississippiN5TAM BN5TAM GљЊ@KLѓ$џџ2hюБГNatchezMississippiN5TAM CN5TAM GаVЈР' ѓ$џџ2hюВДTupeloMississippiK5LLO AK5LLO G сЇѓ$џџ2hюГЕџџџџџџџџџџџџџџџџTupeloMississippiK5LLO BK5LLO G№e…€[ѓ$џџ2hюДЖTupeloMississippiK5LLO CK5LLO GрюЊѓ$џџ2hюЕЗTupeloMississippiKE5LUX BKE5LUX G№e…@KLѓ$џџ2hюЖИџџџџџџџџџџџџџџџџAlamogrodoNew MexicoW6DHS BW6DHS GРC@KL&Нћџџ2hюЗЙAlamogrodoNew MexicoW6DHS CW6DHS GъЃ€&Нћџџ2hюИКAlbuquerqueNew MexicoK5URR BK5URR GЪ@KL4Щћџџ2hюЙЛџџџџџџџџџџџџџџџџAlbuquerqueNew MexicoK5URR CK5URR GрчРР' 4Щћџџ2hюКМAlbuquerqueNew MexicoW5MPZ BW5MPZ GРйs@KLђћџџ2hюЛНAlbuquerqueNew MexicoW5URD BW5URD GШщ~@KL&‚ћџџ2hюМОџџџџџџџџџџџџџџџџAztecNew MexicoKF5VBE AKF5VBE GРѓL-1%ћџџ2hюНПBloomfieldNew MexicoKF5VBD AKF5VBD GрюM-1‚ћџџ2hюОРBloomfieldNew MexicoKF5VBD CKF5VBD GxGІР' ‚ћџџ2hюПСџџџџџџџџџџџџџџџџFarmingtonNew MexicoKF5VBF AKF5VBF G Ч§L-1;|ћџџ2hюРТFarmingtonNew MexicoKF5VBF BKF5VBF G№0y@KL;|ћџџ2hюСУLas CrucesNew MexicoW5GB CW5GB GР™РР' $ ћџџ2hюТФџџџџџџџџџџџџџџџџLos AlamosNew MexicoNM5WR BNM5WR GЈо^@KLўћџџ2hюУХRatonNew MexicoKD0RDI BKD0RDI Gи>Ё@KLŽћџџ2hюФЦSanta FeNew MexicoW5SF BW5SF G­@KL9Aћџџ2hюХЧџџџџџџџџџџџџџџџџSanta FeNew MexicoW5SF CW5SF GКЇР' 9Aћџџ2hюЦШSocorroNew MexicoW5AQA BW5AQA G ˆ~@KL:3!ћџџ2hюЧЩAltusOklahomaAJ5Q BAJ5Q Ghб[@KLѓ џџ2hюШЪџџџџџџџџџџџџџџџџBlanchardOklahomaKF5ZLE BKF5ZLE GCg@KLѓ џџ2hюЩЫElk CityOklahomaK5ELK AK5ELK G€жуL-1ѓ џџ2hюЪЬElk CityOklahomaK5ELK BK5ELK Ghh@KLѓ џџ2hюЫЭџџџџџџџџџџџџџџџџElk CityOklahomaK5ELK CK5ELK GH<ОР' ѓ џџ2hюЬЮEufaulaOklahomaKG5EEP BKG5EEP GбЯ@KLѓ џџ2hюЭЯMoorelandOklahomaW5OKT BW5OKT G8{@KLѓ џџ2hюЮаџџџџџџџџџџџџџџџџNormanOklahomaW5TC BW5TC GАX‚@KLѓ џџ2hюЯбOklahoma CityOklahomaWD5AII BWD5AII Gшыa@KLѓ џџ2hюавOklahoma CityOklahomaWD5AII CWD5AII GhNШР' ѓ џџ2hюбгџџџџџџџџџџџџџџџџTulsaOklahomaKN5V BKN5V G@Ša@KLѓ џџ2hювдTulsaOklahomaW5IAS BW5IAS GРЄg@KLѓ џџ2hюгеVinitaOklahomaNO5RA BNO5RA GИЩh@KLѓ џџ2hюджџџџџџџџџџџџџџџџџVinitaOklahomaNO5RA CNO5RA GHХР' ѓ џџ2hюезWalsh MountainOklahomaWX5ASA BWX5ASA GpЌZ@KLѓ џџ2hюжиWalsh MountainOklahomaWX5ASA CWX5ASA GhNШР' ѓ џџ2hюзйџџџџџџџџџџџџџџџџWoodwardOklahomaWW5EM BWW5EM Gx&~@KLѓ џџ2hюикWoodwardOklahomaWW5EM CWW5EM G8йЧР' ѓ џџ2hюйлAllenTexasK5PRK AK5PRK G`>M-1ѓ џџ2hюкмџџџџџџџџџџџџџџџџAllenTexasK5PRK BK5PRK GXцQ@KLѓ џџ2hюлнBig SpringTexasW5AW BW5AW GŒ[D@KLѓ џџ2hюмоBig SpringTexasW5AW CW5AW G@ДЦР' ѓ џџ2hюнпџџџџџџџџџџџџџџџџBorgerTexasKF5YVX AKF5YVX G€жуL-1ѓ џџ2hюорBorgerTexasKF5YVX BKF5YVX GœFN@KLѓ џџ2hюпсBorgerTexasKF5YVX CKF5YVX GPІК@Bѓ џџ2hюртџџџџџџџџџџџџџџџџBrucevilleTexasW5HAT BW5HAT GhgC@KLѓ џџ2hюсуBrucevilleTexasW5HAT CW5HAT G@ДЦР' ѓ џџ2hютфBryanTexasW5AC BW5AC G@Пm@KLѓ џџ2hюухџџџџџџџџџџџџџџџџCorsicanaTexasK5NEM CK5NEM Gр:ШР' ѓ џџ2hюфцDallasTexasK5TIT AK5TIT G@M-1ѓ џџ2hюхчDallasTexasK5TIT BK5TIT G€bX@KLѓ џџ2hюцшџџџџџџџџџџџџџџџџDallasTexasK5TIT CK5TIT G‰ШР' ѓ џџ2hючщDallasTexasW5FC AW5FC GР!0M-1ѓ џџ2hюшъDallasTexasW5FC BW5FC GЄB@KLѓ џџ2hющыџџџџџџџџџџџџџџџџDallasTexasW5FC CW5FC G‚ІР' ѓ џџ2hюъьDentonTexasW5NGU AW5NGU GРЗM-1ѓ џџ2hюыэDentonTexasW5NGU BW5NGU GШf@KLѓ џџ2hюьюџџџџџџџџџџџџџџџџDentonTexasW5NGU CW5NGU GшЩ@Bѓ џџ2hюэяEl PasoTexasW5ELP CW5ELP G`>НР' Щћ џџ2hюю№Fort WorthTexasKB5DRP BKB5DRP GpBB@KLѓ џџ2hюяёџџџџџџџџџџџџџџџџFort WorthTexasKF5MMX BKF5MMX GŒ[D@KLѓ џџ2hю№ђFort WorthTexasW5SH BW5SH GиX@KLѓ џџ2hюёѓGranburyTexasK1DRP BK1DRP GЩC@KLѓ џџ2hюђєџџџџџџџџџџџџџџџџGranburyTexasW5HCT BW5HCT GpwN@KLѓ џџ2hюѓѕHoustonTexasKG5FAE BKG5FAE Gо9@KLѓ џџ2hюєіHoustonTexasKG5FAE CKG5FAE G€ШГР' ѓ џџ2hюѕїџџџџџџџџџџџџџџџџHoustonTexasN5HDS CN5HDS G˜•ІР' ѓ џџ2hюіјHoustonTexasW5HDT AW5HDT G@M-1ѓ џџ2hюїљHouston TMCTexasW5HDR AW5HDR G€ЊM-1ѓ џџ2hюјњџџџџџџџџџџџџџџџџHouston TMCTexasW5HDR BW5HDR GРC@KLѓ џџ2hюљћHouston TMCTexasW5HDR CW5HDR GpєК@Bѓ џџ2hюњќLaredoTexasKE5WFB BKE5WFB GРC@KLѓ џџ2hюћ§џџџџџџџџџџџџџџџџLaredoTexasKE5WFB CKE5WFB G‰ШР' ѓ џџ2hюќўLongviewTexasK5LET BK5LET GX…v@KLѓ џџ2hю§џLongviewTexasK5LET CK5LET G ѕУР' ѓ џџ2hюўџџџџџџџџџџџџџџџџMagnoliaTexasN5MDS BN5MDS G4НD@KLѓ џџ2hюџMagnoliaTexasN5MDS CN5MDS GPІК@Bѓ џџ2hюMcAllenTexasND5N CND5N G€2ЬР' ѓ џџ2hюџџџџџџџџџџџџџџџџMesquiteTexasNT5RN ANT5RN G`>M-1ѓ џџ2hюMesquiteTexasNT5RN BNT5RN Ghh@KLѓ џџ2hюMesquiteTexasNT5RN CNT5RN G0аІР' ѓ џџ2hюџџџџџџџџџџџџџџџџNederlandTexasW5SSV BW5SSV GюD@KLѓ џџ2hюParisTexasK5PTR BK5PTR GШJZ@KLѓ џџ2hюRosstonTexasKE5YAP AKE5YAP G€ЊM-1ѓ џџ2hю џџџџџџџџџџџџџџџџRosstonTexasKE5YAP BKE5YAP G4НD@KLѓ џџ2hю RosstonTexasKE5YAP CKE5YAP Gа„Ъ@Bѓ џџ2hю  San AngeloTexasKG5CNG AKG5CNG GРЖLЗѓ џџ2hю  џџџџџџџџџџџџџџџџSan AngeloTexasKG5CNG BKG5CNG GpK@KLѓ џџ2hю  San AngeloTexasKG5CNG CKG5CNG GА&Ѓѓ џџ2hю San AntonioTexasWD5STR AWD5STR G 1M-1ѓ џџ2hю џџџџџџџџџџџџџџџџSan AntonioTexasWD5STR BWD5STR GРC@KLѓ џџ2hюSan AntonioTexasWD5STR CWD5STR GBЛ@Bѓ џџ2hюSeguinTexasKG5FJW BKG5FJW Ghб[@KLѓ џџ2hюџџџџџџџџџџџџџџџџSeguinTexasKG5FJW CKG5FJW GPЌР' ѓ џџ2hюSpringTexasKF5KHM AKF5KHM G@hM-1ѓ џџ2hюSpringTexasKF5KHM BKF5KHM GЄB@KLѓ џџ2hюџџџџџџџџџџџџџџџџSpringTexasKF5KHM CKF5KHM G`ЖЉР' ѓ џџ2hюSulphur SpringsTexasK5SST BK5SST G8{@KLѓ џџ2hюSulphur SpringsTexasK5SST CK5SST G ѕУР' ѓ џџ2hюџџџџџџџџџџџџџџџџTempleTexasK5CTX AK5CTX G сM-1ѓ џџ2hюTempleTexasK5CTX BK5CTX GШрA@KLѓ џџ2hюTempleTexasK5CTX CK5CTX Gр:ШР' ѓ џџ2hюџџџџџџџџџџџџџџџџTylerTexasW5ETX BW5ETX GPпƒ@KLѓ џџ2hюTylerTexasW5ETX CW5ETX G€пФАq ѓ џџ2hюWacoTexasW5ZDN CW5ZDN G МТР' ѓ џџ2hюџџџџџџџџџџџџџџџџWalburgTexasKE5RCS AKE5RCS G€ЊM-1ѓ џџ2hюWalburgTexasKE5RCS BKE5RCS GЄB@KLѓ џџ2hю WalburgTexasKE5RCS CKE5RCS G‚ІР' ѓ џџ2hю!џџџџџџџџџџџџџџџџAnaheimCaliforniaW6HRO AW6HRO GhІТLЗІћџџ2iю "AnaheimCaliforniaW6HRO BW6HRO G€а@KLІћџџ2iю!#AnaheimCaliforniaW6HRO CW6HRO GPНЫxќ&Іћџџ2iю"$џџџџџџџџџџџџџџџџConcordCaliforniaW6CX CW6CX G@†Є %&ѓџџ2iю#%CoronaCaliforniaKJ6GRS BKJ6GRS Gї@KLMћџџ2iю$&CoronadoCaliforniaW6MLI AW6MLI GРp‘LЗMћџџ2iю%'џџџџџџџџџџџџџџџџCoronadoCaliforniaW6MLI BW6MLI GрŠЂ@KLMћџџ2iю&(CoronadoCaliforniaW6MLI CW6MLI G зШ ЁMћџџ2iю')DanvilleCaliforniaK6DDV AK6DDV G сЇР' ѓџџ2iю(*џџџџџџџџџџџџџџџџDanvilleCaliforniaK6DDV BK6DDV GјlS@KLѓџџ2iю)+DanvilleCaliforniaK6DDV CK6DDV GрюЊР' ѓџџ2iю*,FolsomCaliforniaKS6HRP CKS6HRP GxWЭР' ѓџџ2iю+-џџџџџџџџџџџџџџџџGilroyCaliforniaKJ6WZS BKJ6WZS GˆЇo@KLѓџџ2iю,.Laguna BeachCaliforniaK6SOA AK6SOA G@ьrLЗІћџџ2iю-/Laguna BeachCaliforniaK6SOA BK6SOA G(ы@KLІћџџ2iю.0џџџџџџџџџџџџџџџџLaguna BeachCaliforniaK6SOA CK6SOA GИ‰ЕР' Іћџџ2iю/1Laguna NiguelCaliforniaK6VO CK6VO G˜ш­Іћџџ2iю02Los AngelesCaliforniaKI6JKA BKI6JKA GЛЇ@KLІћџџ2iю13џџџџџџџџџџџџџџџџLos AngelesCaliforniaKJ6MFU AKJ6MFU GРЖLЗІћџџ2iю24Los AngelesCaliforniaKJ6MFU BKJ6MFU Gpи)Іћџџ2iю35Los AngelesCaliforniaKJ6MFU CKJ6MFU GиюЦР' Іћџџ2iю46џџџџџџџџџџџџџџџџLos AngelesCaliforniaWA6IRC AWA6IRC GЏsLЗІћџџ2iю57Los AngelesCaliforniaWA6IRC BWA6IRC GJЅ@KLІћџџ2iю68Los AngelesCaliforniaWA6IRC CWA6IRC G@–Ыxќ&Іћџџ2iю79џџџџџџџџџџџџџџџџMalibuCaliforniaKJ6BWR BKJ6BWR G5“@KLІћџџ2iю8:MonroviaCaliforniaW9WDX BW9WDX GрŠЂ@KLІћџџ2iю9;Mt. BullionCaliforniaW6HHD AW6HHD G Я‰LЗѓџџ2iю:<џџџџџџџџџџџџџџџџMt. BullionCaliforniaW6HHD BW6HHD Gƒ@KLѓџџ2iю;=Mt. BullionCaliforniaW6HHD CW6HHD Gр›Ѓ€ѓџџ2iю<>Mt. ShastaCaliforniaW6BML BW6BML GxRM@KLѓџџ2iю=?џџџџџџџџџџџџџџџџNapaCaliforniaW6CO BW6CO GPЁ:@KLѓџџ2iю>@OrovilleCaliforniaKJ6LVV BKJ6LVV G8{@KLѓџџ2iю?APalm SpringsCaliforniaK6IFR BK6IFR G аІ@KLšћџџ2iю@BџџџџџџџџџџџџџџџџPalomar Mtn.CaliforniaKI6MGN BKI6MGN G H“@KLѓћџџ2iюACPalomar Mtn.CaliforniaKI6MGN CKI6MGN Ghs­Р' ѓћџџ2iюBDSan BernardinoCaliforniaKI6WZX BKI6WZX G ›š@KLѓћџџ2iюCEџџџџџџџџџџџџџџџџSan DiegoCaliforniaKI6KQU BKI6KQU Gˆ’Б@KLѓћџџ2iюDFSan DiegoCaliforniaKW6HRO BKW6HRO G _Є@KLѓћџџ2iюEGSan JoseCaliforniaWW6BAY BWW6BAY Gј x@KLѓџџ2iюFHџџџџџџџџџџџџџџџџSan LeandroCaliforniaAC6SO AAC6SO G ъL МОѓџџ2iюGISan LeandroCaliforniaAC6SO CAC6SO GРеЖР' ѓџџ2iюHJSanta CruzCaliforniaK6BJ BK6BJ GјlS@KLѓџџ2iюIKџџџџџџџџџџџџџџџџSanta RosaCaliforniaK6ACS BK6ACS GєZ@KLѓџџ2iюJLSanta RosaCaliforniaK6ACS CK6ACS G€"Ѕ€ѓџџ2iюKMSanta YnezCaliforniaKK6GFX BKK6GFX GБ@KLѓџџ2iюLNџџџџџџџџџџџџџџџџVictorvilleCaliforniaKJ6KTV CKJ6KTV GPНЫxќ&Mћџџ2iюMOVisaliaCaliforniaK6VIS AK6VIS GУЋLЗІћџџ2iюNPVisaliaCaliforniaK6VIS BK6VIS G`і\@KLІћџџ2iюOQџџџџџџџџџџџџџџџџVisaliaCaliforniaK6VIS CK6VIS GЗЄ %&Іћџџ2iюPRVistaCaliforniaKJ6FCH BKJ6FCH G№“Ї@KLMћџџ2iюQSWrightwoodCaliforniaKJ6LJZ BKJ6LJZ GxkБ@KLMћџџ2iюRTџџџџџџџџџџџџџџџџGoodyearArizonaKG7HBZ BKG7HBZ GмE@KLк!ћџџ2jюSUMesaArizonaKE7JFH AKE7JFH GPvЁLЗЩћџџ2jюTVMesaArizonaKE7JFH BKE7JFH Gи •@KLЩћџџ2jюUWџџџџџџџџџџџџџџџџMesaArizonaKE7JFH CKE7JFH GˆnІР' Щћџџ2jюVXOro ValleyArizonaW0HF BW0HF G@^’@KLЩћџџ2jюWYPeoriaArizonaKG7NUI AKG7NUI GРЖLЗ ћџџ2jюXZџџџџџџџџџџџџџџџџPeoriaArizonaKG7NUI BKG7NUI Gpb ћџџ2jюY[ScottsdaleArizonaKF7CUF BKF7CUF G0Ј”@KLћџџ2jюZ\TucsonArizonaKG7PJV BKG7PJV G\Bˆ@KLcћџџ2jю[]џџџџџџџџџџџџџџџџWilliamsArizonaK7NAZ BK7NAZ Gl-’@KL ћџџ2jю\^WilliamsArizonaK7NAZ CK7NAZ GxGІР'  ћџџ2jю]_GlobeArizonaN7CI BN7CI G!“@KLAћџџ2jю^`џџџџџџџџџџџџџџџџKingmanArizonaW7KDS AW7KDS GIˆLЗ‡ћџџ2jю_aKingmanArizonaW7KDS BW7KDS Gрф“@KL‡ћџџ2jю`bKingmanArizonaW7KDS CW7KDS G˜•ІР' ‡ћџџ2jюacџџџџџџџџџџџџџџџџPhoenixArizonaW7MOT AW7MOT G`Т†LЗБћџџ2jюbdPhoenixArizonaW7MOT BW7MOT GдCF@KLБћџџ2jюcePhoenixArizonaW7MOT CW7MOT G˜•ІР' Бћџџ2jюdfџџџџџџџџџџџџџџџџTucsonArizonaK7RST AK7RST GŒLЗj ћџџ2jюegTucsonArizonaK7RST BK7RST Gрф“@KLj ћџџ2jюfhTucsonArizonaK7RST CK7RST GPLЩ@Bj ћџџ2jюgiџџџџџџџџџџџџџџџџTucsonArizonaKR7ST CKR7ST GxGІР' Ÿћџџ2jюhjJeromeIdahoKF7VTM BKF7VTM Gƒ@KLЋ ћџџ2jюikBillingsMontanaK7EFA BK7EFA G@2У@KL.u$ћџџ2jюjlџџџџџџџџџџџџџџџџLas VegasNevadaN7ARR AN7ARR GрXM€БOvћџџ2jюkmLas VegasNevadaN7ARR BN7ARR G€ Ё@KLvћџџ2jюlnLas VegasNevadaN7ARR CN7ARR Gи1ЇР' vћџџ2jюmoџџџџџџџџџџџџџџџџLas VegasNevadaW7AES AW7AES G№ЗoLЗvћџџ2jюnpLas VegasNevadaW7AES BW7AES GXјЫ@KLvћџџ2jюoqLas VegasNevadaW7AES CW7AES GXыбР' vћџџ2jюprџџџџџџџџџџџџџџџџRenoNevadaN7NDS BN7NDS Ghp€@KLѓџџ2jюqsCorvallisOregonKF7LDG BKF7LDG G03ь@KLѓџџ2jюrtGrants PassOregonKE7LKX BKE7LKX GЄь@@KLѓџџ2jюsuџџџџџџџџџџџџџџџџHillsboroOregonN7QQU BN7QQU GpBB@KLѓџџ2jюtvMedfordOregonKE7MVI BKE7MVI Gxs@KLѓџџ2jюuwMedfordOregonKG7FOJ AKG7FOJ Gˆ…M-1ѓџџ2jюvxџџџџџџџџџџџџџџџџMedfordOregonKG7FOJ BKG7FOJ Gв€@KLѓџџ2jюwyMedfordOregonKG7FOJ CKG7FOJ GPНР' ѓџџ2jюxzMt HeboOregonW7GC CW7GC G0ўШР' ѓџџ2jюy{џџџџџџџџџџџџџџџџSherwoodOregonWB7DZG AWB7DZG G[M-1ѓџџ2jюz|SherwoodOregonWB7DZG BWB7DZG GДЋ{@KLѓџџ2jю{}SherwoodOregonWB7DZG CWB7DZG GPНР' ѓџџ2jю|~џџџџџџџџџџџџџџџџAmerican ForkUtahNT3ST BNT3ST GаЧ@KLj ћџџ2jю}Cedar CityUtahWR7AAA BWR7AAA GА,Г@KL5ћџџ2jю~€Cedar CityUtahWR7AAA CWR7AAA G0аІР' 5ћџџ2jюџџџџџџџџџџџџџџџџLoganUtahAC7O BAC7O GXŽГ@KLu$ћџџ2jю€‚LoganUtahAC7O CAC7O G0аІР' u$ћџџ2jюƒLoganUtahN7RDS BN7RDS GЫВ@KLљћџџ2jю‚„џџџџџџџџџџџџџџџџMorganUtahKM7ARC BKM7ARC G„]Г@KLсћџџ2jюƒ…MorganUtahKM7ARC CKM7ARC GЇР' сћџџ2jю„†ParadiseUtahKF7VJO BKF7VJO GА,Г@KLлћџџ2jю…‡џџџџџџџџџџџџџџџџPriceUtahK7YI BK7YI GјЕ@KLћџџ2jю†ˆSalt Lake CityUtahKF6RAL AKF6RAL GРЖLЗ ћџџ2jю‡‰Salt Lake CityUtahKF6RAL BKF6RAL GјЕ@KL ћџџ2jюˆŠџџџџџџџџџџџџџџџџSalt Lake CityUtahKF6RAL CKF6RAL GˆnІР'  ћџџ2jю‰‹WellsvilleUtahNU7TS BNU7TS GXјЫ@KL'#ћџџ2jюŠŒWest BountifulUtahKF7ZNS BKF7ZNS GXŽГ@KLAћџџ2jю‹џџџџџџџџџџџџџџџџWest BountifulUtahKF7ZNS CKF7ZNS G\ŸІР' Aћџџ2jюŒŽAuburnWashingtonKF7NOD AKF7NOD GpПЎѓџџ2jюAuburnWashingtonKF7NOD BKF7NOD G4eІѓџџ2jюސџџџџџџџџџџџџџџџџAuburnWashingtonKF7NOD CKF7NOD GѓЈѓџџ2jю‘Bainbridge I.WashingtonW7NPC AW7NPC G wыL-1ѓџџ2jю’Bainbridge I.WashingtonW7NPC BW7NPC GD|@KLѓџџ2jю‘“џџџџџџџџџџџџџџџџBellevueWashingtonK7LWH AK7LWH G€жуL-1ѓџџ2jю’”BellevueWashingtonK7LWH BK7LWH Gф˜h@KLѓџџ2jю“•BellevueWashingtonK7LWH CK7LWH GШАЕ@Bѓџџ2jю”–џџџџџџџџџџџџџџџџBellinghamWashingtonWC7SO BWC7SO GxA@KLѓџџ2jю•—BellinghamWashingtonWC7SO CWC7SO GрvОР' ѓџџ2jю–˜BurienWashingtonKF7CLD BKF7CLD Gш n@KLѓџџ2jю—™џџџџџџџџџџџџџџџџBurienWashingtonKF7GVL BKF7GVL GhœO@KLѓџџ2jю˜šCle ElumWashingtonWR7KCR BWR7KCR Gtг„@KLѓџџ2jю™›EdmondsWashingtonNW7DR ANW7DR Gд:@KLѓџџ2jюšœџџџџџџџџџџџџџџџџEdmondsWashingtonNW7DR BNW7DR Gд:@KLѓџџ2jю›EnumclawWashingtonW7JD BW7JD Gшыa@KLѓџџ2jюœžEverettWashingtonNR7SS BNR7SS G05?@KLѓџџ2jюŸџџџџџџџџџџџџџџџџFederal WayWashingtonWA7FW BWA7FW Gt@KLѓџџ2jюž Federal WayWashingtonWA7FW CWA7FW GР™РР' ѓџџ2jюŸЁGrahamWashingtonWA7DR BWA7DR GШf@KLѓџџ2jю ЂџџџџџџџџџџџџџџџџIssaquahWashingtonKG7DWG AKG7DWG GРЖLЗѓџџ2jюЁЃIssaquahWashingtonKG7DWG BKG7DWG Gh27ѓџџ2jюЂЄIssaquahWashingtonKG7DWG CKG7DWG G ЂМѓџџ2jюЃЅџџџџџџџџџџџџџџџџKirklandWashingtonN7IH AN7IH G€п M-1ѓџџ2jюЄІKirklandWashingtonN7IH BN7IH Gиjp@KLѓџџ2jюЅЇKirklandWashingtonN7IH CN7IH Gx"С@Bѓџџ2jюІЈџџџџџџџџџџџџџџџџLake StevensWashingtonKF7UUY BKF7UUY GЄ!M@KLѓџџ2jюЇЉMaple ValleyWashingtonKF7NPL BKF7NPL G8Џb@KLѓџџ2jюЈЊNewcastleWashingtonW7RNK BW7RNK GT^L@KLѓџџ2jюЉЋџџџџџџџџџџџџџџџџSaint GeorgeWashingtonKF7YIX BKF7YIX GА,Г@KLТ%ћџџ2jюЊЌSaint GeorgeWashingtonKF7YIX CKF7YIX G0аІР' Т%ћџџ2jюЋ­SeattleWashingtonWA7HJR BWA7HJR G<Ё€@KLѓџџ2jюЌЎџџџџџџџџџџџџџџџџSnoqualmieWashingtonN7SNO BN7SNO Gрc@KLѓџџ2jю­ЏSpokaneWashingtonKB7ARA AKB7ARA G 1M-1Mћџџ2jюЎАSpokaneWashingtonKB7ARA BKB7ARA Gi@KLMћџџ2jюЏБџџџџџџџџџџџџџџџџSpokaneWashingtonWA7DRE AWA7DRE G 1M-1Mћџџ2jюАВSpokaneWashingtonWA7DRE BWA7DRE Gi@KLMћџџ2jюБГTukwilaWashingtonKF7BFS BKF7BFS G8>@KLѓџџ2jюВДџџџџџџџџџџџџџџџџTukwilaWashingtonKF7BFT BKF7BFT G(Z@@KLѓџџ2jюГЕCheyenneWyomingKC7SNO BKC7SNO GЈЈ@KL ўћџџ2jюДЖGilletteWyomingNE7WY CNE7WY G`ЖЉР' Wћџџ2jюЕЗџџџџџџџџџџџџџџџџRivertonWyomingN8CZI BN8CZI Gиjp@KL5 ћџџ2jюЖИAuburn HillsMichiganK8DXA BK8DXA Gdшz@KLѓ$џџ2kюЗЙAuburn HillsMichiganK8DXA CK8DXA G‚ІР' ѓ$џџ2kюИКџџџџџџџџџџџџџџџџBattle CreekMichiganW8DF CW8DF GpжПР' ѓ$џџ2kюЙЛCharlotteMichiganK8ETN BK8ETN GМQn@KLѓ$џџ2kюКМCharlotteMichiganK8ETN CK8ETN G€“ЇР' ѓ$џџ2kюЛНџџџџџџџџџџџџџџџџGaylordMichiganKD8QCC BKD8QCC G|yw@KLѓ$џџ2kюМОGrand RapidsMichiganWX8GRR AWX8GRR G ъLЗѓ$џџ2kюНПGrand RapidsMichiganWX8GRR BWX8GRR G№Ц`@KLѓ$џџ2kюОРџџџџџџџџџџџџџџџџGrand RapidsMichiganWX8GRR CWX8GRR GwЧР' ѓ$џџ2kюПСHellMichiganK8LCD AK8LCD G€2(M-1ѓ$џџ2kюРТHellMichiganK8LCD BK8LCD G$лw@KLѓ$џџ2kюСУџџџџџџџџџџџџџџџџHellMichiganK8LCD CK8LCD G?ЦР' ѓ$џџ2kюТФHollyMichiganW8CMN AW8CMN GРp‘LЗѓ$џџ2kюУХHollyMichiganW8CMN BW8CMN Gtžx@KLѓ$џџ2kюФЦџџџџџџџџџџџџџџџџHollyMichiganW8CMN CW8CMN G0#Ўѓ$џџ2kюХЧHowellMichiganW8LIV BW8LIV G|yw@KLѓ$џџ2kюЦШHowellMichiganW8LIV CW8LIV G@hЉР' ѓ$џџ2kюЧЩџџџџџџџџџџџџџџџџIthacaMichiganKD8IEK BKD8IEK GмНi@KLѓ$џџ2kюШЪIthacaMichiganKD8IEK CKD8IEK GАTХР' ѓ$џџ2kюЩЫMuskegonMichiganWD8MKG BWD8MKG Gдw@KLѓ$џџ2kюЪЬџџџџџџџџџџџџџџџџMuskegonMichiganWD8MKG CWD8MKG G€ЊР' ѓ$џџ2kюЫЭOwossoMichiganW8SHI BW8SHI Gрz{@KLѓ$џџ2kюЬЮOwossoMichiganW8SHI CW8SHI GР/ЈР' ѓ$џџ2kюЭЯџџџџџџџџџџџџџџџџStutsmanvilleMichiganW8CCE BW8CCE G˜]m@KLѓ$џџ2kюЮаCincinnatiOhioK8BIG BK8BIG Gчv@KLѓ$џџ2kюЯбCincinnatiOhioK8BIG CK8BIG GpнЉР' ѓ$џџ2kюавџџџџџџџџџџџџџџџџClevelandOhioWB8THD BWB8THD GX]@KLѓ$џџ2kюбгClevelandOhioWB8THD CWB8THD GpнЉР' ѓ$џџ2kювдColumbusOhioW8CMH BW8CMH Gчv@KLѓ$џџ2kюгеџџџџџџџџџџџџџџџџColumbusOhioW8CMH CW8CMH GPЌР' ѓ$џџ2kюджColumbusOhioW8DIG AW8DIG G@‹—LЗѓ$џџ2kюезColumbusOhioW8DIG BW8DIG GMb@KLѓ$џџ2kюжиџџџџџџџџџџџџџџџџColumbusOhioW8DIG CW8DIG GАyЊР' ѓ$џџ2kюзйDaytonOhioW8RTL AW8RTL GрЇ€LЗѓ$џџ2kюикDaytonOhioW8RTL BW8RTL Ghh@KLѓ$џџ2kюйлџџџџџџџџџџџџџџџџDaytonOhioW8RTL CW8RTL GшЄФР' ѓ$џџ2kюкмDaytonOhioW9IPA BW9IPA GdГn@KLѓ$џџ2kюлнDaytonOhioW8HEQ BW8HEQ GЬ\F@KLѓ џџ2lюLake CountyIllinoisKC9OKW BKC9OKW G’ЇL@KLѓ џџ2lюџџџџџџџџџџџџџџџџLake ZurichIllinoisKC9VUF AKC9VUF G 1M-1ѓ џџ2lюLake ZurichIllinoisKC9VUF BKC9VUF Gt@KLѓ џџ2lюLake ZurichIllinoisKC9VUF CKC9VUF G|@Ўѓ џџ2lюџџџџџџџџџџџџџџџџNorthbrookIllinoisWX9NC AWX9NC Gа&LЗѓ џџ2lюNorthbrookIllinoisWX9NC BWX9NC GšЗW@KLѓ џџ2lюNorthbrookIllinoisWX9NC CWX9NC GwЧР' ѓ џџ2lюџџџџџџџџџџџџџџџџPeoriaIllinoisW9PIA AW9PIA G€uM-1ѓ џџ2lюPeoriaIllinoisW9PIA BW9PIA GЮЫn@KLѓ џџ2lюPeoriaIllinoisW9PIA CW9PIA Gh ІР' ѓ џџ2lюџџџџџџџџџџџџџџџџRock IslandIllinoisW9QCR BW9QCR GF@KLѓ џџ2lюRolling MeadowsIllinoisKC9RBB BKC9RBB G€—d@KLѓ џџ2lюSpringfieldIllinoisW9DUA BW9DUA G‚s@KLѓ џџ2lюџџџџџџџџџџџџџџџџSwanseaIllinoisKC9WKE AKC9WKE G@%Щѓ џџ2lюSwanseaIllinoisKC9WKE BKC9WKE G  ѓ џџ2lюSwanseaIllinoisKC9WKE CKC9WKE G|@Ўѓ џџ2lю џџџџџџџџџџџџџџџџBloomingtonIndianaK9IU BK9IU G Ђ„@KLѓ$џџ2lю!BloomingtonIndianaK9IU CK9IU GрЩХР' ѓ$џџ2lю "Fort WayneIndianaW9TE BW9TE GVŒg@KLѓ$џџ2lю!#џџџџџџџџџџџџџџџџIndianapolisIndianaW9ICE AW9ICE GўO@KLѓ$џџ2lю"$IndianapolisIndianaW9ICE BW9ICE GHЯx@KLѓ$џџ2lю#%IndianapolisIndianaW9ICE CW9ICE G0ўШР' ѓ$џџ2lю$&џџџџџџџџџџџџџџџџLafayetteIndianaW9ARP BW9ARP Gрz{@KLѓ$џџ2lю%'LafayetteIndianaW9ARP CW9ARP GьОР' ѓ$џџ2lю&(MarionIndianaW9EBN BW9EBN G@Пm@KLѓ$џџ2lю')џџџџџџџџџџџџџџџџBarabooWisconsinWB9FDZ CWB9FDZ GИTЉР' ѓ џџ2lю(*GraftonWisconsinW9FRG BW9FRG GОрd@KLѓ џџ2lю)+GraftonWisconsinW9FRG CW9FRG G(ѕЇР' ѓ џџ2lю*,џџџџџџџџџџџџџџџџMadisonWisconsinW9HSY CW9HSY GЈ-ЉР' ѓ џџ2lю+-MilwaukeeWisconsinK9AES CK9AES G8ЈР' ѓ џџ2lю,.MilwaukeeWisconsinKC9LKZ AKC9LKZ Gа™фL-1ѓ џџ2lю-/џџџџџџџџџџџџџџџџMilwaukeeWisconsinKC9LKZ BKC9LKZ Gމ_@KLѓ џџ2lю.0Park FallsWisconsinW9PFP BW9PFP GbК_@KLѓ џџ2lю/1Park FallsWisconsinW9PFP CW9PFP GшЩЉР' ѓ џџ2lю02џџџџџџџџџџџџџџџџRichfieldWisconsinK9PAQ BK9PAQ Gh;t@KLѓ џџ2lю13RichfieldWisconsinK9PAQ CK9PAQ GаРРР' ѓ џџ2lю24Richland CenterWisconsinKC9WDW BKC9WDW GЬв_@KLѓ џџ2lю35џџџџџџџџџџџџџџџџSheboyganWisconsinKC9SJY BKC9SJY GbК_@KLѓ џџ2lю46SheboyganWisconsinKC9SJY CKC9SJY GиюЦР' ѓ џџ2lю57WausauWisconsinW9BCC AW9BCC G KkLЗѓ џџ2lю68џџџџџџџџџџџџџџџџWausauWisconsinW9BCC BW9BCC Gމ_@KLѓ џџ2lю79WausauWisconsinW9BCC CW9BCC GHCЈР' ѓ џџ2lю8:WonewocWisconsinKD9BLN BKD9BLN GЖ:r@KLѓ џџ2lю9;џџџџџџџџџџџџџџџџWonewocWisconsinKD9BLN CKD9BLN GxБОР' ѓ џџ2lю:<Battlement MesaColoradoK0RV AK0RV G˜YАР'   ћџџ2mю;=Battlement MesaColoradoK0RV BK0RV GЄ”Ђ@KL  ћџџ2mю<>џџџџџџџџџџџџџџџџBattlement MesaColoradoK0RV CK0RV GXL­Р'   ћџџ2mю=?BoulderColoradoKC0DS AKC0DS Gф/†LРсф ?ћџџ2mю>@BoulderColoradoKC0DS BKC0DS GЄ”Ђ@KL ?ћџџ2mю?AџџџџџџџџџџџџџџџџBoulderColoradoKC0DS CKC0DS GьoЊР' ?ћџџ2mю@BBroomfieldColoradoKD0LUX CKD0LUX G˜УШР' Іћџџ2mюACCarnColoradoWR0AEN AWR0AEN G@M-1 Бћџџ2mюBDџџџџџџџџџџџџџџџџCarnColoradoWR0AEN BWR0AEN GPЭ@KL Бћџџ2mюCECarnColoradoWR0AEN CWR0AEN G˜fЊ@KL Бћџџ2mюDFColorado SpringsColoradoKC0CVU BKC0CVU GєWЃ@KL7ђћџџ2mюEGџџџџџџџџџџџџџџџџColorado SpringsColoradoKC0CVU CKC0CVU G(fЊР' 7ђћџџ2mюFHDenverColoradoW0CDS AW0CDS G„Ж‡LЗ)ћџџ2mюGIDenverColoradoW0CDS BW0CDS GDЄ@KL)ћџџ2mюHJџџџџџџџџџџџџџџџџDenverColoradoW0CDS CW0CDS GаVЈР' )ћџџ2mюIKFort CollinsColoradoW0QEY AW0QEY G„Ж‡LЗ -j ћџџ2mюJLFort CollinsColoradoW0QEY BW0QEY GTбЁ@KL -j ћџџ2mюKMџџџџџџџџџџџџџџџџFort CollinsColoradoW0QEY CW0QEY GаVЈР' -j ћџџ2mюLNGrand JunctionColoradoKD0RED BKD0RED Gи>Ё@KLѓџџ2mюMOLovelandColoradoK0AEN AK0AEN G€cŽL-1 /"ћџџ2mюNPџџџџџџџџџџџџџџџџLovelandColoradoK0AEN BK0AEN GШ'Ш@KL /"ћџџ2mюOQLovelandColoradoK0AEN CK0AEN G@hЉР' /"ћџџ2mюPRParkerColoradoK0PRA BK0PRA GаcЂ@KL8{ћџџ2mюQSџџџџџџџџџџџџџџџџCedar FallsIowaW0MG BW0MG Gв€@KLѓ џџ2mюRTCedar RapidsIowaN0CXX BN0CXX Gа%Y@KLѓ џџ2mюSUCedar RapidsIowaN0CXX CN0CXX GШ8Щ0ѓ џџ2mюTVџџџџџџџџџџџџџџџџDes MoinesIowaKD0IAN BKD0IAN GXPj@KLѓ џџ2mюUWDes MoinesIowaKD0IAN CKD0IAN GшЄФР' ѓ џџ2mюVXMount PleasantIowaKD0NJC BKD0NJC G0>|@KLѓ џџ2mюWYџџџџџџџџџџџџџџџџNew LondonIowaKD0PKU BKD0PKU G  ѓ џџ2mюXZReinbeckIowaW0RBK BW0RBK Gј@„@KLѓ џџ2mюY[LouisburgKansasK0HAM AK0HAM GРЖLЗѓ џџ2mюZ\џџџџџџџџџџџџџџџџLouisburgKansasK0HAM BK0HAM GШJZ@KLѓ џџ2mю[]LouisburgKansasK0HAM CK0HAM G[ІР' ѓ џџ2mю\^OlatheKansasWA0RC BWA0RC GHe`@KLѓ џџ2mю]_џџџџџџџџџџџџџџџџScott CityKansasW0MI BW0MI GЈk@KLѓ џџ2mю^`Travese CityMichiganWI0OK CWI0OK G€ЊР' ѓ$џџ2mю_aBloomingtonMinnesotaWT0O BWT0O G f@KLѓ џџ2mю`bџџџџџџџџџџџџџџџџBloomingtonMinnesotaWT0O CWT0O G0аІР' ѓ џџ2mюacChaskaMinnesotaKD0JOS AKD0JOS GрЇ€LЗѓ џџ2mюbdChaskaMinnesotaKD0JOS BKD0JOS GШJZ@KLѓ џџ2mюceџџџџџџџџџџџџџџџџChaskaMinnesotaKD0JOS CKD0JOS Gp)ЧР' ѓ џџ2mюdfChaskaMinnesotaKD0JOT AKD0JOT G eqLЗѓ џџ2mюegDuluthMinnesotaN0EO BN0EO GРo[@KLѓ џџ2mюfhџџџџџџџџџџџџџџџџDuluthMinnesotaN0EO CN0EO G˜УШР' ѓ џџ2mюgiFaribaultMinnesotaKD0ZSA BKD0ZSA Ghp€@KLѓ џџ2mюhjLittle FallsMinnesotaW0REA BW0REA Gчv@KLѓ џџ2mюikџџџџџџџџџџџџџџџџMinneapolisMinnesotaKD0JOU AKD0JOU G š}LЗѓ џџ2mюjlMinneapolisMinnesotaKD0JOU BKD0JOU Gј@„@KLѓ џџ2mюkmMinneapolisMinnesotaKD0JOU CKD0JOU G№3ІР' ѓ џџ2mюlnџџџџџџџџџџџџџџџџRamseyMinnesotaW0MDT AW0MDT G`–ЗLЗѓ џџ2mюmoRamseyMinnesotaW0MDT BW0MDT GHe`@KLѓ џџ2mюnpRamseyMinnesotaW0MDT CW0MDT GаVЈР' ѓ џџ2mюoqџџџџџџџџџџџџџџџџRochesterMinnesotaW0MXW BW0MXW Gt@KLѓ џџ2mюprShoreviewMinnesotaKC0WLB BKC0WLB Gчv@KLѓ џџ2mюqsShoreviewMinnesotaW8WRR AW8WRR G ъLЗѓ џџ2mюrtџџџџџџџџџџџџџџџџShoreviewMinnesotaW8WRR BW8WRR G№ћl@KLѓ џџ2mюsuSt. CloudMinnesotaKD0YLG BKD0YLG Gt@KLѓ џџ2mюtvWandaMinnesotaKD0IAI BKD0IAI GЈHw@KLѓ џџ2mюuwџџџџџџџџџџџџџџџџColumbiaMissouriWX0BC BWX0BC GX]@KLѓ џџ2mюvxKansas CityMissouriW0CW AW0CW GN˜LЗѓ џџ2mюwyKansas CityMissouriW0CW BW0CW G@Пm@KLѓ џџ2mюxzџџџџџџџџџџџџџџџџPacificMissouriKD0ZEA BKD0ZEA G`і\@KLѓ џџ2mюy{PacificMissouriKD0ZEA CKD0ZEA GPІК@Bѓ џџ2mюz|RollaMissouriW0EEE BW0EEE GЈ†Р@KLѓ џџ2mю{}џџџџџџџџџџџџџџџџSpringfieldMissouriW0OMD CW0OMD Gи›ПР' ѓ џџ2mю|~St LouisMissouriK0MDG AK0MDG G@‹—LЗѓ џџ2mю}St LouisMissouriK0MDG BK0MDG G˜(a@KLѓ џџ2mю~€џџџџџџџџџџџџџџџџSt LouisMissouriK0MDG CK0MDG GXEУР' ѓ џџ2mюWashingtonMissouriK0FDG BK0FDG G mx@KLѓ џџ2mю€‚ColumbusNebraskaWA0COL BWA0COL G[@KLѓ џџ2mюƒџџџџџџџџџџџџџџџџColumbusNebraskaWA0COL CWA0COL GјZТР' ѓ џџ2mю‚„Grand IslandNebraskaKD0PBV CKD0PBV G(юНР' ѓ џџ2mюƒ…KearneyNebraskaKD0PBW CKD0PBW G№УР' ѓ џџ2mю„†џџџџџџџџџџџџџџџџLincolnNebraskaW0MAO BW0MAO GpЌZ@KLѓ џџ2mю…‡LincolnNebraskaW0MAO CW0MAO GаVЈР' ѓ џџ2mю†ˆOmahaNebraskaKD0CGR BKD0CGR GШJZ@KLѓ џџ2mю‡‰џџџџџџџџџџџџџџџџOmahaNebraskaKD0CGR CKD0CGR Gи1ЇР' ѓ џџ2mюˆŠFargoNorth DakotaKD0SWQ BKD0SWQ Gчv@KLѓ џџ2mю‰‹Sioux FallsSouth DakotaW0ZWY BW0ZWY G0дc@KLѓ џџ2mюŠŒџџџџџџџџџџџџџџџџWasillaAlaskaWL7CWI AWL7CWI G@M-1ѓџџ2nю‹WasillaAlaskaWL7CWI BWL7CWI G€bX@KLѓџџ2nюŒŽWasillaAlaskaWL7CWI CWL7CWI GР УР' ѓџџ2nюџџџџџџџџџџџџџџџџKetchikanAlaskaKL7FF CKL7FF G зШР' ѓџџ2nюސHonoluluHawaiiWH6DIG BWH6DIG GH…@KLѓџџ2oю‘HonoluluHawaiiWH6DIG CWH6DIG GрЩХР' ѓџџ2oю’џџџџџџџџџџџџџџџџAntigonishNova ScotiaVE1JSR BVE1JSR G 8l@KLѓ(џџ3xю‘“AntigonishNova ScotiaVE1JSR CVE1JSR G 8l@KLѓ(џџ3xю’”BridgewaterNova ScotiaVE1DSR CVE1DSR GѓЈР' ѓ(џџ3xю“•џџџџџџџџџџџџџџџџBlainvilleQuebecVE2YUU AVE2YUU G eqLЗѓ$џџ3yю”–BlainvilleQuebecVE2YUU BVE2YUU G€bX@KLѓ$џџ3yю•—BlainvilleQuebecVE2YUU CVE2YUU GD•ѓ$џџ3yю–˜џџџџџџџџџџџџџџџџCovey HillQuebecVA2REX AVA2REX GрЇ€LЗѓ$џџ3yю—™Covey HillQuebecVA2REX BVA2REX GˆхИ@KLѓ$џџ3yю˜šCovey HillQuebecVE2REX CVE2REX G№†­Р' ѓ$џџ3yю™›џџџџџџџџџџџџџџџџCrabtreeQuebecVA2RIU AVA2RIU GрЇ€LЗѓ$џџ3yюšœCrabtreeQuebecVA2RIU BVA2RIU G`џ™ѓ$џџ3yю›CrabtreeQuebecVA2RIU CVA2RIU G@†Єѓ$џџ3yюœžџџџџџџџџџџџџџџџџGatineauQuebecVE2REH BVE2REH GMb@KLѓ$џџ3yюŸGatineauQuebecVE2REH CVE2REH G HЫѓ$џџ3yюž Grand-MereQuebecVE2SKG AVE2SKG G eqLЗѓ$џџ3yюŸЁџџџџџџџџџџџџџџџџGrand-MereQuebecVE2SKG BVE2SKG G€bX@KLѓ$џџ3yю ЂGrand-MereQuebecVE2SKG CVE2SKG GD•ѓ$џџ3yюЁЃLac-ЩchoQuebecVA2RMP AVA2RMP G€ЭІLЗѓ$џџ3yюЂЄџџџџџџџџџџџџџџџџLac-ЩchoQuebecVA2RMP BVA2RMP G0 p@KLѓ$џџ3yюЃЅLac-ЩchoQuebecVA2RMP CVA2RMP GpNЌР' ѓ$џџ3yюЄІLongueuilQuebecVE2QE AVE2QE G@(јI-1ѓ$џџ3yюЅЇџџџџџџџџџџџџџџџџLongueuilQuebecVE2QE BVE2QE G<™@KLѓ$џџ3yюІЈLongueuilQuebecVE2QE CVE2QE G HЫѓ$џџ3yюЇЉMont-ONeilQuebecVE2RMF AVE2RMF GРyL-1ѓ$џџ3yюЈЊџџџџџџџџџџџџџџџџMont-OrfordQuebecVE2RTO AVE2RTO G 'wK@KLѓ$џџ3yюЉЋMont-OrfordQuebecVE2RTO BVE2RTO G€bX-1ѓ$џџ3yюЊЌMontrealQuebecVE2RHH AVE2RHH GРЕSJЗѓ$џџ3yюЋ­џџџџџџџџџџџџџџџџMontrealQuebecVE2RHH BVE2RHH G” t@KLѓ$џџ3yюЌЎMontrealQuebecVE2RHH CVE2RHH G HЫѓ$џџ3yю­ЏMontrealQuebecVA2RKA BVA2RKA GpЕ—@KLѓ$џџ3yюЎАџџџџџџџџџџџџџџџџMontrealQuebecVA2RKA CVA2RKA GА&ЃР' ѓ$џџ3yюЏБMontrealQuebecVE2RIO AVE2RIO GРyLЗѓ$џџ3yюАВMontrealQuebecVE2RIO BVE2RIO GˆOб@KLѓ$џџ3yюБГџџџџџџџџџџџџџџџџMontrealQuebecVE2RIO CVE2RIO G№ТЃР' ѓ$џџ3yюВДMt.SaintGrщgoireQuebecVE2RVR BVE2RVR G@єy@KLѓ$џџ3yюГЕQuebec CityQuebecVE2RQT BVE2RQT GˆOб@KLѓ$џџ3yюДЖџџџџџџџџџџџџџџџџQuebec CityQuebecVE2RQT CVE2RQT G№ТЃР' ѓ$џџ3yюЕЗRigaud MountainQuebecVE2RM BVE2RM G3\@KLѓ$џџ3yюЖИRimouskiQuebecVE2RKI CVE2RKI G№ТЃР' ѓ$џџ3yюЗЙџџџџџџџџџџџџџџџџSaint-CalixteQuebecVA2RKB CVA2RKB GpNЌР' ѓ$џџ3yюИКSherbrookeQuebecVE2RQF AVE2RQF G A}K-1ѓ$џџ3yюЙЛSherbrookeQuebecVE2RQF CVE2RQF G ѕУР' ѓ$џџ3yюКМџџџџџџџџџџџџџџџџSorel-TracyQuebecVE2CST AVE2CST G@(јI-1ѓ$џџ3yюЛНSorel-TracyQuebecVE2CST CVE2CST G(аТР' ѓ$џџ3yюМОSorel-TracyQuebecVE2FCT BVE2FCT G<™@KLѓ$џџ3yюНПџџџџџџџџџџџџџџџџSorel-TracyQuebecVE2FCT CVE2FCT GPНР' ѓ$џџ3yюОРTrois-RiviшresQuebecVA2LX AVA2LX G TЈL-1ѓ$џџ3yюПСTrois-RiviшresQuebecVA2LX BVA2LX GИ<О@KLѓ$џџ3yюРТџџџџџџџџџџџџџџџџTrois-RiviшresQuebecVA2LX CVA2LX GdЋР' ѓ$џџ3yюСУVictoriarilleQuebecVA2RVO BVA2RVO G№ћl@KLѓ$џџ3yюТФAlmonteOntarioVA3AAR AVA3AAR G@‚ZLЗѓ$џџ3zюУХџџџџџџџџџџџџџџџџAlmonteOntarioVA3AAR BVA3AAR G mx@KLѓ$џџ3zюФЦAlmonteOntarioVA3AAR CVA3AAR GАъЌР' ѓ$џџ3zюХЧArnpriorOntarioVA3JJA AVA3JJA G€ЭІLЗѓ$џџ3zюЦШџџџџџџџџџџџџџџџџArnpriorOntarioVA3JJA BVA3JJA G€њ’ѓ$џџ3zюЧЩArnpriorOntarioVA3JJA CVA3JJA G0#Ўѓ$џџ3zюШЪBlenheimOntarioVA3IBA CVA3IBA G0”Аѓ$џџ3zюЩЫџџџџџџџџџџџџџџџџCalgaryOntarioVA3URU BVA3URU GлН@KLѓ$џџ3zюЪЬCobourgOntarioVE3RTR CVE3RTR G˜pСР' ѓ$џџ3zюЫЭCornwallOntarioVA3SDG BVA3SDG GаФ}@KLѓ$џџ3zюЬЮџџџџџџџџџџџџџџџџCornwallOntarioVA3SDG CVA3SDG Gа8­Р' ѓ$џџ3zюЭЯCumberlandOntarioVA3ODH AVA3ODH G€ФiLЗѓ$џџ3zюЮаCumberlandOntarioVA3ODH BVA3ODH GPпƒ@KLѓ$џџ3zюЯбџџџџџџџџџџџџџџџџCumberlandOntarioVA3ODH CVA3ODH Gе­ѓ$џџ3zюавFonthillOntarioVE3PLF AVE3PLF G eqLЗѓ$џџ3zюбгFonthillOntarioVE3PLF BVE3PLF Gї@KLѓ$џџ3zювдџџџџџџџџџџџџџџџџHamiltonOntarioVA3FS AVA3FS G€ЭІLЗѓ$џџ3zюгеHamiltonOntarioVA3FS BVA3FS GшП’ѓ$џџ3zюджHamiltonOntarioVA3FS CVA3FS GpNЌР' ѓ$џџ3zюезџџџџџџџџџџџџџџџџHamiltonOntarioVE3WIK BVE3WIK Gќ^q@KLѓ$џџ3zюжиHamiltonOntarioVE3WIK CVE3WIK GPЉР' ѓ$џџ3zюзйKanata-KatimavikOntarioVA3AIT AVA3AIT GрЇ€LЗѓ$џџ3zюикџџџџџџџџџџџџџџџџKanata-KatimavikOntarioVA3AIT BVA3AIT Gрф“ѓ$џџ3zюйлKanata-KatimavikOntarioVA3AIT CVA3AIT GpNЌР' ѓ$џџ3zюкмLanarkOntarioVE3ENH AVE3ENH G eqLЗѓ$џџ3zюлнџџџџџџџџџџџџџџџџLanarkOntarioVE3ENH BVE3ENH G€bX@KLѓ$џџ3zюмоLanarkOntarioVE3ENH CVE3ENH GD•ѓ$џџ3zюнпLeamingtonOntarioVE3LNK CVE3LNK G Џѓ$џџ3zюорџџџџџџџџџџџџџџџџLittle CurrentOntarioVE3RXR BVE3RXR Gа%Y@KLѓ$џџ3zюпсLittle CurrentOntarioVE3RXR CVE3RXR G0AЉР' ѓ$џџ3zюртLondonOntarioVE3TTT BVE3TTT G`і\@KLѓ$џџ3zюсуџџџџџџџџџџџџџџџџMapleOntarioVA3ITL BVA3ITL G” [@KLѓ$џџ3zютфMapleOntarioVE3LEO AVE3LEO G eqLЗѓ$џџ3zюухMapleOntarioVE3LEO BVE3LEO G€k•ѓ$џџ3zюфцџџџџџџџџџџџџџџџџMapleOntarioVE3LEO CVE3LEO Gрз™ѓ$џџ3zюхчMilvertonOntarioVE3NMN AVE3NMN GPЂpLЗѓ$џџ3zюцшMilvertonOntarioVE3NMN BVE3NMN G рѓ$џџ3zючщџџџџџџџџџџџџџџџџMilvertonOntarioVE3NMN CVE3NMN Gи_Щѓ$џџ3zюшъMississaugaOntarioVA3PMO BVA3PMO GЗz@KLѓ$џџ3zющыMississaugaOntarioVE3RSD BVE3RSD G” t@KLѓ$џџ3zюъьџџџџџџџџџџџџџџџџMississaugaOntarioVE3RSD CVE3RSD G HЫѓ$џџ3zюыэMt.St. PatrickOntarioVE3STP AVE3STP GPЂpLЗѓ$џџ3zюьюMt.St. PatrickOntarioVE3STP BVE3STP G” t@KLѓ$џџ3zюэяџџџџџџџџџџџџџџџџMt.St. PatrickOntarioVE3STP CVE3STP G HЫѓ$џџ3zюю№NewmarketOntarioVE3YRK BVE3YRK GєИ~@KLѓ$џџ3zюяёNewmarketOntarioVE3YRK CVE3YRK GрЩХР' ѓ$џџ3zю№ђџџџџџџџџџџџџџџџџNiagaraOnTheLakeOntarioVA3NAG CVA3NAG G eqLЗѓ$џџ3zюёѓNiagaraOnTheLakeOntarioVA3YYZ BVA3YYZ Gд­^@KLѓ$џџ3zюђєNiagaraOnTheLakeOntarioVA3YYZ CVA3YYZ GаtЃР' ѓ$џџ3zюѓѕџџџџџџџџџџџџџџџџNorfolkOntarioVE3HJ BVE3HJ GpK@KLѓ$џџ3zюєіOakvilleOntarioVE3OBP BVE3OBP GZ†ѓ$џџ3zюѕїOttawaOntarioVA3ODG AVA3ODG G€ФiLЗѓ$џџ3zюіјџџџџџџџџџџџџџџџџOttawaOntarioVA3ODG BVA3ODG GPпƒ@KLѓ$џџ3zюїљOttawaOntarioVA3ODG CVA3ODG GœЌР' ѓ$џџ3zюјњPerthOntarioVA3RDD BVA3RDD Gƒ@KLѓ$џџ3zюљћџџџџџџџџџџџџџџџџPerthOntarioVA3RDD CVA3RDD G@ДЦР' ѓ$џџ3zюњќPeterBoroughOntarioVE3SSF CVE3SSF G‰ШР' ѓ$џџ3zюћ§Sault Ste. MarieOntarioVA3SNR CVA3SNR GКЇР' ѓ$џџ3zюќўџџџџџџџџџџџџџџџџScarboroughOntarioVE3VXZ AVE3VXZ G eqLЗѓ$џџ3zю§џScarboroughOntarioVE3VXZ BVE3VXZ G Чiѓ$џџ3zюўScarboroughOntarioVE3VXZ CVE3VXZ G HЫѓ$џџ3zюџџџџџџџџџџџџџџџџџSimcoe CountyOntarioVE3LSR BVE3LSR G0>|@KLѓ$џџ3zюSimcoe CountyOntarioVE3LSR CVE3LSR GplЇР' ѓ$џџ3zюSt CathgarinesOntarioVE3NUU BVE3NUU GVancouverBritish ColumbiaVA7ICM CVA7ICM G€"ЅР' ѓџџ3~ю=?VictoriaBritish ColumbiaVA7DSR CVA7DSR GіљL-1ѓџџ3~ю>@џџџџџџџџџџџџџџџџVictoriaBritish ColumbiaVE7VIC AVE7VIC GрЙњL-1ѓџџ3~ю?AVictoriaBritish ColumbiaVE7VIC BVE7VIC G€bX@KLѓџџ3~ю@BVictoriaBritish ColumbiaVE7VIC CVE7VIC GРОЅР' ѓџџ3~юACџџџџџџџџџџџџџџџџWhistlerBritish ColumbiaVA7WHI CVA7WHI Gр#ЗР' ѓџџ3~юBDSt JohnsNewfoundlandVO1TZ BVO1TZ G@Пm@KLѓ.џџ3юCESt JohnsNewfoundlandVO1TZ CVO1TZ GахЅР' ѓ.џџ3юDFџџџџџџџџџџџџџџџџCharlottetownPrince Edward I.VE1UHF BVE1UHF G 8l@KLѓ(џџ3юEGCharlottetownPrince Edward I.VE1UHF CVE1UHF GxБОР' ѓ(џџ3юFHKensingtonPrince Edward I.VY2DSR AVY2DSR GРЕSJ-1ѓ(џџ3юGIџџџџџџџџџџџџџџџџKensingtonPrince Edward I.VY2DSR BVY2DSR G˜аТ@KLѓ(џџ3юHJKensingtonPrince Edward I.VY2DSR CVY2DSR GиюЦР' ѓ(џџ3юIKWhitehorseYukon TerritoryVY1RDS AVY1RDS GРЕSJ-1ѓџџ3юJLџџџџџџџџџџџџџџџџWhitehorseYukon TerritoryVY1RDS BVY1RDS GX…v@KLѓџџ3юKMWhitehorseYukon TerritoryVY1RDS CVY1RDS GР™РР' ѓџџ3юLNChihuahuaChihuahuaXE2ITZ CXE2ITZ GˆпЈР'  ћџџ4€юMOџџџџџџџџџџџџџџџџCancunQuintana RooXE3RCC CXE3RCC G ЉР' ѓ$џџ4€юNPMixcoGuatemalaTG0AA CTG0AA GАуТР' ѓ џџ5юOQSan SalvadorSan SalvadorYS1YS CYS1YS G0Qа@Bѓ џџ6‚юPRџџџџџџџџџџџџџџџџBuenos AiresBuenos AiresLU3AOC ALU3AOC G€ФiLЗѓ,џџ<ŒюQSBuenos AiresBuenos AiresLU3AOC BLU3AOC GpЯь@KLѓ,џџ<ŒюRTBuenos AiresBuenos AiresLU3AOC CLU3AOC GhNШР' ѓ,џџ<ŒюSUџџџџџџџџџџџџџџџџCѓrdobaCѓrdobaLU4HH BLU4HH G ь@KLѓ,џџ<ŒюTVRosario DeptSanta FeLU5FB CLU5FB G№УР' ѓ,џџ<ŒюUWRio de JaneiroRio de JaneiroPY1EGR APY1EGR G o_M?Ћѓ,џџ=юVXџџџџџџџџџџџџџџџџRio de JaneiroRio de JaneiroPY1EGR BPY1EGR G`W8@KLѓ,џџ=юWYRio de JaneiroRio de JaneiroPY1EGR CPY1EGR G0:ПР' ѓ,џџ=юXZNiteroiRio de JaneiroPY1GVK APY1GVK G o_M?Ћѓ,џџ=юY[џџџџџџџџџџџџџџџџNiteroiRio de JaneiroPY1GVK BPY1GVK GЙ8@KLѓ,џџ=юZ\NiteroiRio de JaneiroPY1GVK CPY1GVK G0:ПР' ѓ,џџ=ю[]NiteroiRio de JaneiroPY1GVN APY1GVN G o_M?Ћѓ,џџ=ю\^џџџџџџџџџџџџџџџџNiteroiRio de JaneiroPY1GVN BPY1GVN GЙ8@KLѓ,џџ=ю]_NiteroiRio de JaneiroPY1GVN CPY1GVN G№ЋР' ѓ,џџ=ю^`Rio de JaneiroRio de JaneiroPY1MRD BPY1MRD GИѕ7@KLѓ,џџ=ю_aџџџџџџџџџџџџџџџџRio de JaneiroRio de JaneiroPY1MRE CPY1MRE GАОР' ѓ,џџ=ю`bNova FriburgoRio de JaneiroPY1NDN CPY1NDN Gp)ЧР' ѓ,џџ=юacRio de JaneiroRio de JaneiroPY1RSU BPY1RSU GА9@KLѓ,џџ=юbdџџџџџџџџџџџџџџџџItapeviSуo PauloPY2KBH APY2KBH GhWaM?Ћѓ,џџ=юceItapeviSуo PauloPY2KBH BPY2KBH G”7@KLѓ,џџ=юdfItapeviSуo PauloPY2KBH CPY2KBH G№ЋР' ѓ,џџ=юegџџџџџџџџџџџџџџџџArtur NogueiraSуo PauloPY2KCA CPY2KCA GАЈР' ѓ,џџ=юfhSуo PauloSуo PauloPY2KEP CPY2KEP GаOОР' ѓ,џџ=юgiSуo PauloSуo PauloPY2KPE BPY2KPE GЙ8@KLѓ,џџ=юhjџџџџџџџџџџџџџџџџSуo PauloSуo PauloPY2KPP APY2KPP G@ьrL-1ѓ,џџ=юikSуo PauloSуo PauloPY2KPP BPY2KPP GX|9@KLѓ,џџ=юjlSуo PauloSуo PauloPY2KPP CPY2KPP GаЧЊР' ѓ,џџ=юkmџџџџџџџџџџџџџџџџSуo PauloSуo PauloPY2KRJ APY2KRJ G@ѕЏL-1ѓ,џџ=юlnSуo PauloSуo PauloPY2KRJ CPY2KRJ GрЩХР' ѓ,џџ=юmoBrasiliaDistrito FederalPT2DIG BPT2DIG G”7@KLѓ,џџ=юnpџџџџџџџџџџџџџџџџBrasiliaDistrito FederalPT2MTD CPT2MTD GPНР' ѓ,џџ=юoqBelo HorizonteMinas GeraisPY4RCR APY4RCR G TЈL-1ѓ,џџ=юprBelo HorizonteMinas GeraisPY4RCR BPY4RCR G`",@KLѓ,џџ=юqsџџџџџџџџџџџџџџџџBelo HorizonteMinas GeraisPY4RCR CPY4RCR GР УР' ѓ,џџ=юrtN.Sra do SocorroSergipePP6DV APP6DV G o_M?Ћѓ,џџ=юsuN.Sra do SocorroSergipePP6DV BPP6DV Gр<2@KLѓ,џџ=юtvџџџџџџџџџџџџџџџџN.Sra do SocorroSergipePP6DV CPP6DV GPНР' ѓ,џџ=юuwWillemstadCuraчaoPJ2A BPJ2A GрЩм@KLѓ(џџ>ŽюvxWillemstadCuraчaoPJ2A CPJ2A G€§ПР' ѓ(џџ>ŽюwyџџџџџџџџџџџџџџџџCanberraACTVK1RWN CVK1RWN GdфНР' ѓ`џџFюxzSomersbyNew South WalesVK2RAG BVK2RAG GO РeRѓ`џџFюy{SomersbyNew South WalesVK2RAG CVK2RAG GO РeRѓ`џџFюz|џџџџџџџџџџџџџџџџSydneyNew South WalesVK2RBV BVK2RBV Gи,'@KLѓ`џџFю{}WyeeNew South WalesVK2RHK BVK2RHK GШAРeRѓ`џџFю|~Maddens PlainsNew South WalesVK2RMP CVK2RMP GkПР' ѓ`џџFю}џџџџџџџџџџџџџџџџFairfieldNew South WalesVK2ROZ BVK2ROZ GєРeRѓ`џџFю~€Terrey Hills SDNNew South WalesVK2RWN AVK2RWN G ыK-1ѓ`џџFюTerrey Hills SDNNew South WalesVK2RWN BVK2RWN Gt!РeRѓ`џџFю€‚џџџџџџџџџџџџџџџџTerrey Hills SDNNew South WalesVK2RWN CVK2RWN GDxТР' ѓ`џџFюƒBendigoVictoriaVK3RCE BVK3RCE GєE)ѓ`џџFю‚„HorshamVictoriaVK3RDK CVK3RDK GМ‚НР' ѓ`џџFюƒ…џџџџџџџџџџџџџџџџSheppartonVictoriaVK3RGV BVK3RGV GРfРeRѓ`џџFю„†Berwick MELVictoriaVK3RMC BVK3RMC GШAРeRѓ`џџFю…‡Berwick MELVictoriaVK3RMC CVK3RMC GkПР' ѓ`џџFю†ˆџџџџџџџџџџџџџџџџMt Macedon MELVictoriaVK3RMM BVK3RMM GаРeRѓ`џџFю‡‰SunburyVictoriaVK3RPJ BVK3RPJ GєE)ѓ`џџFюˆŠSunburyVictoriaVK3RPJ CVK3RPJ Gр Іѓ`џџFю‰‹џџџџџџџџџџџџџџџџOlinda/MelbourneVictoriaVK3RWN AVK3RWN Gр+юK-1ѓ`џџFюŠŒOlinda/MelbourneVictoriaVK3RWN BVK3RWN G`эРeRѓ`џџFю‹Olinda/MelbourneVictoriaVK3RWN CVK3RWN GєДСР' ѓ`џџFюŒŽџџџџџџџџџџџџџџџџKynetonVictoriaVK3RWW AVK3RWW GhэK-1ѓ`џџFюKynetonVictoriaVK3RWW BVK3RWW GpЃРeRѓ`џџFюސBlackwaterQueenslandVK4RBD CVK4RBD GМ‚НР' ѓ`џџFю‘џџџџџџџџџџџџџџџџIpswichQueenslandVK4RBX CVK4RBX GЌЬПР' ѓ`џџFю’MackayQueenslandVK4RBY BVK4RBY G@$@KLѓ`џџFю‘“MackayQueenslandVK4RBY CVK4RBY GГНР' ѓ`џџFю’”џџџџџџџџџџџџџџџџManoora CairnsQueenslandVK4RCN BVK4RCN GO РeRѓ`џџFю“•Mt TamborineQueenslandVK4RDK BVK4RDK G4 РeRѓ`џџFю”–WoombyeQueenslandVK4RDS BVK4RDS G@$@KLѓ`џџFю•—џџџџџџџџџџџџџџџџWoombyeQueenslandVK4RDS CVK4RDS G\ ПР' ѓ`џџFю–˜WongawallanQueenslandVK4RDW BVK4RDW GАА РeRѓ`џџFю—™ToowoombaQueenslandVK4RTQ BVK4RTQ G 2@KLѓ`џџFю˜šџџџџџџџџџџџџџџџџSarinaQueenslandVK4RUS BVK4RUS GP7"@KLѓ`џџFю™›Laidley HeightsQueenslandVK4TUX CVK4TUX G`ђŸѓ`џџFюšœPort LinconSouth AustraliaVK5REX BVK5REX GhШРeRѓ^џџFю›џџџџџџџџџџџџџџџџRenmark WestSouth AustraliaVK5RMK BVK5RMK Gx~РeRѓ^џџFюœžAdelaideSouth AustraliaVK5RWN AVK5RWN G ыK-1ѓ^џџFюŸAdelaideSouth AustraliaVK5RWN BVK5RWN Gt!РeRѓ^џџFюž џџџџџџџџџџџџџџџџAdelaideSouth AustraliaVK5RWN CVK5RWN G<УР' ѓ^џџFюŸЁFremantle/PerthWesternAustraliaVK6RLX BVK6RLX GpЃРeRѓXџџFю ЂFremantle/PerthWesternAustraliaVK6RLX CVK6RLX GЄёРjѓXџџFюЁЃџџџџџџџџџџџџџџџџRoleystone/PerthWesternAustraliaVK6RWN AVK6RWN Gр+юK-1ѓXџџFюЂЄRoleystone/PerthWesternAustraliaVK6RWN BVK6RWN GРeRѓXџџFюЃЅRoleystone/PerthWesternAustraliaVK6RWN CVK6RWN GќРР' ѓXџџFюЄІџџџџџџџџџџџџџџџџHobartTasmaniaVK7RCR CVK7RCR GDxТjѓ`џџFюЅЇRichmondTasmaniaVK7RRR BVK7RRR GШAРeRѓ`џџFюІЈRichmondTasmaniaVK7RRR CVK7RRR GєДСР' ѓ`џџFюЇЉџџџџџџџџџџџџџџџџDarwinNorthern Terr.VK8RAD AVK8RAD GРЗM-1ѓ^џџFюЈЊDarwinNorthern Terr.VK8RAD BVK8RAD G0Ы&@KLѓ^џџFюЉЋDarwinNorthern Terr.VK8RAD CVK8RAD GрvОР' ѓ^џџFюЊЌџџџџџџџџџџџџџџџџBucklands BeachAuklandZL1ZLD AZL1ZLD GЈ&M-1ѓhџџG‘юЋ­Bucklands BeachAuklandZL1ZLD BZL1ZLD Gиa3@KLѓhџџG‘юЌЎPort WaikatoAuklandZL1VHD BZL1VHD G@KLѓhџџG‘ю­ЏџџџџџџџџџџџџџџџџPort WaikatoAuklandZL1VHD CZL1VHD GPqЎР' ѓhџџG‘юЎАPapamoa HillsBay of PlentyZL1TPD BZL1TPD GшoЯ@KLѓhџџG‘юЏБPapamoa HillsBay of PlentyZL1TPD CZL1TPD G€§ПР' ѓhџџG‘юАВџџџџџџџџџџџџџџџџTe RangaBay of PlentyZL1IBD CZL1IBD GH–ЏР' ѓhџџG‘юБГMt ThreaveHawke's BayZL2HBD BZL2HBD Gап@KLѓhџџG‘юВДHamiltonWaikatoZL1CCT CZL1CCT GpнЉР' ѓhџџG‘юГЕџџџџџџџџџџџџџџџџKapiti CoastWellingtonZL2KB BZL2KB GpнЉР' ѓhџџG‘юДЖUpper HuttWellingtonZL2VH BZL2VH G@$@KLѓhџџG‘юЕЗUpper HuttWellingtonZL2VH CZL2VH GhЋР' ѓhџџG‘юЖИџџџџџџџџџџџџџџџџDededoGuamAH2G BAH2G G ‘Л@KLѓhџџH’юЗЙDededoGuamAH2G CAH2G G$РР' ѓhџџH’юИџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџЙџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAsiaAfricaEuropeNorth AmericaSouth AmericaOceaniaџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJapanThailandNamibiaSouth AfricaAustriaBelgiumBulgariaCroatiaCzech RepublicDenmarkFranceGermanyGreeceItalyLuxembourgNetherlandsNorwayPolandPortugalSan MarinoSloveniaSpainSwedenSwitzerlandUnited KingdomUSACanadaMexicoGuatemalaEl SalvadorArgentinaBrazilCuracaoAustraliaNew ZealandGuamџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJA1 : KantoJA2 : TokaiJA3 : KansaiJA4 : ChugokuJA5 : ShikokuJA6 : KyushuJA7 : TohokuJA8 : HokkaidoJA9 : HokurikuJA0 : ShinetsuThailandNamibiaSouth AfricaAustriaBelgiumBulgariaCroatiaCzech RepublicDenmarkFranceGermanyGreeceItalyLuxembourgNetherlandsNorwayPolandPortugalSan MarinoSloveniaSpainSwedenSwitzerlandNorth EnglandMidlandsSouth-EastWales & MarchesScotlandW1W2W3W4W5W6W7W8W9W0WLWHVE1/VA1VE2/VA2VE3/VA3VE4/VA4VE5/VA5VE6/VA6VE7/VA7VO / VYMexicoGuatemalaEl SalvadorArgentinaBrazilCuracaoAustraliaNew ZealandGuamџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNexus 7:EF:4B:29)KяцPиџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)KяцPи\'.АœЛї1~ќёп3жТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџу,(#єџMШ9,dб05dT…м“VГСŽ Ё(#БџЌ#ю­žІх&9O;А%ЈџcЏЏъ4(#тџ4.4oњЋ+e‰Ћнpњ Џ'ЯаM Ё(#3ўdtд№'И>>bЊџЭ<ЏЏю”(#•џЉІ”|P.ўѕ‘œВ,cЉ@и Ё(#ёџ3xУ-ааš'›wV{ЏЉџљЏЏ х(#Ьџэc7ч€2)ДN‰эдY5Wњ Ё(##МŽк…џWXq'R&6В—5fЅџ”ЏЏ юЎ(#іџЦ ?Ў,Ї1ищй60Už і Ё(#\*/ Ÿь@'$bAyІЇџ5ЏЏNі&6§  ЁЮQё;ЅHФџЏЏN}K…Q§Z ЁМœYЕWŸ‘LаЏЏNALY§v ЁЕ-ь„{&ЁЄS§ЏЏЏB‡тІ.YЇ@Ќ~рЈЖ! ,*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJyY2xhc3MiOiAiVEhENzRSYWRpbyIsICJ2ZW5kb3IiOiAiS2Vud29vZCIsICJtb2RlbCI6ICJUSC1ENzQgKGNsb25lIG1vZGUpIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Icom_IC-U82.img0000644000175000017500000001450014411666130016761 0ustar hibbyhibby@ш P@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџа"„ P @џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ш P@џџџџџ zzJzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџа5€ ЊD  @€r ЊD  @ Jџџџџџџџџџџџџџџџџ џџџџ џџџџ џџџџ џџџџ џџџџ џџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ џџџџџџџџ Шџ 28260001chirp-20240224/tests/images/Leixen_VV-898.img0000644000175000017500000002000014411666130017320 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЁџџџџџєЂџџџџџєџџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№ЊџџџџџєŠ‰Ÿџџџџѕџџџџџџџ№џџџџџџџ№ŠџџџџџѓŠџџџџџѓџџџџџџџџ™™џџ &џџџџџџџџџџџџџџџџџ`@DC &џLeixenџLX-‰…cџџџџџџџџџЧ"џьfђ‡I" џ йБcАё <у<џџџ0F}aа 1ro IOo•аlMiB Р`џџ њњ222PџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPO №№APRO ТjBC Lock ТBeep  CHASave 3DTMF Т @@@DW @@@DecType C  DecCode SEncType c EncCode s @@@FM ƒ@@@FM SCAN FM SQL №FM DW Font .RKeyLock   Keypad .Lamp NameSYS   NameCHA в NamEdit #@@@OpenDIS Р6Р@P1 Long "№!№P1Short "TP2 Long !№!№P2Short !TP3 Long #№!№P3Short #TPower Т€€€PTT ID Т €€€Roger ЦReverse Ѓ  RPT SET RPTType SaveBat SCAN “  SCNMode †  SCANADD Т SQL  Step цPd№Tail Т Talk Г  TOT † >TxStop @@@Vox ‚ Vox D 0:№Vox S VXB ЦWIDNAR Т@@@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ OFF ON OFF 10M 20M 30M 40M 50M 1H1.5H 2H 4H 6H 8H 10H 12H 14H 16HCompScra OFF KeyCont LowHighNarrWide K+S PTT KEY ALL CO TO OFF FMMONIMOLO SQMMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 5K6K25 10K12K5 25K ALLTimeUser SYS 1S 2S 3S 4S OFF 10S 20S 30S 40S 50S 60S 70S 80S 90S100S110S120SSING-RPT+RPT OFF CTCNDCSIDCSSMAL BIG OFF FMBANDTIMEMOLOMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 2K5 5K6K25 10K12K5 25K OFFCompScraTXScRXScџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџVV-898 џџџџџџџџ LEIXEN Welcome Waiting Debug Day CHA- Menu ( ) Vol Call Reset ? ALL RES FUN RES DEL B Send Error TX Stop KeyLock SEND џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџG‡PG‡Pџџџў№ќ$Q$Qџџџў№ќ@P@Pџџџў№ќ@@џџџў№ќCQCQџџџў№ќF™F™џџџў№ќ@@џўpќF™F™џўpќaaџџџў№ќQQџџџў№ќ@@џџџў№ќaaџџџўpќ@@џџџўpќCQCQџџџ~pќ@@џџџў0ќ@@џў0ќ@@џў0ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Name001 Name002 Name003 Name004 Name005 Name006 Name007 Name008 Name009 Name010 A Name012 Name013 Name014 chirp-20240224/tests/images/Retevis_RB618.img0000644000175000017500000000340514411666130017410 0ustar hibbyhibby%`D%`DHHџџџu`Du`DHHџџџ%1`D%1`DHHџџџuC`DuC`DHHџџџ%V`D%V`DHHџџџuh`Duh`DHHџџџ%`D%`DHHџџџu“`Du“`DHHџџџ%aD%aD&€&€џџџuaDuaD&€&€џџџ%1aD%1aD&€&€џџџuCaDuCaD&€&€џџџ%VaD%VaD&€&€џџџuhaDuhaD&€&€џџџ%aD%aD&€&€џџџu“aDu“aD&€&€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџї3103PџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjYxOCIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjExMTE4IiwgInJjbGFzcyI6ICJSQjYxOFJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Baofeng_BF-1904.img0000644000175000017500000000223514451231774017456 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ@@џџџџ џџџ0D0D`` џџџPPDPPD…… џџџ%eD%eD…… џџџ%wD%wD…… џџџ%…D%…D…… џџџ%—D%—D%€%€ џџџ%(D%(D44 џџџ%CD%CDt‚t‚ џџџ%’C%’Css џџџPbUEPbUE џџџPruEPruEgg џџџP‚…EP‚…E(( џџџP‡3@P‡3@џџџџ џџџ%D%Dџџџџ џџџP™GP™Gџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџ<<<<<<<<<<<<<<<<<;;;;;;;:UUџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџUUџџџџџџџUUUU (++џџџ@>52TR><'&SQ  -џџDFHJLNPRTџџџџџ}џџџџџџџUUUUUUUUUџџџџџџџџџџџџї7013PџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJCRjE5MDRSYWRpbyIsICJ2ZW5kb3IiOiAiQmFvZmVuZyIsICJtb2RlbCI6ICJCRi0xOTA0IiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDIzMDYxNyJ9chirp-20240224/tests/images/Baofeng_UV-9G.img0000644000175000017500000002025514411666130017377 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%FžžDP‡%FP‡%FžžDP&FP&FžžDP7&FP7&FžžDPb&FPb&FžžDP‡&FP‡&FžžDP'FP'FžžDPbuFPbuFP‡uFP‡uFPvFPvF P7vFP7vF PbvFPbvF P‡vFP‡vF PwFPwF P%FP%FžžDu%Fu%FžžD&F&FžžD%&F%&FžžDP&FP&FžžDu&Fu&FžžD'F'FžžD%'F%'FžžDP%FPuFUUDu%FuuFUU&FvFUU%&F%vFUUP&FPvFUUu&FuvFUU'FwFUU%'F%wFUUP%FPuFDu%FuuFD&FvFD%&F%vFDP&FPvFDu&FuvFD'FwFD%'F%wFDP%FPuFDu%FuuFD&FvFD%&F%vFDP&FPvFDu&FuvFD'FwFD%'F%wFDP%FPuFDu%FuuFD&FvFD%&F%vFDP&FPvFDu&FuvFD'FwFD%'F%wFDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDP%џџџџD$џџџџDu$џџџџD%$џџџџDP$џџџџD%џџџџD%%џџџџDPџџџџDuџџџџDPџџџџD џџџџDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ÿ€.L.џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ……џџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRSџџџџџџџџџџџџGMRS1џџџџџџџџџџџGMRS2џџџџџџџџџџџGMRS3џџџџџџџџџџџGMRS4џџџџџџџџџџџGMRS5џџџџџџџџџџџGMRS6џџџџџџџџџџџGMRS7џџџџџџџџџџџGMRS8џџџџџџџџџџџGMRS9џџџџџџџџџџџGMRS10џџџџџџџџџџGMRS11џџџџџџџџџџGMRS12џџџџџџџџџџGMRS13џџџџџџџџџџGMRS14џџџџџџџџџџGMRS15џџџџџџџџџџGMRS16џџџџџџџџџџGMRS17џџџџџџџџџџGMRS18џџџџџџџџџџGMRS19џџџџџџџџџџGMRS20џџџџџџџџџџGMRS21џџџџџџџџџџGMRS22џџџџџџџџџџREPTR1џџџџџџџџџџREPTR2џџџџџџџџџџREPTR3џџџџџџџџџџREPTR4џџџџџџџџџџREPTR5џџџџџџџџџџREPTR6џџџџџџџџџџREPTR7џџџџџџџџџџREPTR8џџџџџџџџџџDIY1џџџџџџџџџџџџDIY2џџџџџџџџџџџџDIY3џџџџџџџџџџџџDIY4џџџџџџџџџџџџDIY5џџџџџџџџџџџџDIY6џџџџџџџџџџџџDIY7џџџџџџџџџџџџDIY8џџџџџџџџџџџџDIY9џџџџџџџџџџџџDIY10џџџџџџџџџџџDIY11џџџџџџџџџџџDIY12џџџџџџџџџџџDIY13џџџџџџџџџџџDIY14џџџџџџџџџџџDIY15џџџџџџџџџџџDIY16џџџџџџџџџџџDIY17џџџџџџџџџџџDIY18џџџџџџџџџџџDIY19џџџџџџџџџџџDIY20џџџџџџџџџџџDIY21џџџџџџџџџџџDIY22џџџџџџџџџџџDIY23џџџџџџџџџџџDIY24џџџџџџџџџџџDIY25џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOAA0џџџDNOAA1џџџDNOAA2џџџDNOAA3џџџDNOAA4џџџDNOAA5џџџDNOAA6џџџDNOAA7џџџDNOAA8џџџDNOAA9џџџDNOAA10џџDNOAA11џџDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ???????????џџџџџAOFENG UV-9G 180122NџџџџџџџџџBAOFENG UV-9G ???????џџџџџџџџџќќќќќќћћњњњћћћќќќњјііјњќњњњњњџџџхххфууууутссссссхусппрсутттттџџџЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯЯџџџџџџџџ?џџџџџџџ?1 <џџpsv}‡ 1 џ€6t џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ123456BF9166ЊDFpнџchirpюimgeyJ2ZW5kb3IiOiAiQmFvZmVuZyIsICJtb2RlbCI6ICJVVi05RyIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Baofeng_UV-5R.img0000644000175000017500000001451014411666130017403 0ustar hibbyhibbyЊBFB231н``D`џDџ``џ``џ``Dџ``DџџџџџџџџџџџџџџџџџDP“DUDџD€yUUDџD%F33Dџ%"F%"F;; Dџ%3F%3FPP Dџ%DF%DFxx Dџ%UF%UFЫЫ Dџ%"@%"@ Dџ%tC%tCDџu™Gu™GDџP…P…DџPvPvDџP'P'Dџ…C…CDџWWDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0D€DD€s€yшD@t@tuDPDPeDuD%)D%yD0DP3DPƒDD%(D%xDDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ s yDicљљDttDPDPSDљљD0S0GFD0R0FD q wD`f``ЄD€h€b|D r xшD`q`wЄDuDuQDшDPDPbDЄD@h@buD@r@xD€i€cЮDPRPFDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$$D%$%$DP$P$Du$u$D%%D%%%%DP%P%DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPWPWD77DRDRDD7‡7‡Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ф8vЕА&9У%€5 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ€pџџџџџџџџџџџџџџџџџ2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџP FM 65-75Mџџ FM 76-108MџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџOCVHFџџџџџџџџџџџOCUHFџџџџџџџџџџџWUVHFџџџџџџџџџџџWUUHFџџџџџџџџџџџOCPORџџџџџџџџџџџITELMџџџџџџџџџџџOLONYџџџџџџџџџџџ09џџџџџџџџџџџџџџ10џџџџџџџџџџџџџџ11џџџџџџџџџџџџџџ12џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHTAC1џџџџџџџџџџџHTAC2џџџџџџџџџџџHTAC3џџџџџџџџџџџHTAC4џџџџџџџџџџџHTAC5џџџџџџџџџџџHTAC6џџџџџџџџџџџHTAC7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџARESD1џџџџџџџџџџWAPRIRџџџџџџџџџџWAPRISџџџџџџџџџџWASECRџџџџџџџџџџOEMNCSџџџџџџџџџџHEARTNџџџџџџџџџџCLACKџџџџџџџџџџџCLATSPџџџџџџџџџџCOLUMBџџџџџџџџџџTMOOK1џџџџџџџџџџTMOOK2џџџџџџџџџџTMOOK3џџџџџџџџџџTMOOK4џџџџџџџџџџMULTNMџџџџџџџџџџCLARKџџџџџџџџџџџARCџџџџџџџџџџџџџVERNIAџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWX1џџџџџџџџџџџџџWX2џџџџџџџџџџџџџWX3џџџџџџџџџџџџџWX4џџџџџџџџџџџџџWX5џџџџџџџџџџџџџWX6џџџџџџџџџџџџџWX7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџVCALLџџџџџџџџџџџVTAC11џџџџџџџџџџVTAC12џџџџџџџџџџVTAC13џџџџџџџџџџџџџџџџџџџџџџџџџџ1203101VER-05 џџAllGoodNow Ver BFB231 кдаЪЫХЪЭбдзизиxЪЪЪШЩЧЫЯаааведдx†‚~}{xxtwvvvw77ponnlmhfgfghiii700а +2Ш,d1?Р2b|3 ђG+ьO@N):VRn-pql< x=  @˜T@00Є#$%&'()*+Dџ€#$%&'()*+Dџ€6sџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Baofeng_UV-13Pro.img0000644000175000017500000011026114566340166020032 0ustar hibbyhibbyч џџџџџџџџџџ%QCџџџџuIџџџџ%C%Cџџџџ%C%Cџџџџџ%!C%!Cџџџџџ%1C%1Cџџџџџ%AC%ACџџџџџ%QC%QCџџџџџ%D%Dџџџџџ%D%Dџџџџџ%!D%!Dџџџџџ%1D%1Dџџџџџ%AD%ADџџџџџ%QD%QDџџџџџuIuIџџџџџ%Q%Qџџџџџ%a%aџџџџџ%q%qџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџuIuIџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&WELCOMEџџџџџџџџџџ@R`@#—џџџџџџџџџџџџџџџџџџџџџџџџPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjEzUHJvIiwgInZlbmRvciI6ICJCYW9mZW5nIiwgIm1vZGVsIjogIlVWLTEzUHJvIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Puxing_PX-888K.img0000644000175000017500000001000014411666130017453 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@%џџџџџџ@%џџџџџџPX888Dџ@`@HџџџџџџџџџџџџџџџџШX€: џ657628џџPX888Dџџ12345 џџPUXINGџџџџuџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@%@%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(џ 4_џџџџџџџџџџџџџџџџџџџџFЎFЎdЎFЎ4_<<AŒШ–зцЭџџџџ41752013PX888518chirp-20240224/tests/images/Retevis_RT47.img0000644000175000017500000000222114411666130017341 0ustar hibbyhibby%'F%'FbФbФљџPb%FPb%Fpp§P‡%P‡%FP‡%Fˆˆ§P&P&FP&Fss§P7&P7&FP7&F§Pb&Pb&FPb&Fee§%&%&F%&Fss§%'%'F%'Fee§P‡&P‡&FP‡&F§P'P'FP'Fbb§P%P%FP%F00§u%u%Fu%FCЧCЧ§&&F&F2У2У§P&P&FP&FCТCТ§u&u&Fu&F††§''F'F1Ч1Ч§%'%'F%'FbФbФ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹џџџџџџџџSMP558јџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDQ3IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjA5MTciLCAicmNsYXNzIjogIlJUNDdSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Baofeng_UV-B5.img0000644000175000017500000001006014411666130017357 0ustar hibbyhibbyKT511 Radio Program data v1.08iAc%!E3я%%2E %2%CEџџџ%TEџ%%eE&&я%%vE00я%%‡E44џ%%˜EJJџџџ%Feeяu%"Fmmџџџ%3F‚‚џџџ%DF0AAџ%%UF0““џџџ%"@џџџ%tCџџџu™FџџџP…P…PvџџџP'P'…C…Wџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ…CHяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяў™џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"џџ џ!џ#џџ!џџџ!џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp ўџџџџџџџџџџџџџџџџџџџџџџџџџџџрџџџџџџџџџџџџџHKT511џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`@@GџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHPX`fnv~†Žџџџџџџ(08@HPX\dlџџџџџџ““‰ƒ€˜‹KB@@;73B”’™ ЂЁЁRLGC@BDDchirp-20240224/tests/images/Yaesu_FTM-350.img0000644000175000017500000020020014411666130017236 0ustar hibbyhibbyAH033$ FR@  D9L ‡ ’џџРU FRЃ "  „F(ŒdP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ D9Œ "  0€ dP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџRџџџџџџџџ ‡ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџqџџ .IV^cjw..  аЪЭЯџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFRŒ џџџџџџџџџџџџџџџџ d!џџџџџџџџџџџџџџџџџџџџџџџџD9L џџџџџџџџџџџџџџџџ ddddџџџџџџџџџџџџџџџџџџџџџџџџK7TAYЪ ЪЪЪЪЪЪЪЪЪЪЪ*******Ъ/>/R/-YYœ ? 7x FxFxЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******ЪCQ*******ЪQST******ЪYAESU****ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪBLN?*****ЪBLN?ЪЪЪЪЪЪBLN?ЪЪЪЪЪЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪ“CHd“@5(d‘G2%  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  “CH d‘G8Œ ‘GDL “AU d“„B’Žd“C5™d“„B‚dFRL D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  ‘G2Œ ‘FŒ ‘G@L “@5(“d‘E3Ѓ ‘E#Ѓ D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  ‘FRЃ ‘FRЃ ‘FR Ѓ ‘FR0Ѓ ‘FR@Ѓ ‘FRPЃ ‘FR`Ѓ ‘FRŒ ‘FR@Œ ‘FR@Œ ‘FR@Œ ‘FR@Œ ‘FR@L ‘FR@  ‘FR@  FR@  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  ‘D9L D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  D  0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 d0 ddddЪddddddddddЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪ Jdd Jdd Jdd Jdd Jdd Jdd JddЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪ d d JJ JJ J1'Jd d($57ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪ$%&'()*+d>?@ABCD dЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪ ddddЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪphone deadЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPT202WH6KO LARCH €WIDE2 Outback MobileЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTUTUPTN7QXO LARCH €ЪЪЪЪЪЪЪ'2B=o*sv/]"4o}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪT5TWWPKD7RUSLARCH €WIDE1 #`2<~l o>/'"5$}MT-RTG|!"%5'S|!wV,!|3ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪEH3TSQK7PAL JUPITR€N7QXO `21_l"5k/>"3h}444.700 103.5 QAЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRS PACCTYSALEM €ЪЪЪЪЪЪЪD@171506z4511.81N/12358.04W_326/012g025t046r000p001P001h81b10255.U21hЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRHH2N7HQR NEWPRT€WIDE2 =4458.50N/12400.49Wv194/000ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPW251AC7KP KOPEAK€WIDE2 2_02100041c071s000g000t044r000p000P000h00b00000wU2KЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NKB7WUKN7QXO ‰ЪЪЪЪЪЪЪ8=/7K3B/OthV BPHG2167 Mult,OR An OATVA Station %195,%002ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTWSQWSWA7BVQWIDE1 €WIDE2 '22%l -/]ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTV5WRSWB7OR KOPEAK€WIDE2 `2T&l"Zu/]"4Q}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPT311K7CPU SSADDL€WIDE1 ?/092354z4532.50N/12257.69Wv027/000/A=000209/TM-733, TT3+, GPS2 ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTU3PTPK7POS LARCH €N7QXO `2Fb!6VK\]"5]}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTW2WXWWX7W SOMTN €WIDE2 `2)}lIij/]"3u}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN383WOLF BRNSVL€WIDE2 5!4337.00NS12213.80W#PHG5830/W2,ORn,KD7CGF OR OAKRIDGEЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN390HEBOWXLARCH €WIDE2 D@004705z4512.89NS12345.29W_333/016g019t031r000p000P000h00b10187.WxDgЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NWB7AYUSOMTN €WIDE2 >160102zUI-View32 V2.03ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪGPSMV WN7M JUPITR€N7QXO #$GPGGA,155328,,,,,0,00,,,M,,M,,*6E ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPW251N7GME JUPITR€N7QXO 2_02081613c008s000g000t035r000p000P000h81b10263wDAVЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪT7RWVVN7RIF SOMTN €N7QXO `2AEq-M>/ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NKD7MQMALAKES€WIDE2 b@090056z4609.52N/11917.50W_038/000g000t048r000p000P000h53b10210South Kennwick ele.1400 ft. {UIV32}ЪAPN382JUNIPRLARCH €WIDE2 ;!4544.24N/12043.50W#PHG5840/W2,WAn,Juniper Point APRS KF7LNЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪT7STRUWA4OSHSOMTN €N7QXO `2apnJ>/'"4u}|!E&9'H|!wwT!|3ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NKM7LJ N7QXO ‰WIDE2 E@092357z4537.88N/12234.88W_180/000g000t044b10242h00r000P000/ {UIV32N}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪBEACONERINB JUPITR€WIDE2 D!4752.35N\12328.18W+ ELKHORN RS here soon...BBB...K7IDX up the ELWHAЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪBEACONLARCH ЪЪЪЪЪЪЪЪЪЪЪЪЪЪ$>224720T100 LARCH MOUNTAIN,WA,KB7APUЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN382KOPEAKN7QXO ‰WIDE2 /!4627.66NS12332.96W#PHG5660/W2,WAn,KOPEAK WA7RWЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPOTU0KC7DX BULLMT€ЪЪЪЪЪЪЪ> ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPW251N7TQZ W7PFR WIDE2 2_02081811c351s000g000t031r000p000P000h97b10260wRSWЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRS KC7RJKTCPIP EUGENEB@081657z4410.03N/12345.12W_215/000g000t042r000P001p001h00b10246v31ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪBEACONN1KEZ LARCH €WIDE2 "!4526.63N/12250.08W#PHG53306/N1KEZЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN382MEGLERLARCH €WIDE2 7!4617.16NS12353.83W#_PHG5768/W2,WAn,Chinook WIDE-KB7ADOЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN390SALEM LARCH €ЪЪЪЪЪЪЪ5!4453.15NS12255.93W#PHG5130/W2,ORn,...Salem.OR..N7IFJЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPOTU0K7HRY GRZZLY€WIDE2 !4405.06N/12120.52W>008/000REV4ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTUSQUPK7TAY BULLMT€ЪЪЪЪЪЪЪ`2R}l!m>/`"4Y}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPOT21TWOODSSOMTN €WIDE2 5!4645.38N/12207.08W#kd7isz testing new firmware 54746ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NEUGENEBRNSVL€SALEM -=4406.46NS12308.93W#PHG63604/W2,ORn,OR KC7RJKЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NNN7U KOPEAK€WIDE2 *=4608.53N/12352.58W-Nr Lewis & Clark NP HQЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPBL10KE7WKM BULLMT€LARCH !4529.34N/12249.37Wv098/030ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPTW01K7ZQU BRNSVL€WIDE2 %!4424.77N/12151.86W_ Santiam Pass, ORЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPT314KA1FZD BULLMT€ЪЪЪЪЪЪЪ)!4528.30N/12248.18W<228/010/A=000246!w($!ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRS W7ZQD EUGENE€WIDE2 !4347.64n/12301.10w-ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪGPSMV KC7ILK N7QXO ‰WIDE2 O$GPGGA,235400.000,4539.6403,N,12237.7142,W,2,09,1.0,82.5,M,-19.3,M,1.8,0000*74 ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPOT03KC7OHYSOMTN €WIDE2 b/081619z4717.73N/12225.36Ws019/000/A=000016 14.0V 13C HDOP01.2 SATS06****** Live from MEGA WACHT 4ЪAPN383COLDSPWA2WA €WIDE3 C!4529.04NS11626.37W#PHG5940/W3,IDn, Cold Springs APRS Digi - KC7DBAЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTURYXSK7JDF BULLMT€WIDE2 `2S?mp%>/"4Q}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪT5SUXWN4WSQ LARCH €WIDE1 2`2D'l?Hu/]"4"}18 wheels across america! 146.52MhzЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN391SNOPASJUPITR€N7QXO :!4725.13NS12124.48W#PHG4540W2,WAn-n,Snoqualmie Pass KC7JLUЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPX203N7QNM SOMTN €WIDE2 ?@092345z4737.17N/12202.70W_360/000g000t041r000P000p000h98b10231ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN390ROCKWYHEBOWX€SALEM >EBT046.9FЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRS WW7RA SOMTN €WIDE2 /!4732.88N/12248.45W_>WW7RA Digi & Remote Wx StaЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTUSSSTKF7SNQ BULLMT€ЪЪЪЪЪЪЪ`2R+nUJj/]"4W}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPOT21ALAKESJUNIPR€WIDE2 4!4457.51N/11814.69W_345/000g000t018p000h96b10052T2WXЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪT4UVTPW7BDB SALEM €ЪЪЪЪЪЪЪ`3Ycl"3k/`"4F}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪT5RYRUKE7JFF BULLMT€ЪЪЪЪЪЪЪ$`2L\m!jj/'"3r}MW66 mwave.org !w:t!|4ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN391SOMTN LARCH €WIDE2 3!4719.20NS12320.73W#PHG2860/W2,WAn South Mtn KB7UVCЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPOT21AA7BG SSADDL€WIDE1 >Tracker2ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN N7QXO LARCH €ЪЪЪЪЪЪЪ,!4558.26NS12259.95W#PHG7650/W2,WAN,VANCOUVERЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTT3SRWKI7AY CRVLS WIDE2 `3,pn4g>/]"4Y}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPBL10K7RKT BULLMT€ЪЪЪЪЪЪЪ!4526.21N/12244.73W-ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN391BULLMTN7QXO ЪЪЪЪЪЪЪ5!4525.00NF12249.67W#PHG2667/KB7WUK OR Bull Mt Fill inЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN383TIGER KOPEAK€WIDE2 3!4730.52NN12159.11W#PHG3860/K7NWS WA TIGER MTN APRSЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPTT4 KJ7DZ SALEM €WIDE2 5/000000h4452.92NI12304.60W&Salem OR - iGate - OpenwrtЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRS NG7N SOMTN €WIDE2 D@090020z4739.10N/12224.32W_328/001g003t043r000p000P000h77b10237.DsVPЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPT311WA7KRN LARCH €SALEM >Think EVЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪEFCXUUKA7JNY BULLMT€ЪЪЪЪЪЪЪ$`2MZlf=>/]"4\}442.225 or 440.450 MHzЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPWW10K7TYE GRZZLY€WIDE2 "@005047h4426.24NI12117.90W&PHG2020ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPT311KD7ITS N7QNM €WIDE2 >TT3+EVERETT, WAЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPVR30KC7RJK TCPIP EUGENE>;IRLP-3543*081556z4406.46NI12308.94W0145.500MHz T100 -060 IDLEЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTTTVTSW7KKE IDIOTV€OR2 '2== s-v/]"6{}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪID DGDAVEKOPEAK€WIDE2 0>DIGI_NED: digipeater W7AUW in S.E. Hoquiam, Wa.ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPOTW1KC7RASKOPEAK€WIDE2 4!4736.27N/12219.82W_270/000g000t044P+43h70b10449OTW1ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN383FLO LARCH €ЪЪЪЪЪЪЪ6!4357.33NS12404.50W#PHG2640/W2,ORn-N W7ZQD OR FlorenceЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTUSRXTKC0CRD LARCH €WIDE1 `2Bml!@Y\>"53}=ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN390PACCTYHEBOWX€IDIOTVD@165505z4511.02N112356.07W_000/000g000t047r000p005P004h95b10261.WxDgЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN390ROSLDGSSADDL€WIDE1 D@074508z4501.34NF12351.41W_000/000g000t046r000p000P000h00b......U2k ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN382PATSY LARCH €WIDE1 D@181202z4436.81N112339.02W_000/000g000t044r000p000P000h97b10235.WxDgЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPT311N7DUD BULLMT€WIDE2 >n7dud@winlink.orgЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPWW10K7FZO KOPEAK€WIDE2 =@004028h4727.90N/12140.74W;446.525MHz Toff Simplex - EchoIRLPЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPWW10K7TYE GRZZLY€WIDE2 ?/091546z4426.28N/12117.93W_000/001g005t045r000p000P000h57b10200ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NEUGENELARCH €ЪЪЪЪЪЪЪK;VALLEY *071948z4404.22N/12308.22W+Club meet Mar 1 7pm VEexams Feb 13 7pmЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN382KC7ILKLARCH €ЪЪЪЪЪЪЪ5!4539.64N/12237.72W#PHG5130/A=000285Minnehaha StationЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPZ123N7QME BULLMT€N7QXO I!4541.81N/12252.15WY 13.18 33.0 48.5 -1 48 70.1 -1 70 30.6 0.0 ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN391KD7MPGLARCH €ЪЪЪЪЪЪЪA!4502.97N/12329.65W_PHG3430/A=000455/Sheridan, OR WX - NWS: AS405ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪE73XQPKD7IDYSOMTN €WIDE2 `2\>o?Qu/]"4(}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRX26SSADDLBULLMT€ЪЪЪЪЪЪЪ >http://www.danplanet.com/ssaddlЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NW7YKM YAKIMA€WIDE2 X@090104z4642.66N/12043.17W_288/012g014t040r000p000P000h28b10184Naches Heights WX StationЪЪЪЪЪЪЪЪЪЪЪT5RWPWNM7B BULLMT€ЪЪЪЪЪЪЪ`2OBmft[/`"6;}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPTT4 AI7MC BULLMT€ЪЪЪЪЪЪЪ!>Power 25W, Antenna J-Pole 400 ftЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN390YAKIMAJUNIPR€WIDE2 0!4638.43NS12023.75W#PHG57304/W2,WAn,Yakima-N7HHUЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPN382DRAIN EUGENE€WIDE2 3!4338.32NS12319.63W#PHG5730 W2 ORn-N DRAIN OR W7ZQDЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTTSSZZKI6VEYBRNSVL€WIDE2 `3+l>yu/`"4Y}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTUTVXRKD7HPASSADDL€WIDE1 `2>] tv/]"4N}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NWB7DDLBRNSVL€SALEM .=4432.78N/12315.64W-tparsons@peak.org {UIV32N}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPX199W7AUW KOPEAK€N7QXO ?=4658.88N/12351.95WxPHG7250 LinuxXastir1.9.7 IGATE/145.63 AUW-2ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪTW4PSPN9VW K9JEB ‚WIDE2 `2^elH4K\]"4'}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NEUGENELARCH €ЪЪЪЪЪЪЪ[@081556z4406.46N/12308.93W_031/002g005t037r000P000p001h93b10247KC7RJK www.eugeneweather.netЪЪЪЪЪЪЪЪAPOTC1N7IME LARCH €WIDE1 7!4536.88N/12241.84Ws000/000 13.5V HDOP01.0 SATS09 Azul ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPU25NAC7TK EUGENE€WIDE2 %=4404.90NI12303.85W&PHG31302 {UIV32N}ЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪAPRS ASTRWXKOPEAK€WIDE2 D@001705z4615.77N/12353.22W_287/004g008t047r000p002P001h..b10190.U21hЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0! #RWH6KO - 9EQ"I 88 KM7LJ - 4€ N7QXO -14EE"8!+  #CKD7RUS- 4EGF"2b+ #K7PAL - 9G4"!C+@@ PACCTY- 2EQ#X1\RN7HQR - 9DX2$18@@ #PAC7KP €&K*KB7WUK E3A"4 +WA7BVQ- 7G1I"" ' !WB7OR -14FW"V +0 #TK7CPU - 1E22"WE?? #K7POS - 9E0("BF+ WX7W - 9G'W"a+ IWOLF C7"P8@@ SHEBOWX EY#E1\WB7AYU €%TWN7M - 9РЬЬЬм@@N7GME €&KN7RIF - 9G'B"7)&@@# SKD7MQM- 1F 421\  #WJUNIPR ED C28 WA4OSH G4" T+@@  #WKM7LJ E7X"4X1X0 #RERINB - 5GR##(1# #FLARCH € UKOPEAK F'B#2`8KC7DX -10€@@UN7TQZ €&K@@ VKC7RJK- 3D#E 1\N1KEZ - 1E&?"P:# MEGLER F#SS1 #@SALEM DS"U]8TK7HRY - 9D! 48 K7TAY - 9E12"Ta+! RTWOODS FE&"1 #TEUGENE D.#]: #HNN7U F5#R:1 KE7WKM- 9E)""I%8@ K7ZQU - 7D$M!QV10 $KA1FZD- 9E("H88!W7ZQD CG@# 1  #TKC7ILK- 9E9@"7GQ0@KC7OHY GI"%$??(COLDSP E)&%8  GK7JDF - 9E)S"U#* # YN4WSQ E5W"@ + SNOPAS G% !$08@@ #FN7QNM G7"F1\ GROCKWY €@"WW7RA G2X"H-1 VKF7SNQ- 9E3""T+@@ #PALAKES DW3E1M G W7BDB - 9DV(#G+  KE7JFF- 9E)"H@+ #DSOMTN G# I8 1AA7BG - 9€ #PN7QXO - 9EX"Y_8  KI7AY - 9D3#T+ #UK7RKT - 2E&"DI1 BULLMT E%"IC8 #ETIGER G04!Y 8 #GKJ7DZ DR\#<8@@ GNG7N G9 "$ 1\ #FWA7KRN- 9€  4KA7JNY- 9E(7"I>+ HK7TYE D&!Z? YKD7ITS-11€ VIRLP-3543D.#^B  #HW7KKE - 9DF+"3!+/ #DDGDAVE €@@ #HKC7RAS- 8G6"R1@FLO CW!$28  #TKC0CRD- 9E2T"8Q+@@ #FPACCTY E#V1\@@ROSLDG E"#Q)1\@@ VPATSY D6Q#91\N7DUD - 9€" AK7FZO G'Z!@J8@@ #EK7TYE - 2D&!]1\&VALLEY D#B$ #TKC7ILK E9@"7H885N7QME - 6EAQ"R1@$& #XKD7MPG- 2Ea#)A88  KD7IDY-14G8 ""+"SSADDL €@@ W7YKM - 3FBB C1\   NM7B - 7E'"Q&+ !AI7MC €YAKIMA F8+ #K:DRAIN C8 #?8 !KI6VEY-14€D3џ#џ+  #WKD7HPA-15EFR"4A+ WB7DDL D2N#@1$W7AUW FXX#Q_8  GN9VW - 7G@"I+@@VEUGENE- 2D.#]1\ #QN7IME - 2E6X"AT8  #WAC7TK DZ#U8@@ #PASTRWX FM#S1\џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFR@  D9L ‡ ’џџРUchirp-20240224/tests/images/Retevis_RA85.img0000644000175000017500000001636114411666130017332 0ustar hibbyhibbyPb%FPb%FžžDP‡%FP‡%FЄЄDP&FP&FљљDP7&FP7&F&&DPb&FPb&FUUDP‡&FP‡&F……DP'FP'FЖЖDPbuFPbuF''DP‡uFP‡uFDPvFPvFDP7vFP7vF DPbvFPbvF DP‡vFP‡vF DPwFPwFDP%FP%FЮЮDu%Fu%FббD&F&FЂЂD%&F%&FљљDP&FP&FDu&Fu&FXXD'F'FЮЮD%'F%'FUUDP%FPuFUUDu%FuuFUUD&FvFUUD%&F%vFUUDP&FPvFUUDu&FuvFUUD'FwFUUD%'F%wFUUDPb%FPb%FžžDP‡%FP‡%FЄЄDP&FP&FљљDP7&FP7&F&&DPb&FPb&FUUDP‡&FP‡&F……DP'FP'FЖЖDPbuFPbuF''DP‡uFP‡uFDPvFPvFDP7vFP7vF DPbvFPbvF DP‡vFP‡vF DPwFPwFDP%FP%FЮЮDu%Fu%FббD&F&FЂЂD%&F%&FљљDP&FP&FDu&Fu&FXXD'F'FЮЮD%'F%'FUUDP%FPuFUUDu%FuuFUUD&FvFUUD%&F%vFUUDP&FPvFUUDu&FuvFUUD'FwFUUD%'F%wFUUDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџq џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQTg1IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjAyMTQiLCAicmNsYXNzIjogIlJhZGlvZGRpdHlHQTUxMFJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Explorer_QRZ-1.img0000644000175000017500000002152114411666130017636 0ustar hibbyhibbyрС—рС—џџ рС—рС—џџ рС—рС—џџ ЈЛbЈЛbžž ЄЫ—ЄЫ—ww „”Ј„”Јэ э  8Э8Э„„  , ,џџ рп’рп’џџ @Ъ“@Ъ“џџ ˜˜џџ HъХHъХџџ $Б‘$Б‘џџ H•H•џџ DМБDМБџџ lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu lмlмu n†І‡€№‰АeŠрМ@Їл“pў•Аš–№Ї™pрš№‰ž0—Ё0Єџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?џџ№†ЭР!†ЭР'P10blмlмu lмlмu lмlмu lмlмu рС—рС—ш рС—рС—ш lмlмu lмlмu lмlмu р‚ьр‚ьџџ зu зuџџ`ъШХ—ШХ—џџ р‚ьр‚ьџџ А6wА6wџџ`ърС—рС—џџ  !BррёAё рС%@ж B000000rIѓёAёšМо№4Vx'24W˜4P4Vx24W˜4_4VxB4ex4P4VxB4ex4_4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx Уi№ №Vx 4VxšМо№4Vx ˜vT2Мо№4Vx 24W˜4_B4ex4_ рС—рС—rIѓёAё рСVЬ2T-01  VЬyOжP  4Vx 5T-01  4Vx 5T-02  4Xx123456 5T-03  ‡eC!123456 5T-04  5W„123456 5T-05  4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx `а4Vx‡eC!F 4VxšМ5T-01  4V‡ŠМ 5T-02  ‡eC!šМ5T-03  5W„šМ5T-04  4VxšМ 4VxšМ 4VxšМ 4VxšМ …ЯР€ …ЯР€ ZblмZblмџџџџџџџџџ&)"(ZZZZZdddddddddddddddZ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡вввввввввввввввввввввммм<<HR\fpz„Ž˜ЌРдш#-7AKZdnx‚Œ– ЅІІІІІІІІІІІІІІІІcWK=3/-*.1œ—ŒˆŠŠ”šЧХТСІЃІВХЭІІІІІІІІІІІІІІІPG<<62($*+0}wqhb[XXSQSTW_`мммммммммммммммІІІІІІІІІІІІІІІІ8  Ќ–X&„Ž ФP PІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІfpz„Ž˜ЌОд&0:DS]gq{…™ЃІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІqsuwy{}ƒ…‡‰‹‘“•—јјІІІІІІІІІІІІІІІІІІІІп’`шШЈŠРшШІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІп’`шаЈŠРшаРС,€СUАРІІІІІІІІІІІІІІІІџџ  ч 8&zP%  џџџџџџџџ(<PZBetterSafeRadioІІІІІІІІІІІІІІІІWOUXUN20220609ИЃНЈЪЁШЊжнЪа000000B4_PX3.0deШЩ,-‘єѕXYМН !„…чџџџџџџџџHAM101201301401501601701801901ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІп’`п’`шуаџџЈŠРЈŠРшуаџџUАџџџџшуРџџaџџџџшуРџџg5џџџџшуРџџ‡@АџџџџшуРџџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџпkPпkPшуаџџп†Јп†Јшуаџџп˜<п˜<шуаџџпžпžъуаџџпЃєпЃєъуаџџрё№рё№шуаџџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџЁАЁАшуаџџЈ–xЈ–xшуаџџЈБаЈБашуаџџЉNЉNшуаџџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџоy мyhуаџџоy œ уџџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџјџџџџу€џџїЭ€џџџџу€џџїъЬџџџџу€џџїзDџџџџу€џџїсџџџџу€џџїєџџџџу€џџїўTџџџџу€џџіЈˆџџџџу€џџій\џџџџу€џџџџџџџџџџџџџџџ§џџяBџџџџу€џџЙd№џџџџу„џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџЈŠРџџџџу€џџџџџџџџџџџџџџџџџџІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІ2m CALL70cmCALL220 CALLH3 C2.50H3 C6.50H3 C7.50H2 P6.42H2 S6.49H2 S6.53H2 W6.55H2 T6.56H2 S7.42H4 S1.10H4 P6.03H4 S6.10H4 S6.50ISS DxISS RptNOAA WX1NOAA WX2NOAA WX3NOAA WX4NOAA WX5NOAA WX6NOAA WX7NOAA WX8NOAA WX9MMS 16EMAIR EMBSR SHTFІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІ<<}}}}ќќќќќќќќќќќќќќ<<<<<<ќќќќќќќќќќќќќќ<<<<ќќќќќќќќќќќќќќќќ>=ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќ}}}}}}}}}ќ}}ќќќќќќ}ІІІІІІІІІІІІІІІІІІІІІІІІ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ №№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ№№№џџ №№№џџ№№№џџU 101џџU 102џџU 103џџU 104џџU 105џџU 106џџU 107џџU 108џџU 109џџU 110џџU 111U 112U 113џџU 114џџU 115џџU 116џџU 117џџU 118џџU 119џџU 120џџ  !"#$%&'()*+,-./0123456789:;<=>?ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІџchirpюimgeyJyY2xhc3MiOiAiS0dVVjlQWFJhZGlvIiwgInZlbmRvciI6ICJXb3V4dW4iLCAibW9kZWwiOiAiS0ctVVY5UFgiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMwMTE3In0=chirp-20240224/tests/images/Baofeng_W31E.img0000644000175000017500000000126114467633002017246 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%BE%BEЕЕџ0џџ%CE%CEшшџ0џџ%DE%DEъъџ0џџ%EE%EEѓѓџ0џџ%FE%FEr r џ0џџ%GE%GE((џ0џџ%HE%HEL(L(џ0џџ%IE%IE…(…(џ0џџ%QE%QEЦ(Ц(џ0џџ%RE%RE ) )џ0џџ%SE%SEC)C)џ0џџ%TE%TE†)†)џ0џџ%UE%UEь)ь)џ0џџ%!@%!@џџџџџ0џџPUCPUCџџџџџ0џџP‰FP‰Fџџџџџ0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJXMzFFIiwgInZlbmRvciI6ICJCYW9mZW5nIiwgIm1vZGVsIjogIlczMUUiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMwODEwIn0=chirp-20240224/tests/images/BTECH_FRS-B1.img0000644000175000017500000000222514411666130016743 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%FџџџџџџџP‡%FP‡%FџџџџџџџP&FP&FџџџџџџџP7&FP7&FџџџџџџџPb&FPb&FџџџџџџџP‡&FP‡&FџџџџџџџP'FP'FџџџџџџџPbuFPbuFџџџџџџџP‡uFP‡uFџџџџџџџPvFPvFџџџџџџџP7vFP7vFџџџџџџџPbvFPbvFџџџџџџџP‡vFP‡vFџџџџџџџPwFPwFџџџџџџџP%FP%Fџџџџџџџu%Fu%Fџџџџџџџ&F&Fџџџџџџџ%&F%&FџџџџџџџP&FP&Fџџџџџџџu&Fu&Fџџџџџџџ'F'Fџџџџџџџ%'F%'FџџџџџџџP%P%џџџџџџџ$$џџџџџџџu$u$џџџџџџџ%$%$џџџџџџџP$P$џџџџџџџ%%џџџџџџџ%%%%џџџџџџџџџџџџџџџџ!6!6 6 6778899::::<<<52TR><'&SQ  -џџDFHJLNPRTџџџџџџџџџџџџџUUUUUџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџї7013PџџџџџџџџUџchirpюimgeyJ2ZW5kb3IiOiAiQlRFQ0giLCAibW9kZWwiOiAiRlJTLUIxIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMTEyMjEiLCAicmNsYXNzIjogIkZSU0IxUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Icom_IC-V86.img0000644000175000017500000001305514411666130016772 0ustar hibbyhibby РџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџПџџџџџџяГР' яГР'  ™РЗЛCALL яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ яГяГ ШШ€јгРќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЗЛ 40660001џchirpюimgeyJ2ZW5kb3IiOiAiSWNvbSIsICJtb2RlbCI6ICJJQy1WODYiLCAiY2hpcnBfdmVyc2lvbiI6ICJsZWdhY3ktMjAyMjEyMTciLCAicmNsYXNzIjogIkR5bmFtaWNSYWRpb0FsaWFzIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_FT-4XE.img0000644000175000017500000002076114411666130017226 0ustar hibbyhibby4123џџџџџџџџџџџџC 0FPFeGu RPU‡PVV%V7PVPVbPVbP V‡PV‡PV‡PW W%W%W7PWPWbPWu WuW‡PW‡PџW‡PџCP@џC%@џC%@џCP@џCu@џCu@џC@џCP @џCbP @џCu@џC‡P@џC@џC% @џCPШџCu@џC @џCP@џCu @џCP @џCP @џC@џC7P @џCbP@џCu @џCP@џCu @џC0%џCQPџCTuЏџC”‡P 0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCP @џF7P џCP@џCџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC 0@  P @ C 0 P @ C 0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCFPFeGuRPU‡PVV%V7PVPVbPVbPV‡PV‡PV‡PWW%W%W7PWPWbPWuWuW‡PW‡PW‡PCPC%C%CPCuCuCCPCbPCuC‡PCC%CPCuCCPCuCPCPCC7PCbPCuCPCuC0%CQPCTuC”‡Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ---------..------------------------------------------------------------------------------------------------------------------------------------------------------S% S%  P@џchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIllhZXN1IiwgIm1vZGVsIjogIkZULTRYRSIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Yaesu_FTM-7250D_R.img0000644000175000017500000017757014551723752017751 0ustar hibbyhibbyAH75Mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџf…BRSTOL џџџџџџџџџ  џџџџ `џџџџџџџџџџџџџџџџ ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ% ЈBŽ Ј % ( EdџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУџџџџџџЯџџџџџУџџџџџџЯџџџџ Pџџџџџџџџџџџџџџџџ p@P€ џџџџ Pџџџџџџџџџџџџџџџџ p@P€  џџџџ C0Pџџџџџџџџџџџџџџџџ BG€ Н џџџџ C0Pџџџџџџџџџџџџџџџџ BG€ НУџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€€ tУџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€€ tџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBANK 1џџџџџџџџџџBANK 2џџџџџџџџџџBANK 3џџџџџџџџџџBANK 4џџџџџџџџџџBANK 5џџџџџџџџџџBANK 6џџџџџџџџџџBANK 7џџџџџџџџџџBANK 8џџџџџџџџџџBANK 9џџџџџџџџџџBANK10џџџџџџџџџџBANK11џџџџџџџџџџBANK12џџџџџџџџџџBANK13џџџџџџџџџџBANK14џџџџџџџџџџBANK15џџџџџџџџџџBANK16џџџџџџџџџџBANK17џџџџџџџџџџBANK18џџџџџџџџџџBANK19џџџџџџџџџџBANK20џџџџџџџџџџBANK21џџџџџџџџџџBANK22џџџџџџџџџџBANK23џџџџџџџџџџBANK24џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ e аџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ D`аџџџџџџџџџџџџџџџџP €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ Pаџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0аџџџџџџџџџџџџџџџџP €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ Pаџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0аџџџџџџџџџџџџџџџџP €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPа€Aџџџџџџџџџџџџџџџ €`@€Bџџџџџџџџџџџџџџџ`@€Cџџџџџџџџџџџџџџџ`@€Dџџџџџџџџџџџџџџџ`@€Eџџџџџџџџџџџџџџџ`@€Fџџџџџџџџџџџџџџџ`@€Gџџџџџџџџџџџџџџџ`@€Hџџџџџџџџџџџџџџџ`@€Iџџџџџџџџџџџџџџџ`@€JџџџџџџџџџџџџџџџPРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ 'D(PрџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ sA€DONKEYџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФџџџџџџ?€YYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******CQ*******QST******YAESU****џџџџџџџџџBLN******BLN*џџџџџBLN*џџџџџFxx  xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:A? џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ******џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCHIRPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<ePDeџџџџџt{џ0AZazi9**џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ DGID 00 DGID 01 DGID 02 DGID 03 DGID 04 DGID 05 DGID 06 DGID 07 DGID 08 DGID 09 DGID 10џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџ џchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlRNLTcyNTBEIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMDA3MTAiLCAicmNsYXNzIjogIkZUTTcyNTBSYWRpbyIsICJ2YXJpYW50IjogIlIifQ==chirp-20240224/tests/images/KYD_IP-620.img0000644000175000017500000002000014551723752016470 0ustar hibbyhibby 0 0џџџџёєџџp0p0џџџџёєџџ0000џџџџёіџџ@0@0џџџџёіџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџџџџџџџџџџџџџ§џџџ11žžт11žžъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ›dG—P7ЌO2џџџџџџџ0 ™0 ™0 ™0 ™џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  Ч7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџтџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@џџџџ0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Icom_ID-800H_v2.img0000644000175000017500000003430014411666130017432 0ustar hibbyhibbyxџџџџџџџџџ–IcomDX-2788R1.00"швфБ-!Ъ06[lшв ф2-!Ъ05r xˆф2+ЕV@6ZхшвPф2+ЕV@5rаxˆф0)свP6[qшШPф1)свP5ZбшШPф1)ЖN@ZŸшШPф1)о-r”x’ф2,Дxяqfx’ф2*/вЃrєxвф2-еŠXРq†x’ф2+•ыŠ€sxШф2+•’Њ€sx Ыф1$T]%YŒшвPф2%I4[?швPф2%QEеrxxф0$TYTr„xф0$TYVs8xф0$T]Frxф0rxф0rxф0rxф0rxф0X)шШ@ф0(€ЯHt @X)шШ@ф0(€жы+@X)шШ@ф0(Ю›u @X)шШ@ф0-0А€@X)шШ@ф0(ЩР@X)шШ@ф0(Щ(@@X)шШ@ф0(Щ8Р@X)шШ@ф0(ЩH@@X)шШ@ф0(ЩX@@X)шШ@ф0(ЩXР@X)шШ@ф0(Щ!@X)шШ@ф0(г # @X)шШ@ф0(ЎЫЂ@X)шШ@ф0(‹-b@X)шШ@ф0(‹-c@X)шШ@ф0(о;у@X)шШ@ф0(о"@X)шШ@ф0(о#@rxф0sxШ@ф0(РЯHt @sxШ@ф0(Ржы+@sxШ@ф0(ЭЮ›u @sxШ@ф0-0АР@sxШ@ф0(ЭЩР@sxШ@ф0(ЭЩ(@@sxШ@ф0(ЭЩ8Р@sxШ@ф0(ЭЩH@@sxШ@ф0(ЭЩX@@sxШ@ф0(ЭЩXР@sxШ@ф0(ЭЩ!@sxШ@ф0(Эг " @sxШ@ф0(ЭЎЫЂ@sxШ@ф0(Э‹-b@sxШ@ф0(Э‹-v@sxШ@ф0(Эо;і@sxШ@ф0(Эо"@sxШ@ф0(Эо#@rxф0XGшШ@ф0(€ЯHt @XGшШ@ф0(€жы+@XGшШ@ф0*ьИ€@XGшШ@ф0-s$c@XGшШ@ф0-s$Ё@XGшШ@ф0-Ћ$у@XGшШ@ф0-s%!@XGшШ@ф0-k%a@XGшШ@ф0-k%c@XGшШ@ф0-sЩ!@XGшШ@ф0(г " @XGшШ@ф0(г # @XGшШ@ф0(‹-b@XGшШ@ф0(‹-c@XGшШ@ф0(о;у@XGшШ@ф0(о"@XGшШ@ф0(о#@rxф0X=шШ@ф0(€ЯHt@X=шШ@ф0(€жы+@X=шШ@ф0(Ю›u@X=шШ@ф0(Вд€@X=шШ@ф0(ЩР@X=шШ@ф0(Щ(@@X=шШ@ф0(Щ8Р@X=шШ@ф0(ЩH@@X=шШ@ф0(ЩX@@X=шШ@ф0(ЩXР@X=шШ@ф0(Щ!@X=шШ@ф0(г " @X=шШ@ф0(г # @X=шШ@ф0(ЎЫЂ@X=шШ@ф0(‹-c@X=шШ@ф0(о;у@X=шШ@ф0(о"@X=шШ@ф0(о#@rxф0rxф0sxШ@ф0(РЯHt@sxШ@ф0(Ржы+@sxШ@ф0(ЭЮ›u@sxШ@ф0(ВдР@sxШ@ф0(ЭЩР@sxШ@ф0(ЭЩ(@@sxШ@ф0(ЭЩ8Р@sxШ@ф0(ЭЩH@@sxШ@ф0(ЭЩX@@sxШ@ф0(ЭЩXР@sxШ@ф0(ЭЩ!@sxШ@ф0(Эг " @sxШ@ф0(Эг # @sxШ@ф0(ЭЎЫЂ@sxШ@ф0(Э‹-b@sxШ@ф0(Эо;у@sxШ@ф0(Эо"@sxШ@ф0(Эо#@rxф0rдxˆ@ф0(РЯHt @rдxˆ@ф0(Ржы+ @rдxˆ@ф0-уМР @rдxˆ@ф0(ЭЩР @rдxˆ@ф0(ЭЩ(@ @rдxˆ@ф0(ЭЩ8Р @rдxˆ@ф0(ЭЩH@ @rдxˆ@ф0(ЭЩX@ @rдxˆ@ф0(ЭЩXР @rдxˆ@ф0(ЭЩ! @rдxˆ@ф0(Эг " @rдxˆ@ф0(Эг # @rдxˆ@ф0(ЭЎЫЂ @rдxˆ@ф0(Э‹-b @rдxˆ@ф0(Э‹-c @rдxˆ@ф0(Эо" @rдxˆ@ф0(Эо# @qH@ф0X3шШ@ф0(€ЯHt @X3шШ@ф0(€жы+ @X3шШ@ф0(Ю›u @X3шШ@ф0-сВ " @X3шШ@ф0(ЩР @X3шШ@ф0(Щ(@ @X3шШ@ф0(Щ8Р @X3шШ@ф0(ЩH@ @X3шШ@ф0(ЩX@ @X3шШ@ф0(ЩXР @X3шШ@ф0(Щ! @X3шШ@ф0(г " @X3шШ@ф0(г # @X3шШ@ф0(ЎЫЂ @X3шШ@ф0(‹-b @X3шШ@ф0(‹-c @X3шШ@ф0(о;у @X3шШ@ф0(о# @rxф0qbxˆ@ф0(РЯHt @qbxˆ@ф0(Ржы+ @qbxˆ@ф0(ЭЮ›u @qbxˆ@ф0-сВ # @qbxˆ@ф0(ЭЩР @qbxˆ@ф0(ЭЩ(@ @qbxˆ@ф0(ЭЩ8Р @qbxˆ@ф0(ЭЩH@ @qbxˆ@ф0(ЭЩX@ @qbxˆ@ф0(ЭЩXР @qbxˆ@ф0(ЭЩ! @qbxˆ@ф0(Эг " @qbxˆ@ф0(Эг # @qbxˆ@ф0(ЭЎЫЂ @qbxˆ@ф0(Э‹-b @qbxˆ@ф0(Э‹-c @qbxˆ@ф0(Эо;у @qbxˆ@ф0(Эо" @rxф0rpШˆф0(uЬР@qH@ф0X8шШ@ф0(€жы+@X8шШ@ф0(Ю›u@X8шШ@ф0*/д€@X8шШ@ф0(ЩР@X8шШ@ф0(Щ(@@X8шШ@ф0(Щ8Р@X8шШ@ф0(ЩH@@X8шШ@ф0(ЩX@@X8шШ@ф0(ЩXР@X8шШ@ф0(Щ!@X8шШ@ф0(г " @X8шШ@ф0(г # @X8шШ@ф0(ЎЫЂ@X8шШ@ф0(‹-b@X8шШ@ф0(‹-c@X8шШ@ф0(о;у@X8шШ@ф0(о"@X8шШ@ф0(о#@rxф0rxф0rxф0rxф0rxф0rnШШ@ф0(Ржы+@rnШШ@ф0(ЭЮ›u@rnШШ@ф0*/дР@rnШШ@ф0(ЭЩР@rnШШ@ф0(ЭЩ(@@rnШШ@ф0(ЭЩ8Р@rnШШ@ф0(ЭЩH@@rnШШ@ф0(ЭЩX@@rnШШ@ф0(ЭЩXР@rnШШ@ф0(ЭЩ!@rnШШ@ф0(Эг " @rnШШ@ф0(Эг # @rnШШ@ф0(ЭЎЫЂ@rnШШ@ф0(Э‹-b@rnШШ@ф0(Э‹-c@rnШШ@ф0(Эо;у@rnШШ@ф0(Эо"@qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0X)шШPф0(sЂlЄ+@X)шШPф0)ЏВМР,@X)шШPф0,ЏЖP*@X)шШPф0(€†œЅ)@X)шШPф0(bЪK€(@X)шШPф0)ВКЙД'@X)шШPф0-0А€@sxШф0-0АР@qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0qH@ф0X)шШ`ф0+eВ #6@X)шШ`ф0)!Ыzn5@X)шШ`ф0,%ЫJ4@X)шШ`ф0,4ЫЃ3@X)шШ`ф0*%Ъщ@2@X)шШ`ф0,ш–`#0@X)шШ`ф0(m— "1@X)шШ`ф0(ЁЪр#/@X)шШ`ф0)ь‡0#.@X)шШ`ф0)dІр#-@zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz sxШ@ф0-0АР@X)шШ@ф0-0А€@‘нРш ""ГяГя 'Рш 0 Е… Е…€ш 0Z Z Рш 09о9оLK@ш 0ЭeЭeш 05Єщ5Єщш 0  „(&+2 ТМ  'РшWCO C 0 DyPB€Гя 'Рш 0џџџ9оLK@ш 0џџџГя 'Рш 0џџџІ‚ 'Рш 0@ 27880001  (+2џџџџџџџџџџџџџџџџџЛ€B@ш 0@ џџ0134567G  (+2 Гя 'Рш 0 џџџџџџџџџџ  (+2џџџџџџџџџџџџџџџџџNU5D UREF001CLREF002ALREF003CLREF004ALREF005ALREF005CLREF010ALK5CTX K5CTX IK5CTX BLK5CTX CLW5LM IW5LM BLW5HAT W5HAT IW5HAT BLW5HAT CL/W5HAT B/W5HAT CW5ZDN IW5ZDN CL/W5ZDN CKE5RCS KE5RCS IKE5RCSBLKE5RCSCL/KE5RCSB/KE5RCSC/W5KA CW5HDR BLW5HDR CL/W5HDR B/W5HDR C/WD5STRB/WD5STRC/WA5UNHB/K5TIT B/NT5RN CKE5WFBCLBLANK K0DPS WY0X KL0RG N2RCG KB2WF AA4RC KJ4VO KE5C WD5ERD N5MIJ KE5KAF KB5NFT KB5B KV5E W5HMN K6JV NJ6N WA6YTD KI7IL K7VE N7MK K9NBR M0TMX M1CMN G4TKR M3PPU VA3TO VE3EI DF6RK DL9MB IZ3CLG VK3JKF VK4TUX VK8HF /JP4YDUA/JP1YIWA/JP1YIWBG4UUI REF019A 01 K5CTX BK5CTX CK5CTX GW5LM BW5LM GW5HAT BW5HAT CW5HAT GW5ZDN CW5ZDN GKE5RCS BKE5RCS CKE5RCS GW5KA CW5KA GK5TIT BK5TIT GNT5RN CNT5RN GWD5STR BWD5STR CWD5STR GWA5UNH BWA5UNH GW5HDR AW5HDR BW5HDR CW5HDR GKE5WFB BKE5WFB CKE5WFB G DB0HRF BGB7GD CLU3AOC BIR0UAC BGB7DX BGB7FK BGB7DE CGB7DG CGB7YD CGB7SF CGB7AU BGB7IC BVK5REX BVK6RWN CVK8RAD CVK3RWN CCQCQCQ KE5RCS CKE5RCS G/KR7ST BW5LM BW5LM GCQCQCQ KE5RCS KE5RCS GCQCQCQ W5KA W5KA G 800H џџџџџџџџџџџџџџџAA5RT W5ZDN CW5ZDN CLR STEVE K5CTX B*7A STEVE /K5CTX B STEVE REF 1 C STEVE REF 4 A STEVE REF 5 A STEVE REF 5 C џџџџџџџџџџџџџџ 27880001chirp-20240224/tests/images/Retevis_RB619.img0000644000175000017500000000222514411666130017410 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%`D%`DHHч`Du`Du`DHHч`D%1`D%1`DHHч1`DuC`DuC`DHHчC`D%V`D%V`DHHчV`Duh`Duh`DHHчh`D%`D%`DHHч`Du“`Du“`DHHч“`D%aD%aD&€&€чaDuaDuaD&€&€чaD%1aD%1aD&€&€ч1aDuCaDuCaD&€&€чCaD%VaD%VaD&€&€чVaDuhaDuhaD&€&€чhaD%aD%aD&€&€чaDu“aDu“aD&€&€ч“aDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџšјџџSMP5558џџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjYxOSIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwNjA0IiwgInJjbGFzcyI6ICJSQjYxOVJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Icom_IC-208H.img0000644000175000017500000002300014411666130017017 0ustar hibbyhibbyrxф0WРшPф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0rxф0 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzrxф0WРшPф0‘нРш Гя 'РГя 'Рш 0 Е…€ Е…€ш 0Z РZ Рш 09оLK@9оLK@ш 0ЭeЭeш 05Єщ5Єщш 0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'Рш 0 Гя 'Рш 0џџџџџџџџџџ9оLK@ш 0џџџџџџџџџџГя 'Рш 0џџџџџџџџџџГя 'Рш 0 џ џџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'Рш 0 џ џџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'Рш 0 џ џџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџ26320001chirp-20240224/tests/images/Quansheng_TG-UV2+.img0000644000175000017500000002034114411666130020153 0ustar hibbyhibbyTG-UV2+ Radio Program Data v1.0џџџџџџџџџџџџџџџџF%bPџџF%‡PџџF&PџџF&7PџџF&bPџџF&‡PџџF'PџџFubPџџFu‡PџџFvPџџFv7PџџFvbPџџFv‡PџџFwPџџF%PџџF%uџџF&џџF&%џџF&PџџF&uџџF'џџF'%џџџџџџџџџџџџџџџџџџD`%џџD`uџџD`1%џџD`CuџџD`V%џџD`huџџD`%џџD`“uџџDa%џџDauџџDa1%џџDaCuџџDaV%џџDahuџџDa%џџDa“uџџEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC†Pv џџWu џџGu џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџЬџџ @џџџџџџџ 8™•џџџџџџџ E‚Ьџџ Q™•џџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓsѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓџѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓѓџџџџџџџџџѓёёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџЫЩ Щџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ''џџџџџџџџџџ''џџџџџџџџџџ''џџџџџџџџџџ''џџџџџџџџџџ''џџџџџџџџџџ''џџџџџџџџџџ''џџџџџџџџџџ''џџџџџџџџџџ' 'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ' џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџџџџџџџџџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ' џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџ'џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ'''џџџџџџџџџџ'''џџџџџџџџџџ''''џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUXVhbnNoZW5nIiwgIm1vZGVsIjogIlRHLVVWMisiLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIyMDExOCIsICJyY2xhc3MiOiAiUXVhbnNoZW5nVEdVVjJQIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/BTECH_UV-50X2_G2.img0000644000175000017500000004024114411666130017367 0ustar hibbyhibby%f%f%v%v%D%D%D%D џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  Шп  џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџ WELCOME UV-50X2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ŸџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНџџџџџџdџџџџџџNџџџџџџІџџџџџџџџџџџџhџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜џџџџџџЪџџџџџџ$џџџџџџˆџџџџџџxџџџџџџњџџџџџџ†џџџџџџ&џџџџџџ<<џџџџџџџџџџџџџ џџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџ џџџџџџџџџџџџџџџџџџџџНd­ћ‹…NІhЁ9и}џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜Ъ$ˆG ~Тxњ†&nтdы;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2 UV-50XUC2M12  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000UC2M12000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJ2ZW5kb3IiOiAiQlRFQ0giLCAibW9kZWwiOiAiVVYtNTBYMl9HMiIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJVVjUwWDJfRzIiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Yaesu_FT-857_897_US.img0000644000175000017500000001647114411666130020172 0ustar hibbyhibby€€H 3i‡@e2HВВ22222J @2Х›‹222ф…†ˆ…†‡``"…‚q  4ї`ŽbHП 'џџџџџџџџ` @€и'џџџџџџџџ` H€)и'џџџџџџџџg H Њ'џџџџџџџџ`HqФ'џџџџџџџџa @Уй'џџџџџџџџa@Џф'џџџџџџџџaH u’'џџџџџџџџbH€&ю'џџџџџџџџa@+X'џџџџџџџџbHLbА'џџџџџџџџEO†GџџџџџџџџDKД РџџџџџџџџAHлКъ`џџџџџџџџAN РЁ џџџџџџџџb@€*И†'џџџџџџџџbHП 'џџџџџџџџ`HW0'џџџџџџџџbHШ'џџџџџџџџ`H Ў`'џџџџџџџџbHB@'џџџџџџџџaH\Р'џџџџџџџџaHw@'џџџџџџџџaH 'џџџџџџџџaH%bP'џџџџџџџџaH*Й€'џџџџџџџџAHLK@† џџџџџџџџEO†GџџџџџџџџDKД РџџџџџџџџAHлКъ`џџџџџџџџAN РЁ џџџџџџџџdHу`'џџџџџџџџeH-*€'џџџџџџџџEHP%”† џџџџџџџџEHп’`ъ`џџџџџџџџENЈŠРЁ џџџџџџџџ`H Ў`'CH-109 EKо№ъ`StPete `H Ў]'CH-109 П  @LK@ReРЅЄˆ рН4Canton2mF€H М'CH-110 F€H Щъ'CH-111 F€HyЧ'CH-112 F€Hx''CH-100 F€Hž_'CH-101 F€H &‡'CH-102 F€H *o'CH-103 F€H&o'CH-104 F€H*шo'CH-105 E€H-*€'CH-068 AЁ€HL|'CH-097 F€HLЌш† CH-106 F€HLК”† CH-107 F€HLсЄ† CH-108 E€HP%”† CH-069 A€Kм ъ`CH-094 EdKнk˜ъ`џџџџџџџџdK н{8ъ`KG4BJD dKнƒъ`PnPkARESdKнŠиъ`ZphHls dKн’Јъ`Dunedin dKнšxъ`Dndn d€KнЂHъ`Wes|ChpldKнЊъ`StPete dK нБшъ`NI4CE SPЄK нЙИъ`N4AACStPdK нСˆъ`W4GDN LLdKнЩXъ`NPR ARC EdK нб(ъ`џџџџџџџџdKнијъ`StPete dKнрШъ`WA4SWC TdK нш˜ъ`NI4CE VedKн№hъ`StPete dKнј8ъ`StPete dK оъ`Tampa K п†Јъ`Brdtn ELEKп’`ъ`CH-070 EKпЉаъ`CH-071 dKпЕˆъ`BdnSTARCEdK пЛdъ`џџџџџџџџdKпС@ъ`N9EE dKпЧъ`Lklnd dK пЬјъ`W4GDN NPdKпвдъ`K4LKL LadK пфhъ`N4SER SadKпъDъ`Valrico dK п№ ъ`NI4CE HodK пћиъ`W4BNC SPdKр lъ`Tampa dKрHъ`W4ORM SPEdK ръ`џџџџџџџџdKр$мъ`Gibsntn EdKр*Иъ`џџџџџџџџEdKр0”ъ`џџџџџџџџdKр6pъ`NI4M TpadK рB(ъ`LrgoCARSdKрHъ`Bartow ЄKрMръ`W4TCH ЄKрY˜ъ`WA4AKH SЄKрePъ`V.A. BP EЄKрk,ъ`џџџџџџџџЄKрqъ`Ruskin ЄKрvфъ`N4TP TpaЄKр|Ръ`StPete ЄKр‚œъ`ZphHillsЄKрˆxъ`Holiday ЄKрŽTъ`K4TN BrnEЄKр”0ъ`џџџџџџџџEЄKрš ъ`џџџџџџџџЄKрŸшъ`Clrwtr ЄKрЅФъ`Ruskin ЄKрЋ ъ`Tampa ЄKрН4ъ`StPete EЄK рУъ`џџџџџџџџЄKрШьъ`StPete ЄKрдЄъ`RayJay ЄKрк€ъ`StPete ЄKрр\ъ`N4KEG LkЄKрїЬъ`W4TCH? AN“UЁ CH-095 ЅNЂ+фъ`StPete ЅNЂ\Иъ`StPete ЅNЂŒъ`Clwtr ЅN ЂЊиъ`Clwtr ЅNЂДœъ`Dunedin ЅNЂбшъ`Gbsntn ЅNЂхpЁ K4TAP SaЅNЂјјЁ W4BNC DnЅNЃ €ъ`Clwtr ЅNЃ ъ`SunCty ЅNЃ3ъ`StPete ЅNЃ=Tъ`Tampa ЅN ЃGЁ RvrVw ЅNЃZ ъ`NPR ЅN ЃddЁ W4ORM SPЅN Ѓn(Ё Port RchЅNЃ•8ъ`Tampa ЅN ЃВ„Ё NI4CE PDЅN Ѓй”ъ`Hudson ЅN ЃуXЁ NI4CE VeЅN Ѓэъ`KAGAK ELЅNЄЄЁ N4TP E.LЅN Є hъ`Clrwtr ЅNЄ1xъ`Valrico ЅN ЄEЁ K4LX BrdЅNЄXˆъ`Ruskin EЅN ЄlЁ џџџџџџџџЅNЄ˜ъ`BearsTpaЅNЄ‰\ъ`Clwtr ЅNЄ“ ъ`?? ЅNЄœфЁ W4TCH ЅN ЄІЈЁ NI4CE SPЅN ЄАlЁ KA4GAK ЅN ЄК0Ё K4TN BraЅNЄЭИЁ Sara EL ЅNЄєШъ`Dade CtyЅNЄўŒЁ N4TCP TpЅN Ѕ%œЁ Tampa ЅNЅBшЁ W4BNC SPЅNЅ`4ъ`StPete ЅNЅiјъ`Prt RchyЅNЅsМъ`Holiday ЅNЅ}€Ё BEARS1 ЅN Ѕ‘ъ`StPete ЅNЅЄъ`PrtRichyЅNЅЎTъ`Clrwtr ЅN ЅИъ`Dunedin ЅNЅСмъ`StPete ЅN Ѕеdъ`StPete ЅNЅп(Ё N4DAV LzЅN Іќъ`ZphrhllsЅN ІРЁ RvrVw ЅNІ-Hъ`TrpnSpgsЅNІ7 Ё SpSPARC ЅNІ@аЁ Largo ЅN ІJ”ъ`Tampa ЅNІ^ъ`Largo ЅNІgрЁ Mur EL ЅNІ{hъ`PrtRchy ЅN І…,Ё BRS TPA3ЅNІŽ№ъ`StPete ЅNІ˜ДЁ RIX SP ЅNІЌ<Ё N4KEG LaЅNІгLЁ BRA EL ЅNІнЁ W4HSO tpЅNІ№˜Ё Bart EL ENЈŠРЁ CH-067 ENСаzЁ CH-150 ENСк>Ё CH-151 ENСфЁ CH-152 ENСэЦЁ CH-153 ENСїŠЁ CH-154 ENТNЁ CH-155 ENТ Ё CH-156 ENЩqšЁ CH-157 ENЩ{^Ё CH-158 ENЩ…"Ё CH-159 ENЩŽцЁ CH-160 EN٘ЊЁ CH-161 ENЩЂnЁ CH-162 ENЩЌ2Ё CH-163 EKяBъ`N9EE EKяЃЈъ`N9EE EKяЪИъ`N9EE EKяЗ0ъ`N9EE EЄKрk,ъ`џџџџџџџџEЄKрš ъ`џџџџџџџџEЄ€K рУъ`џџџџџџџџEd€K ръ`џџџџџџџџEdK рB(ъ`џџџџџџџџEЄKр|Ръ`џџџџџџџџEЄKрˆxъ`џџџџџџџџEdKнЙИъ`џџџџџџџџEdKр0”ъ`џџџџџџџџEЄKрvфъ`џџџџџџџџEЄKр”0ъ`џџџџџџџџEdKнk˜ъ`џџџџџџџџEdKнш˜ъ`џџџџџџџџEЄKрŸшъ`џџџџџџџџEdKр$мъ`џџџџџџџџEdKрHъ`џџџџџџџџEdK нЊъ`џџџџџџџџEЄ€KрШьъ`џџџџџџџџEЅN ЄlЁ џџџџџџџџEЅNЄ1xЁ џџџџџџџџEЅNІнЁ џџџџџџџџEЅN Ѓ3Ё џџџџџџџџEЅNЄЄЁ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџaHтŽ'џџџџџџџџ" $$$$$&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$&$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$}T›@ы}T H Њ'CH-109 aH"а'џџџџџџџџaH)'џџџџџџџџaH0р'џџџџџџџџaH2д'џџџџџџџџaH?T'џџџџџџџџchirp-20240224/tests/images/Ruyage_UV58Plus.img0000644000175000017500000012031114430171343020026 0ustar hibbyhibbyWelcome UV5118Plus uABˆ@  4@Пџџџџџџџџџџџџџџџџџџџџџ,Œ0,Œ0 џџџџ----------Ь’0Ь’0 џџџџ----------l™“0l™“0 џџџџ---------- •0 •0 џџџџ----------ЌІ–0ЌІ–0 џџџџ----------L-˜0L-˜0 џџџџ----------ьГ™0ьГ™0 џџџџ----------Œ:›0Œ:›0 џџџџ----------,Сœ0,Сœ0 џџџџ----------ЬGž0ЬGž0 џџџџ----------l%м0l%м0 џџџџ---------- Ќн0 Ќн0 џџџџ----------џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ 00 џџџ----------`”Е0`”Е0$џџџ----------@012345џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSdXlhZ2VVVjU4UGx1c1JhZGlvIiwgInZlbmRvciI6ICJSdXlhZ2UiLCAibW9kZWwiOiAiVVY1OFBsdXMiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMwMjE5In0=chirp-20240224/tests/images/Polmar_DB-50M.img0000644000175000017500000010000014411666130017270 0ustar hibbyhibbyЅЅ{ŠW5% ФЊ;A]izЦ“R7{’Т—Ÿ EURONфDB-50M226569212013-5-18џџџџџџџџџџџџџџџџџџџџџџџџџˆˆˆˆˆˆˆˆјџџ""" "№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™  d  3#E$de*de* њ‘ A$H:3 d ‘$AyOжF2Kd 2FFўџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџ Fжt"D%P(Ђ+:/3F7Ю;К@ОKЌXєQњ_F PC5EцEPч5` ч€&% ч3P` чEP` ч3P` чEP` ч5` ч€&% ч3P` чEP` ч3P` чч чPчч6ччч чPчч6ччI†‘ A$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$F5ю EPCALL 2MчEQ%чERPчESuчEUчEV%чEHuчEGPчEF%чEEч3PCall 70ч3Q%ч3RPч3Suч3Uч3V%ч3Huч3GPч3F%ч3Eчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!P` AIR EMGч ‡P` DISCEMGч"5` BALLON1ч"`` BALLON2ч"GP` ZWEEF 1ч"P` ZWEEF 2ч#5` ZWEEF 3ч#7P` ZWEEF 4ч#P` ZWEEF 5ч)—P` ZWEEF 6ч0P` ZWEEF 7ч"€` PARA 1 ч#BP` ULV 1 ч#@` INT AA1ч#E` INT AA2ч#GP` INT AA3ч& ` VOLMET ч!P`AIR EMGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFb PMR 1 чF‡ PMR 2 чF PMR 3 чF7 PMR 4 чFb PMR 5 чF‡ PMR 6 чF PMR 7 чF 7 PMR 8 чџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0'P` PI2NON*чEp`QPI3HVN ч0P`QPI2HVN чEcu`PI3FRL ч0`PI2FRL чErP`PI3WAD чEwP`PI3ALW ч0%PI2ALW чEu`PI3GRN ч0#u`PI2GRO чEa%`PI3APM ч02P`PI2DZL ч0`PI2WSN чEe`PI3MEP ч0P`PI2MEP ч0`PI2ASN чEbP`PI3ZOD чEsu`PI3FLD ч0(u`PI2FLD чEhu`QPI3VHP ч0P`PI2KMP ч06%`PI2DEV чEgP`PI3NOV ч0&%`PI2NOV чErP`PI3APD ч0`PI2APD ч0`PI2ANH ч0!%`PI2TWR чEu`PI3NYM ч01%`PI2NMG чEhu`PI3DTC чE``PI3TWE#ч0"P`PI2TWE ч0%`PI2NYM ч0%WPPI2YSS чEcu`PI3ZUT ч0%`PI2JUT ч0u`PI2APD чEWP`PI3UTR*ч0P`PI2ZST чE``PI3ALK ч07P` PI2ALK чEwP` PI3ASD ч0 ` PI2ASD ч0P` PI2YDN ч0%` PI2RGK ч0&%` PI2RDH чEcu` PI3HWD ч0"P` PI2HWD ч0P` PI2NOS чEq%` PI3ZAZ ч02P` PI2ZAZ чEf%` PI3ZDM ч05` PI2HGL ч0u` PI2DFT чEgP` PI3RTD ч00` PI2RTD чEu` PI3RAZ ч06%` PI2DEC ч0&%` PI2SWK ч0u` PI2RWL чEhu` PI3BOZ ч0!%` PI2BOZ ч0(u`PI2KAR чEe`PI3BRD ч02P`PI2BRD ч0#u`PI2SHB чEp`PI3EHV ч0`PI2EHV ч0%`PI2NEN ч07P`PI2OSS чErP` PI3GOE чExu` PI3VLI ч03u` PI2GRP ч0P` PI2VLI чE`` PI3ZVL чErP`PI3ZLB ч0 `PI2NLB ч0P`PI2MST ч06%`PI2RMD чDdPdPPI6RAH чE``PI3SRT ч05`PI2VNR чџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџEWP`PI3xxx чExu`PI3xxx ч0%`PI2xxx ч07P`PI2xxx ч8e`DL0xxx ч9BP`DL0xxx ч3`M0xxx ч37P`M0xxx ч€&%C2000L ч„˜uC2000L чchirp-20240224/tests/images/Baofeng_BF-T1.img0000644000175000017500000000400014411666130017327 0ustar hibbyhibbyp@џџџџџP2EP‚џџџџџu3EuƒџџџџџP7F P7UџџџџџPFPUџџџџџPUFPџџџџџ%F%UџџџџџPb8EPbˆџџџџџuFugџџџџџ€@џџџџџP0EP€џџџџџP7EP‡џџџџџP1EPџџџџџP1EPџџџџџ%8E%ˆџџџџџPb8EPbˆџџџџџ@џџџџџ@џџџџџ@џџџџџ @џџџџџ0@џџџџџ`@@Gџџџџџџџџџџсџ`Bџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ??????????????  ????????????????????џџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџ  .џџџџџџџџџџџџџџџџџџџџџџџ16.06.08 BF9100S§џџ§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Retevis_RB628B.img0000644000175000017500000000126514411666130017515 0ustar hibbyhibby%`D%`D||u`Du`D||%1`D%1`D||NuC`DuC`D||%V`D%V`D||uh`Duh`D||%`D%`D|| u“`Du“`D||%aD%aD((uaDuaD((%1aD%1aD((uCaDuCaD((%VaD%VaD((uhaDuhaD((%aD%aD((u“aDu“aD((џ&D&D %&D%&D P&DP&D u&Du&D 'D'D %'D%'D џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSQjYyOEJSYWRpbyIsICJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjYyOEIiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Yaesu_FT-1D_R.img0000644000175000017500000037671314411666130017366 0ustar hibbyhibbyAH44Mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Uuџџџџџџџџџџџџџџџџ џџџџ €џџџџџџџџџџџџџџџџ ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџ Cvџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ% ЈBЈџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒџџџџџУџџџџџџJƒџџџџџУџџџџџџJџџџџ @џџџџџџџџџџџџџџџџ p@@€ `џџџџ @џџџџџџџџџџџџџџџџ p@@€ ` џџџџ Cvџџџџџџџџџџџџџџџџ BGC€ f џџџџ Cvџџџџџџџџџџџџџџџџ BGC€ fУџџџџџџ €џџџџџџџџџџџџџџџџ ˜€€€ ЗУџџџџџџ €џџџџџџџџџџџџџџџџ ˜€€€ Зџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ  џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ J@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ Рџџџџџџџџџџџџџџџџ ‰€Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ CРџџџџџџџџџџџџџџџџv GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ  J@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ Рџџџџџџџџџџџџџџџџ ‰€Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ CРџџџџџџџџџџџџџџџџv GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ  J@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ Рџџџџџџџџџџџџџџџџ ‰€Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ CРџџџџџџџџџџџџџџџџv GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@Рџџџџџџџџџџџџџџџџ C2bР $ $џџџџџџџџWС$ џџџџџџџџџџџ TРџџџџџџџџџџTPРџџџџџџџџџџVР$џџџџџџџџџџџVР$џџџџџџџџџџџVС џџџџџџџџџџџџџV%Р$џџџџџџџџџџџV7С џџџџџџџџџџџџџ VPС$џџџџџџџџџџџVbР џџџџџџџџџџџџџVuС$џџџџџџџџџџџ V‡С $ џџџџџџџџџџWСџџџџџџџџџџџџџџWС џџџџџџџџџџџџџW%С$џџџџџџџџџџџ W7С $џџџџџџџџџџWPС$џџџџџџџџџџџWbС $ џџџџџџџџџџWuС$џџџџџџџџџџџ W‡Р $џџџџџџџџџџUuС$ џџџџџџџџџ C2bР $ џџџџџџџџџC2bР $ џџџџџџџџџ CТ$ џџџџџџџџџџ  C%Р џџџџџџџџџ C$PСџџџџџџџџџџџџ1P C$PСџџџџџџџџџџџџ1PC4PРџџџџџџџџџџC‡‡С џџџџџџџџџџvC‡‡С џџџџџџџџџџv CС џџџџџџџџџџ CС џџџџџџџџџџ C%С$џџџџџџџџџџ C7С џџџџџџџџџџ CPС$џџџџџџџџџџ  CbС џџџџџџџџџџ CuС$џџџџџџџџџџ  C‡С џџџџџџџџџџ CС$ џџџџџџџџџџ  CС џџџџџџџџџџ C%С$џџџџџџџџџџ C7Р џџџџџџџџџџџџ CPС$џџџџџџџџџџ CbС џџџџџџџџџџ  CuСџџџџџџџџџџџџџ C‡С џџџџџџџџџџ CС$ џџџџџџџџџџ CС џџџџџџџџџџ C%С $ џџџџџџџџџџ C7С џџџџџџџџџџџџ CPРџџџџџџџџџџ CbС џџџџџџџџџџџ CuС џџџџџџџџџџ C‡С џџџџџџџџџџџ CСџџџџџџџџџџџџ CС џџџџџџџџџџџ C%Сџџџџџџџџџџџџ C7С џџџџџџџџџџџ  CPСџџџџџџџџџџџџ CbС џџџџџџџџџџ CuРџџџџџџџџџџџџ C‡С џџџџџџџџџџџ C%С џџџџџџџџџџ C7Р џџџџџџџџџџџ CPСџџџџџџџџџџ CuС џџџџџџџџџџ C‡С џџџџџџџџџџџ CС џџџџџџџџџџџџ CС џџџџџџџџџџџ C%С џџџџџџџџџџ C7С џџџџџџџџџџџ CPСџџџџџџџџџџџџ CbР џџџџџџџџџџџ CuСџџџџџџџџџџџџ C‡С џџџџџџџџџџџ CСџџџџџџџџџџџ CС џџџџџџџџџџџ C%С #џџџџџџџџџџ C7Р џџџџџџџџџџџ CPСџџџџџџџџџџџџ CbС џџџџџџџџџџџ CuСџџџџџџџџџџџџ C‡Р џџџџџџџџџџџ C%Сџџџџџџџџџџџџ CPС џџџџџџџџџџџџ CuСџџџџџџџџџџџџCPРџџџџџџџџџџџџCbС џџџџџџџџџџџCuСџџџџџџџџџџ CР џџџџџџџџџџC%СџџџџџџџџџџџџCPСџџџџџџџџџџџџC‡С џџџџџџџџџџџ  CbС џџџџџџџџџџџџ CbС џџџџџџџџџџџџC‡С џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC3ЧџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ JРџџџџџџџџџџџџџџџџ ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФџџџџџџ?РYYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******CQ*******QST******YAESU****џџџџџџџџџBLN******BLN*џџџџџBLN*џџџџџFxx  xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:A? џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ******џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџI џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<SuC4Pџџџџџq{џ0AZazi9**џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTU3X41 `9A3DSL- 9ђIR3AH -11vIR3DP р№')IBn?/>/]"3m}  Ј3  TS R0/GO RU16/UD-PN R5/Dstar = qD KU2k žIџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRSW `IR3DP `IR3UCP-11vWIDE1 с№;IR3G *145725z4544.84N/01144.63Er R5 Echolink 507445 œСџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN383 `IQ4SC -11vIR3DP рџџDE2 с№!4435.88N/01041.40E#PHG31802/WIDE1-1 DIGI - iq4sc@amsat.org AriScandiano cџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBEACON `IR3UCP-11vIR3EG -11іџџ3EG -11ї№;IQ3VI *291758z4532.42N\01131.59EaARI-VI aperto merc. 21-23pUџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN383 `IQ4SC -11vIR3DP рџџDE2 с№;IR4UBC *181304z4433.01N/01044.99EmRU15 430.375 +1600 TSQ77 AriScandiano ымџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT5RR29 IK30RE- 6lIR3DM -11їџџDE2 с№`&Rznz`>/op.–E042z4546.0 NE01212.5 E&No Tide info in last hourso232N} џ eo Mezzomonte 630 Mt.slm - {UIV32} ЧЪџџџџџџџџџџџџџџџџџџџџџџџџAPT311 `IZ3LCJ- 4hWIDE2 `IR3UCP-11і№!4548.12N/01217.49E-255/000/A=000213GџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTU2SR2 `IW2HJO рIR2BZ `WIDE2 с№'al -/]= М1.10E# Gruppo APRS G.R.P. QRV 145.200 MHz%№Padova"ђLWTеoџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPU16N рIK3ZGB `IR3UCP-11vWIDE2 с№@291042z4542.75N/01142.00E_.../...g...t042r...b10254h54Home made solar powered wx station {UIV23} e˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPNU19 рIR2AO `IR3DP `WIDE2 с№!4531.69NR00919.89E#PHG3230 Fill-in digi ARI Cernusco - SysOp: IK2CHZМеssisi@gmail.comYrџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBEACON `IR3UCP-11vIR3EG -11іџџDE2 с№@290944z4529.83N/01132.07E# Ari Vicenza Echolink Ru3 nodo nА677889L;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRSVV рIR3CA aџџ3DP рџџDE2 с№!4600.64N/01222.30E# JN66EA APRS www.arivv.itЉ›l, Quake & Tide serviceеJ R_џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPQSVW `IK3SVW `TCPIP `IZ3LSV- 4щ№;SISMA2-28*280608z4016.80N\01559.58EQMontemurro(Potenza) ML=3.22 Prof=16.5Km 06:08z”юџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI01- 2dIK3PQG-11vIR3DM -11їџџDE2 с№@290941z4530.76N/01119.40E_121/001g002t042r000p000P000h33b10217Wx3in1 WeatherQ’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRS `IR5UCJ рIR2CV рџџDE2 с№!4345.11N/01033.17Er RU31a Monte Serra 950Mt IW5ECI Щђtp://www.9radio.it ”t—PџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRS рIQ4BQ `IR3DP `WIDE2 с№!4429.12N\01117.25EaSezione ARI Bologna?и2r000p000P000h16b08656www.meteobrentonico.euЃHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPU25N рIK2CHZ- 3fIR3DP `WIDE3 с№>290931zDX: IW4BNT 44.22.73N 11.00.29E 151,2km 136ј 10:28 >Ж џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI01 `IZ4UFQ-10tIR3DP `WIDE2 с№!4429.15N/01120.92E#PHG2350/Digi and IGate in Bologna Italyж%43/STAZIONE LA CROSSE {UIV32N} аtџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI04 `IR4AZ `WIDE2 aџџDE2 с№!4451.66N/01139.02E#PHG3360/Nodo APRS e iGate di Ferrara--SysOp IZ4WNA˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPU25N рIZ4EKD `IR3DP рџџDE2 с№=4439.45N/01035.48E-op.giuliano ari scandiano qrv RU 15 {UIV32N} Rmeteo-bologna.it +џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRSW `IZ3KFA `IR3DP рџџ3LSV- 4щ№=4540.02N/01146.37E#PHG50304/IZ3KFA Op. Emanuele m§msat.org AriScandiano ќ›џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI01 `IR3EG -11vWIDE2 - 1cџџDE2 с№@290937z4544.85N/01129.48E# ARI THIENE aprs@arithiene.it@žC JN65VP ( diano (7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTU3R28 `IZ2BVC- 9ђIR3UCP-11vWIDE1 р№`':}l"oj/`"4>}_" 8llo ma non mollo_" эч Op.Alberto QTH Ferrara Loc JN54TT *Test Tx*, Antenna Diamond X200 - TxPwr 10W* lasciate4nџџџџAPRSW `IR3DP `WIDE1 сџџ3UCP-11ї№;IQ3CW *145725z4546.79N\01144.75EaARI Bassano - Apre Ven.H21-23 сWo,Nosedole MN iz2nai@alice.it {UIV32N} ЎБџџџџџџџџџџџџџџџџџџџџџџџџAPQSVW `IK3SVW `TCPIP `IZ3LSV- 4щ№;SISMA1-27*271507z3844.88N\01541.16EQTropea(Costa Calabra sud) ML=3.37 15:07z€r 2000mtYнm. slm + SETI@home {UIV32N} ]GџџџџџџџџџџџџџџџџAPU25N рIZ2SQG `IW2HUZ-11vWIDE3 с№=4516.58N/00925.59E-Cristiano -Borgo San Giovanni (LO) {UIV32N} ™Xz3lsv.netegna.it ™џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPTW01 `IZ3HDT- 4hIR3CA `TRACE3 с№_01221043c232s005g006t044r000p000P000h..b.....tU2k$\H==>10450 H AriScandiano ёHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRS `IR3DJ рIR3DP `WIDE2 с№!4526.44N/01219.79E# - APRS VENEZIAёjџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT6PS68 `IW3BTI- 9ђWIDE1 `WIDE2 с№`'*3lsU>/]"9/}www.radioclubvalsugana.it ЧRtova iz2nai@alice.it‰Й(Firenze) ML=2.96 17:02zйџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI01 `S59DGO- 5jWIDE1 aџџDE1 с№@290945z4535.30NT01426.84E&PHG28304/iGate SneznikŸ\ 15 {UIV32N} hhKmщ№o cџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBEACON `S59DGO- 5jIR3DP `WIDE2 с№;145.625kp*290934z4546.30N/01403.20ErToff R50kѓIZ3VEO.IT ______ Œ†z3lsv.netŸWџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPNU19- 3цIK3SVW-11vWIDE2 сџџDE2 с№>UIDIGI 1.9b3 W4,ITn (3)ъу5N 8.55.63E 412,3 miles 184ј 11:22 Їг.org ХA˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPU16N рIW4BNT aџџ3DP `џџDE2 с№>291117z- - Montombraro (MO) 710 mt Slm - BUONE FESTE A TUTTI —n23 ™ьџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI01 `IR3EG -11vWIDE2 сџџDE2 с№;IQ3BM *290939z4542.21N\01128.89EaARI THIENE aperto Mar 21-23KЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPIC24 `IZ4IRL `IR3DP рџџDE2 с№=4449.30N/01139.21E-17.9V 22.6C 1024.6mB Op.Alberto QTH Ferrara Loc JN54TT *Test Tx*, Antenna Diamond X200 - TxPwr 10W* lasciate{џџџџTURR20 `IZ3GME- 7юWIDE1 `џџDE1 р№`'P-l [/`_$ ѕ04z4429.34N\01117.35EL В­41r000p000P000h99b10270WX RIMINI 65m Slm {UIV32} $ЇџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT5RS44 `IZ3CFY рIR3CA `IR3DP р№''L=l r/>op\SAURO"SELVAZZANO шq0g000t047r000p000P000h90b10177 meteo Montelupo F.no ( FI ) {UIV32N} KШџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPU25N рIW4EGP `IR3DP `WIDE3 с№=4402.74N/01230.70E-OP PAOLO QTH RIMINI {UIV32} нэP000b10280h84> Reggio Emilia (ITA) 58 m. slm + SETI@home {UIV32N} ™JџџџџџџџџџџџџџџџџAPMI06 `IZ2GIU-10tIW2HUZ-11vWIDE2 с№>Igate , Lonate Pozzoloђ_3ano {UIV32N} qђcholink 507445 œСџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPJI23 `IK2CHZ-11vIW2HUZ-11vWIDE3 с№!4521.86NJ00941.08E&javAPRSIgate TCP<=>RF ik2chz.no-ip.biz:10152 www.qrz.com/db/ik2chz0_џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRS рIR4X -11vIR3DP `WIDE2 с№!4425.89N\01116.06E#Sezione ARI BolognaМ29A2CD 2™j H==>10450 H AriScandiano zЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPOT21 рIR3BF рWIDE - 3gџџDE2 с№!4603.10N/01217.00E#13.6V 2C Wу- 6khz ARI Reggio E. {UIV32N} ‚ъrtlycloudy/ Davis VP2 - HF, 144.8, 432.5, TCP {UIV32N} $ХџџџџџџџџџџџџAPNW01 `IR3AS `IR3DP `WIDE2 с№@291154z4603.03N/01120.08E#Radioclub Valsugana sysop IN3XSV~ teo Cima Panarotta 2000mtЌЎ30 Mt.slm - {UIV32} г!џџџџџџџџџџџџџџџџџџџџџџџџAPU25N рIK4RVG-11vIR4AZ `WIDE2 с№=4444.41N/01213.29E#IL DIGI DEI LIDI FERRARESI JN64CR |} 1ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPOT21 рIR2BT рIR2CV рџџ3DP р№!4537.19N/01027.26E#12.7V PHG28302/W3 - A.R.їМV.d.G./ik2bcp@hamlan.orgќGetЅUIV32} jІџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT5TS15 `IW3HHN-12xIR3UCP-11vWIDE2 с№`'8YlgFj/'"5d}!wf[!|3}24E_197/000g000t033r001p037P001h51b10253jDavis Pro2 Plus - http://meteo.iw2gob.it6yџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPU25N рIZ4SJB- 3fIR4X -11vWIDE2 с№@290937z4429.79N/01117.46E_213/005g007t036r000p008P000h79b10253www.meteo-bologna.it ˜ FI ) {UIV32N} K<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPEWX `IK3SVW- 3fWIDE1 рџџDE2 с№!4540.62N/01212.52E_083/002g004t037r000b10240h44v+02 Prev.SerenoЂЌџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPZ18 рIR3DM -11vAPRS `џџDE2 с№!4511.54N/01216.57E#/GRUPPO APRS ARI CHIOGGIA - SOTTOMARINA - VENEZIA 6DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPZ18 рIQ3PY -11vAPRS `џџDE2 с№!4519.06N/01201.10E# IQ3PY APRS - Gruppo Radio Piovese - Padova"ђteo Montelupo F.no ( FI ) {UIV32N} sшџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT5RX14 `IZ3LBC- 9ђIR2DD `WIDE2 с№`&O-l!7`/>"5/}TH D72 GABRY_ARI-RE VERONA_EST 145.500= xРa) ML=3.63 Prof=8.5Km 15:51zЪXџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTU4ZLL `IZ3KLB рIR3UCP-11vWIDE1 р№`'GYmqK>/]"5&}= YЩ4432.69N/01042.98EVATV RPT in1240 H==>10450 H AriScandiano `ў(ITA) 58 m. slm + SETI@home {UIV32N} гLџџџџџџџџџџџџџџџџBEACON `IR3UDX `IR3DP `WIDE2 с№@290936z4546.24N/01058.16E# WWW.IR3UDX.EU’*000p000P000h34b08597www.meteobrentonico.euЊ–џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI01 `IR2CV `IR3DP `WIDE3 с№@290943z4505.21N/01046.24EISezione ARI Mantova iz2nai@alice.itБзsop IZ4ISN 73 de Marco**rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRSW `IR3DP `WIDE3 - 3gџџDE2 с№=4547.25N/01140.00E#PHG3850/ ARI Bassano del Grappa Wh86b10234/STAZIONE LA CROSSE {UIV32N} žБџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTT3Q91 `IZ4FTD- 9ђIR3DP рџџDE3 с№'&Pho?1>/]"54} ІK01426.84E&PHG28304/iGate Sneznik7RONA EST Lџ3)<–џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTU2QT8 `IK2PYX- 9ђIR2BZ `WIDE2 с№`-~#U0>/]"4l}=  E# APRSDIGI-Hohenwart 1818m NN Beacon2=РIV32N} їџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBEACON `S59DGO- 5jIR3DP `WIDE2 с№;S50HQ *290944z4632.09N/01535.04E-ZRS HQ•Ÿ- Go IV3CTT@Gmail.comм‚,Nosedole MN iz2nai@alice.it {UIV32N} оРџџџџџџџџџџџџџџџџџџџџџџџџAPU25N рIZ5OQO- 2dWIDE3 aџџ№=4321.29N/01124.91EIWIFISIENA.IT,TCP-IP,VOIP,TS3,WIFI 5,7Ghz {UIV32N} §ћSN 73 de Marco**—ю) {UIV32N} T&џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT5TQ56 IR3AH -11IR3DP рџџACE3 с№`)Hy #/CISAR Trieste APRS Digi M. GrisaМя Sez. VERONA EST д‘1-23 ™ь.it ”tџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIZ3GMETestџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШџдchirp-20240224/tests/images/Wouxun_KG-UV8D.img0000644000175000017500000010000014411666130017544 0ustar hibbyhibbyџџџџџџџџџџџџџџџџžЈџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџbZмkbZмkЭў` fЭў` fџџџџџџџџџџџџџџџџџџџџџџџџџџџOID@<99765757564ZZ[[\\]]^^__`abZЭў`ЙўЙўџџџџџџџџџџџџџџџџџџцхсссмзззззвзззв•ŽŒŒŠŠŠŠˆˆ‡‡„„~znniidddd__ZZZZUPbZџџџџџџџџџџџD ->X D>X X џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџMIDA?<;:9::99998XXYYZZ\\\\]^_`bZЭў`ЙўЙўџџџџџџџџџџџџџџџџџџШШШШШШУОЙДЏЊЊЊtsppppnnllligdb`^]]^^____^]Эў`џџџџџџџџD -<X D>X X чџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKGUV8DSVSain SonicSain Sonic01000001UV8DV1.05џџџџџџ20140924џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџcdЧШ+,ѓєWXЛМ ƒ„чџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ000000000000№№џџџџџџјџџџџџџџџџџџџџџџџџџџџџџŸЁ€ђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџлє˜ђ™џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸ˜Ÿ˜1ЇeШЇeШђљџЏ-јЏ-јђљџку(ку(ђљџмимиђљџо>ˆо>ˆђљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџžžžžžžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Yaesu_VX-2.img0000644000175000017500000007752314411666130017023 0ustar hibbyhibbyAH015$№$№џџџџ @џџџџџџ џџџџŒ @џџџџџџ џџџџŒЌ€ŠI@ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA@Рџџџџџџ @Рџџџџџџ @Рџџџџџџ †Рџџџџџџ †@Рџџџџџџ E€Рџџџџџџ e Рџџџџџџ †@Рџџџџџџ #Рџџџџџџ D`РџџџџџџP †GРџџџџџџ †Рџџџџџџ џџџџџџџџџџџџџџџџџџ q С$$$$$$RС$$$$$$џџA@Рџџџџџџ @Рџџџџџџ @Рџџџџџџ †Рџџџџџџ †@Рџџџџџџ E€Рџџџџџџ @Рџџџџџџ †@Рџџџџџџ #Рџџџџџџ CРџџџџџџP †GРџџџџџџ †Рџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ3333333333333333333333333333333333333333333333@Рџџџџџџ 0%PР !$$$P 0$Р !$$$P 0$uР !$$$P 0$%Р !$$$P 0$PР !$$$P 0%Р !$$$P 0%%Р !$$$P q€С$$$$$$%D%Т$$$$$$P 0%Сœ 7P %D&P$$$$$$PRС$$$$$$%D@P$$$$$$P%DHP$$$$$$PRТ$$$$$$ s$$$$$$%DB%$$$$$$P q С$$$$$$ DB%$$$$$$PqР– $ %DDР$$$$$$P q%Р– $ quР– $ 0%PР !$$$P 0$Р !$$$P 0$uР !$$$P 0$%Р !$$$P 0$PР !$$$P 0%Р !$$$P 0%%Р !$$$P T0џџџџџџ %D@uТџџџџџџP DYPџџџџџџP eD(џџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%Т$$$$$$P џџџџџџџџџџџџџџџџџџ%D&P$$$$$$PRС$$$$$$%D@P$$$$$$P%DHP$$$$$$PRС$$$$$$ s$$$$$$%DB%$$$$$$P q С$$$$$$ DB%$$$$$$Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%DDР$$$$$$P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0F%b$$P0F%‡$$P0F&$$P0F&7$$P0F&b$$P0F&‡$$P0F'$$P0Fub$$P0Fu‡ $$P0Fv$P0Fv7$P0Fvb$P0Fv‡$P0Fw$P0F%PР$P0F%uР$P0F&Р$P0F&%Р$P0F&PР$P0F&uР$P0F'Р$P0F'%Р$PџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџQpС $R`С” $ i С $ sС—$ s€С”$џџџџџџџџџџџџџџџџџџ"8`Р    D%С $P DPР” $$P D'%С—$P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ D5%С  P D5PС   P D@PС $P DCPР  "P DEС”$P DHPС—$P’tУ—$$PE’vС $P’xuС—$P  D5%С  Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ00Р—"$0PР” !3PС  "6Р—$RPС   SPС—$$ g@С  $ q€С   "8 С  $"D@Р—$"I`Р” $$ DС—$P! DPС” #P  DР” $$P"D@Р—$ DРŠ  $P D%С—$$P  DuС $P D PР—$P D#PС”$P  D%PР    P D%uС—$$P D2С  $P  D6PРŠ!$P DAuР $P DBPС”$Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%С  $1Р  $60Р   џџџџџџџџџџџџџџџџџџQ0Р  $џџџџџџџџџџџџџџџџџџQС”  RС—$RPС”  RPС—$RPСŠ !$SС $$T0С” $$TPР—  $fС”#"#$f@С” $f`С” $gС  $g С   h Р—$h€С  $$i`С” $$ p@С”   p`С  $$ q Р” $ r@Р” $ r`Р  $ s С”$ s С”$џџџџџџџџџџџџџџџџџџ sСŠ $$"AРŠ!$"A€С” $"C`Р”  "DС   "D€С”$"EР  "$"FР—$"GС—$"H€С  $$ DР” $$P DРŠ !$Pџџџџџџџџџџџџџџџџџџ DР”$P D7Р  $P D%С” #P DPС” P DPС$$$$$$P DPС”$P DС”  P D%Р”$$P DuС” #P  DС”  P D%Р” $P D%С  $P DPС” #P DPС” #Pџџџџџџџџџџџџџџџџџџ D %С—$P D uС— $P D"uС—# $$P D#%Р”$$P D#uС   P D$С  "$P D$%С  $$P D$PС "$$P D$uР $$P D"uС—# $$P D%С  $P D%%С—$P D&%СŠ !$P D&PС—$P D&uС   P D'С” $P D(С $$P D0Р— $$P D0%Р— $$Pџџџџџџџџџџџџџџџџџџ D3%С—$P D3PС  P D3uС—  $P D4%Р—$P D4uР”$P D5РŠ!$P D7%Р  $P D8%С”!$$P  D9PРŠ!$P D9uС—$$P D@%С !$$P D@uС”$P DAPС—$P  DB%С $$P DD%С” P DDPС” $$P DEР  "$P DFPС—$P# DFPР  $$P DFuС— $$P DHСŠ$P DHuС”$P DI%С”$P DIPР” "$P’p7С”  !P’pbУ—$PE’quС—$Pџџџџџџџџџџџџџџџџџџ’quС—$P’quС—$Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ D%С  $Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ–`С   $(&PР $1PС”!$QС” $S0С $SpС”$SР   TС— $f€С $g`Р” $hС $h@С $$h`С   i@С” $ pС”  qС  $ q@С” $ rР”   r€С #$ s С”$u@С”"8С” $$"8@С $$"9@Р $"A@Р” "B€Р—$"CР   "C Р   $"D С #$"D`Р” ! "E РŠ $"E`С  "F€С   $ "G С—"$"G@С $"G€С—$$"HС” $"H`РŠ ! $"IС  "I@С” $ B9uС—$$B‰uџџџџџџџџџџџџџџџџџџ D%С— $$P DР " $$P D%Р” Pџџџџџџџџџџџџџџџџџџ DPР—$$P DuС” #"P D%СŠ ! $P D%Р”!$P DuР” $P DPС”$P  DPС— $P DС $$P DuР $$P DuС—$P D!%С” P D!uР—#$$P D"С #$P D"%Р”$P D#Р” "P D%bС—!$P D'PС—$P D'uС— $P D(%С— $P D(PС”$P D)С $P D)PС—#$P D)uС— $$P D)uР— $$P D0PС   P D0uС—$P D1PС— $P D1uС—$$P  D2%Р” P D3С— $P D4С   P D4PС—$P D5uС   P D6С $P D6uРŠ!$P D8PС  P D8uС— $P D9%Р”!$P D9uС—$$P D9uС—$$P DAС” $P DBС” $P  DCС”$P DC%С” $$P DCuС—$$P DDuР—$P DE%Р  P DEPР  $P DEuС " $$P DFР— $P DF%Р $P DGС— $P DIС $P’pС   Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџG  UџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџОchirp-20240224/tests/images/Feidaxin_FD-268A.img0000644000175000017500000000400014551723752017664 0ustar hibbyhibbyџюFџџџџџџџџџџџџџ e eџџџџњџџџ€e€eџџџџњџџџPQPEџџH њџџџSGџџ0њџџџ0S0Gџџ5њџџџPSPGџџњџџџTHџџњџџџ@f@`џџњџџџ`f``џџ0њџџџ@g@aџџњџџџ`g`aџџњџџџhbџџ0њџџџ h€bџџ%њџџџ@h@bџџњџџџicџџsњџџџ i cџџ…њџџџ`i`cџџDњџџџ`i`cџџsњџџџ€i€cџџ0њџџџ@p@vџџњџџџqwџџњџџџ q wџџњџџџ`r`xџџ˜њџџџ`r`xџџњџџџ€r€xџџњџџџ€r€xџџyњџџџsyџџ0њџџџ s yџџњџџџ@s@yџџ0њџџџ€s€yџџњџџџsyџџџџњџџџ  џџџџњџџџ€€џџџџњџџџ@@џџџџњџџџFFџџџџњџџџPGPGџџџџњџџџ$џџџџџџџџњџџџ%$џџџџџџџџњџџџP$џџџџџџџџњџџџu$џџџџџџџџњџџџ%џџџџџџџџњџџџ%%џџџџџџџџњџџџP%џџџџџџџџњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP$P$9џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџЯю$џџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Abbree_AR-F5.img0000644000175000017500000001636514465123766017204 0ustar hibbyhibby%C%Cžž%f%fžž%aC%aCшш%XC%XC%‘C%‘C99%1C%1CДД%!C%!Cžž%C%Cžž%D%Dшш%rC%rCЯЯ%RC%RCVV%€C%€CЯЯ%C%C%–C%–C%6C%6CU•CU•C%dC%dC%iC%iCЯЯ%YC%YCЄЄџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%–C%–CuuџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠVVџџџџџџџџžžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJBYmJyZWVBUkY1UmFkaW8iLCAidmVuZG9yIjogIkFiYnJlZSIsICJtb2RlbCI6ICJBUi1GNSIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Retevis_RT86.img0000644000175000017500000000111514411666130017345 0ustar hibbyhibby%C%Cžž PbCPbCЄЄ %C%Cљљ PbCPbC&& % C% CUU џџPb%CPb%Cљљ %0C%0CUU Pb5CPb5C…… %@C%@CЖЖ џџPbECPbECЮЮ %PC%PCуЉуЉ PbUCPbUCкЈкЈ %VPbeCPbeCЃЈЃЈ FPbuCPbuC†)†) 282Pb…CPb…CйЉйЉ 626Pb•CPb•C2Љ2Љ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSVDg2UmFkaW8iLCAidmVuZG9yIjogIlJldGV2aXMiLCAibW9kZWwiOiAiUlQ4NiIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Icom_ID-51_Plus.img0000644000175000017500000037550014551723752017657 0ustar hibbyhibbyrx €ф2m Call ‡FtP @ @ \p €ф70cm Call ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ Zо` …фKC0DS ‡FtP @ @ qžx4афW0MTZ ‡FtP @ @ qЄx8рфW0CRA ‡FtP @ @ rŠx0€фW0DK ‡FtP @ @ rœx0€фW0DK ‡FtP @ @ rЂx$фK0DK ‡FtP @ @ rЈx0€фW0IA ‡FtP @ @ rоx0€фKI0HG ‡FtP @ @ sx0РфW0ENO ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ p€x €ф ‡FtP @ @ _ш €€ф ‡FtP @ @ p€x €ф ‡FtP @ @ s x €ф ‡FtP @ @ O№ш €€ф ‡FtP @ @ _ш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџј€№Р€Рџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Calling Ch Boulder County џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџџџ‡dЪrcЮ NWџ@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ W1AW TEST E ICALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNEcho Test Repeater Info џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ†џџџџџ №џџџџџџџџ‹__ШШ++џџњNWџџџ API51,DSTAR*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/[/b/>/-џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘нР3@ €Гя 'Р@ €9оLK@@ €‘нР3@ €Гя 'Р@ €9оLK@@ €>ЦИ CQCQCQ CQCQCQ CQCQCQ CQCQCQ џџ NEџџџџџџџ REF000ALREF000AL CQCQCQ NEџџџГя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџ9оLK@@ €CQCQCQ џџџџџџџџџџџџџџџџ>ЦџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќџџџџџџџџџџўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/BTECH_UV-50X3.img0000644000175000017500000010000014411666130017026 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"џџџџџџ`џџџџџџ€џџџџџџ@џџџџџџu™$џџџџџџ0џџџџџџ@џџџџџџHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP4џџџџџџ`џџџџџџ@џџџџџџ0џџџџџџ%Cџџџџџџu™Qџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџVGC6600MDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџА—…Фџџ!T‚657628џџџџџџџџџџ UV-50X3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџuџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џ?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<#! }mwœџ|nx™џSPdNM_3/1/.-њњNN‚‚LMdeРРРРњњџџџџџџџџџџџџџџџЇЎДЛРkoswzDGIJMвОДЌЊi_ZVU'),6[()-6\QPUKLM.01-./њњPQ‚‚PMffРРРРџџџџџџџџџџџџџџџџџ/Ki”О;DXd‚  5c7dџџџџџџ/G[О@H]g‚  3`7dџџџџџџџџџџџџџџџџџџџџџџ’NB?B;*%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP%џџџџџџ$џџџџџџu$џџџџџџ%$џџџџџџP$џџџџџџ%џџџџџџ%%џџџџџџPџџџџџџuџџџџџџu2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"`€`@0@Hџџџџџџџџџџџџџџџџџџџџџџџџ€`@%@HRџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџUSA6600A52013417chirp-20240224/tests/images/TYT_TH-UV3R-25.img0000644000175000017500000000546014551723752017215 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ\ЇŸ|HЇџџџ џ ЦЃ,gЋџџџ џЅ4ГЌџџsџ$ џа^Ё№џЈџџџ$џ ЫЅРl­џџrџ$ џœ%ЅМЦЌџџџ$&џPeрАOсџџџ$% џ,ЄLЕЋџџ"џ џ˜№ІИ‘Ўџџ"џ џxšнАмџџџ џЧпМмоџџHџ  џ`’п`’пџџ8ї џNЉNЉџџ8ї џ,єоŒопџџџ! џнІ0~Ўџџ џ"# џЬИ ьYЈџџџ џФNЄфяЋџџџ&!џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ˜h“˜h“88џ %џЈ“Ј“88џ %џ№zп№zп88џ %џ˜h“˜h“88џ %џ\MЎ\MЎ88џ %џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьRОьRОџџџџџ  џXRмXRмџџџџџ џ\bѕ\bѕџџџџџ!џјјџџџџџ џ€Эї€Эїџџџџџ џzаСzаСџџ8П  џ>кС>кСџџ8П  џфСфСџџ8П  џЦэСЦэСџџ8П  џŠїСŠїСџџ8П  џNТNТџџ8П  џ Т Тџџ8П  џšqЩšqЩџџ8П  џ^{Щ^{Щџџ8П џ"…Щ"…Щџџ8П џцŽЩцŽЩџџ8П џЊ˜ЩЊ˜Щџџ8П џnЂЩnЂЩџџ8П џ2ЌЩ2ЌЩџџ8П џ˜ЫС˜ЫСџџ8џ  џ\еС\еСџџ8џ  џ пС пСџџ8џ  џфшСфшСџџ8џ  џЈђСЈђСџџ8џ  џlќСlќСџџ8џ  џ0Т0Тџџ8џ  џєТєТџџ8џ  џ˜ЫСИlЩџџџ џ\еС|vЩџџџ џ пС@€Щџџџ џфшСŠЩџџџ џЈђСШ“Щџџџ џlќСŒЩџџџ џ0ТPЇЩџџџ џєТБЩџџџ џАЈчАЈчџџ8П" џ Рч Рчџџ8П" џзчзчџџ8П" џшкышкыџџ8џ ! џ цы цыџџ8џ ! џHЙюHЙюџџџџџ џрѓюрѓюџџџџџ џhяhяџџџџџ џ№я№яџџџџџ џBяBяџџџџџ џ€ Ѓ ­Њџџpџ$џL€Ÿl!ЇџџHџ$ џh ЄШєЄџџ8џ џŒЂЌ.Њџџ"џ#! џМsЅм­џџџ#" џ№ЄПЋHHџ$! џ8{нимџџHџ$$ џ^І<џ­џџ…џ џШƒЂш$Њџџsџ$ џдцІє‡Ўџџeџ џh™Ёˆ:ЉџџTџ$ џŒЂЌ.Њџџџ#! џdЛпбоџџgџ$! џшŸрHŠсџџџ$! џL€ŸL€ŸHHџ џа@І№с­џџџ џЖІ WЎџџ8џ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџx5й˜жрџџ$џ џџџџџџџџџџџџџџџџџџџџџx5й Ё§џџ$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўџџўџџџџџџџџџџџџџџџџР р§ђєшd” !№рџџџџџџџџџџџџџџџџPXT5RЊZblм…ЯР€ џџџџџџџџџџџџџџџџп&џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Wouxun_KG-UV8H.img0000644000175000017500000010026514430171343017563 0ustar hibbyhibbyннннннннннннннннŸЉ<ннннннннннннннннннннннннннннннннннннннннннннџbZмk€о€мkб   fлКсг† н<šнннннннннннннннн bZЯ…ннннннннннннннннннООООООООООООФФУЦ# $/8=>CORRU^bgj %*4?CBIPVbZџџџннннннннннннннннннннннннннннннннннннннннC$b^.ннннннннннннннннннннннннннннннннннннннннннннннннннннннннbZЩУ€ннннннннннннннннннннннннннннннннннннннннннннннннннннннCJPV\bhnty…‹‘—R\dnx‚Œ–ЅДУвмнннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн bZЯ…ннннннннннннннннннДДДДДДУУММММЬihfefddXJ?:8>LJHFC>:620.-0Я…ннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннbZЩУ€ннннннннннннннннннннннннннннннннннннннннннннннннннннннCKPW\biouz†Œ’˜žR\dnx‚Œ–ЅДУвмннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннWOUXUNSVИЃНЈЪЁWOШЊжнЪаИЃ000000UV8HV1.03ПЊЪМ+Н20221129ннChirpNxtџџннннннннннннннннннннннннннннннннннннннннннннннннннннннcdЧШ+,ѓєWXЛМ ƒ„чнннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн------------------------------------------------------------------------------------------------------------------------ннннннннјјјјјјјјјјјјјјјјјјјјннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннBuyTwoWayRadios000000000000№№јннннннннннннннннbcФннннннннннннннннннннннннннннннннннннннннннннннннбdннннннннннннннннннннннннннннннннннннннннннннннннџџџџџџџџџџџџџџџџб  лК!Ск>Ск>БGMСфСфёџСэЦСэЦёџСїŠСїŠёџТNТNёџТ Т ƒVƒVБGMЩqšЩqš№џЩ{^Щ{^№џЩ…"Щ…"№џЩŽцЩŽц№џ٘Њ٘Њ№џЩЂnЩЂn№џЩЌ2ЩЌ2№џСۘСۘёџСе\Се\ёџСп Сп ёџСшфСшфёџСђЈСђЈёџСќlСќlёџТ0Т0ёџТєТєёџСۘЩlИёџСе\Щv|ёџСп Щ€@ёџСшфЩŠёџСђЈЩ“ШёџСќlЩŒёџТ0ЩЇPёџТєЩБёџТєЩБ…U…UёџСۘЩlИ…………ёџСп Щ€@…………ёџТ0ЩЇP…………ёџСۘЩlИ…………ёџСۘЩlИ…………ёџр&апTxStop @@@Vox ‚ Vox D 0:№Vox S VXB ЦWIDNAR Т@@@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ OFF ON OFF 10M 20M 30M 40M 50M 1H1.5H 2H 4H 6H 8H 10H 12H 14H 16HCompScra OFF KeyCont LowHighNarrWide K+S PTT KEY ALL CO TO OFF FMMONIMOLO SQMMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 5K6K25 10K12K5 25K ALLTimeUser SYS 1S 2S 3S 4S OFF 10S 20S 30S 40S 50S 60S 70S 80S 90S100S110S120SSING-RPT+RPT OFF CTCNDCSIDCSSMAL BIG OFF FM CHA VOLMOLOMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 2K5 5K6K25 10K12K5 25K OFFCompScraTXScRXScџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJT270M џџџџџџџџ JET STREAM Waiting Debug Day CHA- Menu ( ) Vol Call Reset ? ALL RES FUN RES DEL CHA Send Error TX Stop KeyLock SEND џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџG‡PG‡Pџџџў№ќ$Q$Qџџџў№ќ@@џџџў№ќsyџџў№ўCQCQџџџў№ќF™F™џџџў№ќ@@џўpќF™F™џўpќaaџџџў№ќQQџџџў№ќ@@џџџў№ќaaџџџўpќ@@џџџўpќCQCQџџџ~pќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ``џџџў№ќ``џџџўpќ``џџџўАќ``џџџџ№ќ``џџџўрќ``џџџю№ќ``џџџўєќ``џџџќ№ќ``џџџ~№ќ``џџџО№ќ``џџџі№ќ``џџџўаќ``џџџњ№ќ``џџў№ќ``џџў№ќ``џkџў№ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDEDEџџџО№ќџџџџџџџџџџџџџџџџ Name001 Name002 Name003 Name004 Name005 Name006 Name007 Name008 Name009 Name010 A BASe Lowpowr NFM noscan blckoff tailcut rxscram voxon PTTIDon dtmfon aliasop rev TA DCS017N DCS017I DCS754N Name199 chirp-20240224/tests/images/Feidaxin_FD-268B.img0000644000175000017500000000400014551723752017665 0ustar hibbyhibbyџюGџџџџџџџџџџџџџPCPCџџџџѓџџџ`C`Cџџџџѓџџџ€C€Cџџџџѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњџџџџџџџџџџџџџџџџџџџџџџџџџџџк-џџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Retevis_RA685.img0000644000175000017500000001636114411666130017420 0ustar hibbyhibbyVVPVPVP7VP7VPbVPbVWW%W%WP7WP7WuWuWu0Cu0Cu1Cu1C%2C%2C%3C%3CuDCuDC%FC%FCuCCuCCuGCuGCџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQTY4NSIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwMjE0IiwgInJjbGFzcyI6ICJSYWRpb2RkaXR5R0E1MTBSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Kenwood_TS-480_CloneMode.img0000644000175000017500000000571214411666130021422 0ustar hibbyhibby .\k№ BLYN *а&0 LYMAN 1З№1З№ CULTUS &0&0 VICTORIA!wШ!wШSMPLX €€RESCRS 5§А  GRASSMTN  <Юh<ЮhCMPMRY80<с№<с№80M-ALT <֘<֘EOC-80M   n„јn„јEOC-40M nŒШnŒШCMPMRY40   QVDQVD Q”ФQ”Ф QНШQНШ QіlQіl RslRsl                                                                                      ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`ѕ`*<Юh.\2d=KJL?=KJL?TS-480_CloneModeџchirpюimgeyJ2ZW5kb3IiOiAiS2Vud29vZCIsICJtb2RlbCI6ICJUUy00ODBfQ2xvbmVNb2RlIiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIlRTNDgwUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/TYT_TH-UVF8D.img0000644000175000017500000004031114411666130017047 0ustar hibbyhibbyџџџџџџџџџџџџ`@@Re€e€DD8џџџZONA 50џP€P€#Р#РZ50 PRIPEPE008џџџUHF CHLџ%4ˆppџuSџџCNF RLCџP9uˆ((џ%IџџCNF RLIџ e eџџџџџџџSER VHFџ0C0CџџџџџџџSER UHFџbbџџџSC SBD1џ……SC SBD2P0P000џџџCB MTSRџu2u2џџџCB BUINџ%C%CppџџџCB COLIџPEPE……MU SBD1PEPEџџџMU SBD2џFF6#6#џџџCB PNFLџGG——џџџCB PTALџ%G%G22CB SJDMPP  џџџCB STGOџ%P%PssџџџO ECO13џuPuP……џџџCB ISLMџuQuQџџџCB QLCRџPRPRџџџџџџџCB NCNLџPSPS22џџџCB QNTNџTTџџџCB NUNOџ%T%TDDџџџCB LGRJџuTuT““џџџCB TILTџPUPUt t џџџCB CONCџWWbbџџџCB MAIPџu™u3……џfџџOMEGA 0џџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џА ˆЊџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџџџџџџџџџџџџџ8џџџџџџџџџџџ% % џџџџџџџџџџџџџџџ% % џџџџџџџџџџџџџџџџџ<RHўџџџџџџџџџџџџџџџ џџњџџџџџџџџџџџџџџ2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џњ<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`@@Rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‡3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџg џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФ@еЋ@ЌВ€ГdДЫРЛ М Уџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<9<9:4<7XWVUBAA>  SRQP>;<9B><7XWVUџџџџџџџџџџџџ !!B;5/("џє2 €  џŒ}xџџ?ѕ LzdњњўPPPџџџF<<<<<<<<<< < < < < <9========??џџџџџџџџџџџџ242445454523237:7:7::<:<:<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2 рїћџџ@>74TR><-*SQ---џџ8:<>@BEGIџџџџџТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJCRlQyMCIsICJ2ZW5kb3IiOiAiQmFvZmVuZyIsICJtb2RlbCI6ICJCRi1UMjAiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMxMTI5In0=chirp-20240224/tests/images/Retevis_RT22FRS.img0000644000175000017500000000225514411666130017714 0ustar hibbyhibbyP3207!јџџџџџџPb%FPb%Fžž P‡%FP‡%FЄЄ P&FP&Fљљ 'P7&FP7&F&& 4Pb&FPb&FUU A%&F%&Fљљ N%'F%'FUU [P‡&FP‡&F…… hP'FP'FЖЖ uP%FP%FЮЮ ‚u%Fu%FуЉуЉ &F&FкЈкЈ œP&FP&FЃЈЃЈ Љu&Fu&F†)†) Ж'F'FйЉйЉ У%'F%'F2Љ2Љ аџџџџџџџџP3207!јџџџџџџPb%FPb%Fžž P‡%FP‡%FЄЄ P&FP&Fљљ 'P7&FP7&F&& 4Pb&FPb&FUU A%&F%&Fљљ N%'F%'FUU [P‡&FP‡&F…… hP'FP'FЖЖ uP%FP%FЮЮ ‚u%Fu%FуЉуЉ &F&FкЈкЈ œP&FP&FЃЈЃЈ Љu&Fu&F†)†) Ж'F'FйЉйЉ УP3207!јџџџџџџPb%FPb%Fžž P‡%FP‡%FЄЄ P&FP&Fљљ 'P7&FP7&F&& 4Pb&FPb&FUU A%&F%&Fљљ N%'F%'FUU [P‡&FP‡&F…… hP'FP'FЖЖ uP%FP%FЮЮ ‚u%Fu%FуЉуЉ &F&FкЈкЈ œP&FP&FЃЈЃЈ Љu&Fu&F†)†) Ж'F'FйЉйЉ УRT22FRS џchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDIyRlJTIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMDEwMTQiLCAicmNsYXNzIjogIlJUMjJGUlMiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Wouxun_KG-935G.img0000644000175000017500000010025114411666130017455 0ustar hibbyhibbyннннннннннннннннŸЉ<ннннннннннннннннннннннннннннннннннннннннннннџbZмkbZмkЯ… fЯ… f н<šнннннннннннннннн !#$'bZЯ…ннннннннннннннннннžЂЂЊЌЌЌЌДДДД‹“МР"/8@;>FLQRsy_a"+2Ск>1СфСф1СэЦСэЦ1СїŠСїŠ1ТNТN1Т Т 1ЩqšЩqš0Щ{^Щ{^0Щ…"Щ…"0ЩŽцЩŽц0٘Њ٘Њ0ЩЂnЩЂn0ЩЌ2ЩЌ20СۘСۘ1Се\Се\1Сп Сп 1СшфСшф1СђЈСђЈ1СќlСќl1Т0Т01ТєТє1СۘЩlИ1Се\Щv|1Сп Щ€@1СшфЩŠ1СђЈЩ“Ш1СќlЩŒ1Т0ЩЇP1ТєЩБ1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS-01GMRS-02GMRS-03GMRS-04GMRS-05GMRS-06GMRS-07GMRS-08GMRS-09GMRS-10GMRS-11GMRS-12GMRS-13GMRS-14GMRS-15GMRS-16GMRS-17GMRS-18GMRS-19GMRS-20GMRS-21GMRS-22RPT-15RPT-16RPT-17RPT-18RPT-19RPT-20RPT-21RPT-22џџџџџџџџџџџџџџџџžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннџchirpюimgeyJ2ZW5kb3IiOiAiV291eHVuIiwgIm1vZGVsIjogIktHLTkzNUciLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIyMDQwOCIsICJyY2xhc3MiOiAiS0c5MzVHUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/BTECH_UV-5001.img0000644000175000017500000004000014551723752016770 0ustar hibbyhibby%F%FџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPHPHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШџџџџџџџџџџџЧџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))-  €2 2880џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000V192040000000000000000000000HHTYUV-168V19204U880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000chirp-20240224/tests/images/Midland_DBR2500.img0000644000175000017500000003150514411666130017515 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџQP ђCPP ђWELCOMEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ dd–88888 12345 23456 34567 45678 FFFd–d 2F4^ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 123456   QPCP  ђџchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIk1pZGxhbmQiLCAibW9kZWwiOiAiREJSMjUwMCIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/BTECH_GMRS-V2.img0000644000175000017500000002024114411666130017104 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%FDP‡%FP‡%FDP&FP&FDP7&FP7&FDPb&FPb&FDP‡&FP‡&FDP'FP'FDPbuFPbuFP‡uFP‡uFPvFPvFP7vFP7vFPbvFPbvFP‡vFP‡vFPwFPwFP%FP%FDu%Fu%FD&F&FD%&F%&FDP&FP&FDu&Fu&FD'F'FD%'F%'FDP%FPuFDu%FuuFD&FvFD%&F%vFDP&FPvFDu&FuvFD'FwFD%'F%wFDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$$D%$%$DP$P$Du$u$D%%D%%%%DP%P%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFANGXIAODONGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ FM 65-75Mn FM 76-108MџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS01џџџџџџџџџџGMRS02џџџџџџџџџџGMRS03џџџџџџџџџџGMRS04џџџџџџџџџџGMRS05џџџџџџџџџџGMRS06џџџџџџџџџџGMRS07џџџџџџџџџџGMRS08џџџџџџџџџџGMRS09џџџџџџџџџџGMRS10џџџџџџџџџџGMRS11џџџџџџџџџџGMRS12џџџџџџџџџџGMRS13џџџџџџџџџџGMRS14џџџџџџџџџџGMRS15џџџџџџџџџџGMRS16џџџџџџџџџџGMRS17џџџџџџџџџџGMRS18џџџџџџџџџџGMRS19џџџџџџџџџџGMRS20џџџџџџџџџџGMRS21џџџџџџџџџџGMRS22џџџџџџџџџџREPT15џџџџџџџџџџREPT16џџџџџџџџџџREPT17џџџџџџџџџџREPT18џџџџџџџџџџREPT19џџџџџџџџџџREPT20џџџџџџџџџџREPT21џџџџџџџџџџREPT22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOAA01џџџџџџџџџџNOAA02џџџџџџџџџџNOAA03џџџџџџџџџџNOAA04џџџџџџџџџџNOAA05џџџџџџџџџџNOAA06џџџџџџџџџџNOAA07џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ140902N џџWELCOME џџUS32419USG2419џџ-----------0AA0-eeeee77777777eeeiiiiiiiiiџџџ #! џџџџџ џџџџџ( <~юџpsv}‡ 1 џ€6t џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ123456BF9166Њ6t нџchirpюimgeyJ2ZW5kb3IiOiAiQlRFQ0giLCAibW9kZWwiOiAiR01SUy1WMiIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJHTVJTVjIiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Abbree_AR-63.img0000644000175000017500000000074114411666130017135 0ustar hibbyhibbyP—CP—CЮЮ0џџџ%C%C  0џџџRrCRrCžž0ESCESC<(<(0uACuAC0џџ•!C•!CUU0P™CP™C((0PaWCPaWCU(U(0exCexCuu0P!CP!CЮЮ0%3C%3C990PxaCPxaCшш0%a%YC%YCМ(М(0FCCjЈjЈ0џџџ%FC%FCЄЄ0џџџ™C™Cшш0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiQWJicmVlIiwgIm1vZGVsIjogIkFSLTYzIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjA3MDMiLCAicmNsYXNzIjogIkFSNjNSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/BTECH_UV-5X3.img0000644000175000017500000002026714560403070016763 0ustar hibbyhibbyџџџџџџџџџџџџџџџџaaџџџџDP9P9џџџџD%@%@џџџџDP™GP™GџџџџDeCeCЧ Ч DUUввDџ%‡E%‡EDџ%˜E%˜EDџ%F%F33Dџ%"F%"F;; Dџ%3F%3FPP Dџ%DF%DFxx Dџ%UF%UFЫЫ Dџ%"@%"@ Dџ%tC%tCDџu™Gu™GDџP…P…DџPvPvDџP'P'Dџ…C…CDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџWWDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџ џџџџџ џџџџџ џџџџџџџџџџџџџџџџџџџџџ  џџџ  џџџ OџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDCDCXIAODONGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPџP FM 65-75Mј FM 76-108Mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ160508N WELCOME UVVG301UVV300 џџ !"#$%&'()*+,-.$%&'()*+,-./0123)*+,-./012345678     0 <Пџpsv}‡  *4>HT_juWELCOME 0y"% Њ0y"% нџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjVYMyIsICJ2ZW5kb3IiOiAiQlRFQ0giLCAibW9kZWwiOiAiVVYtNVgzIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Retevis_RB615.img0000644000175000017500000000410514411666130017403 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ7р V1.01њ ‚-џT < < ,џP < < +џP < < +џP < < )џP < < )џP < < (џP < < (џP < < 'џP < < (џP < < (џP < < (џP < < ,џP < < ,џP < < ,џP < < ,џP < < џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ,6џџџџџџџџџџ7иGFAxџџџЈ1|Ј1|ЄџџџЈ’|Ј’|ЄџџџЈ–ѕ|Ј–ѕ|ЄџџџЈ›з|Ј›з|ЄџџџЈ Й|Ј Й|ЄџџџЈЅ›|ЈЅ›|ЄџџџЈЊ}|ЈЊ}|ЄџџџЈЏ_|ЈЏ_|ЄџџџЈДA@ЈДA@ЄџџџЈЙ#@ЈЙ#@ЄџџџЈО@ЈО@ЄџџџЈТч@ЈТч@ЄџџџЈЧЩ@ЈЧЩ@ЄџџџЈЬЋ@ЈЬЋ@ЄџџџЈб@Јб@ЄџџџЈжo@Јжo@ЄџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџџџџРџџџџџРџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjYxNSIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwNzAzIiwgInJjbGFzcyI6ICJSQjYxNVJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_FT-70D.img0000644000175000017500000017731314411666130017166 0ustar hibbyhibbyAH51Gџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ% ЈBЈ :џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУџџџџџџЭџџџџџџџУџџџџџџЭџџџџ Pџџџџџџџџџџџџџџџџ p@P€ џџџџ Pџџџџџџџџџџџџџџџџ p@P€  џџџџ C0џџџџџџџџџџџџџџџџ BG€ ƒ џџџџ C0џџџџџџџџџџџџџџџџ BG€ ƒУџџџџџџ €џџџџџџџџџџџџџџџџ ˜€€€ ЗУџџџџџџ €џџџџџџџџџџџџџџџџ ˜€€€ Зџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџ џџџџџџџџџџџџџџ џџџџџџџџџџџџџџ џџџџџџџџџџџџџџ џџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBANK 1џџџџџџџџџџBANK 2џџџџџџџџџџBANK 3џџџџџџџџџџBANK 4џџџџџџџџџџBANK 5џџџџџџџџџџBANK 6џџџџџџџџџџBANK 7џџџџџџџџџџBANK 8џџџџџџџџџџBANK 9џџџџџџџџџџBANK10џџџџџџџџџџBANK11џџџџџџџџџџBANK12џџџџџџџџџџBANK13џџџџџџџџџџBANK14џџџџџџџџџџBANK15џџџџџџџџџџBANK16џџџџџџџџџџBANK17џџџџџџџџџџBANK18џџџџџџџџџџBANK19џџџџџџџџџџBANK20џџџџџџџџџџBANK21џџџџџџџџџџBANK22џџџџџџџџџџBANK23џџџџџџџџџџBANK24џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ J@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ Рџџџџџџџџџџџџџџџџ ‰€Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ Pаџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0аџџџџџџџџџџџџџџџџ €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ  J@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ Рџџџџџџџџџџџџџџџџ ‰€Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ Pаџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0аџџџџџџџџџџџџџџџџ €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ  J@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ Рџџџџџџџџџџџџџџџџ ‰€Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ Pаџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0аџџџџџџџџџџџџџџџџ €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPаџџџџџџџџџџџџџџџџ €…$C1uбGB3AUџ…$C0PбGB3AVџ…W‡бGB3BFџ…$C1uбGB3BLџ…$C0%СGB3BVџ…VСGB3ELџ…$C3PСGB3HRџ…$C3%СGB3HWџ…$C2PСGB3LTџ…$C0PСGB3LVџ…$C СGB3LWџv…$C0СGB3MKџ…$C1СGB3NKџ …WuСGB3NLџ…$C1%СGB3OVџ …$C PСGB3OYџv…WPСGB3PIџ…$C2СGB3PYџ…$C2%СGB3TUџ…$C3%СGB3VHџ…$C1СGB7HFџ…C—РGB7PTџ…$C2uбGB7SVџ…S7СMB7IDTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$C0%СGB3BVџ$C0%СGB3BVџ$C1СGB7HFџ$C‡РGB3BPџvV‡СGB3DCџ$C2PСGB3DYџ$C3СGB3EEџWСGB3HHџдV7GB3INџV%СGB3NFџ$C1uСGB3NMџ$C2СGB3RBџ$C3%СGB3SMџ $C2%СGB3STџ дC–PРGB7INџдC–РGB7RRџ$C bСGB7SHџvдC–uРGB7SNџдC–uРGB7SNџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџХPаџџMEM900џџџџџџџџџџ €џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФџџџџџџ?РYYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******CQ*******QST******YAESU****џџџџџџџџџBLN******BLN*џџџџџBLN*џџџџџFxx  xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:A? џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ******џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<SuC4Pџџџџџќ џ i9**џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџchirp-20240224/tests/images/Retevis_RB27V.img0000644000175000017500000001035114411666130017446 0ustar hibbyhibby  џџџ€€џџџ@@џџџpEpEџџџFFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ–џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjI3ViIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjExMjEzIiwgInJjbGFzcyI6ICJSZXRldmlzUlQyN1YiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Retevis_RB628.img0000644000175000017500000000103114411666130017402 0ustar hibbyhibby%`D%`Du`Du`D%1`D%1`DuC`DuC`D%V`D%V`Duh`Duh`D%`D%`D  u“`Du“`D%aD%aD))uaDuaD))c%1aD%1aD))uCaDuCaD))%VaD%VaD))uhaDuhaD))%aD%aD))џџџu“aDu“aD))џ&D&D %&D%&D P&DP&D u&Du&D 'D'D %'D%'D џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSQjYyOFJhZGlvIiwgInZlbmRvciI6ICJSZXRldmlzIiwgIm1vZGVsIjogIlJCNjI4IiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDIzMDIwOSJ9chirp-20240224/tests/images/Retevis_RT9000D_136-174.img0000644000175000017500000004027114411666130020514 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  6t6t 2d6` 2d‘ A$H:3 d ‘$AyOж2d ўџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџ < џР]h)P-œ1А6Ф;=<;:9:;<bZџџџнннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн".6EQ[huƒŽœЉЗФз_nv~†Žœнннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн %$##"!!!bZЭў`ннннннннннннннннннssssspphнннннннннннннннн:888<>>>Эў`нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн'3>JUbmxƒœЈГН_nv~†Ž–ннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннWOUXUNSVИЃНЈЪЁWOШЊжнЪаИЃ01000001UV8D(Plus)V1.0220170822ннKGUV8D00ннннннннннннннннннннннннннннннннннннннннннннннннннннннcdЧШ+,ѓєWXЛМ ƒ„чннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнннннннн"јјјјјјјјјјјјјјјјјјјннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннwww.wouxun.com 000000000000№№" нннннннннннннннннно№ъ`‚žнннннннннннннннннннннннннннннннннннннннннннннннн]l ˜Р‚žQннннннннннннннннннннннннннннннннннннннннннннннннџџџџџџџџџџџџџџџџbcФbcФ1џџџџџџџџПџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннchirp-20240224/tests/images/Kenwood_TH-D75.img0000644000175000017500000172167514563632215017531 0ustar hibbyhibbyџџџџџџџџ000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@3Р' CQCQCQDIRECTDIRECT€пФР'  Pџџ‘ Pџџџџџџџџџџџџџџџџџџ‘џџ+*џџ‘К џ`?=џџџџџџџџџџџџџџџџnnџџџџчŒS=Т`W>Т1УР`W>ТЄ№=ТОРУРD>ТМ]>ТЈIТ%#Р >ТŸАР@3Р' CQCQCQDIRECTDIRECTџџџџџџџџРЕJ jwCQCQCQDIRECTDIRECTџџџџџџџџо9@KLˆCQCQCQDIRECTDIRECTџџџџџџџџ`=D!CQCQCQDIRECTDIRECTџџџџџџџџрg55CQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџР2 DCQCQCQDIRECTDIRECTџџџџџџџџ`?=ЛCQCQCQDIRECTDIRECTџџџџџџџџ€‰U!CQCQCQDIRECTDIRECTџџџџџџџџD•Р' CQCQCQDIRECTDIRECTџџџџџџџџАЦ ЊCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџРЕJ jwCQCQCQDIRECTDIRECTџџџџџџџџРЄg@KLˆCQCQCQDIRECTDIRECTџџџџџџџџp^[ЊCQCQCQDIRECTDIRECTџџџџџџџџиЈЙ@KLqѕ€CQCQCQW1IXU BW1IXU BџџџџџџџџиЈЙ@KLqѕ€CQCQCQW1IXU BW1IXU Bџџџџџџџџџџџџџџџџџџџџџџџџ   џџ2€_ цп I€p€Ёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€б№qœCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   "#$000$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHi K0TFUTH-D75џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџK0TFU-7џџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/[Fx<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTEMPџџџ*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL,QST,CQ,KWDџџџџџ000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ /E /E /EџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTH-D75џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Р Р Р Р Р Р Р Р Р Рџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"џџ"џџ"џџ"џџ"џџ"џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJPNNAMZAFAUTBELBGRHRVCZEDNKFRADEUGRCHUNISLITANLDNORPOLPRTSMRSVNESPSWECHEGBRUSACANMEXGTMSLVARGBRACUWAUSNZLGUMџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJA1JA2JA3JA4JA5JA6JA7JA8JA9JA0NAMZAFKAENOEOOESABSTETIRWIEBELBGRHRVCZEDNKFRABWBYBEHBHHHEMVNINWRPSNSTSHTHGRCHUNISLABRAPUCALCAMEMIFRILAZLOMPIESARSICTOSUMBVENNLDNORPOLPRTSMRSVNESPSWECHESARNORCENSESWWMSCONIW1W2W3W4W5W6W7W8W9W0KL7KH6VE1VE2VE3VE4VE5VE6VE7VY1VY2MEXGTMSLVARGBRACUWAUSNZLGUMџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp7›Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`4І@KL€‚ џџџџџџџџџџџџџџџџ`4І@KL€P7"@KL€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ iЛР' €6‰@KL€аљ‰@KL€џџџџџџџџџџџџџџџџАъЌР'  НŠ@KL€p€‹@KL€рЋЪР' @KL€TМР' џџџџџџџџџџџџџџџџ€ЛР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрvОР' ‚ џџџџџџџџџџџџџџџџ HЫР' њЪР' dЋР' ‚ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЗЛР' рМР' TМР' џџџџџџџџџџџџџџџџ€k•@KL€рVR jpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`4І@KL€‚ €пФР'  `>НР' џџџџџџџџџџџџџџџџрvОР' ‚ plЇР' ‚pTМ@KL€‚ 0аІР'  ПР' ‚ vЕ@KL€‚џџџџџџџџџџџџџџџџ№Г@KL€‚ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрЩХР'  №ЄЈР' ‚ x/Л@KL€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPЌР' ‚ џџџџџџџџџџџџџџџџРН@KL€‚ „СР' "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@aПР' @CФР' АЈР' ‚р:ШР'  PЉР' ‚ џџџџџџџџџџџџџџџџ8WФ@KL€‚*а@KL€‚џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЗЛР' рМР' TМР' €k•@KL€рVR jpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€пФР'  џџџџџџџџџџџџџџџџрЩХР'  №ЄЈР' ‚ PЌР' ‚ рXУР'  рчРР' ‚ PЭ@KL€‚ џџџџџџџџџџџџџџџџXјЫ@KL€‚ №ЄЈР' ‚ ` ТР' ‚ Р™РР' ‚ €§ПР' ‚ ЦР'  џџџџџџџџџџџџџџџџ KРР' ‚ РН@KL€‚ ЈЈ@KL€‚ аРРР' ‚ АЈР' ‚ КЇР' ‚ џџџџџџџџџџџџџџџџ№ЄЈР' ‚ 0аІР' ‚ ‚ІР' ‚  кНР' ‚  žЧР'  јIС@KL€‚ џџџџџџџџџџџџџџџџинХ@KL€‚ И”\@KL€ ЈЉR@KL€ 6СР' ‚ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPЌР' ‚ dЋР' ‚ €ŒНР' ‚ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрЭР' РьЧР' ѕУ@KL€‚@CФР' 0AЉР' ‚џџџџџџџџџџџџџџџџ -ХР' @CФР' РDH jpPНР' ‚@aПР' ‚ „СР' ‚џџџџџџџџџџџџџџџџ@CФР' ЇУР' PЌР' ‚ЦР'  кНР' ‚ `‘ФР'  џџџџџџџџџџџџџџџџрчРР' ‚ ХОР' ‚ 8"И@KL€‚џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЗЛР' џџџџџџџџџџџџџџџџрМР' TМР' €k•@KL€рVR jppNЌР' œЌР' џџџџџџџџџџџџџџџџАъЌР' а8­Р' №†­Р' е­Р' 0#ЎР' PqЎР' џџџџџџџџџџџџџџџџpПЎР'  ЏР' А[ЏР' аЉЏР' №їЏР' FАР' џџџџџџџџџџџџџџџџ0”АР'  1КР' @КР' `ЭКР' €ЛР'  iЛР' џџџџџџџџџџџџџџџџ ЂМР' @№МР' @%ЩР' `sЩР' €СЩР'  ЪР' џџџџџџџџџџџџџџџџР]ЪР' рЋЪР' њЪР'  HЫР' @–ЫР' `фЫР' џџџџџџџџџџџџџџџџ€2ЬР'   @KL€РтА@KL€ІБ@KL€`Q jp€lQ jpџџџџџџџџџџџџџџџџ КQ jpРR jpЅR jpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРf@KL€pЃ@KL€pЃ@KL€џџџџџџџџџџџџџџџџШA@KL€‚ р@KL€pЃ@KL€PГД@KL€‚ АъЌР' `4І@KL€‚ џџџџџџџџџџџџџџџџ`4І@KL€ШђЛ@KL€‚ рЋЪР' pЃ@KL€<™@KL€‚ `ЭКР' џџџџџџџџџџџџџџџџ€ЛР'  ЂМР'  iЛР' 0”АР' Љ-@KL€€2ЬР' џџџџџџџџџџџџџџџџpЃ@KL€А[ЏР' ШђЛ@KL€‚ рЋЪР'  -ХР' Шv)@KL€џџџџџџџџџџџџџџџџ -ХР' Шv)@KL€`iВ@KL€‚pNЌР'  \Џ@KL€‚ Ах,@KL€џџџџџџџџџџџџџџџџpЃ@KL€` ТР' ‚ 1КР' аЉЏР' `фЫР'  -ХР' џџџџџџџџџџџџџџџџШv)@KL€ -ХР' Шv)@KL€ -ХР' Шv)@KL€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрvОР' ‚ 6СР' ‚`>НР' 0|Х@KL€‚ `гЪ@KL€‚ Р{ХР' џџџџџџџџџџџџџџџџ` ТР' ‚ \Џ@KL€‚ €пФР'  рЩХР'  @CФР' р @KL€‚ џџџџџџџџџџџџџџџџPГД@KL€‚ `4І@KL€‚ аЧ@KL€‚Р{ХР'  Гg jp‚А[ЏР' џџџџџџџџџџџџџџџџШђЛ@KL€‚  -ХР' `iВ@KL€‚ \Џ@KL€‚ ПР' ‚аЉЏР' џџџџџџџџџџџџџџџџ%Р@KL€‚ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@%ЩР' €2ЬР' ˆАЌ@KL€‚№9Ж@KL€‚џџџџџџџџџџџџџџџџРЗЛР' €k•@KL€РтА@KL€ІБ@KL€А[ЏР' p7›Р' џџџџџџџџџџџџџџџџ№Г@KL€‚аЧЊР' ‚ аЧЊР' XYЇ@KL€иs­@KL€аЧ@KL€‚ џџџџџџџџџџџџџџџџаЧ@KL€њЪР' HBЮ@KL€‚dЋР' ‚ €nТР' ‚ (lК@KL€‚ џџџџџџџџџџџџџџџџјIС@KL€‚ рXУР'  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№PА PIЅР' џџџџџџџџџџџџџџџџP­ЄР' А&ЃР' №ТЃР' ЄР' pћЄР' А—ЅР' џџџџџџџџџџџџџџџџахЅР' 0_ЄР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџаЭК@KL€‚ HЫР' œЌР' џџџџџџџџџџџџџџџџ ЪР'  iЛР' рЋЪР' pЃ@KL€@KL€рЏ‡@KL€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџplЇР' ‚€ К@KL€pTМ@KL€‚ P~Ј@KL€‚  iЛР' џџџџџџџџџџџџџџџџР™РР' роe jphЅ@KL€‚ 1КР'  ПР' ‚ vЕ@KL€‚џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЉ; PhбD PшzH Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0аІР' А,Г@KL€ˆnІР' јЕ@KL€ШђЛ@KL€‚ џџџџџџџџџџџџџџџџ` ТР' ‚рNЌ@KL€‚pА@KL€‚ 0|Х@KL€‚ мћВ@KL€ш^З@KL€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџCQCQCQDIRECTDIRECT№PА pџџџџџџџџџџџџџџџџџџџџџџџџЎ pџџџџџџџџџџџџџџџџџџџџџџџџј+Џ pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈhЎ pџџџџџџџџџџџџџџџџџџџџџџџџPЪЎ pџџџџџџџџџџџџџџџџџџџџџџџџ Џ pџџџџџџџџџџџџџџџџџџџџџџџџHяЏ pџџџџџџџџџџџџџџџџџџџџџџџџP•Ђ pџџџџџџџџџџџџџџџџџџџџџџџџ˜}Є pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџј`Л pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЗЛР' CQCQCQDIRECTDIRECTD•Р' CQCQCQDIRECTDIRECTрVR jwCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџРЕJ jwCQCQCQDIRECTDIRECT€k•@KLˆCQCQCQDIRECTDIRECTо9@KLˆCQCQCQDIRECTDIRECTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRS DHRARptr DHRASplx DrprEMCM CrnrCnyn CrscntVw Draper Eastrdge HdnVly Meadows MtnPoint RivrView SouthMtn Suncrest DHRARptr Farns Hidden Scott Prmntry BearLake Medicine Pisgah Orem Levan Frisco Monroe Blowhard Tods WestMtn Navajo Malad Jumpoff Sawtelle Sedgwick Harrison MtnHome Shafer Snowbank Jacob Eldon TowerMtn WhteTnks Sctsdale Potosi WestMtn Toquerv WebbHill SAF_1 SAF_2 SAF_3 SAF_4 SAF_5 SAF_6 SAF_7 SAF_8 SAF_9 SAF_10 SAF_11 SAF_12 SAF_13 SAF_14 SAF_15 SAF_16 SAF_17 SAF_18 SAF_19 SAF_20 SAF_21 SAF_22 SAF_23 SAF_24 SAF_25 SAF_26 SAF_27 SAF_28 SAF_29 SAF_30 SAF_31 SAF_32 SAF_33 SAF_34 SAF_35 SAF_36 SAF_37 SAF_38 SAF_39 SAF_40 SAF_41 SAF_42 SAF_43 SAF_44 Vlly-1 Vlly-2 Vlly-3 Vlly-4 Vlly-5 Vlly-6 Vlly-7 Vlly-8 Vlly-9 Vlly10 Vlly11 CITY-1 CITY-2 CITY-3 CITY-4 CITY-5 CITY-6 CITY-7 CITY-8 CITY-9 CITY10 CITY11 CITY12 CITY13 CITY14 RACES UDXA SLCWx 6mLnk NAT146 NAT446 State1 State2 State3 APRS TRAL-1 TRAL-2 TRAL-3 TRAL-4 TRAL-5 TRAL-6 TRAL-7 ERC-1 ERC-2 ERC-3 ERC-4 ERC-5 ERC-6 ERC-7 WxSLC PAC-1 PAC-2 PAC-3 PAC-4 PAC-5 PAC-6 PAC-7 PAC-8 PAC-9 EOC-1 EOC-2 EOC-3 EOC-4 EOC-5 EOC-6 EOC-7 EOC-8 EOC-9 HOSP-1 HOSP-2 HOSP-3 HOSP-4 HOSP-5 HOSP-6 HOSP-7 HOSP-8 HOSP-9 HOSP10 HOSP11 UHPSLC UHP 2 UHPC2C DSTAR1 DSTAR2 DSTAR3 DSTAR4 FUSN_1 FUSN_2 FUSN_3 FUSN_4 FUSN_5 DMR-1 DMR-2 WX 1WX 2WX 3WX 4WX 5WX 6WX 7WX 8WX 9WX 10Call VHF (FM)Call VHF (DV)Call 220M (FM)Call 220M (DV)Call UHF (FM)Call UHF (DV)џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGRP-0GRP-1GRP-2GRP-3GRP-4GRP-5GRP-6GRP-7GRP-8GRP-9GRP-10GRP-11GRP-12GRP-13GRP-14GRP-15GRP-16GRP-17GRP-18GRP-19GRP-20GRP-21GRP-22GRP-23GRP-24GRP-25GRP-26GRP-27GRP-28GRP-29WeatherџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџABџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAkihabaraTokyoJP1YLA AJP1YLA G€2у@KL#)ќ!‹.ф ѓ\џџюџџHamacyoTokyoJP1YIU AJP1YIU Gkф@KL#)а‹/\ѓ\џџъHamacyoTokyoJP1YIU BJP1YIU G §L-1#)а‹/\ѓ\џџюџџџџџџџџџџџџџџџџEdogawaTokyoJP1YJK AJP1YJK G0­+@KL#*@‹3,ѓ\џџъEdogawaTokyoJP1YJK BJP1YJK Gа§L-1#*@‹3,ѓ\џџъEbisuTokyoJR1VF AJR1VF GАDњL-1#&а ‹+„ѓ\џџюџџџџџџџџџџџџџџџџSugamoTokyoJR1WN AJR1WN G—,@KL#+˜!‹,иѓ\џџюTokyoDenkiUnivTokyoJP1YDG AJP1YDG G Hт@KL#,Œ#‹0иѓ\џџюNishitokyoTokyoJP1YIW BJP1YIW GPЫћL-1#,ш‹Pѓ\џџъ џџџџџџџџџџџџџџџџKomaeTokyoJP1YJO AJP1YJO G/@KL#&”‹"|ѓ\џџю HamFair 430-ATokyoJP1YJJ AJP1YJJ GPl.@KL#%„‹/„ѓ\џџю HamFair 1200TokyoJP1YJJ BJP1YJJ GАгїL-1#%„‹/„ѓ\џџю џџџџџџџџџџџџџџџџHamFair 430-CTokyoJP1YJJ CJP1YJJ G0­+@KL#%„‹/„ѓ\џџю Yokohama-KohokuKanagawaJP1YJY AJP1YJY Gрф@KL#X‹%ф ѓ\џџю Yokohama-KonanKanagawaJP1YIQ AJP1YIQ Gа-@KL#`"‹"ф ѓ\џџю џџџџџџџџџџџџџџџџShonanKoukaDaiKanagawaJP1YJV BJP1YJV GpЈљL-1#ј‹шѓ\џџюEbinaKanagawaJP1YJX AJP1YJX G_+@KL#ј‹ ѓ\џџюEbinaKanagawaJP1YJX BJP1YJX GPZљL-1#ј‹ ѓ\џџюџџџџџџџџџџџџџџџџInageChibaJP1YJQ AJP1YJQ GpК.@KL#'xŒФ"ѓ\џџюFunabashiChibaJP1YFY AJP1YFY G`Uх@KL#+ЄŒАѓ\џџюKisarazuChibaJP1YEM AJP1YEM GpI,@KL#”‹8Аѓ\џџюџџџџџџџџџџџџџџџџNagareyamaChibaJP1YJR AJP1YJR GPћ+@KL#6Ш‹6„ѓ\џџюYachimataChibaJP1YJT AJP1YJT G Йф@KL#&АŒѓ\џџюKatoriChibaJP1YDS AJP1YDS Gа-@KL#5ќ!Œ€%ѓ\џџюџџџџџџџџџџџџџџџџChiba-NagaraChibaJP1YKM AJP1YKM GрЋс@KL#дŒ Єѓ\џџюSaitama-MinamiSaitamaJP1YLQ AJP1YLQ Gр:п@KL#2x‹'ѓ\џџюFurukawaIbarakiJP1YIK AJP1YIK G00@KL$ ˆ‹+%ѓ\џџюџџџџџџџџџџџџџџџџTsukubaIbarakiJP1YJZ AJP1YJZ GPн0@KL$ ŒИ$ѓ\џџюKashimaIbarakiJP1YKH AJP1YKH G/@KL#9ЄŒ%мѓ\џџюShizuokaShizuokaJP2YGY AJP2YGY GPн0@KL";ŠЄѓ\џџюџџџџџџџџџџџџџџџџSU-HamamatsuShizuokaJP2YIC AJP2YIC GpI,@KL"+Д‰*H&ѓ\џџюGifuGifuJP2YGR AJP2YGR Gp+1@KL#Dˆ-дѓ\џџю Gifu-KinkazanGifuJP2YDS AJP2YDS Gа2@KL#˜!ˆ.шѓ\џџю!џџџџџџџџџџџџџџџџEnaGifuJR2WO AJR2WO GаТ*@KL#€%‰ѓ\џџю "Ibi-OnoGifuJP2YHR AJP2YHR G žо@KL#` ˆ%dѓ\џџю!#YaotsuGifuJP2YGA AJP2YGA G№ђ/@KL#р‰$ѓ\џџю"$џџџџџџџџџџџџџџџџNagoya-UnivAichiJP2YGI AJP2YGK GA0@KL#  ˆ:Шѓ\џџю#%JRC-NagoyaDai2HPAichiJP2YGG AJP2YGE G№Q§L-1#Xˆ9%ѓ\џџъ$&FujitaHealthUnivAichiJP2YGE AJP2YGE GаТ*@KL#lˆ;Ќ&ѓ\џџю%'џџџџџџџџџџџџџџџџFujitaHealthUnivAichiJP2YGE BJP2YGE G §L-1#lˆ;Ќ&ѓ\џџъ&(KasugaiAichiJP2YGK AJP2YGK G00@KL#˜!ˆ:H ѓ\џџю')NishioAichiJP2YDN AJP2YDN G0.@KL"4P‰` ѓ\џџю(*џџџџџџџџџџџџџџџџKotaAichiJP2YDP AJP2YDP GPн0@KL"0%‰ єѓ\џџю)+Kyoto-HieizanKyotoJP3YCS AJP3YIX Gр:п@KL#ќ!‡1Шѓ\џџю*,Kyoto-NishikyoKyotoJP3YIV AJP3YIV G€Ср@KL"90‡&H&ѓ\џџю+-џџџџџџџџџџџџџџџџArashiyamaKyotoJP3YHV AJP3YHV GA0@KL#‡'4!ѓ\џџю,.Kyoto-MinamiKyotoJP3YIX AJP3YIX G@–т@KL":H&‡+T ѓ\џџю-/Kyoto-FushimiKyotoJP3YJE AJP3YJE G‰п@KL"8$‡/№ ѓ\џџю.0џџџџџџџџџџџџџџџџShiga-MoriyamaShigaJR3WZ AJR3WZ GАЧ1@KL# ‡9 ѓ\џџю/1NaraNaraJP3YIA AJP3YIA Gа-@KL"(А‡1шѓ\џџю02SakuraiNaraJP3YIW AJP3YIW G€2у@KL"А‡2 ѓ\џџю13џџџџџџџџџџџџџџџџNarayamaNaraJP3YHL AJP3YHH Gа2@KL"*|‡0tѓ\џџю24WTCOsakaJP3YHF AJP3YHH Gа§L-1"&T ‡Ф"ѓ\џџъ35HiranoOsakaJP3YHH AJP3YHH G00@KL"%|‡"шѓ\џџю46џџџџџџџџџџџџџџџџHiranoOsakaJP3YHH BJP3YHH GАЕќL-1"%|‡"шѓ\џџю57IkomaOsakaJP3YHJ AJP3YHH GаТ*@KL"( ‡(dѓ\џџю68IkomaOsakaJP3YHJ BJP3YHH G№Q§L-1"( ‡(dѓ\џџю79џџџџџџџџџџџџџџџџSakaiOsakaJP3YHT AJP3YHT GАV/@KL"4‡єѓ\џџю8:NeyagawaOsakaJP3YHX AJP3YHX Gp+1@KL"-Є‡&ѓ\џџю9;Kii-TanabeWakayamaJP3YIC AJP3YIC Gа2@KL!/L‡ѓ\џџю:<џџџџџџџџџџџџџџџџAritaWakayamaJP3YCV ApК.@KL"D‡ H&ѓ\џџю;=AritaWakayamaJP3YCV B0›іL-1"D‡ H&ѓ\џџъ<>Arita-MinamiWakayamaJP3YJC AJP3YJC G0.@KL"œ‡ќѓ\џџю=?џџџџџџџџџџџџџџџџKoyasanWakayamaJP3YHN AJP3YHN G№+@KL" ф%‡$Ф ѓ\џџю>@KoyasanWakayamaJP3YHN BJP3YHN GpќL-1" ф%‡$Ф ѓ\џџъ?AWakayama-SusamiWakayamaJP3YIU AJP3YIU G0­+@KL!!0‡Єѓ\џџю@BџџџџџџџџџџџџџџџџRokko-MinamiHyogoJR3VK AJR3VK GPн0@KL"-ш‡ ѓ\џџюACRokko-MinamiHyogoJR3VK BJR3VK G№ѓL-1"-ш‡ ѓ\џџъBDNadaHyogoJP3YES A!т@KL"-T$‡€ ѓ\џџюCEџџџџџџџџџџџџџџџџOkayamaOkayamaJP4YEF AJP4YEF G№ђ/@KL",…2јѓ\џџюDFKurashikiOkayamaJP4YDV AJP4YDV GаЄ/@KL"„….pѓ\џџюEGYamaguchiYamaguchiJP4YEG AJP4YEG GаЄ/@KL" 0ƒlѓ\џџюFHџџџџџџџџџџџџџџџџHatsukaichiHiroshimaJP4YEB AJP4YEB Gа2@KL"Ј„№#ѓ\џџюGITakamatsuKagawaJP5YCN AJP5YCN Gp+1@KL"$†Xѓ\џџюHJMatsuyama CastleEhimeJP5YCU AJP5YCU Gy1@KL!2„„-T$ѓ\џџюIKџџџџџџџџџџџџџџџџKochiKochiJP5YCQ AJP5YCQ GАЧ1@KL!"є…!Dѓ\џџюJLFukuokaFukuokaJP6YHS AJP6YHS G—,@KL!%‚јѓ\џџюKMIizuka-SangunsanFukuokaJP6YFA AJP6YFA Gњс@KL!!ф ‚#,ѓ\џџюLNџџџџџџџџџџџџџџџџNagasakiNagasakiJP6YHI AJP6YHI GАЧ1@KL .,3№#ѓ\џџюMOKumamotoKumamotoJP6YHN AJP6YHN G№+@KL 0t‚.Мѓ\џџюNPYatsushiroKumamotoJP6YHR AJP6YHR Gy1@KL €%‚#$ѓ\џџюOQџџџџџџџџџџџџџџџџGinowanOkinawaJR6YZ AJR6YZ Gy1@KL,-4ѓ\џџюPRSendaiMiyagiJP7YEL AJP7YEL Gа2@KL&ДŒ7Ќ ѓ\џџюQSFukushimaFukushimaJP7YEZ AJP7YEZ Gа-@KL%.0ŒT ѓ\џџюRTџџџџџџџџџџџџџџџџSapporoHokkaidoJP8YDZ AJP8YDZ Gа2@KL*;4!xѓ\џџюSUChitoseHokkaidoJP8YEB AJP8YEB GАЧ1@KL*2L&,ѓ\џџюTVIshikariHokkaidoJP8YEM AJP8YEM Gа-@KL+( `"ѓ\џџюUWџџџџџџџџџџџџџџџџHakodateHokkaidoJP8YEA AJP8YEA G№+@KL)1рŒ,pѓ\џџюVXAsahikawaHokkaidoJP8YEE AJP8YEE Gp+1@KL+.œŽАѓ\џџюWYObihiroHokkaidoJP8YEC AJP8YEC Gy1@KL*8d ѓ\џџюXZџџџџџџџџџџџџџџџџKitamiHokkaidoJP8YEF AJP8YEF GPн0@KL+1D7,ѓ\џџюY[ToyamaToyamaJP9YEO AJP9YEO G00@KL$*Ќ&‰ ѓ\џџюZ\TakaokaToyamaJP9YEG AJP9YEG G№+@KL$+lˆ;@ѓ\џџю[]џџџџџџџџџџџџџџџџNantoToyamaJP9YEI AJP9YEI GАЧ1@KL$!Œ ˆ6Аѓ\џџю\^NiigataNiigataJP0YDR AJP0YDR G№-@KL%50Š:И$ѓ\џџ ю]_NagaokaNiigataJP0YDU AJP0YDU Gp+1@KL%lŠ2јѓ\џџ ю^`џџџџџџџџџџџџџџџџUedaNaganoJP0YDP AJP0YDP G№+@KL$xŠ,ѓ\џџ ю_aUtsukushigaharaNaganoJP0YCI AJP0YDP G0­+@KL$ Š№#ѓ\џџ ю`bNagano-ShinonoiNaganoJP0YEC AJP0YEC G№ђ/@KL$"œŠјѓ\џџ юacџџџџџџџџџџџџџџџџFarm OzondjisseErongoV53DV CV53DV GЎ­Р'  %ї<џџ юbdWindhoekKhomasV53W CV53W G 4ЏР' ', Аї<џџ юcePort ElizabethEastern CapeZU9KDL CZU9KDL GXL­Р' !;Дќї@џџ юdfџџџџџџџџџџџџџџџџPretoriaGautengZS6PTA CZS6PTA GteЏР' )дЈї@џџ юegSandton JNBGautengZS6STN CZS6STN GшБР' \ьї@џџ юfhDurbanKwaZulu-NatalZS0PMB CZS0PMB GЬЏР' -4!+Pї@џџ юgiџџџџџџџџџџџџџџџџPietermaritzburgKwaZulu-NatalZU9PKF BZU9PKF G*€їs#ќ!ї@џџ юhjLKH VillachOE8XVK BOE8XVK BOE8XVK G№Н#€їs.$” 2dѓ<џџюikNebelsteinOE3XNR BOE3XNR BOE3XNR GO €їs0(Œ .Рѓ<џџюjlџџџџџџџџџџџџџџџџUnterbergOE3XVI BOE3XVI BOE3XVI GИ‹€їs/8№ 1Аѓ<џџюkmHochwechselOE3XWU BOE3XWU BOE3XWU GИР+€їs/4!64!ѓ<џџюlnRied-SenftenbachOE5XDN BOE5XDN BOE5XDN GЈе!€їs08 dѓ<џџ юmoџџџџџџџџџџџџџџџџLinz-BreitensteiOE5XOL BOE5XOL BOE5XOL GH\#€їs0Œ#”ѓ<џџ юnpGernkogelOE2XGR BOE2XGR BOE2XGR GH\#€їs/ ф%ѓ<џџ!юoqSchoecklOE6XAG BOE6XAG BOE6XAG Gиї€їs/ Ф"№#ѓ<џџ"юprџџџџџџџџџџџџџџџџDoblOE6XDF COE6XDF COE6XDF G|@ЎР' .8H&Pѓ<џџ"юqsHochsteinOE7XLI BOE7XLI BOE7XLI G˜$€їs.1И *ѓ<џџ#юrtWien AKHOE1XDS COE1XDS COE1XDS GXL­Р' 0 ˜мѓ<џџ%юsuџџџџџџџџџџџџџџџџBoomAntwerpON0DP AON0DP GhWaM?Ћ3мѓ<џџ'ъtvKluisbergenEast FlandersON0VA BON0VA GhШ€їs2-,"Аѓ<џџ'юuwLokerenEast FlandersON0LOK BON0LOK G`э€їs3аPѓ<џџ'юvxџџџџџџџџџџџџџџџџSint-NiklaasEast FlandersON0SNW BON0SNW G@Ж0€їs3 Ј  ѓ<џџ'юwyDiestFlemish BrabantON0DST BON0DST Gy1€їs3ˆ ѓ<џџ'юxzGosseliesHainautON0CPS BON0CPS G13€їs2аœѓ<џџ'юy{џџџџџџџџџџџџџџџџLe RoeulxHainautON0PLL CON0PLL GteЏР' 2Ь|ѓ<џџ'юz|MonsHainautON0MON BON0MON G4S,€їs2T Ќ ѓ<џџ'ю{}Signal BotrangeLiшgeON0TB BON0TB GИ‹€їs2АDѓ<џџ'ю|~џџџџџџџџџџџџџџџџUniv. of LiшgeLiшgeON0ULG CON0ULG GЈЎР' 2#а"мѓ<џџ'ю}VrerenLimburgON0LB BON0LB GЄ‚(€їs2,Ф ѓ<џџ'ю~€NivellesWalloon BrabantON0NIV BON0NIV GмД,€їs2$Pаѓ<џџ'юџџџџџџџџџџџџџџџџOostendeWest FlandersON0OS AON0OS G o_M?Ћ3 p7иѓ<џџ'ю€‚OostendeWest FlandersON0OS BON0OS Gр<2€їs3 p7иѓ<џџ'юƒOostendeWest FlandersON0OS CON0OS GteЏР' 3 p7иѓ<џџ'ю‚„џџџџџџџџџџџџџџџџEdelvaisBurgasLZ0DAD BLZ0DAD G њ"€їs*/%'T ѓ<џџ(юƒ…EdelvaisBurgasLZ0DAD CLZ0DAD G,}­Р' */%'T ѓ<џџ(ю„†HaskovoHaskovoLZ0DAX CLZ0DAX G,}­Р' )6ѓ<џџ(ю…‡џџџџџџџџџџџџџџџџPetrohanMontanaLZ0DAA BLZ0DAA GD%€їs+Ќ&Xѓ<џџ(ю†ˆPetrohanMontanaLZ0DAA CLZ0DAA G,}­Р' +Ќ&Xѓ<џџ(ю‡‰KarlovoPlovdivLZ0DVB BLZ0DVB GPl.€їs*+,7шѓ<џџ(юˆŠџџџџџџџџџџџџџџџџPlovdivPlovdivLZ0DAP BLZ0DAP G њ"€їs);Є+аѓ<џџ(ю‰‹rayon VitoshaSofiaLZ0DSR BLZ0DSR GАх,@KL*"Ш ѓ<џџ(юŠŒCelavacLika-Senj9A0DZD A9A0DZD GшOM?Ћ,D/xѓ<џџ)ю‹џџџџџџџџџџџџџџџџCelavacLika-Senj9A0DZD B9A0DZD GјЭ.€їs,D/xѓ<џџ)юŒŽZagrebZagreb9A0DZG B9A0DZG GhШ€їs-58Lѓ<џџ)юDrahouaCentral BohemiaOK0DRB BOK0DRB G 2€їs2x Ќ&ѓ<џџ*юސџџџџџџџџџџџџџџџџDrahouaCentral BohemiaOK0DRB COK0DRB G,}­Р' 2x Ќ&ѓ<џџ*ю‘Krkonose Mtns NPHradec KraloveOK0BCA BOK0BCA G )€їs2)*Xѓ<џџ*ю’Krkonose Mtns NPHradec KraloveOK0BCA COK0BCA GрЩХР' 2)*Xѓ<џџ*ю‘“џџџџџџџџџџџџџџџџOstravaMoravian-SilesiaOK0DSK BOK0DSK G@$€їs1%%4!ѓ<џџ*ю’”DrahanyOlomoucOK0PVD BOK0PVD GЈ .€їs1ќ!68ѓ<џџ*ю“•DrahanyOlomoucOK0PVD COK0PVD G,}­Р' 1ќ!68ѓ<џџ*ю”–џџџџџџџџџџџџџџџџSvratouchPardubiceOK0BAF BOK0BAF G@$€їs1,АXѓ<џџ*ю•—SvratouchPardubiceOK0BAF COK0BAF GXL­Р' 1,АXѓ<џџ*ю–˜Star§ PlzenecPlzeHOK0DPL BOK0DPL Gр<2€їs1(ќ! Ф"ѓ<џџ*ю—™џџџџџџџџџџџџџџџџStar§ PlzenecPlzeHOK0DPL COK0DPL G,}­Р' 1(ќ! Ф"ѓ<џџ*ю˜šPraguePragueOK0HCS BOK0HCS Gy1€їs2T$ѓ<џџ*ю™›BrnoSouth MoraviaOK0BRQ BOK0BRQ Gy1€їs1 ”,ѓ<џџ*юšœџџџџџџџџџџџџџџџџ`oaovkaSouth MoraviaOK0DHD BOK0DHD GP7"€їs1Є- ѓ<џџ*ю›`oaovkaSouth MoraviaOK0DHD COK0DHD GXL­Р' 1Є- ѓ<џџ*юœžCopenhagenCapitalOZ2REA BOZ2REA Gœžь€„7(€ ѓ<џџ+юŸџџџџџџџџџџџџџџџџCopenhagenCapitalOZ2REA COZ2REA GteЏР' 7(€ ѓ<џџ+юž GillelejeCapitalOZ1RET AOZ1RET G№LfM?Ћ8” №#ѓ<џџ+ъŸЁGillelejeCapitalOZ1RET BOZ1RET GlGч€„8” №#ѓ<џџ+ю ЂџџџџџџџџџџџџџџџџGillelejeCapitalOZ1RET COZ1RET GФ(АР' 8” №#ѓ<џџ+юЁЃHillerјdCapitalOZ2RET AOZ2RET GPЦdM?Ћ77ќ! Шѓ<џџ+юЂЄHillerјdCapitalOZ2RET BOZ2RET GФхц€„77ќ! Шѓ<џџ+юЃЅџџџџџџџџџџџџџџџџHillerјdCapitalOZ2RET COZ2RET GlŠАР' 77ќ! Шѓ<џџ+юЄІFrederikshavnNorth DenmarkOZ0DST BOZ0DST G˜ч€„9ш ˜ѓ<џџ+юЅЇOdenseSouthern DenmarkOZ2REE BOZ2REE G„ц@ 70  ѓ<џџ+юІЈџџџџџџџџџџџџџџџџParisParisF1ZPL BF1ZPL GфHЅРn04@ ѓ<џџ,юЇЉParisParisF1ZPL CF1ZPL G4XЌР' 04@ ѓ<џџ,юЈЊHochblauenDB0DB BDB0DB BDB0DB GЌ’3€їs/.p*Xѓ<џџ2юЉЋџџџџџџџџџџџџџџџџGoeppingenDB0RIG BDB0RIG BDB0RIG GdЊ1€їs0)№ 20ѓ<џџ2юЊЌWertheim am MainDB0SWR BDB0SWR BDB0SWR GX!€їs1)` ѓ<џџ2юЋ­Titisee-NeustadtDB0TIT BDB0TIT BDB0TIT G 2€їs/84!ѓ<џџ2юЌЎџџџџџџџџџџџџџџџџDonauwіrthDB0DON BDB0DON BDB0DON GЮТ1€їs0, /4ѓ<џџ3ю­ЏGrandsberg/StrauDB0RDH BDB0RDH BDB0RDH G8л1€їs08№# 3dѓ<џџ3юЎАGrandsberg/StrauDB0RDH CDB0RDH CDB0RDH GЧЏР' 08№# 3dѓ<џџ3юЏБџџџџџџџџџџџџџџџџNќrnbergDB0VOX BDB0VOX BDB0VOX Gˆž2€їs1р H ѓ<џџ3юАВWќrzburgDB0WZ BDB0WZ BDB0WZ G„K9Рn1.Œ# 6hѓ<џџ3юБГSchneebergDB0ZB BDB0ZB BDB0ZB G13€їs2ш 3ѓ<џџ3юВДџџџџџџџџџџџџџџџџBerlinDB0DF BDB0DF BDB0DF GdЊ1€їs4  ѓ<џџ4юГЕBernau / BerlinDB0TA BDB0TA BDB0TA GАА €їs4& $8ѓ<џџ4юДЖBremenDB0HFT BDB0HFT BDB0HFT G 2€їs5Ќ /дѓ<џџ6юЕЗџџџџџџџџџџџџџџџџHamburgDM0HMB EDM0HMB EDM0HMB GюО †5!Ь <ѓ<џџ7юЖИBaunatal/DARCDB0AFZ BDB0AFZ BDB0AFZ G8л1€їs3d дѓ<џџ8юЗЙFernwald/SteinbaDB0GIS BDB0GIS BDB0GIS GАА €їs2!,-Єѓ<џџ8юИКџџџџџџџџџџџџџџџџGroпer FeldbergDB0HRF BDB0HRF BDB0HRF Gy1€їs2 №#Рѓ<џџ8юЙЛRimbergDB0HRR CDB0HRR CDB0HRR G 4ЏР' 2/4! ,ѓ<џџ8юКМKleiner FeldbergDB0MOT BDB0MOT BDB0MOT GМH1€їs2  мѓ<џџ8юЛНџџџџџџџџџџџџџџџџGiessenDB0SIF BDB0SIF BDB0SIF G 2€їs2# (pѓ<џџ8юМОLќdersdorfDM0LUE BDM0LUE BDM0LUE G03€їs51( 1шѓ<џџ9юНПSagard / RuegenDM0RUG BDM0RUG BDM0RUG GаQ(€їs6!˜ #8ѓ<џџ9юОРџџџџџџџџџџџџџџџџBremerhavenDB0BHN BDB0BHN BDB0BHN G\Я2€їs5 Œ#"Аѓ<џџ:юПСOsterodeDB0OHA BDB0OHA BDB0OHA G13€їs3'ф% pѓ<џџ:юРТRoeddensenDB0ROE BDB0ROE BDB0ROE GX!€їs4(# :ѓ<џџ:юСУџџџџџџџџџџџџџџџџWilhelmshavenDB0WHV BDB0WHV BDB0WHV GH\#€їs5"Ф"4!ѓ<џџ:юТФBochumDB0BS CDB0BS CDB0BS G,}­Р' 3< |ѓ<џџ;юУХSiebengebirgeDB0DBN CDB0DBN CDB0DBN G,}­Р' 2(№#(#ѓ<џџ;юФЦџџџџџџџџџџџџџџџџDortmundDB0DDO CDB0DDO CDB0DDO GH–ЏР' 3ˆФ ѓ<џџ;юХЧSiegenDB0EIS BDB0EIS BDB0EIS GЂѓ1€їs22Д„ѓ<џџ;юЦШGummersbachDB0GM BDB0GM BDB0GM GP7"€їs2;(#ѓ<џџ;юЧЩџџџџџџџџџџџџџџџџMarlDB0NG BDB0NG BDB0NG Gиa3€їs3)Мѓ<џџ;юШЪKruftDB0LJ BDB0LJ BDB0LJ Gh27Рn2T јѓ<џџ<юЩЫHіhr-GrenzhausenDB0RPL BDB0RPL BDB0RPL GH\#€їs2ј+T$ѓ<џџ<юЪЬџџџџџџџџџџџџџџџџOberwiesenthalDB0FIB BDB0FIB BDB0FIB GЌ’3€їs2 9Ф ѓ<џџ>юЫЭLeipzigDM0LEI BDM0LEI BDM0LEI G8л1€їs3Œ „ѓ<џџ>юЬЮTangermќndeDB0AMK BDB0AMK BDB0AMK Gy1€їs2ш 3ѓ<џџ?юЭЯџџџџџџџџџџџџџџџџSchoenebeckDB0SLK BDB0SLK BDB0SLK G03€їs3:X &мѓ<џџ?юЮаHelgolandDB0HEL BDB0HEL BDB0HEL GИР+€їs6 „5аѓ<џџ@юЯбGeesthachtDB0OST BDB0OST BDB0OST GPl.€їs5м T$ѓ<џџ@юавџџџџџџџџџџџџџџџџMeuselwitzDB0ABL BDB0ABL BDB0ABL G`W8Рnь ѓ<џџAюбгHermsdorfDB0HDF BDB0HDF BDB0HDF G”7Рn26\ 3Єѓ<џџAювдSaalfeld / SaaleDB0SLF BDB0SLF BDB0SLF GD%€їs2%є ( ѓ<џџAюгеџџџџџџџџџџџџџџџџAthensAtticaSV1P BSV1P Gш1€їs%8l &&Ќ&ѓ<џџEюджPaianiaAtticaSW1I BSW1I G\š&€їs%8(#0ф%ѓ<џџEюезSerresCentralMacedoniaSZ7SER BSZ7SER G„,€їs)@ Аѓ<џџEюжиџџџџџџџџџџџџџџџџThessalonikiCentralMacedoniaSV2F BSV2F Gш1€їs(м єѓ<џџEюзйZante IslandIonian IslandsSV8S BSV8S Gш1€їs%, 7И$ѓ<џџEюикLesvos I/MitliniNorth AegeanSZ8LSV BSZ8LSV Gќ (€їs'Р!шѓ<џџEюйлџџџџџџџџџџџџџџџџVolosThessalySV4J BSV4J GЈе!€їs'Xtѓ<џџEюкмFlorinaWesternMacedoniaSZ2RLF BSZ2RLF Gt`/€їs(.Ш` ѓ<џџEюлнMt. ViglaWesternMacedoniaSV2Q BSV2Q Gt`/€їs(.Ф ѓ<џџEюмоџџџџџџџџџџџџџџџџЩrdPestHG7RUF BHG7RUF GЈе!€їs/М6Œ ѓ<џџFюнпReykjavikCapitalTF3RPI BTF3RPI GА9@KL?:М&Шћ<џџGюорL' AquilaAbruzzoIR6L CIR6L GPqЎР' * (# мѓ<џџPюпсџџџџџџџџџџџџџџџџMonte MaiellaAbruzzoIR6UCC BIR6UCC GTxЁ@KL* XИ$ѓ<џџPюртMonte MaiellaAbruzzoIR6UCC CIR6UCC GЬЏР' * XИ$ѓ<џџPюсуOrtonaAbruzzoIR6UCX BIR6UCX GЅ@KL*ќ!аѓ<џџPютфџџџџџџџџџџџџџџџџSulmonaAbruzzoIR6UDO BIR6UDO Gœ`Ѓj*| 7ѓ<џџPюухBariApuliaIR7UBA BIR7UBA G`лЅj(:Ј7мѓ<џџQюфцBariApuliaIR7UBA CIR7UBA Gдо­Р' (:Ј7мѓ<џџQюхчџџџџџџџџџџџџџџџџCavallinoApuliaIR7UBY AIR7UBY G(RM€УЩ(Ф" hѓ<џџQюцшCavallinoApuliaIR7UBY BIR7UBY GЈУЇ@KL(Ф" hѓ<џџQючщCavallinoApuliaIR7UBY CIR7UBY Gдо­Р' (Ф" hѓ<џџQюшъџџџџџџџџџџџџџџџџNevianoApuliaIR7UBP BIR7UBP G шЈ@KL(јєѓ<џџQющыCosenzaCalabriaIR8AF CIR8AF GPqЎР' 'Ашѓ<џџSюъьCosenzaCalabriaIR8BP CIR8BP GјвЎР' '4! ѓ<џџSюыэџџџџџџџџџџџџџџџџCosenzaCalabriaIR8UBW BIR8UBW GѓЃj'dœѓ<џџSюьюVillaSanGiovanniCalabriaIR8UCN CIR8UCN GteЏР' & t&јѓ<џџSюэяAvellinoCampaniaIR8UAF BIR8UAF GœУj(8М+Рѓ<џџTюю№џџџџџџџџџџџџџџџџBattipagliaCampaniaIR8BT BIR8BT GЈУЇ@KL($є:dѓ<џџTюяёNapoliCampaniaIR8AW BIR8AW GЈУЇ@KL(4ф Ф ѓ<џџTю№ђMonte CimoneEmilia-RomagnaIR4MO CIR4MO G„­Р' , H& *ф ѓ<џџUюёѓџџџџџџџџџџџџџџџџFontanafreddaFriuli V.G.IR3UBK AIR3UBK G@ІNM€УЩ.L ! ѓ<џџVюђєm.te Bernadia UdFriuli V.G.IR3EF CIR3EF G,}­Р' . pѓ<џџVюѓѕMonte Sabotino GFriuli V.G.IR3UJ BIR3UJ GxlЂj-;` %Ќ&ѓTџџVюєіџџџџџџџџџџџџџџџџPordenoneFriuli V.G.IR3UIB BIR3UIB GˆŒИj. xѓ<џџVюѕїTriesteFriuli V.G.IR3UIC BIR3UIC G0юИj-' . ѓ<џџVюіјUdineFriuli V.G.IR3UBZ BIR3UBZ GшoЯj.” Јѓ<џџVюїљџџџџџџџџџџџџџџџџRomaLazioIR0UHW AIR0UHW GаlГK?Ћ*ш hѓ<џџWюјњBernate TicinoLombardyIR2UEZ AIR2UEZ GxиRM€[-((#1 ѓ<џџYюљћBernate TicinoLombardyIR2UEZ BIR2UEZ GTтЙj-((#1 ѓ<џџYюњќџџџџџџџџџџџџџџџџCamposauroLombardyIR8BA CIR8BA GlŠАР' ) ,#@ѓ<џџYюћ§TorinoPiedmontIR1CJ CIR1CJ GlUЄ@B-8*4ѓ<џџ[юќўFirenzeSardiniaIR5UBO AIR5UBO G@ІNM€УЩ+4< lѓ<џџ\ю§џџџџџџџџџџџџџџџџџCaltagironeSiciliyIR9UBQ BIR9UBQ GШ/Ѓj%( œѓ<џџ]юўCataniaSiciliyIR9UBK BIR9UBK GXЇ@KL%"ќ!ќ!ѓ<џџ]юџSiracusaSiciliyIR9BR BIR9BR G`лЅ@KL%@ ѓ<џџ]юџџџџџџџџџџџџџџџџFigline ValdarnoToscanaIR5UBM BIR5UBM GTxЁj+(ќ! И ѓ<џџ^юFirenzeToscanaIR5AY CIR5AY GXL­Р' +0(  ѓ<џџ^юMonte Cascetto LToscanaIR5UBS BIR5UBS G њЗj+- ѓ<џџ^юџџџџџџџџџџџџџџџџValdarnoToscanaIR5AF CIR5AF GЬЏР' ++ "ьѓ<џџ^юTerniUmbriaIR0K BIR0K GмmІj*„ %ˆѓ<џџ`юTerniUmbriaIR0K CIR0K Gдо­Р' *„ %ˆѓ<џџ`юџџџџџџџџџџџџџџџџMonseliceVenetoIR3UEF CIR3UEF GиfГрШ-ќ ,Јѓ<џџaю FirenzeSardiniaIR5UBO BIR5UBO GИyЅj+4< lѓ<џџzю FirenzeSardiniaIR5UBO CIR5UBO GXL­Р' +4< lѓ<џџzю  џџџџџџџџџџџџџџџџBredaNorth BrabantPI1HWB BPI1HWB G р€їs3"@,Рѓ<џџ!dю  AmsterdamNorth HollandPI1RYS BPI1RYS Gа€їs43мѓ<џџ!dю  DelftSouth HollandPI1HGL BPI1HGL G*€їs4Ь` ѓ<џџ!dю џџџџџџџџџџџџџџџџDordrechtSouth HollandPI1DEC BPI1DEC G€Y€їs30М*ќѓ<џџ!dю DrammenBuskerudLD3DV BLD3DV GHSц€„;- И ѓ<џџ"eюKongsvingerHedmarkLD2KR BLD2KR GФхц€„<” И ѓ<џџ"eюџџџџџџџџџџџџџџџџOsloOsloLD1OT BLD1OT G˜ч€„;;€ (шѓ<џџ"eюBjerkreimRogalandLD4GA CLD4GA G,}­Р' :%4|ѓ<џџ"eюSandnesRogalandLD4VF CLD4VF G|@ЎР' :7 /Јѓ<џџ"eюџџџџџџџџџџџџџџџџTromsјTromsLD9TN BLD9TN G€…ъ€„E&%7|ѓ<џџ"eюKvinesdalVest-AgderLD4LK CLD4LK GЬЏР' :4 ѓ<џџ"eюKorfantѓwkaKuyavi-PomeraniaSR2VVV CSR2VVV Gиa3€їs5˜ѓ<џџ#fюџџџџџџџџџџџџџџџџKrakѓwLesser PolandSR9UVC BSR9UVC GР›*€їs1:8ѓ<џџ#fюRTCN KrakѓwLesser PolandSR9UVM BSR9UVM G@Ж0€їs19P№#ѓ<џџ#fюZakopaneLesser PolandSR9UVZ BSR9UVZ GЉ-€їs108xѓ<џџ#fюџџџџџџџџџџџџџџџџAѓdzAѓdzSR7UVL BSR7UVL G:*€їs3.4! ѓ<џџ#fюAѓdz Centrum AѓdzSR7ULD CSR7ULD G 4ЏР' 3-(#ѓ<џџ#fюPiaskowaAѓdzSR7UTM CSR7UTM GteЏР' 3 Ф"Аѓ<џџ#fюџџџџџџџџџџџџџџџџBiaBa PodlaskaLublinSR8UVB BSR8UVB Gч0€їs4 ь.hѓ<џџ#fюWBodawaLublinSR8UWD CSR8UWD G 4ЏР' 3!Р!lѓ<џџ#fюRadomMasoviaSR5UVR BSR5UVR GH\#€їs3t @ѓ<џџ#fю џџџџџџџџџџџџџџџџWarsawMasoviaSR5UVA BSR5UVA GМH1€їs4 ф%;€%ѓ<џџ#fю!BrzezieOpoleSR6UVO CSR6UVO G 4ЏР' 2-М4€%ѓ<џџ#fю "GibyPodlaskieSR4UG CSR4UG G$ЂЎР' 6H&tѓ<џџ#fю!#џџџџџџџџџџџџџџџџGdyniaPomeraniaSR2UVG BSR2UVG G з%€їs6@@ѓ<џџ#fъ"$KatowiceSilesiaSR9UVK CSR9UVK GlŠАР' 2`" ѓ<џџ#fю#%KielceZwitokrzyskieSR7UVK BSR7UVK G„,€їs23 єѓ<џџ#fю$&џџџџџџџџџџџџџџџџGmina PasBkWarmian-MasuriaSR4UVE CSR4UVE G$ЂЎР' 6H&'˜ѓ<џџ#fю%'SzczecinWest PomeraniaSR1UVS BSR1UVS Gч0€їs5Д „ѓ<џџ#fю&(PortalegreAlentejoCQ0DSM BCQ0DSM Gt+#€їs'Аьћ<џџ$gю')џџџџџџџџџџџџџџџџFѓiaAlgarveCQ0DFO BCQ0DFO G˜$€їs%(##T ћ<џџ$gю(*Serra CandieirosCentroCQ0DLR BCQ0DLR GH\#€їs' €%4ћ<џџ$gю)+Torres VedrasCentroCQ0DTV BCQ0DTV G8І%€їs'Є Dћ<џџ$gю*,џџџџџџџџџџџџџџџџRamadaLisbonCQ0DLX BCQ0DLX G№Н#€їs&0L ќ!ћ<џџ$gю+-ChavesNorteCQ0DBO CCQ0DBO GlŠАР' ))ќ!Œ ћ<џџ$gю,.Oliveira/AzemщisNorteCQ0DOA BCQ0DOA Gh§*€їs(2 Dћ<џџ$gю-/џџџџџџџџџџџџџџџџSan MarinoSan MarinoT79DV BT79DV G њЗj+8Є `"ѓ<џџ'jю.0LjubljanaCentral SloveniaS55DLJ BS55DLJ G€YРЯj.'˜ѓ<џџ*lю/1MariborDravaS55DMX BS55DMX GЉ-€їs.H&#ˆѓ<џџ*lю02џџџџџџџџџџџџџџџџMt. TrsteljGoriziaS55DGO BS55DGO G њ"€їs-3\ *` ѓ<џџ*lю13CѓrdobaAndalusiaED7ZAD BED7ZAD GH\#€їs%881˜ћ<џџ+mю24ZaragozaAragonED2ZAA BED2ZAA GАА €їs)& 5H&ћ<џџ+mю35џџџџџџџџџџџџџџџџAlgaidaBalearic IslandsED6ZAB BED6ZAB GP7"€їs'ш7Œ ѓ<џџ+mю46IrunBasque CountryED2ZAB CED2ZAB G˜YАР' +-єћ<џџ+mю57CuencaCastillaLaManchaED4ZAD BED4ZAD GX!€їs(˜` ћ<џџ+mю68џџџџџџџџџџџџџџџџBarcelonaCataloniaED3YAK CED3YAK GPqЎР' ) `"ѓ<џџ+mю79Castellar VallщsCataloniaEA3RCC BEA3RCC Gј˜"€їs)& Lѓ<џџ+mю8:MadridCmty. of MadridED4YAG BED4YAG GАА €їs(0(( ћ<џџ+mю9;џџџџџџџџџџџџџџџџColl de RatesValencian Cmty.ED5YAU BED5YAU GИ‹€їs&+0„ћ<џџ+mю:<DщniaValencian Cmty.ED5ZAC AED5ZAC G ‰eM?Ћ&2Ј0ѓ<џџ+mю;=DщniaValencian Cmty.ED5ZAC BED5ZAC G`э€їs&2Ј0ѓ<џџ+mю<>џџџџџџџџџџџџџџџџDщniaValencian Cmty.ED5ZAC CED5ZAC GЬЏР' &2Ј0ѓ<џџ+mю=?ValenciaValencian Cmty.ED5ZAB BED5ZAB GРf€їs')Рћ<џџ+mю>@VaxjoKronobergSK7HW BSK7HW Gрўш€„84и34!ѓ<џџ,nю?AџџџџџџџџџџџџџџџџGladsaxSkхneSK7RNQ CSK7RNQ G,}­Р' 7!4!ѓ<џџ,nю@BMinnesbergSkхneSK7RDS CSK7RDS Gю3­Р' 7 ѓ<џџ,nюACStockholmStockholmSK0MQ CSK0MQ G,}­Р' ;€%Œ#ѓ<џџ,nюBDџџџџџџџџџџџџџџџџTyresoStockholmSK0QO BSK0QO G˜ч€„;Ф дѓ<џџ,nюCEUmeaVфsterbottenSK2AT CSK2AT G@†ЄР' ?:h9˜!ѓ<џџ,nюDFVхrgхrdaVфstra GіtalandSK6DZ CSK6DZ G,}­Р' :@ 1@ѓ<џџ,nюEGџџџџџџџџџџџџџџџџBrienzBernHB9BO AHB9BO G€УKР./48ѓ<џџ-oъFHBrienzBernHB9BO BHB9BO Gˆž2€їs./48ѓ<џџ-oюGIBrienzBernHB9BO CHB9BO Gдо­Р' ./48ѓ<џџ-oюHJџџџџџџџџџџџџџџџџFalkenfluhBernHB9BG BHB9BG GO €їs.1ј& ѓ<џџ-oюIKMenznauLuzernHB9AW BHB9AW G„,€їs/Шмѓ<џџ-oюJLMenznauLuzernHB9AW CHB9AW GlŠАР' /Шмѓ<џџ-oюKMџџџџџџџџџџџџџџџџRigi-ScheideggSchwyzHB9RF BHB9RF GdЊ1€їs/dф ѓ<џџ-oюLNBraunauThurgauHB9HD CHB9HD G,}­Р' /ш Ф"ѓ<џџ-oюMOMonte TamaroTicinoHB9H BHB9H G03€їs.$4˜!ѓ<џџ-oюNPџџџџџџџџџџџџџџџџMotto RotondoTicinoHB9DD BHB9DD G@Ж0€їs.$4ќ!ѓ<џџ-oюOQLa BarilletteVaudHB9IAC BHB9IAC GЌ’3€їs.|ѓ<џџ-oюPRLa BarilletteVaudHB9IAC CHB9IAC GФ(АР' .|ѓ<џџ-oюQSџџџџџџџџџџџџџџџџUetlibergZќrichHB9ZRH CHB9ZRH GXL­Р' /ф%”ѓ<џџ-oюRTSt HelensGB7DV BGB7DV BGB7DV GTє3@T‰5 -И$ћ8џџ/ŒъSUCleveleysGB7FC BGB7FC BGB7FC Gр<2@T‰54ˆ„ћ8џџ/ŒюTVџџџџџџџџџџџџџџџџSouth CaveGB7HU BGB7HU BGB7HU G 2@T‰5.м!ќћ8џџ/ŒюUWBarnsleyGB7NA AGB7NA AGB7NA G :SM€[5!Ќ&Œ ћ8џџ/ŒъVXBarnsleyGB7NA BGB7NA BGB7NA Gy1@T‰5!Ќ&Œ ћ8џџ/ŒюWYџџџџџџџџџџџџџџџџBarnsleyGB7NA CGB7NA CGB7NA GјвЎР' 5!Ќ&Œ ћ8џџ/ŒюXZDurhamGB7PB CGB7PB CGB7PB G$ЂЎР' 6,„|ћ8џџ/ŒюY[AlfretonGB3IN CGB3IN CGB3IN G|@ЎР' 5@аћ8џџ/юZ\џџџџџџџџџџџџџџџџStoke-on-TrentGB3VT CGB3VT CGB3VT GH–ЏР' 4 (#ћ8џџ/ю[]BecclesGB7BE BGB7BE BGB7BE GЄЗ4@T‰4œ#Xѓ8џџ/ю\^SkegnessGB7DL BGB7DL BGB7DL Gxш4@T‰5 œ( ћ8џџ/ю]_џџџџџџџџџџџџџџџџMilton KeynesGB7BP BGB7BP BGB7BP Gy1@T‰3;4!,ћ8џџ/Žю^`EastbourneGB7ES BGB7ES BGB7ES GМH1@T‰21єPћ8џџ/Žю_aHerne BayGB7IC AGB7IC AGB7IC GСэL-13 `"ѓ8џџ/Žю`bџџџџџџџџџџџџџџџџHerne BayGB7IC BGB7IC BGB7IC Gy1@T‰3 `"ѓ8џџ/ŽюacHerne BayGB7IC CGB7IC CGB7IC G$ЂЎР' 3 `"ѓ8џџ/ŽюbdBeckenhamGB7OK CGB7OK CGB7OK GteЏР' 34Œ#ћ8џџ/ŽюceџџџџџџџџџџџџџџџџRoystonGB7PI BGB7PI BGB7PI GD>6@T‰4 Lћ8џџ/ŽюdfClacton-on-SeaGB7TE CGB7TE CGB7TE G˜YАР' 30 Œ#ѓ8џџ/ŽюegChelmsfordGB7ZP BGB7ZP BGB7ZP G 2@T‰3-˜!єѓ8џџ/ŽюfhџџџџџџџџџџџџџџџџSt HelierGB7JI BGB7JI BGB7JI Gа?Ў€їs1˜!ќ!ћ8џџ/юgiFarehamGB7RN CGB7RN CGB7RN G|@ЎР' 22X И ћ8џџ/юhjBewdleyGB7WF BGB7WF BGB7WF G 2@T‰4Ьœћ8џџ/юikџџџџџџџџџџџџџџџџGreat MalvernGB7WR BGB7WR BGB7WR GdЊ1@T‰4ш( ћ8џџ/юjlNairnGB7MM BGB7MM BGB7MM Gp 6@T‰9"„5шћ8џџ/‘юkmOmaghGB7WT BGB7WT BGB7WT G€У3@T‰6) ћ8џџ/’юlnџџџџџџџџџџџџџџџџBristolConnecticutW1IXU BW1IXU GиЈЙ@KL)&Ќ&H8ћ$џџ2–шmoBristolConnecticutW1IXU CW1IXU G ЉІР' )&T$H8а ћ$џџ2–юnpEnfieldConnecticutK1CDG BK1CDG Gtг„@KL)/hH$xћ$џџ2–шoqџџџџџџџџџџџџџџџџHaddamConnecticutKB1UHS BKB1UHS GpK@KL)H%„ћ$џџ2–шprKillinglyConnecticutN1GAU BN1GAU G mx@KL)/РG1H ћ$џџ2–шqsMeridenConnecticutW1ECV BW1ECV GЗz@KL)!LH2Шћ$џџ2–шrtџџџџџџџџџџџџџџџџMeridenConnecticutW1ECV CW1ECV GPЌР' )!LH2Шћ$џџ2–шsuNewingtonConnecticutW1HQ AW1HQ GH1ŠLЗ)*`"H+Мћ$џџ2–шtvNewingtonConnecticutW1HQ BW1HQ G щY@KL)*`"H+Мћ$џџ2–шuwџџџџџџџџџџџџџџџџNewingtonConnecticutW1HQ CW1HQ G0ўШР' )*`"H+Мћ$џџ2–шvxNorwalkConnecticutW1NLK BW1NLK GHR@KL)T$IXћ$џџ2–шwySalemConnecticutKD1STR BKD1STR G@Пm@KL)HLћ$џџ2–шxzџџџџџџџџџџџџџџџџVernonConnecticutAA1HD BAA1HD GpЌZ@KL)0HИ ћ$џџ2–шy{VernonConnecticutAA1HD CAA1HD Gр}ЈР' )0HИ ћ$џџ2–шz|WestbrookConnecticutW1BCG BW1BCG Gчv@KL)Ф"H˜ћ$џџ2–ш{}џџџџџџџџџџџџџџџџBiddefordMaineKC1ALA CKC1ALA GАTХР' + F<ћ$џџ2–ш|~BrunswickMaineKS1R BKS1R Gиs­@KL+1дE1<ћ$џџ2–ю}CaribouMaineKA1EAR BKA1EAR GРo[@KL.3а C;`"ћ$џџ2–ш~€џџџџџџџџџџџџџџџџCooperMaineW1SCV CW1SCV G(аТР' ,;( Cћ$џџ2–шHebronMaineKC1SBG BKC1SBG G0>|@KL,єFћ$џџ2–ш€‚TurnerMaineKB1VFA CKB1VFA G€ЊР' ,€%Fф%ћ$џџ2–шƒџџџџџџџџџџџџџџџџBrocktonMassachusettsKB1YAC BKB1YAC GxdЧ@KL* F6Мћ$џџ2–ш‚„BrooklineMassachusettsK1MRA CK1MRA G@їІР' *РGФ ћ$џџ2–шƒ…BrooklineMassachusettsW1MRA BW1MRA Gш^З@KL*LG"Мћ$џџ2–ъ„†џџџџџџџџџџџџџџџџDartmouthMassachusettsKC1BJB AKC1BJB G 1M-1)%ЄF:”ћ$џџ2–ш…‡DartmouthMassachusettsKC1BJB BKC1BJB GаZe@KL)%ЄF:”ћ$џџ2–ш†ˆDartmouthMassachusettsKC1BJB CKC1BJB GѓЈР' )%ЄF:”ћ$џџ2–ш‡‰џџџџџџџџџџџџџџџџFall RiverMassachusettsK1RFI AK1RFI G сЇР' )- G дћ$џџ2–шˆŠFall RiverMassachusettsK1RFI BK1RFI G5Ы@KL)- G дћ$џџ2–ш‰‹Fall RiverMassachusettsK1RFI CK1RFI GрюЊР' )- G дћ$џџ2–шŠŒџџџџџџџџџџџџџџџџFalmouthMassachusettsKB1ZEG CKB1ZEG GКЇР' )$а F#(#ћ$џџ2–ш‹Feeding HillsMassachusettsW1KK AW1KK G eqLЗ* H*ќћ$џџ2–юŒŽFeeding HillsMassachusettsW1KK BW1KK GинХ@KL* H*ќћ$џџ2–шџџџџџџџџџџџџџџџџFeeding HillsMassachusettsW1KK CW1KK G0аІР' * H*ќћ$џџ2–ъސFreetownMassachusettsKB1WUW BKB1WUW G˜Я@KL)-Ќ Gшћ$џџ2–ш‘FreetownMassachusettsKB1WUW CKB1WUW GиаЫ@B)-Ќ Gшћ$џџ2–ш’џџџџџџџџџџџџџџџџHollistonMassachusettsW1DSR BW1DSR GИвЅ@KL* G Lћ$џџ2–ш‘“HollistonMassachusettsW1DSR CW1DSR G ЉІР' * G Lћ$џџ2–ю’”HolyokeMassachusettsAA1KK BAA1KK G˜fЊ@KL*XH&№#ћ$џџ2–ш“•џџџџџџџџџџџџџџџџMarshfieldMassachusettsW1ATD CW1ATD GАyЊР' *dF*№ ћ$џџ2–ю”–North OxfordMassachusettsKC1ACI BKC1ACI GјпЈ@KL*5G5ћ$џџ2–ш•—NorwellMassachusettsAC1M CAC1M GаVЈР' * F1№ ћ$џџ2–ю–˜џџџџџџџџџџџџџџџџWalpoleMassachusettsWA1PLE BWA1PLE G|œ@KL*˜!G ћ$џџ2–ш—™West BridgewaterMassachusettsKA1GG BKA1GG GЌCв@KL*DGћ$џџ2–ш˜šWestfordMassachusettsWB1GOF BWB1GOF GP@_@KL*"дG\ћ$џџ2–ъ™›џџџџџџџџџџџџџџџџWestfordMassachusettsWB1GOF CWB1GOF GPЉР' *"дG\ћ$џџ2–ъšœFremontNew HampshireN1HIT BN1HIT GјIС@KL+ ШF7№#ћ$џџ2–ш›FremontNew HampshireN1HIT CN1HIT G@hЉР' + ШF7№#ћ$џџ2–шœžџџџџџџџџџџџџџџџџGoffstownNew HampshireNE1DV BNE1DV G˜1ž@KL*:Ќ&G#T ћ$џџ2–шŸHamptonNew HampshireK1HBR BK1HBR GИqЪ@KL*6ЈF0ќ!ћ$џџ2–шž HamptonNew HampshireK1HBR CK1HBR G=ЋР' *6ЈF0ќ!ћ$џџ2–шŸЁџџџџџџџџџџџџџџџџKensingtonNew HampshireKB1TIX CKB1TIX GР ЊР' *7шF9ћ$џџ2–ш ЂSalemNew HampshireK1HRO AK1HRO G@M-1*/<G H&ћ$џџ2–шЁЃSalemNew HampshireK1HRO BK1HRO G0>|@KL*/<G H&ћ$џџ2–ъЂЄџџџџџџџџџџџџџџџџSalemNew HampshireK1HRO CK1HRO G@hЉР' */<G H&ћ$џџ2–шЃЅTwin MountainNew HampshireKB1UVE BKB1UVE G3\@KL+xF2Œ#ћ$џџ2–шЄІWindhamNew HampshireKC1EGN CKC1EGN G`ЭК`у*/( GДћ$џџ2–шЅЇџџџџџџџџџџџџџџџџPortsmouthRhode IslandW1AAD CW1AAD G ЉР' )!( GLћ$џџ2–юІЈW.WarwickRhode IslandW1HDN CW1HDN GˆКУР' )'T$Glћ$џџ2–шЇЉAtlantic CityNew JerseyKC2TGB BKC2TGB Gиs­@KL'ф%J№ ћ$џџ2—ъЈЊџџџџџџџџџџџџџџџџBridgetonNew JerseyKC2TXB BKC2TXB G^‹@KL'8K ић$џџ2—шЉЋCedar GroveNew JerseyW2DGL AW2DGL G`M-1(3PJћ$џџ2—шЊЌCedar GroveNew JerseyW2DGL BW2DGL GШрA@KL(3PJћ$џџ2—шЋ­џџџџџџџџџџџџџџџџCedar GroveNew JerseyW2DGL CW2DGL GШ’К@B(3PJћ$џџ2—шЌЎGlassboroNew JerseyKC2TXX BKC2TXX G };@KL'*hKић$џџ2—ш­ЏKendall ParkNew JerseyKC2WBJ BKC2WBJ Glј…@KL(Ќ J!Ф ћ$џџ2—шЎАџџџџџџџџџџџџџџџџLake HopatcongNew JerseyNJ2MC BNJ2MC GHR@KL(8hJ$xћ$џџ2—шЏБLake HopatcongNew JerseyNJ2MC CNJ2MC G№ЋР' (8hJ$xћ$џџ2—юАВLindenwoldNew JerseyK2EOC BK2EOC G&–=@KL'1АJ9мћ$џџ2—шБГџџџџџџџџџџџџџџџџMartinsvilleNew JerseyNJ2DG ANJ2DG GIˆLЗ($J"ћ$џџ2—шВДMartinsvilleNew JerseyNJ2DG BNJ2DG GP S@KL($J"ћ$џџ2—шГЕMartinsvilleNew JerseyNJ2DG CNJ2DG G ЉІР' ($J"ћ$џџ2—юДЖџџџџџџџџџџџџџџџџOceanviewNew JerseyNJ2CM BNJ2CM G6L;@KL' J- ћ$џџ2—шЕЗVinelandNew JerseyK2GOD BK2GOD Gшєž@KL'Ф J;H&ћ$џџ2—шЖИWoodstownNew JerseyNJ2SC BNJ2SC GRЃ†@KL'&KДћ$џџ2—шЗЙџџџџџџџџџџџџџџџџAlbanyNew YorkWA2UMX BWA2UMX G 8l@KL*%XJXћ$џџ2—ъИКBabylonNew YorkW2TOB BW2TOB GЎ=@KL(*Ќ Iьћ$џџ2—юЙЛBrooklynNew YorkWG2MSK BWG2MSK GИh@KL((мI:Xћ$џџ2—шКМџџџџџџџџџџџџџџџџBuffaloNew YorkKC2ZCE CKC2ZCE GˆIСР' *%8N+€%ћ$џџ2—шЛНCarmelNew YorkK2PUT BK2PUT G8ƒ“@KL),I+ьћ$џџ2—юМОClydeNew YorkKA2NDW BKA2NDW GИЩh@KL*;( L8аћ$џџ2—юНПџџџџџџџџџџџџџџџџFairportNew YorkKB2VZS BKB2VZS Gƒ@KL+МMаћ$џџ2—шОРFredoniaNew YorkKD2MNA CKD2MNA GxЦР' *O˜ћ$џџ2—шПСGasportNew YorkKD2STR BKD2STR GL"r@KL+ф N!œћ$џџ2—шРТџџџџџџџџџџџџџџџџHauppaugeNew YorkWD2NY BWD2NY GМ†z@KL(00I Аћ$џџ2—шСУHauppaugeNew YorkWD2NY CWD2NY G№УР' (00I Аћ$џџ2—шТФHaverstrawNew YorkW2LGB BW2LGB GЌЦ@KL)$И J`"ћ$џџ2—шУХџџџџџџџџџџџџџџџџHemlockNew YorkK2BWK BK2BWK GрEo@KL*.M ћ$џџ2—шФЦHemlockNew YorkK2BWK CK2BWK G˜УШР' *.M ћ$џџ2—ъХЧIthacaNew YorkAF2A BAF2A Gш“У@KL*аL\ћ$џџ2—шЦШџџџџџџџџџџџџџџџџNew YorkNew YorkK2DIG AK2DIG G@M-1(,№#I;xћ$џџ2—шЧЩNew YorkNew YorkK2DIG BK2DIG Gx[Š@KL(,№#I;xћ$џџ2—шШЪNiagara FallsNew YorkKD2GBR BKD2GBR G|Ўƒ@KL+ N2ћ$џџ2—шЩЫџџџџџџџџџџџџџџџџOtisvilleNew YorkK9RRD BK9RRD GЖМ@KL)J"„ћ$џџ2—шЪЬStanleyNew YorkKD2HVC BKD2HVC Gрz{@KL*0pMф ћ$џџ2—шЫЭThiellsNew YorkKD2EQY BKD2EQY Gј~Э@KL) шJИ$ћ$џџ2—шЬЮџџџџџџџџџџџџџџџџValhallaNew YorkW2ECA BW2ECA GlЬЖ@KL) I0 ћ$џџ2—шЭЯWestburyNew YorkNC2EC BNC2EC GЖМ@KL(-˜!I!@ћ$џџ2—шЮаWestburyNew YorkNC2EC CNC2EC GАОР' (-˜!I!@ћ$џџ2—юЯбџџџџџџџџџџџџџџџџWashingtonDst. of ColumbiaW3AGB BW3AGB GФay@KL&5€%MLћ$џџ2˜шавBelairMarylandKO3L CKO3L G€пФР' '#XL№ ћ$џџ2˜шбгChesapeake BeachMarylandWG3K BWG3K G0>|@KL&%ˆLмћ$џџ2˜швдџџџџџџџџџџџџџџџџForest HillMarylandKB3TOG AKB3TOG G`=ЗKЗ'"а Ll ћ$џџ2˜шгеForest HillMarylandKB3TOG BKB3TOG G,ПГ@KL'"а Ll ћ$џџ2˜шджForest HillMarylandKB3TOG CKB3TOG G[ІР' '"а Ll ћ$џџ2˜шезџџџџџџџџџџџџџџџџFrederickMarylandW3FDK BW3FDK Gƒ@KL'M№#ћ$џџ2˜шжиGermantownMarylandKV3B BKV3B G@єy@KL' <MИ ћ$џџ2˜юзйLexington ParkMarylandN3PX AN3PX GРЖLЗ&4!L"l ћ$џџ2˜шикџџџџџџџџџџџџџџџџLexington ParkMarylandN3PX BN3PX G mx@KL&4!L"l ћ$џџ2˜шйлLexington ParkMarylandN3PX CN3PX GxЦР' &4!L"l ћ$џџ2˜шкмSalisburyMarylandW3PRO BW3PRO G@єy@KL&tK#мћ$џџ2˜ълнџџџџџџџџџџџџџџџџSalisburyMarylandW3PRO CW3PRO GЬЈР' &tK#мћ$џџ2˜ъмоTowsonMarylandW3DHS AW3DHS GрrtLЗ'L$ћ$џџ2˜шнпTowsonMarylandW3DHS BW3DHS GєZ@KL'L$ћ$џџ2˜шорџџџџџџџџџџџџџџџџTowsonMarylandW3DHS CW3DHS G ЉІР' 'L$ћ$џџ2˜шпсAllentownPennsylvaniaW3OI BW3OI GшІ@KL("ШKxћ$џџ2˜ъртAllentownPennsylvaniaW3OI CW3OI GHХР' ("ШKxћ$џџ2˜ъсуџџџџџџџџџџџџџџџџAtlanticPennsylvaniaK3AWS CK3AWS GАTХР' )иPDћ$џџ2˜штфDrexel HillPennsylvaniaN3AEC BN3AEC Gцˆ:@KL'9№ KЌ&ћ$џџ2˜шухEaglevillePennsylvaniaAA3E AAA3E GижJЗ( \KLћ$џџ2˜ъфцџџџџџџџџџџџџџџџџEaglevillePennsylvaniaAA3E BAA3E G~r†@KL( \KLћ$џџ2˜юхчEast StroudsburgPennsylvaniaKB3TEM CKB3TEM G№,МР' )МK ˜!ћ$џџ2˜шцшGreensburgPennsylvaniaWC3PS AWC3PS G€ЭІLЗ(XOШћ$џџ2˜шчщџџџџџџџџџџџџџџџџGreensburgPennsylvaniaWC3PS BWC3PS GpЌZ@KL(XOШћ$џџ2˜шшъGreensburgPennsylvaniaWC3PS CWC3PS G=ЋР' (XOШћ$џџ2˜шщыGreenvillePennsylvaniaK3WRB CK3WRB G№ЋР' )а Pмћ$џџ2˜шъьџџџџџџџџџџџџџџџџKylertownPennsylvaniaW3PHB CW3PHB GиюЦР' (;N%ћ$џџ2˜шыэLimaPennsylvaniaW3AEC BW3AEC GКЙ:@KL'7шKDћ$џџ2˜шьюMohrsvillePennsylvaniaK3TI BK3TI GАŽ@KL(ЄLl ћ$џџ2˜шэяџџџџџџџџџџџџџџџџNazarethPennsylvaniaW3OK CW3OK G№3ІР' (,ьKаћ$џџ2˜ъю№New CastlePennsylvaniaKB3YBB BKB3YBB GИЩh@KL(;P@ћ$џџ2˜юяёPhiladelphiaPennsylvaniaK3PDR BK3PDR GBэˆ@KL(И$K ќ!ћ$џџ2˜ъ№ђџџџџџџџџџџџџџџџџPhiladelphiaPennsylvaniaK3PDR CK3PDR GPНР' (И$K ќ!ћ$џџ2˜юёѓPittsburghPennsylvaniaW3EXW BW3EXW G0>|@KL(O94!ћ$џџ2˜шђєPittsburghPennsylvaniaW3EXW CW3EXW G KРР' (O94!ћ$џџ2˜шѓѕџџџџџџџџџџџџџџџџSchnecksvillePennsylvaniaW3EPE BW3EPE G(˜‰@KL()Ф K%` ћ$џџ2˜шєіUniversity ParkPennsylvaniaK3CR CK3CR G+ЊР' (/МM3 ћ$џџ2˜шѕїWarrenPennsylvaniaKB3BSA BKB3BSA Ghб[@KL)0Oќћ$џџ2˜шіјџџџџџџџџџџџџџџџџAnnistonAlabamaWB4GNA BWB4GNA GЈо^@KL!АU0|ћ џџ2™шїљBirminghamAlabamaK4DSO AK4DSO G@!LЗ!ЬV'€%ћ џџ2™шјњBirminghamAlabamaK4DSO BK4DSO GВj@KL!ЬV'€%ћ џџ2™шљћџџџџџџџџџџџџџџџџBirminghamAlabamaK4DSO CK4DSO GаЧЊР' !ЬV'€%ћ џџ2™ъњќBirminghamAlabamaKI4SBB AKI4SBB G eqLЗ!XV0Dћ џџ2™шћ§BirminghamAlabamaKI4SBB BKI4SBB GX…v@KL!XV0Dћ џџ2™шќўџџџџџџџџџџџџџџџџBirminghamAlabamaKI4SBB CKI4SBB GъЃ %&!XV0Dћ џџ2™ю§џBirminghamAlabamaKO4TM BKO4TM Gx‡Y@KL!ЄV.˜!ћ џџ2™шўBirminghamAlabamaKO4TM CKO4TM G€PЧР' !ЄV.˜!ћ џџ2™шџџџџџџџџџџџџџџџџџClantonAlabamaW4AEC AW4AEC G eqL МО /а V"Lћ џџ2™шClantonAlabamaW4AEC BW4AEC GиŸ|@KL /а V"Lћ џџ2™шClantonAlabamaW4AEC CW4AEC G`EЇР' /а V"Lћ џџ2™юџџџџџџџџџџџџџџџџEnterpriseAlabamaKJ4OTP BKJ4OTP GMb@KL ШUф ћ џџ2™шFayetteAlabamaKK4QXJ CKK4QXJ GР ЊР' !*ќ!W0Œ#ћ џџ2™юFt PayneAlabamaKI4SAY AKI4SAY G eqLЗ"@U)ћ џџ2™шџџџџџџџџџџџџџџџџFt PayneAlabamaKI4SAY BKI4SAY GHšl@KL"@U)ћ џџ2™шFt PayneAlabamaKI4SAY CKI4SAY G=ЋР' "@U)ћ џџ2™ш GadsdenAlabamaK4RBC BK4RBC GXК‚@KL"№#Vpћ џџ2™ш џџџџџџџџџџџџџџџџGadsdenAlabamaK4RBC CK4RBC GPЌР' "№#Vpћ џџ2™ю  GuntersvilleAlabamaKI4RYX CKI4RYX G ЉІР' "рV № ћ џџ2™ъ  HamiltonAlabamaKI4WX BKI4WX G№Ц`@KL"LX<ћ џџ2™ш  џџџџџџџџџџџџџџџџHuntsvilleAlabamaW4WBC AW4WBC G@‹—LЗ"ЬV$Ф ћ џџ2™ш HuntsvilleAlabamaW4WBC BW4WBC Gш n@KL"ЬV$Ф ћ џџ2™ш HuntsvilleAlabamaW4WBC CW4WBC G€ЊР' "ЬV$Ф ћ џџ2™юџџџџџџџџџџџџџџџџMagnolia SpringsAlabamaKI4SAZ AKI4SAZ G@‹—LЗФ"W1dћ џџ2™шMagnolia SpringsAlabamaKI4SAZ BKI4SAZ Gрz{@KLФ"W1dћ џџ2™шMagnolia SpringsAlabamaKI4SAZ CKI4SAZ G0AЉР' Ф"W1dћ џџ2™шџџџџџџџџџџџџџџџџMentoneAlabamaKI4SBC BKI4SBC Gш n@KL"(@V"аћ џџ2™шMentoneAlabamaKI4SBC CKI4SBC G€ЊР' "(@V"аћ џџ2™шMillportAlabamaKN4BOF CKN4BOF GР/ЈР' !!XX<ћ џџ2™юџџџџџџџџџџџџџџџџMobileAlabamaW4IAX BW4IAX G Ђ„@KL$T X Ф ћ џџ2™шMobileAlabamaW4IAX CW4IAX GАyЊР' $T X Ф ћ џџ2™шMontgomeryAlabamaW4AP AW4AP GIˆLЗ ˜V Єћ џџ2™шџџџџџџџџџџџџџџџџMontgomeryAlabamaW4AP BW4AP GX…v@KL ˜V Єћ џџ2™шMontgomeryAlabamaW4AP CW4AP G@вСР' ˜V Єћ џџ2™шOpelikaAlabamaW4LEE CW4LEE G˜УШР' &дU(#ћ џџ2™ъџџџџџџџџџџџџџџџџRoanokeAlabamaKJ4JNX AKJ4JNX GРyLЗ! рUћ џџ2™шRoanokeAlabamaKJ4JNX BKJ4JNX G Ђ„@KL! рUћ џџ2™шRoanokeAlabamaKJ4JNX CKJ4JNX GР ЊР' ! рUћ џџ2™шџџџџџџџџџџџџџџџџTrussvilleAlabamaKK4YOE BKK4YOE G щY@KL!'xV%Шћ џџ2™ш TrussvilleAlabamaKK4YOE CKK4YOE G€"ЅР\!'xV%Шћ џџ2™ш!TuscaloosaAlabamaW4KCQ AW4KCQ G€cŽLЗ! € WШћ џџ2™ш "џџџџџџџџџџџџџџџџTuscaloosaAlabamaW4KCQ BW4KCQ Gј x@KL! € WШћ џџ2™ш!#TuscaloosaAlabamaW4KCQ CW4KCQ GШНР' ! € WШћ џџ2™ю"$VernonAlabamaKC4UG AKC4UG G 1M-1!,PXPћ џџ2™ш#%џџџџџџџџџџџџџџџџVernonAlabamaKC4UG BKC4UG GЗz@KL!,PXPћ џџ2™ш$&VernonAlabamaKC4UG CKC4UG G[ІР' !,PXPћ џџ2™ш%'BartowFloridaWC4PEM BWC4PEM GLW~@KL4ЄQ0%ћ$џџ2™ш&(џџџџџџџџџџџџџџџџCocoaFloridaKJ4OXT CKJ4OXT GˆКУР' P,Аћ$џџ2™ш')CrestviewFloridaKO4EOC AKO4EOC G ЌїL-1.V!€%ћ$џџ2™ш(*CrestviewFloridaKO4EOC BKO4EOC GР€@KL.V!€%ћ$џџ2™ш)+џџџџџџџџџџџџџџџџCrestviewFloridaKO4EOC CKO4EOC G0аІР' .V!€%ћ$џџ2™ш*,Daytona BeachFloridaKJ4RYH CKJ4RYH G RЊР' аQ@ћ$џџ2™ш+-DeFuniak SpringsFloridaN4EMA BN4EMA G`+i@KL+јVdћ$џџ2™ш,.џџџџџџџџџџџџџџџџFort LauderdaleFloridaW4AB BW4AB GP@_@KLќ!Pˆћ$џџ2™ш-/Fort MyersFloridaW4LCO BW4LCO G‚n@KL#ќQ2<ћ$џџ2™ш.0Fort PierceFloridaW4AKH BW4AKH G ˆ~@KLŒ Phћ$џџ2™ъ/1џџџџџџџџџџџџџџџџFt LauderdaleFloridaW4BUG AW4BUG G€@ќL-1 <Pдћ$џџ2™ш02Ft LauderdaleFloridaW4BUG BW4BUG GРo[@KL <Pдћ$џџ2™ш13Ft LauderdaleFloridaW4BUG CW4BUG G`ЖЉР'  <Pдћ$џџ2™ш24џџџџџџџџџџџџџџџџJacksonvilleFloridaW4RNG CW4RNG G6СР' @Q&€%ћ$џџ2™ш35Jacksonville BCHFloridaKJ4RYG CKJ4RYG G€ЊР' ќQјћ$џџ2™ш46KissimmeeFloridaN4ARG BN4ARG GаФ}@KL,Qtћ$џџ2™ъ57џџџџџџџџџџџџџџџџKissimmeeFloridaN4ARG CN4ARG G?ЦР' ,Qtћ$џџ2™ъ68Madeira BeachFloridaW4THE BW4THE G ˆ~@KL0„R/№#ћ$џџ2™ш79MelbourneFloridaK4RPT BK4RPT G(ФX@KLDP$ќћ$џџ2™ш8:џџџџџџџџџџџџџџџџMiamiFloridaW4NVU BW4NVU Gј x@KL/P „ћ$џџ2™ш9;MiamiFloridaW4NVU CW4NVU GXEУР' /P „ћ$џџ2™ш:<MiamiFloridaWD4ARC CWD4ARC GPЉР' - PРћ$џџ2™ю;=џџџџџџџџџџџџџџџџMiltonFloridaKI4WZA BKI4WZA GH…@KL#€ W€ ћ$џџ2™ъ<>MiltonFloridaKI4WZA CKI4WZA GаШР' #€ W€ ћ$џџ2™ъ=?NaplesFloridaAA4PP AAA4PP G(RM€УЩDQ+,ћ$џџ2™ш>@џџџџџџџџџџџџџџџџNaplesFloridaAA4PP BAA4PP G`СP@KLDQ+,ћ$џџ2™ш?ANaplesFloridaAA4PP CAA4PP GPЌР' DQ+,ћ$џџ2™ш@BNaplesFloridaAB4FL BAB4FL G%РР' LQ/ˆћ$џџ2™шACџџџџџџџџџџџџџџџџNorth NaplesFloridaAC4FL BAC4FL Gјжk@KL H&QPћ$џџ2™шBDOcalaFloridaKG4NXO BKG4NXO GИўt@KL PR Dћ$џџ2™ъCEOcalaFloridaKG4NXO CKG4NXO GPЇР'  PR Dћ$џџ2™юDFџџџџџџџџџџџџџџџџOcalaFloridaKK4DFC CKK4DFC GpжПР'  ДR”ћ$џџ2™юEGOrlandoFloridaK1XC AK1XC G@‹—LЗ!АQф ћ$џџ2™шFHOrlandoFloridaK1XC BK1XC Gјжk@KL!АQф ћ$џџ2™шGIџџџџџџџџџџџџџџџџOrlandoFloridaK1XC CK1XC G KРР' !АQф ћ$џџ2™юHJOrlandoFloridaKN4DCI BKN4DCI GHšl@KL!H QДћ$џџ2™шIKOrlandoFloridaW4AES BW4AES G(.q@KL|Q,ћ$џџ2™юJLџџџџџџџџџџџџџџџџOrlandoFloridaWD4WDW BWD4WDW G€bX@KL Qќ!ћ$џџ2™шKMPalm BeachFloridaK4WPB CK4WPB G@hЉР' 'P@ћ$џџ2™шLNPalm CoastFloridaKA4RES CKA4RES G@hЉР' Qаћ$џџ2™юMOџџџџџџџџџџџџџџџџPalm CoastFloridaKG4TCC AKG4TCC GРЗM-1 `"Q Дћ$џџ2™шNPPalm CoastFloridaKG4TCC BKG4TCC GX]@KL `"Q Дћ$џџ2™шOQSanfordFloridaW4PLB BW4PLB G`і\@KL0ШQЬћ$џџ2™юPRџџџџџџџџџџџџџџџџSanfordFloridaW4PLB CW4PLB G@їІР' 0ШQЬћ$џџ2™юQSSt.PetersburgFloridaW4ICY BW4ICY G0дc@KL3Ќ R'4ћ$џџ2™шRTStuartFloridaKB4DD CKB4DD G=ЋР' Ќ&P H ћ$џџ2™юSUџџџџџџџџџџџџџџџџSun City CenterFloridaW1SCC BW1SCC GP@_@KL* RDћ$џџ2™юTVSun City Center FloridaW1SCC CW1SCC G$ ЧР' *Rћ$џџ2™шUWTallahasseeFloridaNF4DG ANF4DG G@M-1hTЄћ$џџ2™шVXџџџџџџџџџџџџџџџџTallahasseeFloridaNF4DG BNF4DG G‚n@KLhTЄћ$џџ2™шWYTallahasseeFloridaNF4DG CNF4DG G8†РР' hTЄћ$џџ2™шXZTampaFloridaW4RNT BW4RNT GдLƒ@KLdRћ$џџ2™юY[џџџџџџџџџџџџџџџџTavaresFloridaKJ4TJD BKJ4TJD G ˆ~@KL1мQ.№ ћ$џџ2™шZ\TavaresFloridaKK4KYK BKK4KYK G`+i@KL0 Q+ћ$џџ2™ш[]Vero BeachFloridaWA4TCD BWA4TCD Gј@„@KL$МP|ћ$џџ2™ш\^џџџџџџџџџџџџџџџџVero BeachFloridaWA4TCD CWA4TCD GР ЊР' $МP|ћ$џџ2™ю]_Wesley ChapelFloridaW4SRT BW4SRT GX]@KLXRАћ$џџ2™ш^`AlbanyGeorgiaKJ4KLD BKJ4KLD G`ŒD@KL#ЬT ˆћ$џџ2™ш_aџџџџџџџџџџџџџџџџAlbanyGeorgiaKJ4KLD CKJ4KLD GъЃ %&#ЬT ˆћ$џџ2™ш`bAlbanyGeorgiaKJ4KLE BKJ4KLE GИ*D@KL 3T*Мћ$џџ2™шacAlbanyGeorgiaKJ4KLE CKJ4KLE GРMЃ %& 3T*Мћ$џџ2™шbdџџџџџџџџџџџџџџџџApplingGeorgiaKJ4PYA BKJ4PYA GЩC@KL! „R<ћ$џџ2™шceApplingGeorgiaKJ4PYA CKJ4PYA GРОЅР\! „R<ћ$џџ2™юdfAthensGeorgiaKJ4PXY BKJ4PXY G<˜C@KL"иSаћ$џџ2™шegџџџџџџџџџџџџџџџџAthensGeorgiaKJ4PXY CKJ4PXY G 8Є %&"иSаћ$џџ2™шfhAthensGeorgiaKZ4FOX BKZ4FOX GX^@KL"ШSH ћ$џџ2™шgiAtlantaGeorgiaW4DOC AW4DOC G@ьrLЗ!.` Tћ$џџ2™шhjџџџџџџџџџџџџџџџџAtlantaGeorgiaW4DOC BW4DOC GРC@KL!.` Tћ$џџ2™шikAtlantaGeorgiaW4DOC CW4DOC GpнЉР' !.` Tћ$џџ2™юjlBraseltonGeorgiaKE4TV BKE4TV GьдB@KL!ШS/єћ$џџ2™шkmџџџџџџџџџџџџџџџџBraseltonGeorgiaWJ4FD BWJ4FD GьдB@KL"hS.Xћ$џџ2™шlnBufordGeorgiaKJ4BDF BKJ4BDF GюD@KL"hS7аћ$џџ2™шmoChatsworthGeorgiaKJ4KLF BKJ4KLF GЩC@KL"-МT*Œ#ћ$џџ2™шnpџџџџџџџџџџџџџџџџChatsworthGeorgiaKJ4KLF CKJ4KLF GРОЅР\"-МT*Œ#ћ$џџ2™шoqClevelandGeorgiaK4GAR BK4GAR GєЏA@KL"!%S.,ћ$џџ2™шprCummingGeorgiaKI4SBA AKI4SBA G€cŽLЗ" T pћ$џџ2™шqsџџџџџџџџџџџџџџџџCummingGeorgiaKI4SBA BKI4SBA G0>|@KL" T pћ$џџ2™шrtCummingGeorgiaKI4SBA CKI4SBA G€“ЇР' " T pћ$џџ2™шsuDaltonGeorgiaKA4RVT BKA4RVT G ˆ~@KL"+€%Uєћ$џџ2™шtvџџџџџџџџџџџџџџџџDaltonGeorgiaKA4RVT CKA4RVT GPЉР' "+€%Uєћ$џџ2™юuwDoravilleGeorgiaWB4HRO AWB4HRO Gа&LЗ!6Ќ&TЈћ$џџ2™шvxDoravilleGeorgiaWB4HRO BWB4HRO G4НD@KL!6Ќ&TЈћ$џџ2™шwyџџџџџџџџџџџџџџџџDublinGeorgiaKJ4YNR AKJ4YNR GаМvLЗ 4!R8Œ ћ$џџ2™шxzDublinGeorgiaKJ4YNR BKJ4YNR GШрA@KL 4!R8Œ ћ$џџ2™шy{DublinGeorgiaKJ4YNR CKJ4YNR G`EЇР' 4!R8Œ ћ$џџ2™юz|џџџџџџџџџџџџџџџџEllijayGeorgiaW4HHH BW4HHH G,Жv@KL"' Thћ$џџ2™ш{}FayettevilleGeorgiaKK4GQ BKK4GQ GФї`@KL!hTєћ$џџ2™ш|~ForsythGeorgiaKK4JPG CKK4JPG GРОЅР\! №#T ћ$џџ2™ю}џџџџџџџџџџџџџџџџGainesvilleGeorgiaKJ4ZLL BKJ4ZLL GdIV@KL"` S1ћ$џџ2™ш~€GainesvilleGeorgiaKJ4ZLL CKJ4ZLL G[ІР' "` S1ћ$џџ2™шGriffinGeorgiaW4AMI CW4AMI G@йЋР' Ќ Tћ$џџ2™ю€‚џџџџџџџџџџџџџџџџJasperGeorgiaKJ4PYC BKJ4PYC GфљC@KL"€ Tдћ$џџ2™шƒJerseyGeorgiaWC4RG BWC4RG GРЄg@KL!+4!S.ћ$џџ2™ш‚„KathleenGeorgiaWY4EMA BWY4EMA GЄB@KL ф S)H ћ$џџ2™шƒ…џџџџџџџџџџџџџџџџLawrencevilleGeorgiaWD4STR BWD4STR GpBB@KL!9|S;$ћ$џџ2™ш„†LawrencevilleGeorgiaWD4STR CWD4STR G pЅР\!9|S;$ћ$џџ2™ш…‡Lookout MountainGeorgiaN4LMC CN4LMC G@їІР' "3а Uрћ$џџ2™ю†ˆџџџџџџџџџџџџџџџџMaconGeorgiaWX4EMA BWX4EMA GhgC@KL 2мS%ф%ћ$џџ2™ш‡‰MaconGeorgiaWX4EMA CWX4EMA G`ЖЉР' 2мS%ф%ћ$џџ2™шˆŠMariettaGeorgiaW4BTI BW4BTI GŒ[D@KL"ШTћ$џџ2™ш‰‹џџџџџџџџџџџџџџџџMidwayGeorgiaKG4LVN CKG4LVN G` ТР' +И QT$ћ$џџ2™ъŠŒMorgantonGeorgiaKM4MAD CKM4MAD GР ЊР' "0T а ћ$џџ2™ю‹PembrokeGeorgiaKJ4GGV AKJ4GGV GрrtLЗ @Q%Мћ$џџ2™шŒŽџџџџџџџџџџџџџџџџPembrokeGeorgiaKJ4GGV BKJ4GGV G`ŒD@KL @Q%Мћ$џџ2™шPembrokeGeorgiaKJ4GGV CKJ4GGV GЬЈР' @Q%Мћ$џџ2™шސRockmartGeorgiaWX4PCA BWX4PCA GЄB@KL!78Uћ$џџ2™ш‘џџџџџџџџџџџџџџџџRockmartGeorgiaWX4PCA CWX4PCA G`ЖЉР' !78Uћ$џџ2™ш’RomeGeorgiaW4VO BW4VO G RЊР' " „U шћ$џџ2™ш‘“RomeGeorgiaW4VO CW4VO GhgC@KL" „U шћ$џџ2™ю’”џџџџџџџџџџџџџџџџSandersvilleGeorgiaW4SAN BW4SAN Gœ@KL :€ R1мћ$џџ2™ш“•SavannahGeorgiaKK4SGC AKK4SGC G €wLЗ РQ ћ$џџ2™ш”–SavannahGeorgiaKK4SGC BKK4SGC GьдB@KL РQ ћ$џџ2™ш•—џџџџџџџџџџџџџџџџSavannahGeorgiaKK4SGC CKK4SGC Gр›Ѓ %& РQ ћ$џџ2™ъ–˜Stone MountainGeorgiaWX4GPB AWX4GPB GрrtLЗ!0 TШћ$џџ2™ш—™Stone MountainGeorgiaWX4GPB BWX4GPB G`ŒD@KL!0 TШћ$џџ2™ш˜šџџџџџџџџџџџџџџџџStone MountainGeorgiaWX4GPB CWX4GPB GъЃ %&!0 TШћ$џџ2™ю™›ThomasvilleGeorgiaKJ4PYB BKJ4PYB GЩC@KL1|S:ф ћ$џџ2™шšœThomasvilleGeorgiaKJ4PYB CKJ4PYB GРОЅР\1|S:ф ћ$џџ2™ш›џџџџџџџџџџџџџџџџTiftonGeorgiaW4PVW AW4PVW GЏsLЗSЬћ$џџ2™шœžTiftonGeorgiaW4PVW BW4PVW GD|@KLSЬћ$џџ2™шŸTiftonGeorgiaW4PVW CW4PVW G[ІР' SЬћ$џџ2™юž џџџџџџџџџџџџџџџџValdostaGeorgiaW4VLD AW4VLD G([vLЗ2T$S€ ћ$џџ2™шŸЁValdostaGeorgiaW4VLD BW4VLD Gєƒr@KL2T$S€ ћ$џџ2™ш ЂValdostaGeorgiaW4VLD CW4VLD G ЉІР' 2T$S€ ћ$џџ2™шЁЃџџџџџџџџџџџџџџџџDanvilleKentuckyKM4OON BKM4OON GМ†z@KL%(|T(єћ$џџ2™шЂЄHighland HeightsKentuckyK4CO CK4CO GрюЊР' 'шT"ќћ$џџ2™шЃЅLexingtonKentuckyW4DSI BW4DSI G†U@KL&4!TИ$ћ$џџ2™шЄІџџџџџџџџџџџџџџџџLexingtonKentuckyW4DSI CW4DSI G ‹ЋР' &4!TИ$ћ$џџ2™ъЅЇLouisvilleKentuckyKM4SGI BKM4SGI G`•@KL& @U.№#ћ$џџ2™шІЈMiddlesboroKentuckyWA4YZY AWA4YZY GпoLЗ$#ЈS/ˆћ$џџ2™шЇЉџџџџџџџџџџџџџџџџMiddlesboroKentuckyWA4YZY BWA4YZY GdГn@KL$#ЈS/ˆћ$џџ2™шЈЊMiddlesboroKentuckyWA4YZY CWA4YZY G ЉР' $#ЈS/ˆћ$џџ2™шЉЋRichmondKentuckyKE4YVD BKE4YVD GTШd@KL%)XT(#ћ$џџ2™шЊЌџџџџџџџџџџџџџџџџUnionKentuckyWW4KY AWW4KY G@M-1&8xT+ ћ$џџ2™шЋ­UnionKentuckyWW4KY BWW4KY G№e…@KL&8xT+ ћ$џџ2™шЌЎUnionKentuckyWW4KY CWW4KY G0ўШР' &8xT+ ћ$џџ2™ш­ЏџџџџџџџџџџџџџџџџVine GroveKentuckyKM4LNN CKM4LNN GPLЩР' %3Ф"V0ћ$џџ2™шЎАBooneNorth CarolinaKO4VDJ BKO4VDJ G<˜C@KL$ @Q(@ћ$џџ2™шЏБBurlingtonNorth CarolinaAK4EG AAK4EG G€cŽL-1#8@OЄћ$џџ2™шАВџџџџџџџџџџџџџџџџBurlingtonNorth CarolinaAK4EG BAK4EG GЬq„@KL#8@OЄћ$џџ2™шБГBurlingtonNorth CarolinaAK4EG CAK4EG G@hЉР' #8@OЄћ$џџ2™шВДChapel HillNorth CarolinaKR4RDU BKR4RDU G–`@KL#2Oћ$џџ2™шГЕџџџџџџџџџџџџџџџџCharlotteNorth CarolinaKI4WXS AKI4WXS G@3љL-1#шP)lћ$џџ2™шДЖCharlotteNorth CarolinaKI4WXS BKI4WXS GфЭt@KL#шP)lћ$џџ2™шЕЗCharlotteNorth CarolinaKI4WXS CKI4WXS G ЉІР' #шP)lћ$џџ2™шЖИџџџџџџџџџџџџџџџџFletcherNorth CarolinaNC4BS BNC4BS GDg@KL#єR\ћ$џџ2™юЗЙGastoniaNorth CarolinaKA4YMZ BKA4YMZ G,Жv@KL#l Q№#ћ$џџ2™шИКGastoniaNorth CarolinaKA4YMZ CKA4YMZ GРMЃ %&#l Q№#ћ$џџ2™шЙЛџџџџџџџџџџџџџџџџGastoniaNorth CarolinaKK4JDH AKK4JDH G[M-1# %QDћ$џџ2™шКМGastoniaNorth CarolinaKK4JDH BKK4JDH GфЭt@KL# %Qрћ$џџ2™шЛНGastoniaNorth CarolinaNC1L BNC1L G,Жv@KL# Q(#ћ$џџ2™шМОџџџџџџџџџџџџџџџџGreensboroNorth CarolinaW4GSO BW4GSO GЄ‹e@KL$аO1@ћ$џџ2™шНПHendersonvilleNorth CarolinaKJ4JAL BKJ4JAL G(ФX@KL# И$R єћ$џџ2™шОРHendersonvilleNorth CarolinaKJ4JAL CKJ4JAL GиюЦР' # И$R єћ$џџ2™шПСџџџџџџџџџџџџџџџџMt. AiryNorth CarolinaKJ4HFV BKJ4HFV GD|@KL$%P$Ьћ$џџ2™шРТRaleighNorth CarolinaW4RNC BW4RNC G” [@KL#( N ћ$џџ2™шСУShelbyNorth CarolinaW4NYR BW4NYR GlУy@KL!дu*Œ ћ$џџ2™шТФџџџџџџџџџџџџџџџџShelbyNorth CarolinaW4NYR CW4NYR GРОЅР\!дu*Œ ћ$џџ2™шУХTryonNorth CarolinaKK4LVF BKK4LVF GxМe@KL#ф R Ќ&ћ$џџ2™шФЦWingateNorth CarolinaW4FAN BW4FAN G$„@KL":PШћ$џџ2™шХЧџџџџџџџџџџџџџџџџAikenSouth CarolinaKR4AIK BKR4AIK G№m@KL!!ф%Q+@ћ$џџ2™шЦШAikenSouth CarolinaKR4AIK CKR4AIK G@їІР' !!ф%Q+@ћ$џџ2™юЧЩAwendawSouth CarolinaKR4CHS CKR4CHS G[ІР' 7\O)№#ћ$џџ2™шШЪџџџџџџџџџџџџџџџџBeaufortSouth CarolinaKJ4LNJ CKJ4LNJ G@йЋР' * P(Œ#ћ$џџ2™шЩЫBEECH ISLANDSouth CarolinaKM4LOD BKM4LOD GpBB@KL! Qћ$џџ2™шЪЬClemsonSouth CarolinaWD4EOG BWD4EOG GшUz@KL"(R1˜!ћ$џџ2™шЫЭџџџџџџџџџџџџџџџџColumbiaSouth CarolinaKJ4BWK AKJ4BWK GшЗ‹LЗ"шQШћ$џџ2™шЬЮColumbiaSouth CarolinaKJ4BWK BKJ4BWK GВj@KL"шQШћ$џџ2™шЭЯColumbiaSouth CarolinaKJ4BWK CKJ4BWK GР ЊР' "шQШћ$џџ2™шЮаџџџџџџџџџџџџџџџџDillionSouth CarolinaW4PDE AW4PDE G@KLЗ"єO@ћ$џџ2™шЯбDillionSouth CarolinaW4PDE BW4PDE GŒ/u@KL"єO@ћ$џџ2™шавDillionSouth CarolinaW4PDE CW4PDE G`ЖЉР' "єO@ћ$џџ2™шбгџџџџџџџџџџџџџџџџGreenwoodSouth CarolinaW4GWM CW4GWM GрюЊР' " PR hћ$џџ2™швдHilton Head IslaSouth CarolinaW4IAR CW4IAR G˜УШР' ,P+pћ$џџ2™шгеLeesvilleSouth CarolinaKC4GYM BKC4GYM GрEo@KL!4QXћ$џџ2™шджџџџџџџџџџџџџџџџџLeesvilleSouth CarolinaKC4GYM CKC4GYM GЧНР' !4QXћ$џџ2™шезMyrtle BeachSouth CarolinaNE4SC BNE4SC GЌfd@KL!6xO„ћ$џџ2™шжиMyrtle BeachSouth CarolinaNE4SC CNE4SC G 8Є %&!6xO„ћ$џџ2™юзйџџџџџџџџџџџџџџџџSummervilleSouth CarolinaKX4DOR BKX4DOR Gќ)e@KL!8Pќћ$џџ2™шикSummervilleSouth CarolinaKX4DOR CKX4DOR GЬЈР' !8Pќћ$џџ2™шйлBentonTennesseeKM4MCN CKM4MCN G 8Є %&# T!Рћ$џџ2™юкмџџџџџџџџџџџџџџџџCarryvilleTennesseeKK4VQG CKK4VQG G`дЄР\$%TЌ&ћ$џџ2™шлнChattanoogaTennesseeW4PL AW4PL GРѓL-1# И Uф ћ$џџ2™шмоChattanoogaTennesseeW4PL BW4PL GАюi@KL# И Uф ћ$џџ2™шнпџџџџџџџџџџџџџџџџChattanoogaTennesseeW4PL CW4PL GѓЈР' # И Uф ћ$џџ2™юорChattanoogaTennesseeW4RRG BW4RRG Gї@KL":И$Uдћ$џџ2™шпсClevelandTennesseeKK4BXE BKK4BXE GШрA@KL#T38ћ$џџ2™шртџџџџџџџџџџџџџџџџClevelandTennesseeKK4BXE CKK4BXE G@йЋР' #T38ћ$џџ2™юсуJacksonTennesseeNT4MC CNT4MC GРОЅР\#'јX-Xћ$џџ2™ътфKnoxvilleTennesseeK4HXD CK4HXD Gр›Ѓ %&#0єS(@ћ$џџ2™юухџџџџџџџџџџџџџџџџKnoxvilleTennesseeKM4JXA CKM4JXA Gр›Ѓ %&#0S(Єћ$џџ2™шфцKnoxvilleTennesseeKN4EM CKN4EM Gр ІР' #9S7` ћ$џџ2™юхчMemphisTennesseeW4LET BW4LET G,Жv@KL#АY0мћ$џџ2™шцшџџџџџџџџџџџџџџџџMemphisTennesseeW4LET CW4LET G pЅР\#АY0мћ$џџ2™ючщMemphisTennesseeWB4KOG BWB4KOG GќєX@KL#€ Y4шћ$џџ2™шшъMemphisTennesseeWB4KOG CWB4KOG Gр›Ѓ %&#И Y4Аћ џџ2™ъщыџџџџџџџџџџџџџџџџMonteagle MountaTennesseeKN4WAN BKN4WAN GpBB@KL#hU-Јћ џџ2™шъьMorristownTennesseeW4LDG BW4LDG Gx&~@KL$ шS„ћ$џџ2™шыэMorristownTennesseeW4LDG CW4LDG GРMЃ %&$ шS„ћ$џџ2™шьюџџџџџџџџџџџџџџџџNashvilleTennesseeKI4SDI CKI4SDI GрЩХР' $ќV:мћ$џџ2™шэяOneidaTennesseeW4BSF BW4BSF GЌа|@KL$TМћ$џџ2™шю№RockwoodTennesseeKE4RX BKE4RX G†U@KL#3T$T*Ф"ћ$џџ2™шяёџџџџџџџџџџџџџџџџWhitevilleTennesseeKM4GHK BKM4GHK Gќ“}@KL#№ Y Јћ$џџ2™ш№ђAlexandriaVirginiaW4HFH AW4HFH GРp‘LЗ&1Mф ћ$џџ2™шёѓAlexandriaVirginiaW4HFH BW4HFH GрLY@KL&1Mф ћ$џџ2™шђєџџџџџџџџџџџџџџџџAlexandriaVirginiaW4HFH CW4HFH G RЊР' &1Mф ћ$џџ2™юѓѕHamptonVirginiaW4HPT BW4HPT G%z@KL%XLdћ$џџ2™шєіHamptonVirginiaW4HPT CW4HPT G€“ЇР' %XLdћ$џџ2™юѕїџџџџџџџџџџџџџџџџNewport NewsVirginiaW4MT BW4MT G†U@KL% Lћ$џџ2™шіјNewport NewsVirginiaW4MT CW4MT G`\ИР' % Lћ$џџ2™шїљRichmondVirginiaW4FJ AW4FJ GIˆL-1% <MH ћ$џџ2™шјњџџџџџџџџџџџџџџџџRichmondVirginiaW4FJ BW4FJ Gєƒr@KL% <MH ћ$џџ2™шљћRichmondVirginiaW4FJ CW4FJ GиюЦР' % <MH ћ$џџ2™ъњќStaffordVirginiaWS4VA AWS4VA GРбlLЗ&єM8ћ$џџ2™шћ§џџџџџџџџџџџџџџџџStaffordVirginiaWS4VA BWS4VA GјпЈ@KL&єM8ћ$џџ2™шќўStaffordVirginiaWS4VA CWS4VA G@hЉР' &єM8ћ$џџ2™ю§џTysons CornerVirginiaNV4FM ANV4FM G€љuLЗ&6€ M €%ћ$џџ2™шўџџџџџџџџџџџџџџџџTysons CornerVirginiaNV4FM BNV4FM GИxД@KL&6€ M €%ћ$џџ2™шџTysons CornerVirginiaNV4FM CNV4FM G`ЖЉР' &6€ M €%ћ$џџ2™ъWintergreenVirginiaWR4CV BWR4CV G5…@KL%7N8@ћ$џџ2™шџџџџџџџџџџџџџџџџAshburnVirginia KO4NCX BKO4NCX GxњЎ@KL'”MМћ$џџ2™шHamptonVirginia K4HPT BK4HPT GрEo@KL%hLhћ$џџ2™шManassasVirginia W4OVH BW4OVH Gt4`@KL&.€%MЌ ћ$џџ2™шџџџџџџџџџџџџџџџџRoanokeVirginia KO4DQA BKO4DQA GРC@KL%ˆO;Мћ$џџ2™шStaffordVirginia WU5MC BWU5MC GЬв_@KL&,Mpћ$џџ2™шWilliamsburgVirginia KO4VQE BKO4VQE G`ŒD@KL%$L+ћ$џџ2™ш џџџџџџџџџџџџџџџџLittle RockArkansasN5DSD BN5DSD Gдw@KL"\ ћ џџ2šш Little RockArkansasN5DSD CN5DSD GР]Ъ %&"\ ћ џџ2šш  AlexandriaLouisianaKF5PIE CKF5PIE G?ЦР' € \„ћ џџ2šш  џџџџџџџџџџџџџџџџBaton RougeLouisianaKD5CQB BKD5CQB GШf@KL€%[ Lћ џџ2šш  Baton RougeLouisianaKD5CQB CKD5CQB G6СР' 4![ xћ џџ2šш FranklintonLouisianaKF5BSZ AKF5BSZ G@MЗ4АY;ћ џџ2šш џџџџџџџџџџџџџџџџFranklintonLouisianaKF5BSZ BKF5BSZ Gьн@KL4АY;ћ џџ2šшFranklintonLouisianaKF5BSZ CKF5BSZ G€СЩ %&4АY;ћ џџ2šшHaughtonLouisianaW5SLY CW5SLY G@ДЦР' А]Дћ џџ2šшџџџџџџџџџџџџџџџџLaCombeLouisianaW5SLA BW5SLA G mx@KLєY6 ћ џџ2šшLeesvilleLouisianaKE5PFA BKE5PFA Gа%Y@KL` ] ˜!ћ џџ2šшLeesvilleLouisianaKE5PFA CKE5PFA GhNШР' ` ] ˜!ћ џџ2šшџџџџџџџџџџџџџџџџLeesvilleLouisianaKF5QAR BKF5QAR GŒ[D@KL]˜ћ џџ2šшManyLouisianaN5MNY CN5MNY GРР' #] ћ џџ2šшMindenLouisianaN5MAD BN5MAD Gt4`@KL (,] ћ џџ2šшџџџџџџџџџџџџџџџџMindenLouisianaN5MAD CN5MAD GРMЃ %& (,] ћ џџ2šшNew OrleansLouisianaKF5SKU BKF5SKU Gx&~@KL8(#Z ћ џџ2šшNew OrleansLouisianaW5GAD AW5GAD G@‹—LЗ:LZ<ћ џџ2šшџџџџџџџџџџџџџџџџNew OrleansLouisianaW5GAD BW5GAD GH…@KL:LZ<ћ џџ2šшNew OrleansLouisianaW5GAD CW5GAD GШхСР' :LZ<ћ џџ2šюPinevilleLouisianaKC5ZJY CKC5ZJY G0аІР' ,\Мћ џџ2šшџџџџџџџџџџџџџџџџRustonLouisianaN5APB CN5APB G ЉІР' Ќ \(ќ!ћ џџ2šшShreveportLouisianaK5SAR CK5SAR G№3ІР' а]-ћ џџ2šю ShreveportLouisianaW5SHV AW5SHV G@M-1  ],(#ћ џџ2šш!џџџџџџџџџџџџџџџџShreveportLouisianaW5SHV BW5SHV G€bX@KL  ],(#ћ џџ2šш "ShreveportLouisianaW5SHV CW5SHV G‰ШР'  ],(#ћ џџ2šю!#St. MartinvilleLouisianaKF5ZUZ AKF5ZUZ G сM-1˜![0И$ћ џџ2šш"$џџџџџџџџџџџџџџџџSt. MartinvilleLouisianaKF5ZUZ BKF5ZUZ Gt@KL˜![0И$ћ џџ2šш#%St. MartinvilleLouisianaKF5ZUZ CKF5ZUZ GР УР' ˜![0И$ћ џџ2šш$&BrandonMississippiK5RKN BK5RKN GЈ}ƒ@KL  Y:dћ џџ2šш%'џџџџџџџџџџџџџџџџBrandonMississippiK5RKN CK5RKN GPЇР'  Y:dћ џџ2šю&(ClintonMississippiW5DRA BW5DRA G†U@KL Œ Z@ћ џџ2šш')ClintonMississippiW5DRA CW5DRA G зШР' Œ Z@ћ џџ2šш(*џџџџџџџџџџџџџџџџColumbusMississippiKC5ULN BKC5ULN GH…@KL!!єXић џџ2šш)+McHenryMississippiKI4TMJ AKI4TMJ GIˆLЗ,@Yˆћ џџ2šш*,McHenryMississippiKI4TMJ BKI4TMJ Gx&~@KL,@Yˆћ џџ2šш+-џџџџџџџџџџџџџџџџMcHenryMississippiKI4TMJ CKI4TMJ GPЇР' ,@Yˆћ џџ2šш,.NatchezMississippiN5TAM BN5TAM GљЊ@KL ќ[Јћ џџ2šш-/NatchezMississippiN5TAM CN5TAM GаVЈР'  ќ[Јћ џџ2šш.0џџџџџџџџџџџџџџџџTupeloMississippiK5LLO BK5LLO G№e…€["@X( ћ џџ2šш/1TupeloMississippiKE5LUX BKE5LUX G№e…@KL" И X) ћ џџ2šш02TupeloMississippiKE5LUX CKE5LUX G€ŒНР' " И X) ћ џџ2šш13џџџџџџџџџџџџџџџџAlamogrodoNew MexicoW6DHS BW6DHS GРC@KL ;4i:4!ћџџ2šш24AlamogrodoNew MexicoW6DHS CW6DHS GъЃ€ ;4i:4!ћџџ2šш35AlbuquerqueNew MexicoK5URR BK5URR GЪ@KL#\j#` ћџџ2šш46џџџџџџџџџџџџџџџџAlbuquerqueNew MexicoK5URR CK5URR GрчРР' #\j#` ћџџ2šъ57AlbuquerqueNew MexicoW5MPZ BW5MPZ GРйs@KL# djxћџџ2šю68AlbuquerqueNew MexicoW5URD BW5URD GШщ~@KL"*XjАћџџ2šш79џџџџџџџџџџџџџџџџAztecNew MexicoKF5VBE AKF5VBE GРѓL-1$.(#k; ћџџ2šю8:BloomfieldNew MexicoKF5VBD AKF5VBD GрюM-1$'k/Рћџџ2šш9;BloomfieldNew MexicoKF5VBD BKF5VBD Gx‡Y@KL$'dk/Рћџџ2šш:<џџџџџџџџџџџџџџџџBloomfieldNew MexicoKF5VBD CKF5VBD GxGІР' $'k/Рћџџ2šш;=FarmingtonNew MexicoKF5VBF AKF5VBF G Ч§L-1$*ˆl Дћџџ2šш<>FarmingtonNew MexicoKF5VBF BKF5VBF G№0y@KL$*ˆl Дћџџ2šш=?џџџџџџџџџџџџџџџџGrantsNew MexicoKE5FYL BKE5FYL Gв€@KL#ф%k5ф ћџџ2šш>@Las CrucesNew MexicoN5BL CN5BL GР™РР' T j-,ћџџ2šш?ALos AlamosNew MexicoNM5EC CNM5EC GplЇР' #54j ћџџ2šю@BџџџџџџџџџџџџџџџџLos AlamosNew MexicoNM5WR BNM5WR GЈо^@KL#1j `"ћџџ2šшACRatonNew MexicoKD0RDI BKD0RDI Gи>Ё@KL$;|h0ћџџ2šшBDRoswellNew MexicoW5ZU BW5ZU G(c}@KL!Lhћџџ2šшCEџџџџџџџџџџџџџџџџSanta FeNew MexicoNM5HR BNM5HR GРЄg@KL#'иi9H&ћџџ2šшDFSanta FeNew MexicoW5SF BW5SF G­@KL#+i6H&ћџџ2šшEGSanta FeNew MexicoW5SF CW5SF GКЇР' #+i6H&ћџџ2šшFHџџџџџџџџџџџџџџџџSocorroNew MexicoW5AQA BW5AQA G ˆ~@KL"И j9ћџџ2šшGITres PiedrasNew MexicoKF5PFO BKF5PFO Gx‡Y@KL$3jxћџџ2šшHJAltusOklahomaAJ5Q BAJ5Q Ghб[@KL"'Шc„ћ џџ2šшIKџџџџџџџџџџџџџџџџBlanchardOklahomaKF5ZLE BKF5ZLE GCg@KL#€%a)ћ џџ2šюJLElk CityOklahomaK5ELK AK5ELK G€жуL-1#T cРћ џџ2šшKMElk CityOklahomaK5ELK BK5ELK Ghh@KL#T cРћ џџ2šшLNџџџџџџџџџџџџџџџџElk CityOklahomaK5ELK CK5ELK GH<ОР' #T cРћ џџ2šшMOEufaulaOklahomaKG5EEP BKG5EEP GбЯ@KL#$_,ћ џџ2šшNPLawtonOklahomaKG5ACV BKG5ACV GMb@KL"# bћ џџ2šшOQџџџџџџџџџџџџџџџџMoorelandOklahomaW5OKT BW5OKT G8{@KL$€%c ћ џџ2šшPRNormanOklahomaW5TC BW5TC GАX‚@KL# (#a ћ џџ2šшQSOklahoma CityOklahomaW5PAA BW5PAA GH…@KL#№ a Шћ џџ2šшRTџџџџџџџџџџџџџџџџOklahoma CityOklahomaWD5AII BWD5AII Gшыa@KL#"шaЌ ћ џџ2šшSUOklahoma CityOklahomaWD5AII CWD5AII GhNШР' #"шaЌ ћ џџ2šшTVTulsaOklahomaKN5V BKN5V G@Ša@KL$H&_3Ќ&ћ џџ2šюUWџџџџџџџџџџџџџџџџVinitaOklahomaNO5RA BNO5RA GИЩh@KL$%@_ ,ћ џџ2šшVXVinitaOklahomaNO5RA CNO5RA GHХР' $%@_ ,ћ џџ2šшWYWalsh MountainOklahomaWX5ASA BWX5ASA GpЌZ@KL": cœћ џџ2šшXZџџџџџџџџџџџџџџџџWalsh MountainOklahomaWX5ASA CWX5ASA GhNШР' ": cœћ џџ2šшY[WoodwardOklahomaWW5EM BWW5EM Gx&~@KL$ф cЈћ џџ2šшZ\WoodwardOklahomaWW5EM CWW5EM G8йЧР' $ф cЈћ џџ2šш[]џџџџџџџџџџџџџџџџAbileneTexasKG5MMT BKG5MMT G˜’y@KL ˆc,8ћ џџ2šш\^AbileneTexasKG5MMU BKG5MMU G ˆ~@KL Шc,Мћ џџ2šю]_AbileneTexasKG5MUP BKG5MUP G˜’y@KL ф%c*Lћ џџ2šш^`џџџџџџџџџџџџџџџџAllenTexasK5PRK AK5PRK G`>M-1! `(Ьћ џџ2šш_aAllenTexasK5PRK BK5PRK GXцQ@KL! `(Ьћ џџ2šю`bAlvinTexasK5PLD CK5PLD GКЇР' „_Єћ џџ2šшacџџџџџџџџџџџџџџџџAustinTexasK5SOC BK5SOC G@Пm@KL`"a7@ћ џџ2šшbdAustinTexasW5KA AW5KA G€ЊM-1 8a.”ћ џџ2šшceAustinTexasW5KA BW5KA G`ЏПР'  8a.”ћ џџ2šшdfџџџџџџџџџџџџџџџџAustinTexasW5KA CW5KA GЩC@KL 8a.”ћ џџ2šюegBellvilleTexasW5SFA CW5SFA GPљСР' 9М`Ьћ џџ2šшfhBig SpringTexasW5AW BW5AW GŒ[D@KL eћ џџ2šшgiџџџџџџџџџџџџџџџџBig SpringTexasW5AW CW5AW G@ДЦР' eћ џџ2šюhjBrucevilleTexasW5HAT BW5HAT GhgC@KL˜!aЈћ џџ2šшikBrucevilleTexasW5HAT CW5HAT G@ДЦР' ˜!aЈћ џџ2šшjlџџџџџџџџџџџџџџџџBryanTexasKI5MMC BKI5MMC G@Пm@KL&`"`дћ џџ2šшkmBryanTexasW5AC BW5AC G@Пm@KL&„`”ћ џџ2šшlnCorsicanaTexasK5NEM CK5NEM Gр:ШР' h`шћ џџ2šшmoџџџџџџџџџџџџџџџџDallasTexasK5TIT AK5TIT G@M-1 .@`0˜ћ џџ2šшnpDallasTexasK5TIT BK5TIT G€bX@KL .@`0˜ћ џџ2šшoqDallasTexasK5TIT CK5TIT G‰ШР' .@`0˜ћ џџ2šюprџџџџџџџџџџџџџџџџDallasTexasW5FC AW5FC GР!0M-1 5<`.ћ џџ2šшqsDallasTexasW5FC BW5FC GЄB@KL 5<`.ћ џџ2šшrtDallasTexasW5FC CW5FC G‚ІР' 5<`.ћ џџ2šюsuџџџџџџџџџџџџџџџџDentonTexasW5NGU AW5NGU GРЗM-1!˜!a ћ џџ2šшtvDentonTexasW5NGU BW5NGU GШf@KL!˜!a ћ џџ2šшuwDentonTexasW5NGU CW5NGU GшЩ@B!˜!a ћ џџ2šшvxџџџџџџџџџџџџџџџџEl PasoTexasK5WPH BK5WPH GЈk@KL1 jT$ћ џџ2šшwyEl PasoTexasK5WPH CK5WPH G№3ІР' 1 jT$ћ џџ2šюxzEl PasoTexasW5ELP CW5ELP G`>НР' /tj4!ћ џџ2šшy{џџџџџџџџџџџџџџџџFort WorthTexasKB5DRP BKB5DRP GpBB@KL +„aPћ џџ2šшz|Fort WorthTexasKF5MMX BKF5MMX GŒ[D@KL &<aќ!ћ џџ2šш{}Fort WorthTexasW5SH BW5SH GиX@KL 5Ф"a№ ћ џџ2šш|~џџџџџџџџџџџџџџџџGranburyTexasK1DRP BK1DRP GЩC@KL `"a2ћ џџ2šш}GranburyTexasW5HCT BW5HCT GpwN@KL аa.ќ!ћ џџ2šю~€InglesideTexasW5ICC BW5ICC G Ђ„@KL6aЌ&ћ џџ2šшџџџџџџџџџџџџџџџџLa VerniaTexasN5JFP BN5JFP G8zV@KL"Мbќ!ћ џџ2šш€‚LaredoTexasKE5WFB BKE5WFB GРC@KL+#ЈO/Ќ ћ џџ2šшƒLaredoTexasKE5WFB CKE5WFB G‰ШР' +#ЈO/Ќ ћ џџ2šш‚„џџџџџџџџџџџџџџџџLongviewTexasK5LET BK5LET GX…v@KL !^(Ьћ џџ2šшƒ…LongviewTexasK5LET CK5LET G ѕУР' !^(Ьћ џџ2šш„†LubbockTexasK5LIB BK5LIB Ghh@KL! T$e6 ћ џџ2šш…‡џџџџџџџџџџџџџџџџMcAllenTexasND5N CND5N G€2ЬР' Xbћ џџ2šш†ˆMesquiteTexasNT5RN ANT5RN G`>M-1 -`"`&Lћ џџ2šш‡‰MesquiteTexasNT5RN BNT5RN Ghh@KL -`"`&Lћ џџ2šшˆŠџџџџџџџџџџџџџџџџMesquiteTexasNT5RN CNT5RN G0аІР' -`"`&Lћ џџ2šш‰‹NederlandTexasW5SSV BW5SSV GюD@KL:X];И ћ џџ2šюŠŒNederlandTexasW5SSV CW5SSV G`>НР' :X];T ћ џџ2šш‹џџџџџџџџџџџџџџџџOdessaTexasWT5PN BWT5PN G d;@KL4pfдћ џџ2šшŒŽParisTexasK5PTR BK5PTR GШJZ@KL!'d_!€ ћ џџ2šшParisTexasWN5ROC BWN5ROC G8{@KL!'А_"hћ џџ2šшސџџџџџџџџџџџџџџџџParisTexasWN5ROC CWN5ROC G ѕУР' !'А_"hћ џџ2šш‘RosstonTexasKE5YAP AKE5YAP G€ЊM-1!шa„ћ џџ2šш’RosstonTexasKE5YAP BKE5YAP G4НD@KL!шa„ћ џџ2šш‘“џџџџџџџџџџџџџџџџRosstonTexasKE5YAP CKE5YAP Gа„Ъ@B!шa„ћ џџ2šш’”San AngeloTexasKG5CNG AKG5CNG GРЖLЗ˜!d€ ћ џџ2šш“•San AngeloTexasKG5CNG BKG5CNG GpK@KL˜!d€ ћ џџ2šш”–џџџџџџџџџџџџџџџџSan AntonioTexasWA5UNH BWA5UNH G`ŒD@KLьb˜!ћ џџ2šш•—San AntonioTexasWD5STR AWD5STR G 1M-1 œb( ћ џџ2šш–˜San AntonioTexasWD5STR BWD5STR GРC@KL œb( ћ џџ2šш—™џџџџџџџџџџџџџџџџSan AntonioTexasWD5STR CWD5STR GBЛ@B œb( ћ џџ2šш˜šSeguinTexasKG5FJW BKG5FJW Ghб[@KL( a5 ћ џџ2šш™›SeguinTexasKG5FJW CKG5FJW GPЌР' ( a5 ћ џџ2šшšœџџџџџџџџџџџџџџџџSpringTexasKF5KHM AKF5KHM G@hM-1l _dћ џџ2šш›SpringTexasKF5KHM BKF5KHM GЄB@KLl _dћ џџ2šшœžSpringTexasKF5KHM CKF5KHM G`ЖЉР' l _dћ џџ2šшŸџџџџџџџџџџџџџџџџSulphurTexasW5SUL CW5SUL G‰ШР'  x] ћ џџ2šшž TempleTexasK5CTX AK5CTX G сM-1Xaф ћ џџ2šшŸЁTempleTexasK5CTX BK5CTX GШрA@KLXaф ћ џџ2šш ЂџџџџџџџџџџџџџџџџTempleTexasK5CTX CK5CTX Gр:ШР' Xaф ћ џџ2šшЁЃTylerTexasW5ETX BW5ETX GPпƒ@KL Є_Шћ џџ2šшЂЄTylerTexasW5ETX CW5ETX G€пФАq Є_Шћ џџ2šшЃЅџџџџџџџџџџџџџџџџWacoTexasW5ZDN CW5ZDN G МТР' &0a0ћ џџ2šшЄІWalburgTexasKE5RCS AKE5RCS G€ЊM-1,a$Аћ џџ2šшЅЇWalburgTexasKE5RCS BKE5RCS GЄB@KL,a$Аћ џџ2šшІЈџџџџџџџџџџџџџџџџWalburgTexasKE5RCS CKE5RCS G‚ІР' ,Шa$ћ џџ2šюЇЉAnaheimCaliforniaW6HRO AW6HRO GhІТLЗ!2єu8ћџџ2›шЈЊAnaheimCaliforniaW6HRO BW6HRO G€а@KL!2єu8ћџџ2›шЉЋџџџџџџџџџџџџџџџџAnaheimCaliforniaW6HRO CW6HRO GPНЫxќ&!2єu8ћџџ2›юЊЌConcordCaliforniaW6CX CW6CX G@†Є %&%4(#y6ћџџ2›шЋ­CoronaCaliforniaWB6BA BWB6BA GРщš@KL!/„u$јћџџ2›шЌЎџџџџџџџџџџџџџџџџCoronadoCaliforniaW6MLI AW6MLI GРp‘LЗ (|u Ьћџџ2›ш­ЏCoronadoCaliforniaW6MLI BW6MLI GрŠЂ@KL (|u Ьћџџ2›шЎАCoronadoCaliforniaW6MLI CW6MLI G зШ Ё (|u Ьћџџ2›шЏБџџџџџџџџџџџџџџџџFolsomCaliforniaKS6HRP CKS6HRP GxWЭР' 'tyЈћџџ2›юАВGilroyCaliforniaKJ6WZS BKJ6WZS GˆЇo@KL%@y"ф%ћџџ2›шБГLaguna BeachCaliforniaK6SOA AK6SOA G@ьrLЗ!!u-И ћџџ2›шВДџџџџџџџџџџџџџџџџLaguna BeachCaliforniaK6SOA BK6SOA G(ы@KL!!u-И ћџџ2›шГЕLaguna BeachCaliforniaK6SOA CK6SOA GИ‰ЕР' !!u-И ћџџ2›юДЖLos AngelesCaliforniaKI6JKA BKI6JKA GЛЇ@KL"xv$єћџџ2›юЕЗџџџџџџџџџџџџџџџџLos AngelesCaliforniaWA6IRC AWA6IRC GЏsLЗ"дvhћџџ2›шЖИLos AngelesCaliforniaWA6IRC BWA6IRC GJЅ@KL"дvhћџџ2›шЗЙLos AngelesCaliforniaWA6IRC CWA6IRC G@–Ыxќ&"дvhћџџ2›шИКџџџџџџџџџџџџџџџџMalibuCaliforniaKJ6BWR BKJ6BWR G5“@KL"Dv'ћџџ2›шЙЛMt. BullionCaliforniaW6HHD AW6HHD G Я‰LЗ% @xxћџџ2›шКМMt. BullionCaliforniaW6HHD BW6HHD Gƒ@KL% @xxћџџ2›шЛНџџџџџџџџџџџџџџџџMt. BullionCaliforniaW6HHD CW6HHD Gр›Ѓ€% @xxћџџ2›юМОMt. ShastaCaliforniaW6BML BW6BML GxRM@KL)ф%z<ћџџ2›шНПNapaCaliforniaW6CO BW6CO GPЁ:@KL&аzрћџџ2›шОРџџџџџџџџџџџџџџџџOrovilleCaliforniaKJ6LVV BKJ6LVV G8{@KL'Ќ&yрћџџ2›шПСPalomar Mtn.CaliforniaKI6MGN CKI6MGN GPНЫxќ&!@t3Pћџџ2›юРТSan BernardinoCaliforniaKI6WZX BKI6WZX G ›š@KL" Аuф%ћџџ2›юСУџџџџџџџџџџџџџџџџSan DiegoCaliforniaKI6KQU BKI6KQU Gˆ’Б@KL!Дt:H ћџџ2›юТФSan DiegoCaliforniaKW6HRO BKW6HRO G _Є@KL #єt2єћџџ2›шУХSan JoseCaliforniaWW6BAY BWW6BAY Gј x@KL%zєћџџ2›юФЦџџџџџџџџџџџџџџџџSan LeandroCaliforniaAC6SO AAC6SO G ъL МО%+ЬzАћџџ2›шХЧSan LeandroCaliforniaAC6SO CAC6SO GРеЖР' %+ЬzАћџџ2›шЦШSanta RosaCaliforniaK6ACS BK6ACS GєZ@KL&˜!z+€ ћџџ2›шЧЩџџџџџџџџџџџџџџџџSanta RosaCaliforniaK6ACS CK6ACS G€"Ѕ€&˜!z+€ ћџџ2›шШЪSanta YnezCaliforniaKK6GFX BKK6GFX GБ@KL"8w:Мћџџ2›шЩЫVictorvilleCaliforniaKJ6KTV CKJ6KTV GPНЫxќ&"$шuћџџ2›шЪЬџџџџџџџџџџџџџџџџVisaliaCaliforniaK6VIS AK6VIS GУЋLЗ$+Рv8дћџџ2›шЫЭVisaliaCaliforniaK6VIS BK6VIS G`і\@KL$+Рv8дћџџ2›шЬЮVisaliaCaliforniaK6VIS CK6VIS GЗЄ %&$+Рv8дћџџ2›юЭЯџџџџџџџџџџџџџџџџVisaliaCaliforniaKK6NGT AKK6NGT GX†ЌLЗ$ьv34ћџџ2›шЮаVisaliaCaliforniaKK6NGT BKK6NGT G `@KL$ьv34ћџџ2›шЯбVisaliaCaliforniaKK6NGT CKK6NGT G˜$Є %&$ьv34ћџџ2›шавџџџџџџџџџџџџџџџџVistaCaliforniaKJ6FCH BKJ6FCH G№“Ї@KL! Єu ` ћџџ2›шбгWrightwoodCaliforniaKJ6LJZ BKJ6LJZ GxkБ@KL"Lu(ьћџџ2›ювдBakersfieldCalifornia WX6D BWX6D G˜ОH@KL#lv5ићџџ2›шгеџџџџџџџџџџџџџџџџCalexicoCalifornia K6CLX BK6CLX G рЭ@KL 'ˆtМћџџ2›шджDaly CityCalifornia KN6CDC CKN6CDC G№ТЃ %&%*4z№#ћџџ2›юезLa MesaCalifornia KM6VLB BKM6VLB G чЗ@KL /Аuћџџ2›шжиџџџџџџџџџџџџџџџџLos AngelesCalifornia K6PUW BK6PUW GЛЇ@KL"Рv#єћџџ2›шзйMalibuCalifornia KD4PAP BKD4PAP G5“@KL!0vићџџ2›шикPalm Springs EdoCalifornia W6THC BW6THC G аІ@KL!4tћџџ2›шйлџџџџџџџџџџџџџџџџPomonaCalifornia KC6ACS BKC6ACS G€м—@KL"tu0@ћџџ2›шкмSan BernardinoCalifornia KI6WZX CKI6WZX G0oЫxќ&" Аuф%ћџџ2›шлнSan LeandroCalifornia AC6SO BAC6SO GЈ?:@KL%+ЬzLћџџ2›шмоџџџџџџџџџџџџџџџџSanta CruzCalifornia K6DRI CK6DRI G@†Є %&% єzРћџџ2›юнпSantiagoCalifornia KM6LVQ BKM6LVQ Gї@KL!)( u!@ћџџ2›шорWrightwoodCalifornia WB6IRC BWB6IRC GйЂ@KL"\u(Ќ&ћџџ2›шпсџџџџџџџџџџџџџџџџEureka SpringsArizonaKG5JPK BKG5JPK Gш n@KL$Ш],И$ћџџ2œшртGlobeArizonaN7CI BN7CI G!“@KL!И$n1Œ ћџџ2œюсуGoodyearArizonaKG7HBZ BKG7HBZ GмE@KL!Œ#p|ћџџ2œштфџџџџџџџџџџџџџџџџKingmanArizonaW7KDS AW7KDS GIˆLЗ# r˜!ћџџ2œшухKingmanArizonaW7KDS BW7KDS Gрф“@KL# r˜!ћџџ2œшфцKingmanArizonaW7KDS CW7KDS G˜•ІР' # r˜!ћџџ2œшхчџџџџџџџџџџџџџџџџMesaArizonaKE7JFH AKE7JFH GPvЁLЗ!|o&0ћџџ2œшцшMesaArizonaKE7JFH BKE7JFH Gи •@KL!|o&0ћџџ2œшчщMesaArizonaKE7JFH CKE7JFH GˆnІР' !|o&0ћџџ2œюшъџџџџџџџџџџџџџџџџOro ValleyArizonaW0HF BW0HF G@^’@KL Ln8 ћџџ2œшщыPhoenixArizonaW7MOT AW7MOT G`Т†LЗ!"p"hћџџ2œшъьPhoenixArizonaW7MOT BW7MOT GдCF@KL!"p"hћџџ2œшыэџџџџџџџџџџџџџџџџPhoenixArizonaW7MOT CW7MOT G˜•ІР' !"p"hћџџ2œюьюSahauritaArizonaKR7ST CKR7ST GxGІР' 9,n:Јћџџ2œшэяScottsdaleArizonaKF7CUF BKF7CUF G0Ј”@KL!аo6ћџџ2œюю№џџџџџџџџџџџџџџџџTucsonArizonaK7TUS AK7TUS GŒLЗ Ln/ћџџ2œшяёTucsonArizonaK7TUS BK7TUS G№š‘@KL Ln/ћџџ2œш№ђTucsonArizonaK7TUS CK7TUS GPLЩ@B Ln/ћџџ2œшёѓџџџџџџџџџџџџџџџџTucsonArizonaW7NFL BW7NFL G№š‘@KL Єo<ћџџ2œшђєWinslowArizonaKG5JPI BKG5JPI GЛa@KL#/а ^ ћџџ2œшѓѕSierra VistaArizona K7RDG CK7RDG GˆnІР' ln Ьћџџ2œюєіџџџџџџџџџџџџџџџџTucsonArizona KR7ST BKR7ST G0Ј”@KL H n:И ћџџ2œшѕїCabotArkansasW5STR BW5STR GјЁ_@KL#\Аћ џџ2œшіјClarksvilleArkansasWU5PIG BWU5PIG G@Ša@KL#ˆ]T$ћ џџ2œшїљџџџџџџџџџџџџџџџџLittle RockArkansasK5NSX CK5NSX GPЇР' "А\@ћ џџ2œюјњRogersArkansasKG5JPJ BKG5JPJ GHe`@KL$ Œ ^Lћ џџ2œшљћBoiseIdahoW7VOI BW7VOI G№ћl@KL+"Шt˜!ћџџ2œшњќџџџџџџџџџџџџџџџџIdaho FallsIdahoKG7WZG BKG7WZG G ЋС@KL+Мp<ћџџ2œшћ§JeromeIdahoKF7VTM BKF7VTM Gƒ@KL*,Єrћџџ2œюќўMoyie SpringsIdahoKF7MJA CKF7MJA GˆnІР' 0)Шtxћџџ2œю§џџџџџџџџџџџџџџџџџBillingsMontanaK7EFA BK7EFA G@2У@KL-.Ьl" ћџџ2œюўPlainsMontanaW1KGK AW1KGK G`СP@KL/tr%ћџџ2œшџLas VegasNevadaN7ARR AN7ARR GрXM€БO$ ф%s ћџџ2œшџџџџџџџџџџџџџџџџLas VegasNevadaN7ARR BN7ARR G€ Ё@KL$ ф%s ћџџ2œшLas VegasNevadaN7ARR CN7ARR Gи1ЇР' $ ф%s ћџџ2œшLas VegasNevadaW7AES AW7AES G№ЗoLЗ#8шsЈћџџ2œшџџџџџџџџџџџџџџџџLas VegasNevadaW7AES BW7AES GXјЫ@KL#8шsЈћџџ2œшLas VegasNevadaW7AES CW7AES GXыбР' #8шsЈћџџ2œюLas VegasNevadaW7HEN BW7HEN GLЄ@KL# ,sШћџџ2œшџџџџџџџџџџџџџџџџPahrumpNevadaKJ7OIR BKJ7OIR GаcЂ@KL  tpћџџ2œш RenoNevadaN7NDS BN7NDS Ghp€@KL'Рw' ћџџ2œш RenoNevadaN7NDS CN7NDS Gи1ЇР' 'ˆw'„ћџџ2œю  џџџџџџџџџџџџџџџџRenoNevadaW7TA BW7TA Ghp€@KL'xw(˜ћџџ2œш  WinnemuccaNevadaKJ7OSQ BKJ7OSQ G(љd@KL(6€%u- ћџџ2œш  CorvallisOregonKF7LDG BKF7LDG G03ь@KL,d{8ћџџ2œш џџџџџџџџџџџџџџџџGrants PassOregonKE7LKX BKE7LKX GЄь@@KL*l { H&ћџџ2œю HillsboroOregonN7QQU BN7QQU GpBB@KL- z6аћџџ2œшMedfordOregonKE7MVI BKE7MVI Gxs@KL*`"z-Xћџџ2œюџџџџџџџџџџџџџџџџMedfordOregonKG7FOJ AKG7FOJ Gˆ…M-1*јz2H ћџџ2œшMedfordOregonKG7FOJ BKG7FOJ Gв€@KL*јz2H ћџџ2œшMedfordOregonKG7FOJ CKG7FOJ GPНР' *јz2H ћџџ2œшџџџџџџџџџџџџџџџџMt HeboOregonW7GC CW7GC G0ўШР' - ќ!{-<ћџџ2œюSalemOregonW7SRA CW7SRA GрчРР' ,3T { ћџџ2œюSherwoodOregonWB7DZG AWB7DZG G[M-1-Мz& ћџџ2œшџџџџџџџџџџџџџџџџSherwoodOregonWB7DZG BWB7DZG GДЋ{@KL-Мz& ћџџ2œшSherwoodOregonWB7DZG CWB7DZG GPНР' -Мz& ћџџ2œюAmerican ForkUtahNT3ST BNT3ST GаЧ@KL(@o/dћџџ2œюџџџџџџџџџџџџџџџџCedar CityUtahWR7AAA BWR7AAA GА,Г@KL%+q„ћџџ2œшCedar CityUtahWR7AAA CWR7AAA G0аІР' %+q„ћџџ2œшLoganUtahAC7O BAC7O GXŽГ@KL)!Xo8˜ћџџ2œшџџџџџџџџџџџџџџџџLoganUtahAC7O CAC7O G0аІР' )!Xo8˜ћџџ2œюLoganUtahN7RDS BN7RDS GЫВ@KL).xp „ћџџ2œюMorganUtahKM7ARC BKM7ARC G„]Г@KL)Ќ&o)Єћџџ2œш џџџџџџџџџџџџџџџџMorganUtahKM7ARC CKM7ARC GЇР' )Ќ&o)Єћџџ2œш!PriceUtahK7YI BK7YI GјЕ@KL' шn$ф ћџџ2œш "Salt Lake CityUtahKF6RAL AKF6RAL GРЖLЗ('Dp мћџџ2œш!#џџџџџџџџџџџџџџџџSalt Lake CityUtahKF6RAL BKF6RAL GјЕ@KL('Dp мћџџ2œш"$Salt Lake CityUtahKF6RAL CKF6RAL GˆnІР' ('Dp мћџџ2œш#%SandyUtahW7JHL BW7JHL G0­@KL("Œ o14!ћџџ2œш$&џџџџџџџџџџџџџџџџSterlingUtahK7BSK BK7BSK GА,Г@KL' шo+Xћџџ2œю%'SterlingUtahK7BSK CK7BSK G0аІР' ' шo+Xћџџ2œю&(WellsvilleUtahNU7TS BNU7TS GXјЫ@KL)$єo9 ћџџ2œю')џџџџџџџџџџџџџџџџWest BountifulUtahKF7ZNS BKF7ZNS GXŽГ@KL(5o4ћџџ2œш(*West BountifulUtahKF7ZNS CKF7ZNS G\ŸІР' (5o4ћџџ2œш)+Bainbridge I.WashingtonW7NPC AW7NPC G wыL-1/'Ќ z 4!ћџџ2œш*,џџџџџџџџџџџџџџџџBainbridge I.WashingtonW7NPC BW7NPC GD|@KL/'Ќ z 4!ћџџ2œш+-BellevueWashingtonK7LWH AK7LWH G€жуL-1/$Ќ&z шћџџ2œш,.BellevueWashingtonK7LWH BK7LWH Gф˜h@KL/$Ќ&z шћџџ2œш-/џџџџџџџџџџџџџџџџBellevueWashingtonK7LWH CK7LWH GШАЕ@B/$Ќ&z шћџџ2œш.0BellinghamWashingtonWC7SO BWC7SO GxA@KL0)Ф z„ћџџ2œш/1BellinghamWashingtonWC7SO CWC7SO GрvОР' 0)Ф z„ћџџ2œш02џџџџџџџџџџџџџџџџBurienWashingtonKF7CLD BKF7CLD Gш n@KL/ zlћџџ2œш13BurienWashingtonKF7GVL BKF7GVL GhœO@KL/xz10ћџџ2œш24ChehalisWashingtonKK7DFM BKK7DFM GаФ}@KL.T { (#ћџџ2œш35џџџџџџџџџџџџџџџџCle ElumWashingtonWR7KCR BWR7KCR Gtг„@KL/ Xx-T$ћџџ2œш46EdmondsWashingtonNW7DR ANW7DR Gд:@KL/3$zЌ ћџџ2œш57EdmondsWashingtonNW7DR BNW7DR Gд:@KL/3$zЌ ћџџ2œш68џџџџџџџџџџџџџџџџEnumclawWashingtonW7JD BW7JD Gшыa@KL/дzŒ#ћџџ2œш79EverettWashingtonNR7SS BNR7SS G05?@KL/6tz`"ћџџ2œш8:Federal WayWashingtonWA7FW BWA7FW Gt@KL/H ztћџџ2œю9;џџџџџџџџџџџџџџџџFederal WayWashingtonWA7FW CWA7FW GР™РР' /H ztћџџ2œю:<GrahamWashingtonWA7DR BWA7DR GШf@KL/шzф%ћџџ2œш;=IssaquahWashingtonKK7PPV BKK7PPV GРЄg@KL/Дz9H ћџџ2œю<>џџџџџџџџџџџџџџџџKingstonWashingtonK7GKR BK7GKR Gї@KL/2z Dћџџ2œю=?KirklandWashingtonN7IH AN7IH G€п M-1/%˜!z Мћџџ2œш>@KirklandWashingtonN7IH BN7IH Gиjp@KL/%˜!z Мћџџ2œш?AџџџџџџџџџџџџџџџџKirklandWashingtonN7IH CN7IH Gx"С@B/%˜!z Мћџџ2œш@BLake StevensWashingtonKF7UUY BKF7UUY GЄ!M@KL//H z@ћџџ2œшACMaple ValleyWashingtonKF7NPL BKF7NPL G8Џb@KL/ќzШћџџ2œшBDџџџџџџџџџџџџџџџџSaint GeorgeWashingtonKF7YIX BKF7YIX GА,Г@KL%№ q Шћџџ2œшCESaint GeorgeWashingtonKF7YIX CKF7YIX G0аІР' %№ q Шћџџ2œшDFSan Juan IslandWashingtonN7JN BN7JN Gшz_@KL0#H {ˆћџџ2œшEGџџџџџџџџџџџџџџџџSeattleWashingtonWA7HJR BWA7HJR G<Ё€@KL/Ьy8l ћџџ2œюFHSheltonWashingtonKK7DFL CKK7DFL GxИЈР' /H&{јћџџ2œюGISnohomishWashingtonKG7QPU BKG7QPU G``u@KL/8”zЬћџџ2œшHJџџџџџџџџџџџџџџџџSnoqualmieWashingtonN7SNO BN7SNO Gрc@KL/Ly1H ћџџ2œшIKSpokaneWashingtonWA7DRE AWA7DRE G 1M-1/&И$uxћџџ2œюJLSpokaneWashingtonWA7DRE BWA7DRE Gi@KL/&И$uxћџџ2œюKMџџџџџџџџџџџџџџџџTukwilaWashingtonKF7BFS BKF7BFS G8>@KL/єzаћџџ2œшLNTukwilaWashingtonKF7BFT BKF7BFT G(Z@@KL/И zрћџџ2œшMOVancouverWashingtonK7CLL BK7CLL Gд:@KL-+ќ!zрћџџ2œшNPџџџџџџџџџџџџџџџџCheyenneWyomingKC7SNO BKC7SNO GЈЈ@KL)iH&ћџџ2œшOQGilletteWyomingNE7WY CNE7WY G`ЖЉР' , |i ћџџ2œшPRRivertonWyomingN8CZI BN8CZI Gиjp@KL+ l ћџџ2œшQSџџџџџџџџџџџџџџџџAuburn HillsMichiganK8DXA BK8DXA Gdшz@KL*( S xћ$џџ2шRTAuburn HillsMichiganK8DXA CK8DXA G‚ІР' *( S xћ$џџ2юSUBattle CreekMichiganW8DF BW8DF Gd@KL*Uф ћ$џџ2шTVџџџџџџџџџџџџџџџџBattle CreekMichiganW8DF CW8DF GpжПР' *Uф ћ$џџ2шUWCharlotteMichiganK8ETN BK8ETN GМQn@KL*"а T2ћ$џџ2юVXCharlotteMichiganK8ETN CK8ETN G€“ЇР' *"а T2ћ$џџ2шWYџџџџџџџџџџџџџџџџElmiraMichiganNM8ES ANM8ES G@hЉР' -шT2ћ$џџ2юXZEngadineMichiganW8NBY BW8NBY G|yw@KL. \U"ќћ$џџ2шY[HellMichiganK8LCD AK8LCD G€2(M-1*шS94ћ$џџ2шZ\џџџџџџџџџџџџџџџџHellMichiganK8LCD BK8LCD G$лw@KL*шS94ћ$џџ2ш[]HellMichiganK8LCD CK8LCD G?ЦР' *шS94ћ$џџ2ш\^HowellMichiganW8LIV BW8LIV G|yw@KL*#ШS:Pћ$џџ2ш]_џџџџџџџџџџџџџџџџHowellMichiganW8LIV CW8LIV G@hЉР' *#ШS:Pћ$џџ2ю^`IthacaMichiganKD8IEK BKD8IEK GмНi@KL+ T$Ьћ$џџ2ш_aIthacaMichiganKD8IEK CKD8IEK GАTХР' + T$Ьћ$џџ2ш`bџџџџџџџџџџџџџџџџKalamazooMichiganNK8X BNK8X G ˆ~@KL*РU!дћ$џџ2шacLapeerMichiganW8LAP BW8LAP G0дc@KL+œSLћ$џџ2шbdLivoniaMichiganK8UNS BK8UNS Gј@„@KL*4!SМћ$џџ2шceџџџџџџџџџџџџџџџџMidlandMichiganKC8ARJ BKC8ARJ G0>|@KL+'И$T Lћ$џџ2шdfMolineMichiganWM8TG BWM8TG G№Ц`@KL*,4U%( ћ$џџ2шegMuskegonMichiganK8WNJ BK8WNJ Gдw@KL+„Vdћ$џџ2шfhџџџџџџџџџџџџџџџџNilesMichiganKE8GVB BKE8GVB G(љd@KL*€ VXћ$џџ2шgiOwossoMichiganW8SHI BW8SHI Gрz{@KL*:ЄT ( ћ$џџ2шhjOwossoMichiganW8SHI CW8SHI GР/ЈР' *:ЄT ( ћ$џџ2шikџџџџџџџџџџџџџџџџPaw PawMichiganW8VY BW8VY Gј x@KL* U:` ћ$џџ2шjlRoscommonMichiganWD7ROS BWD7ROS GФ,m@KL,МT'ќ!ћ$џџ2шkmSaginawMichiganK8DAC BK8DAC GЄVY@KL+ S"@ћ$џџ2шlnџџџџџџџџџџџџџџџџSt. JohnsMichiganKD8IEI BKD8IEI GœАf@KL*;H T Xћ$џџ2шmoSt. JohnsMichiganKD8IEI CKD8IEI G=ЋР' *;H T Xћ$џџ2шnpSt. JosephMichiganW8MAI BW8MAI GИ”\@KL*@V ћ$џџ2шoqџџџџџџџџџџџџџџџџStutsmanvilleMichiganW8CCE BW8CCE G˜]m@KL-аU(#ћ$џџ2шprTopinabeeMichiganN8RTS BN8RTS GШJZ@KL-T#@ћ$џџ2шqsTravese CityMichiganWI0OK CWI0OK G€ЊР' ,.8U)ћ$џџ2шrtџџџџџџџџџџџџџџџџWarrenMichiganWA8BRO BWA8BRO GќєX@KL*R; ћ$џџ2шsuWestlandMichiganW8DTW BW8DTW Gї@KL*ШSшћ$џџ2шtvAkronOhioKE8LDH BKE8LDH Gt4`@KL)LQ!Аћ$џџ2шuwџџџџџџџџџџџџџџџџCincinnatiOhioK8BIG BK8BIG Gчv@KL'$T№#ћ$џџ2шvxCincinnatiOhioK8BIG CK8BIG GpнЉР' '$T№#ћ$џџ2шwyClevelandOhioWB8THD BWB8THD GX]@KL)ф%)„ћ$џџ2шxzџџџџџџџџџџџџџџџџClevelandOhioWB8THD CWB8THD GpнЉР' )ф%)„ћ$џџ2шy{ColumbusOhioW8CMH BW8CMH Gчv@KL';Ќ&R;Ќ&ћ$џџ2юz|ColumbusOhioW8CMH CW8CMH GPЌР' ';Ќ&R;Ќ&ћ$џџ2ю{}џџџџџџџџџџџџџџџџColumbusOhioW8DIG AW8DIG G@‹—LЗ(xR6Ф"ћ$џџ2ю|~ColumbusOhioW8DIG BW8DIG GMb@KL(xR6Ф"ћ$џџ2ю}ColumbusOhioW8DIG CW8DIG GАyЊР' (xR6Ф"ћ$џџ2ю~€џџџџџџџџџџџџџџџџColumbusOhioW8LT BW8LT G@Ša@KL(ЄS№ ћ$џџ2шDaytonOhioW8HEQ BW8HEQ GЬ[@KL'4!U/hћ$џџ2žшЖИAdamsWisconsinAC9AR BAC9AR GN|\@KL+9$Y1 ћ џџ2žшЗЙџџџџџџџџџџџџџџџџBarabooWisconsinWB9FDZ CWB9FDZ GИTЉР' +l Y'˜ћ џџ2žюИКChippewa FallsWisconsinKD9ICN CKD9ICN G` ТР' ,4Ќ [ћ џџ2žшЙЛDunnvilleWisconsinWW9RS CWW9RS G6СР' ,[ ”ћ џџ2žшКМџџџџџџџџџџџџџџџџEdgertonWisconsinKD9KPT BKD9KPT G`і\@KL*2АYєћ џџ2žшЛНFond du LacWisconsinKD9GXT CKD9GXT GшЩЉР' +0X€ ћ џџ2žюМОGraftonWisconsinW9FRG BW9FRG GОрd@KL+T$W8%ћ џџ2žшНПџџџџџџџџџџџџџџџџGraftonWisconsinW9FRG CW9FRG G(ѕЇР' +T$W8%ћ џџ2žюОРGreen BayWisconsinK9EAM BK9EAM GЊ z@KL,ьW7ић џџ2žшПСHollandaleWisconsinWI9WIN CWI9WIN GdЧР' *7№ Y9јћ џџ2žшРТџџџџџџџџџџџџџџџџMadisonWisconsinW9HSY CW9HSY GЈ-ЉР' +Y@ћ џџ2žюСУMarshfieldWisconsinKD9FUR CKD9FUR GˆКУР' ,(xZ И ћ џџ2žшТФMilwaukeeWisconsinK9AES CK9AES G8ЈР' +И$W:Ќ&ћ џџ2žшУХџџџџџџџџџџџџџџџџMilwaukeeWisconsinKC9LKZ AKC9LKZ Gа™фL-1+мW6№ ћ џџ2žъФЦMilwaukeeWisconsinKC9LKZ BKC9LKZ Gމ_@KL+мW6№ ћ џџ2žъХЧMilwaukeeWisconsinKC9LKZ CKC9LKZ GКЇР' +мW6№ ћ џџ2žюЦШџџџџџџџџџџџџџџџџPark FallsWisconsinW9PFP BW9PFP GbК_@KL-1№#Z$H ћ џџ2žшЧЩPark FallsWisconsinW9PFP CW9PFP GшЩЉР' -1№#Z$H ћ џџ2žшШЪRacineWisconsinWI9RAC BWI9RAC G~žU@KL*+` W3ић џџ2žшЩЫџџџџџџџџџџџџџџџџRichfieldWisconsinK9PAQ BK9PAQ Gh;t@KL+ @X @ћ џџ2žшЪЬRichfieldWisconsinK9PAQ CK9PAQ GаРРР' + @X @ћ џџ2žшЫЭRichland CenterWisconsinKC9WDW BKC9WDW GЬв_@KL+ЬZьћ џџ2žюЬЮџџџџџџџџџџџџџџџџSaynerWisconsinKD9JHE BKD9JHE G€}@KL-;$Y#Ф"ћ џџ2žшЭЯSheboyganWisconsinKC9SJY BKC9SJY GbК_@KL+, W+$ћ џџ2žшЮаSheboyganWisconsinKC9SJY CKC9SJY GиюЦР' +, W+$ћ џџ2žшЯбџџџџџџџџџџџџџџџџWatertownWisconsinW9TTN BW9TTN G№'<@KL+ ЄX- ћ џџ2žшавWausauWisconsinW9BCC AW9BCC G KkLЗ,7ќY)$ћ џџ2žъбгWausauWisconsinW9BCC BW9BCC Gމ_@KL,7ќY)$ћ џџ2žъвдџџџџџџџџџџџџџџџџWausauWisconsinW9BCC CW9BCC GHCЈР' ,7ќY)$ћ џџ2žюгеWonewocWisconsinKD9BLN BKD9BLN GЖ:r@KL+*DZ Аћ џџ2žшджWonewocWisconsinKD9BLN CKD9BLN GxБОР' +*DZ Аћ џџ2žшезџџџџџџџџџџџџџџџџBoulderColoradoKC0DS AKC0DS Gф/†LРсф':Мi0ћџџ2ŸшжиBoulderColoradoKC0DS BKC0DS GЄ”Ђ@KL':Мi0ћџџ2ŸшзйBoulderColoradoKC0DS CKC0DS GьoЊР' ':Мi0ћџџ2ŸшикџџџџџџџџџџџџџџџџColorado SpringsColoradoKC0CVU AKC0CVU G4ќУLЗ&,рh3(#ћџџ2ŸшйлColorado SpringsColoradoKC0CVU BKC0CVU GєWЃ@KL&,рh3(#ћџџ2ŸюкмColorado SpringsColoradoKC0CVU CKC0CVU G(fЊР' &,рh3(#ћџџ2ŸюлнџџџџџџџџџџџџџџџџDenverColoradoW0CDS AW0CDS G„Ж‡LЗ' ipћџџ2ŸшмоDenverColoradoW0CDS BW0CDS GDЄ@KL' ipћџџ2ŸшнпDenverColoradoW0CDS CW0CDS GаVЈР' ' ipћџџ2ŸшорџџџџџџџџџџџџџџџџGrand JunctionColoradoKD0RED BKD0RED Gи>Ё@KL'Ф a ˆћџџ2ŸшпсParkerColoradoK0PRA BK0PRA GаcЂ@KL'%h*аћџџ2ŸшртSalidaColoradoKD0QPG BKD0QPG GLЄ@KL&ЄjМћџџ2ŸюсуџџџџџџџџџџџџџџџџColorado SpringsColorado KE0VUW BKE0VUW GLіЂ@KL'h0tћџџ2ŸштфCedar RapidsIowaN0CXX BN0CXX Gа%Y@KL*d[&№#ћ џџ2ŸшухCedar RapidsIowaN0CXX CN0CXX GШ8Щ0*d[&№#ћ џџ2ŸшфцџџџџџџџџџџџџџџџџDes MoinesIowaKD0IAN BKD0IAN GXPj@KL)&ф ]0јћ џџ2ŸъхчDes MoinesIowaKD0IAN CKD0IAN GшЄФР' )&ф ]0јћ џџ2ŸюцшMount PleasantIowaKD0NJC BKD0NJC G0>|@KL)0[$ћ џџ2ŸшчщџџџџџџџџџџџџџџџџBaldwin CityKansasWV0A BWV0A Gј x@KL&.ь_ ( ћ џџ2ŸюшъLouisburgKansasK0HAM AK0HAM GРЖLЗ&#Є^%˜ћ џџ2ŸшщыLouisburgKansasK0HAM BK0HAM GШJZ@KL&#Є^%˜ћ џџ2ŸшъьџџџџџџџџџџџџџџџџLouisburgKansasK0HAM CK0HAM G[ІР' &#Є^%˜ћ џџ2ŸшыэOlatheKansasWA0RC BWA0RC GHe`@KL&3Ф ^/ˆћ џџ2ŸшьюScott CityKansasW0MI BW0MI GЈk@KL&ˆd7 ћ џџ2ŸшэяџџџџџџџџџџџџџџџџChaskaMinnesotaKD0JOS AKD0JOS GрЇ€LЗ,0ˆ]$ћ џџ2Ÿшю№ChaskaMinnesotaKD0JOS BKD0JOS GШJZ@KL,0ˆ]$ћ џџ2ŸшяёChaskaMinnesotaKD0JOS CKD0JOS Gp)ЧР' ,0ˆ]$ћ џџ2Ÿш№ђџџџџџџџџџџџџџџџџChaskaMinnesotaKD0JOT AKD0JOT G eqLЗ,0]$ћ џџ2ŸшёѓDuluthMinnesotaN0EO BN0EO GРo[@KL./T \˜!ћ џџ2ŸшђєDuluthMinnesotaN0EO CN0EO G˜УШР' ./T \˜!ћ џџ2ŸшѓѕџџџџџџџџџџџџџџџџFaribaultMinnesotaKD0ZSA BKD0ZSA Ghp€@KL,€%]€%ћ џџ2ŸшєіGem LakeMinnesotaKA0JSW AKA0JSW G`,ŸL-1-Ш]˜!ћ џџ2ŸшѕїGem LakeMinnesotaKA0JSW BKA0JSW Gчv@KL-Ш]˜!ћ џџ2ŸшіјџџџџџџџџџџџџџџџџGolden ValleyMinnesotaKD0JOV BKD0JOV G f@KL,;%]`"ћ џџ2ŸшїљLittle FallsMinnesotaW0REA BW0REA Gчv@KL-:Ј^Lћ џџ2ŸшјњMinneapolisMinnesotaKD0JOU AKD0JOU G š}LЗ,;L]l ћ џџ2ŸшљћџџџџџџџџџџџџџџџџMinneapolisMinnesotaKD0JOU BKD0JOU Gј@„@KL,;L]l ћ џџ2ŸшњќMinneapolisMinnesotaKD0JOU CKD0JOU G№3ІР' ,;L]l ћ џџ2Ÿшћ§MinneapolisMinnesotaW1AFV BW1AFV Gpсf@KL,:L]Ф"ћ џџ2ŸшќўџџџџџџџџџџџџџџџџMounds ViewMinnesotaW0ANA BW0ANA Gxs@KL-˜] ф%ћ џџ2Ÿш§џRochesterMinnesotaW0MXW BW0MXW Gt@KL,ф \T$ћ џџ2ŸшўShoreviewMinnesotaKC0WLB BKC0WLB Gчv@KL-,]4!ћ џџ2ŸшџџџџџџџџџџџџџџџџџShoreviewMinnesotaW8WRR AW8WRR G ъLЗ,9] ћ џџ2ŸшShoreviewMinnesotaW8WRR BW8WRR G№ћl@KL,9] ћ џџ2ŸшSt. CloudMinnesotaKD0YLG BKD0YLG Gt@KL-Ќ&^ Ф"ћ џџ2ŸшџџџџџџџџџџџџџџџџWandaMinnesotaKD0IAI BKD0IAI GЈHw@KL,4!_ Шћ џџ2ŸшColumbiaMissouriWX0BC BWX0BC GX]@KL&:А\Lћ џџ2ŸшFreistattMissouriW0OAR BW0OAR G№0y@KL%X]4T ћ џџ2ŸшџџџџџџџџџџџџџџџџJefferson CityMissouriKB4VSP CKB4VSP GhћРР' &!L\  ћ џџ2ŸшKansas CityMissouriW0CW AW0CW GN˜LЗ'ф ^#8ћ џџ2Ÿш Kansas CityMissouriW0CW BW0CW G@Пm@KL'ф ^#8ћ џџ2Ÿш џџџџџџџџџџџџџџџџKansas CityMissouriWB0YRG BWB0YRG G№Ц`@KL'H ^#8ћ џџ2Ÿш  PacificMissouriKD0ZEA BKD0ZEA G`і\@KL&0Z,dћ џџ2Ÿю  PacificMissouriKD0ZEA CKD0ZEA GPІК@B&0Z,dћ џџ2Ÿю  џџџџџџџџџџџџџџџџRollaMissouriW0CMD BW0CMD Gчv@KL%9L[/T ћ џџ2Ÿш RollaMissouriW0EEE BW0EEE GЈ†Р@KL%9р[.И ћ џџ2Ÿш SpringfieldMissouriW0OMD CW0OMD Gи›ПР' %И ] Јћ џџ2ŸшџџџџџџџџџџџџџџџџSt LouisMissouriK0MDG AK0MDG G@‹—LЗ&(PZT$ћ џџ2ŸшSt LouisMissouriK0MDG BK0MDG G˜(a@KL&(PZT$ћ џџ2ŸшSt LouisMissouriK0MDG CK0MDG GXEУР' &(PZT$ћ џџ2ŸюџџџџџџџџџџџџџџџџWashingtonMissouriK0FDG BK0FDG G mx@KL&LZ7Lћ џџ2ŸшColumbusNebraskaWA0COL BWA0COL G[@KL)Ќ a%ћ џџ2ŸъColumbusNebraskaWA0COL CWA0COL GјZТР' )Ќ a%ћ џџ2ŸюџџџџџџџџџџџџџџџџGrand IslandNebraskaKD0PBV CKD0PBV G(юНР' (8db0ћ џџ2ŸшKearneyNebraskaKD0PBW CKD0PBW G№УР' ()xcЄћ џџ2ŸюLincolnNebraskaW0MAO BW0MAO GpЌZ@KL(0Р`)H&ћ џџ2ŸшџџџџџџџџџџџџџџџџLincolnNebraskaW0MAO CW0MAO GаVЈР' (0Р`)H&ћ џџ2ŸшOmahaNebraskaKD0CGR BKD0CGR GШJZ@KL)ј_8<ћ џџ2ŸшOmahaNebraskaKD0CGR CKD0CGR Gи1ЇР' )ј_8<ћ џџ2ŸшџџџџџџџџџџџџџџџџWood RiverNebraskaNI0P BNI0P G`•@KL(10b$мћ џџ2ŸшFargoNorth DakotaKD0SWQ BKD0SWQ Gчv@KL.5Ш`/T$ћ џџ2ŸшSioux FallsSouth DakotaW0ZWY BW0ZWY G0дc@KL+T$`,H ћ џџ2ŸшџџџџџџџџџџџџџџџџFairbanksAlaskaKL7CDA BKL7CDA G€}@KL@7№ “ №#ћџџ2 ш KetchikanAlaskaKL7FF CKL7FF G зШР' 7Дƒ&ћџџ2 ш!WasillaAlaskaWL7CWI AWL7CWI G@M-1=м•*lћџџ2 ш "џџџџџџџџџџџџџџџџWasillaAlaskaWL7CWI BWL7CWI G€bX@KL=м•*lћџџ2 ш!#WasillaAlaskaWL7CWI CWL7CWI GР УР' =м•*lћџџ2 ю"$AieaHawaiiKH6ERO BKH6ERO G`•@KL48„ћџџ2Ёш#%џџџџџџџџџџџџџџџџHonoluluHawaiiWH6DIG BWH6DIG GH…@KL2€ ћџџ2Ёш$&HonoluluHawaiiWH6DIG CWH6DIG GрЩХР' 2€ ћџџ2Ёш%'AntigonishNova ScotiaVE1JSR BVE1JSR G 8l@KL-%ш=:hћ(џџ3Њю&(џџџџџџџџџџџџџџџџBlainvilleQuebecVE2YUU BVE2YUU G€bX@KL-)hI6Lћ$џџ3Ћш')Covey HillQuebecVA2REX BVA2REX GˆхИ@KL-№#I2Рћ$џџ3Ћш(*Covey HillQuebecVE2REX CVE2REX G№†­Р' -№#I2Рћ$џџ3Ћю)+џџџџџџџџџџџџџџџџGatineauQuebecVE2REH BVE2REH GMb@KL-шKPћ$џџ3Ћш*,MaskinongщQuebecVE2RRJ BVE2RRJ GРo[@KL. œIdћ$џџ3Ћш+-Mont-OrfordQuebecVE2RTO AVE2RTO G 'wK@KL-LH\ћ$џџ3Ћш,.џџџџџџџџџџџџџџџџMont-OrfordQuebecVE2RTO BVE2RTO G€bX-1-LH\ћ$џџ3Ћю-/MontrealQuebecVA2RKA BVA2RKA GpЕ—@KL-<I№#ћ$џџ3Ћю.0MontrealQuebecVE2RHH BVE2RHH G” t@KL-!|I*Мћ$џџ3Ћш/1џџџџџџџџџџџџџџџџMontrealQuebecVE2RIO AVE2RIO GРyLЗ-!$I!Аћ$џџ3Ћъ02MontrealQuebecVE2RIO BVE2RIO GˆOб@KL-!$I!Аћ$џџ3Ћъ13MontrealQuebecVE2RIO CVE2RIO G№ТЃР' -!$I!Аћ$џџ3Ћю24џџџџџџџџџџџџџџџџMt.SaintGrщgoireQuebecVE2RVR BVE2RVR G@єy@KL-И$I4ћ$џџ3Ћш35Quebec CityQuebecVE2RQT BVE2RQT GˆOб@KL..Gћ$џџ3Ћъ46Quebec CityQuebecVE2RQT CVE2RQT G№ТЃР' ..Gћ$џџ3Ћю57џџџџџџџџџџџџџџџџRigaud MountainQuebecVE2RM BVE2RM G3\@KL-АJ@ћ$џџ3Ћш68RimouskiQuebecVE2RKI CVE2RKI G№ТЃР' 0ќ!Dћ$џџ3Ћш79Saint-CalixteQuebecVA2RKB CVA2RKB GpNЌР' -:ДI74ћ$џџ3Ћъ8:џџџџџџџџџџџџџџџџSherbrookeQuebecVE2RQF AVE2RQF G A}K-1-G6Ф"ћ$џџ3Ћю9;SherbrookeQuebecVE2RQF CVE2RQF G ѕУР' -G6Ф"ћ$џџ3Ћю:<Sorel-TracyQuebecVE2CST AVE2CST G@(јI-1.АILћ$џџ3Ћъ;=џџџџџџџџџџџџџџџџSorel-TracyQuebecVE2CST CVE2CST G(аТР' .АILћ$џџ3Ћъ<>Sorel-TracyQuebecVE2FCT BVE2FCT G<™@KL.Iћ$џџ3Ћъ=?Trois-RiviшresQuebecVA2LX BVA2LX GИ<О@KL.€ H"4!ћ$џџ3Ћш>@џџџџџџџџџџџџџџџџAlmonteOntarioVA3AAR BVA3AAR G mx@KL- „LDћ$џџ3Ќш?AAlmonteOntarioVA3AAR CVA3AAR GАъЌР' - „LDћ$џџ3Ќш@BCornwallOntarioVA3SDG BVA3SDG GаФ}@KL-ЄJ,hћ$џџ3ЌшACџџџџџџџџџџџџџџџџCornwallOntarioVA3SDG CVA3SDG Gа8­Р' -ЄJ,hћ$џџ3ЌшBDFonthillOntarioVE3PLF BVE3PLF Gї@KL+ Oћ$џџ3ЌшCEHamiltonOntarioVE3WIK BVE3WIK Gќ^q@KL+H&O:Шћ$џџ3ЌшDFџџџџџџџџџџџџџџџџHamiltonOntarioVE3WIK CVE3WIK GPЉР' +H&O:Шћ$џџ3ЌшEGLittle CurrentOntarioVE3RXR BVE3RXR Gа%Y@KL-9ќQ84!ћ$џџ3ЌюFHLittle CurrentOntarioVE3RXR CVE3RXR G0AЉР' -9ќQ84!ћ$џџ3ЌъGIџџџџџџџџџџџџџџџџLondonOntarioVE3TTT BVE3TTT G`і\@KL*;XQdћ$џџ3ЌюHJMapleOntarioVA3ITL BVA3ITL G” [@KL+#ЈO/Ќ ћ$џџ3ЌшIKMississaugaOntarioVA3PMO BVA3PMO GЗz@KL+#€ O&„ћ$џџ3ЌшJLџџџџџџџџџџџџџџџџMississaugaOntarioVE3RSD BVE3RSD G” t@KL+#ЈO/Ќ ћ$џџ3ЌшKMMt.St. PatrickOntarioVE3STP BVE3STP G” t@KL-РL64ћ$џџ3ЌшLNNiagaraOnTheLakeOntarioVA3YYZ BVA3YYZ Gд­^@KL+ ”Oxћ$џџ3ЌшMOџџџџџџџџџџџџџџџџNiagaraOnTheLakeOntarioVA3YYZ CVA3YYZ GаtЃР' + ”Oxћ$џџ3ЌшNPNorfolkOntarioVE3HJ BVE3HJ GpK@KL*7PPИ ћ$џџ3ЌшOQOttawaOntarioVA3ODG BVA3ODG GPпƒ@KL-K)Ќ ћ$џџ3ЌшPRџџџџџџџџџџџџџџџџOttawaOntarioVA3ODG CVA3ODG GœЌР' -K)Ќ ћ$џџ3ЌшQSPerthOntarioVA3RDD BVA3RDD Gƒ@KL,2L Ф ћ$џџ3ЌшRTPerthOntarioVA3RDD CVA3RDD G@ДЦР' ,2L Ф ћ$џџ3ЌшSUџџџџџџџџџџџџџџџџPhelpstonOntarioVE3RIG BVE3RIG Gа%Y@KL, O2l ћ$џџ3ЌшTVSault Ste. MarieOntarioVA3SNR CVA3SNR GКЇР' . єTќ!ћ$џџ3ЌшUWSimcoe CountyOntarioVE3LSR BVE3LSR G0>|@KL,T$O'„ћ$џџ3ЌшVXџџџџџџџџџџџџџџџџSimcoe CountyOntarioVE3LSR CVE3LSR GplЇР' ,T$O'„ћ$џџ3ЌшWYSt CathgarinesOntarioVE3NUU BVE3NUU GлюˆŠCanberraACTVK1RWN CVK1RWN GdфНР' #T$•xї`џџFхю‰‹џџџџџџџџџџџџџџџџFairfieldNew South WalesVK2ROZ BVK2ROZ GєРeR!4ќ–9№ ї`џџFхюŠŒMaddens PlainsNew South WalesVK2RMP CVK2RMP GkПР' "@–9№ ї`џџFхъ‹SomersbyNew South WalesVK2RAG BVK2RAG GO РeR!8—\ї`џџFхъŒŽџџџџџџџџџџџџџџџџSomersbyNew South WalesVK2RAG CVK2RAG GO РeR!8—\ї`џџFхъSydneyNew South WalesVK2RBV BVK2RBV Gи,'@KL!3а — ї`џџFхюސTerrey Hills SDNNew South WalesVK2RWN CVK2RWN GDxТР' !)р— ї`џџFхю‘џџџџџџџџџџџџџџџџWyeeNew South WalesVK2RHK BVK2RHK GШAРeR! ф%—ї`џџFхъ’DarwinNorthern Terr.VK8RAD AVK8RAD GРЗM-1 ‚2јї^џџFхю‘“DarwinNorthern Terr.VK8RAD CVK8RAD GрvОР' ‚2јї^џџFхю’”џџџџџџџџџџџџџџџџBlackwaterQueenslandVK4RBD CVK4RBD GМ‚НР' %а lї`џџFхъ“•IpswichQueenslandVK4RBX CVK4RBX GЌЬПР' ќ˜#Ьї`џџFхю”–MackayQueenslandVK4RBY CVK4RBY GГНР' 4!•„ї`џџFхю•—џџџџџџџџџџџџџџџџManoora CairnsQueenslandVK4RCN BVK4RCN GO РeR7€ ‘+H&ї`џџFхъ–˜Mt TamborineQueenslandVK4RDK BVK4RDK G4 РeR;`"™ %ї`џџFхю—™SarinaQueenslandVK4RUS BVK4RUS GP7"@KLœ•( ї`џџFхъ˜šџџџџџџџџџџџџџџџџToowoombaQueenslandVK4RTQ BVK4RTQ G 2@KL —9tї`џџFхю™›WongawallanQueenslandVK4RDW BVK4RDW GАА РeR5™Јї`џџFхъšœWoombyeQueenslandVK4RDS CVK4RDS G\ ПР' &Ќ&˜9Ќ&ї`џџFхю›џџџџџџџџџџџџџџџџAdelaideSouth AustraliaVK5RWN CVK5RWN G<УР' "0Œ#Š,4!ї^џџFхъœžPort LinconSouth AustraliaVK5REX BVK5REX GhШРeR"*ш‡1єї^џџFхъŸRenmark WestSouth AustraliaVK5RMK BVK5RMK Gx~РeR" <Œ*И$ї^џџFхюž џџџџџџџџџџџџџџџџHobartTasmaniaVK7RCR CVK7RCR GDxТj*3x“Јї`џџFхюŸЁRichmondTasmaniaVK7RRR BVK7RRR GШAРeR*,р“И ї`џџFхю ЂBerwick MELVictoriaVK3RMC CVK3RMC GkПР' &@‘дї`џџFхюЁЃџџџџџџџџџџџџџџџџHorshamVictoriaVK3RDK CVK3RDK GМ‚НР' $+„Ž Œ ї`џџFхъЂЄKynetonVictoriaVK3RWW BVK3RWW GpЃРeR%а lї`џџFхюЃЅMt Macedon MELVictoriaVK3RMM BVK3RMM GаРeR%"дї`џџFхюЄІџџџџџџџџџџџџџџџџOlinda/MelbourneVictoriaVK3RWN BVK3RWN G`эРeR%3р‘xї`џџFхюЅЇOlinda/MelbourneVictoriaVK3RWN CVK3RWN GєДСР' %3р‘xї`џџFхъІЈSheppartonVictoriaVK3RGV BVK3RGV GРfРeR$3є‘( ї`џџFхюЇЉџџџџџџџџџџџџџџџџFremantle/PerthWesternAustraliaVK6RLX CVK6RLX GЄёРj дs:$їXџџFхъЈЊRoleystone/PerthWesternAustraliaVK6RWN CVK6RWN GќРР' дs:$їXџџFхъЉЋPort WaikatoAuklandZL1VHD BZL1VHD G@KL%0Ў0PїhџџGяъЊЌџџџџџџџџџџџџџџџџMt ThreaveHawke's BayZL2HBD BZL2HBD Gап@KL'-МА.H&їhџџGяюЋ­HamiltonWaikatoZL1CCT CZL1CCT GpнЉР' %/lЏ4!їhџџGяъЌЎKapiti CoastWellingtonZL2KB BZL2KB GpнЉР' (3Џф їhџџGяю­ЏџџџџџџџџџџџџџџџџUpper HuttWellingtonZL2VH CZL2VH GhЋР' )˜!ЏРїhџџGяюЎАDededoGuamAH2G CAH2G G$РР' 3МѓhџџHљюЏџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџАџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџћџџџџџџџџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAsiaAfricaEuropeNorth AmericaSouth AmericaOceaniaџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJapanNamibiaSouth AfricaAustriaBelgiumBulgariaCroatiaCzech RepublicDenmarkFranceGermanyGreeceHungaryIcelandItalyNetherlandsNorwayPolandPortugalSan MarinoSloveniaSpainSwedenSwitzerlandUnited KingdomUSACanadaMexicoGuatemalaEl SalvadorArgentinaBrazilCuracaoAustraliaNew ZealandGuamџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJA1 : KantoJA2 : TokaiJA3 : KansaiJA4 : ChugokuJA5 : ShikokuJA6 : KyushuJA7 : TohokuJA8 : HokkaidoJA9 : HokurikuJA0 : ShinetsuNamibiaSouth AfricaKфrntenNiederіsterreichOberіsterreichSalzburgSteiermarkTirolWienBelgiumBulgariaCroatiaCzech RepublicDenmarkFranceBaden-WќrttemberBayernBerlinBremenHamburgHessenMecklenburg-VorpNiedersachsenNordrhein-WestfaRheinland-PfalzSachsenSachsen-AnhaltSchleswig-HolsteThќringenGreeceHungaryIcelandAbruzzoApuliaCalabriaCampaniaEmilia-RomagnaFriuli V.G.LazioLombardiaPiemonteSardegnaSiciliaToscanaUmbriaVenetoNetherlandsNorwayPolandPortugalSan MarinoSloveniaSpainSwedenSwitzerlandSardegnaNorthern EnglandCentral EnglandSouth-EastSouth-WestWales & MarchesScotland/AlbaNorthern IrelandW1W2W3W4W5W6W7W8W9W0KL7KH6VE1VE2VE3VE4VE5VE6VE7VY1VY2MexicoGuatemalaEl SalvadorArgentinaBrazilCuracaoAustraliaNew ZealandGuamџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@`TЩџ•й1@Ш§J6ўљЃZХ§jCЛЉLж Ё`Tьџнб6џшз&=бДo' ЇџR=§§ш`TЩџ^ ж1hwК 9_o™Ч Ё`T•џuV;MЃz.' jцmбЗЅџЭ§§п`T.gq‚ќ3Bъzјїќyл  Ъy Ё`Tєџ6фƒxЛџŸtƒ'6%(дeOЃџЖ=§§шo`TѕџV~oC§Ќ1pщ€Ѕ?ўo1ё‘&_ Ё`T"ь'Еv_Œ'&Ќ‡ЩQЇџ>§§ х)"Vпџ–U0)˜ Ÿ1ъює=– ,˜€jЉ Ё"Vчџ6Ї\L‘џw“:'”‚­9ІџУ§§ юT"Vџ/-Tmљи.ЕЭЎŽњЮ‰Ѓ‚RZ Ё"V €3г Р[^'-ž‰›Јџl?§§`"V}џЏS `Џњё)пћѓ5fх‡ Ё"Vћџ1bŸ;TUT(P6ркЋџQ?§§ {с=s R§І Ё?ФѓњRЇ&Ђn~џ§§{“VЩQ§ ЁеЖМйЎsЙ§§{Ъ7~ћB§ Ёћ№ р˜цАз;§§{qхH§Ф Ё„Awif$ЃP„§§{Kr X§Q ЁвuLшFgЖŸtќ§§{yeы C§ ЁyчsPљC&Tћџ§§{?HЯј<§A Ё]\FDДЧšЧџ§§{о`VL§{ ЁпдHжп+бЛ§§{Џ{’њ=§T Ё*љUn'}в:ў§§{ в]§K ЁЂSШ€<‡fEаЅ§§{пv T§X Ё!.Mнuб,œf ў§§{TЯЗ F§d Ёˆ'›nц?˜M§§{ JH§_ ЁЧ_ТмЩ”з›–§§{ЦMЯH§ Ёevxp%e>ЂЄЯ§§{ђN§І Ё‹Ÿzю„^1§Иў§§{oXH§ ЁЉЇvŽЩR­Q№§§{Лrѓ U§z ЁЏ M“­!ƒиw…§§{‰~ѕњ7§^ ЁAюw–4ƒ(‡§§{Џ bF§ ЁтJy&‡зРW§§ {у?ЯY§д Ёцсљч7&•ЪC‘§§ {ŒI? V§B Ё PLRВ9ЪTП џ§§ {5 }F§ђ ЁaЦ •›Щ_/Ђ§§§ {4Lўd§( Ё}Щз4Ÿ#\Ё§§ {Л. O§U Ён/ѓ~Rˆbc§§{–L:§P Ё™мrY iЃOQџ§§{/“.R§у Ёлс`Ј„=мНў§§{енZ§0 Ё"VŸ]Єр}Јќ§§{|.ЖV§ ЁїЧК)2t]V§§{<nT§9 Ёr”ѕ@Ы†rE4§§{п)1a§п Ёц—ЩV{+gУЬЯ§§{Ф„qH§V ЁKl›єzЭRф\§§§ўјž0o(ўœ9К$uАБ '0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџvџ3Љя …BУsŒŒЂŸЅŠ‰Š|{|nmn’Ÿ€uuvoopŸЂЁ|€|йрйЭдЭшшшssshkgHIF./.wztPRN.,/qsoLOJ%+.K5/-џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘нР3@ €Гя 'Р@ €9оLK@@ €‘нР3@ €Гя 'Р@ €9оLK@@ €>ЦИ CQCQCQ CQCQCQ CQCQCQ CQCQCQ џџ NEџџџџџџџ REF000ALREF000AL CQCQCQ NEџџџГя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџ9оLK@@ €CQCQCQ џџџџџџџџџџџџџџџџ>ЦџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќџџџџџџџџџџўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiSWNvbSIsICJtb2RlbCI6ICJJRC01MSBQbHVzMiIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJJRDUxUExVUzJSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Radtel_RT-470.img0000644000175000017500000013167114430171343017302 0ustar hibbyhibby%pF%pFџџџџџџџџџџџџџџџџuqFuqFџџџџџџџџџџџџџџџџ%sF%sFџџџџџџџџџџџџџџџџutFutFџџџџџџџџџџџџџџџџ%vF%vFџџџџџџџџџџџџџџџџuwFuwFџџџџџџџџџџџџџџџџ%yF%yFџџџџџџџџџџџџџџџџu€Fu€Fџџџџџџџџџџџџџџџџ%‚F%‚FџџџџџџџџџџџџџџџџuƒFuƒFџџџџџџџџџџџџџџџџ%…F%…Fџџџџџџџџџџџџџџџџu†Fu†Fџџџџџџџџџџџџџџџџ%ˆF%ˆFџџџџџџџџџџџџџџџџu‰Fu‰Fџџџџџџџџџџџџџџџџ%‘F%‘Fџџџџџџџџџџџџџџџџu’Fu’Fџџџџџџџџџџџџџџџџ%@%@џџџџџџџџџџџџџџџџuAuAџџџџџџџџџџџџџџџџ%C%CџџџџџџџџџџџџџџџџuDuDџџџџџџџџџџџџџџџџ%F%FџџџџџџџџџџџџџџџџuGuGџџџџџџџџџџџџџџџџ%I%IџџџџџџџџџџџџџџџџPPPPџџџџџџџџџџџџџџџџ…Q…Qџџџџџџџџџџџџџџџџ…S…Sџџџџџџџџџџџџџџџџ%U%UџџџџџџџџџџџџџџџџuVuVџџџџџџџџџџџџџџџџ%X%XџџџџџџџџџџџџџџџџuYuYџџџџџџџџџџџџџџџџ%a%aџџџџџџџџџџџџџџџџububџџџџџџџџџџџџџџџџ%@$%@$џџџџџџџџџџџџџџџџPA$PA$џџџџџџџџџџџџџџџџ%C$%C$џџџџџџџџџџџџџџџџuD$uD$џџџџџџџџџџџџџџџџ%F$%F$џџџџџџџџџџџџџџџџuG$uG$џџџџџџџџџџџџџџџџ%I$%I$џџџџџџџџџџџџџџџџPP$PP$џџџџџџџџџџџџџџџџuQ$uQ$џџџџџџџџџџџџџџџџuS$uS$џџџџџџџџџџџџџџџџ%U$%U$џџџџџџџџџџџџџџџџuV$uV$џџџџџџџџџџџџџџџџ%X$%X$џџџџџџџџџџџџџџџџuY$uY$џџџџџџџџџџџџџџџџ%a$%a$џџџџџџџџџџџџџџџџub$ub$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџKa џџџџџџџџџџџџџџџџеjџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџ,tџџџџџџџџџџџџџџџџжoџџџџџџџџџџџџџџџџ‰Яџџџџџџџџџџџџџџџџƒ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџI>џџџџџџџџџџџџџџџџџџ2љџџџџџџџџџџџџџџџџџЉZџџџџџџџџџ џџџџџџџџbmџџџџџџџџџџџџџџџџџ-ЅџџџџџџџџџџџџџџџџџЈџџџџџџџџџџџџџџџџџџ‰Оџџџџџџџџџџџџџџџџџџ „џџџџџџџџџџџџџџџџџџ‰Оџџџџџџџџџ џџџџџџџџhBџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџэѓџK†џэѓџK†џXџѕЧџSВџѕЧџSВџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      NUM.31NUM.32NUM.33NUM.34NUM.35NUM.36NUM.37NUM.38NUM.39NUM.40NUM.41NUM.42NUM.43NUM.44NUM.45NUM.46NUM.47NUM.48NUM.49NUM.50NUM.51NUM.52NUM.53NUM.54NUM.55NUM.56NUM.57NUM.58NUM.59NUM.60џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSVDQ3MFJhZGlvIiwgInZlbmRvciI6ICJSYWR0ZWwiLCAibW9kZWwiOiAiUlQtNDcwIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDIzMDMxOSJ9chirp-20240224/tests/images/Icom_ID-80H.img0000644000175000017500000017325514551723752016771 0ustar hibbyhibbyrx €`ф ‡FtP @ @ WРш €€ф ‡FtP @ @ r ƒPф ‡FtP @ @ Rф ‚ ф ‡FtP @ @ ˜ Pф ‡FtP @ @ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџd ƒ@ф ‡FtP @ @  > €Pф ‡FtP @ @ p€x €Pф ‡FtP @ @ s x €Pф ‡FtP @ @ WРш €Pф ‡FtP @ @ _ш €Pф ‡FtP @ @ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџ * џџџўф џџџџџџџџџџџџџџџџџџџџџџrx €`ф ‡FtP @ @ WРш €€ф ‡FtP @ @ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ ˆџ џџџџџџџџџџџџџџџџџџџџџџџџџџрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРџџџџџчрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ ‡dЪrcЮ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ џџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@џџџџџџџџџџџџ Гя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџ—H+fкЏъџџџџџџњAPI80,DSTAR*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@џџџџџџџџџџџџ Гя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџ—H+fкЏъџџџџџџњAPI80,DSTAR*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@џџџџџџџџџџџџ Гя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџ—H+fкЏъџџџџџџњAPI80,DSTAR*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГя 'Р@ €CQCQCQ Гя 'Р@ €CQCQCQ Гя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџИ 3@ €LK@3@ € 2РЁ @ €‡Ћ" @ €‰€3@ €Гя 'Р@ € Р€3@ €9оLK@@ €2Љј€@ €џџџџџџџџџџџџџџџџџCQCQCQ CQCQCQ @џџџџџџџџџџџџ Гя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџўџџџ‡H+fкЏъџџџџџџњAPI80,DSTAR*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJJRDgwUmFkaW8iLCAidmVuZG9yIjogIkljb20iLCAibW9kZWwiOiAiSUQtODBIIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/TIDRADIO_TD-H8-HAM.img0000644000175000017500000001767514430171343017627 0ustar hibbyhibbyP31185џџџџџџџџџџџџџџџџџџ%RB%RBџџџџ %cB%cBџџџџ %tB%tBџџџџ %…B%…Bџџџџ %–B%–Bџџџџ %C%Cџџџџ %C%Cџџџџ %(C%(Cџџџџ %9C%9Cџџџџ %BC%BCџџџџ %SC%SCџџџџ %dC%dCџџџџ %uC%uCџџџџ %†C%†Cџџџџ %—C%—Cџџџџ %D%Dџџџџ %D%Dџџџџ %"D%"Dџџџџ %3D%3Dџџџџ %DD%DDџџџџ %UD%UDџџџџ %fD%fDџџџџ %wD%wDџџџџ %ˆD%ˆDџџџџ P—™DP—™Dџџџџ %B%Bџџџџ %S%Sџџџџ %d%dџџџџ %u%uџџџџ P—yP—yџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP%P%џџџџ$$џџџџu$u$џџџџ%$%$џџџџP$P$џџџџ%%џџџџ%%%%џџџџPPџџџџuuџџџџPPџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџвE(@џџџџџџџџџџџџџџџџ@€BEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?№џџџ?№‰P@P@џџџџ PBPBџџџџ џџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJUREg4X0hBTSIsICJ2ZW5kb3IiOiAiVElEUkFESU8iLCAibW9kZWwiOiAiVEQtSDgtSEFNIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Retevis_RB87.img0000644000175000017500000000223514430171343017326 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%Fppя€џP‡%FP‡%Fˆˆя€џP&FP&Fssя€џP7&FP7&Fя€џPb&FPb&Feeя€џP‡&FP‡&Fя€џP'FP'Fbbя€џPbuFPbuFC‚C‚ч€џP‡uFP‡uF2€2€ч€џPvFPvFG€G€ч€џP7vFP7vFQ€Q€ч€џPbvFPbvFS€S€ч€џP‡vFP‡vFe€e€ч€џPwFPwFч€џP%FP%F00я€џu%Fu%FCЧCЧя€џ&F&F2У2Уяџџџ%&F%&FssяџџџP&FP&FCТCТяџџџu&Fu&F††яџџџ'F'F1Ч1Чяџџџ%'F%'FeeяџџџP%FPuFeeэџu%FuuFeeэџ&FvFeeэџ%&F%vFeeэџP&FPvFeeэџu&FuvFeeэџ'FwFeeэџ%'F%wFeeэџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ†јџџSMџP558џ@GџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSQjg3UmFkaW8iLCAidmVuZG9yIjogIlJldGV2aXMiLCAibW9kZWwiOiAiUkI4NyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Yaesu_FT3D_R.img0000644000175000017500000037713414411666130017311 0ustar hibbyhibbyAH72Mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџCEPџџџџџџџџџџџџџџџџ %џџџџ `џџџџџџџџџџџџџџџџ ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ƒџџџџ …™џџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAH72Mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ% ЈBŽЈ@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒџџџџџУџџџџџџ]ƒџџџџџУџџџџџџ]џџџџ Pџџџџџџџџџџџџџџџџ p@P€ џџџџ Pџџџџџџџџџџџџџџџџ p@P€  џџџџ C0Pџџџџџџџџџџџџџџџџ BGC0€ 0 џџџџ C0Pџџџџџџџџџџџџџџџџ BGC0€ 0Уџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€€ tУџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€€ tџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBANK 1џџџџџџџџџџBANK 2џџџџџџџџџџBANK 3џџџџџџџџџџBANK 4џџџџџџџџџџBANK 5џџџџџџџџџџBANK 6џџџџџџџџџџBANK 7џџџџџџџџџџBANK 8џџџџџџџџџџBANK 9џџџџџџџџџџBANK10џџџџџџџџџџBANK11џџџџџџџџџџBANK12џџџџџџџџџџBANK13џџџџџџџџџџBANK14џџџџџџџџџџBANK15џџџџџџџџџџBANK16џџџџџџџџџџBANK17џџџџџџџџџџBANK18џџџџџџџџџџBANK19џџџџџџџџџџBANK20џџџџџџџџџџBANK21џџџџџџџџџџBANK22џџџџџџџџџџBANK23џџџџџџџџџџBANK24џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ e аџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ D`аџџџџџџџџџџџџџџџџP €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ Pаџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0аџџџџџџџџџџџџџџџџP €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ Pаџџџџџџџџџџџџџџџџ €@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0аџџџџџџџџџџџџџџџџP €GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPаџџџџџџџџџџџџџџџџ €U џџџџџџџџџџџџџџџџ U @џџџџџџџџџџџџџџџџ U €џџџџџџџџџџџџџџџџ CUРџџџџџџџџџџџџџџџџP CUџџџџџџџџџџџџџџџџP CU@џџџџџџџџџџџџџџџџP CU€џџџџџџџџџџџџџџџџP U Рџџџџџџџџџџџџџџџџ U џџџџџџџџџџџџџџџџ U @џџџџџџџџџџџџџџџџ U €џџџџџџџџџџџџџџџџ CUРџџџџџџџџџџџџџџџџP CUџџџџџџџџџџџџџџџџP CU@џџџџџџџџџџџџџџџџP CU€џџџџџџџџџџџџџџџџP U Рџџџџџџџџџџџџџџџџ CEРџџџџџџџџџџџџџџџџP CEТџџџџџџџџџџџџџџџџP CEУџџџџџџџџџџџџџџџџP U рџџџџџџџџџџџџџџџџ CEрџџџџџџџџџџџџџџџџP H@Рџџџџџџџџџџџџџџџџ CUРџџџџџџџџџџџџџџџџP %Рџџџџџџџџџџџџџџџџ U Рџџџџџџџџџџџџџџџџ "%Рџџџџџџџџџџџџџџџџ …™Рџџџџџџџџџџџџџџџџ U рџџџџџџџџџџџџџџџџ CUрџџџџџџџџџџџџџџџџP W Рџџџџџџџџџџџџџџџџ  Рџџџџџџџџџџџџџџџџ P Рџџџџџџџџџџџџџџџџ CP РџџџџџџџџџџџџџџџџP …™Рџџџџџџџџџџџџџџџџ P Рџџџџџџџџџџџџџџџџ CP РџџџџџџџџџџџџџџџџP UP`џџџџџџџџџџџџџџџџ ECVРџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФџџџџџџz?ТYYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******CQ*******QST******YAESU****џџџџџџџџџBLN******BLN*џџџџџBLN*џџџџџFxx  xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:A? џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ******џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<ePDeџџџџџ€ ќ џ# i9**џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPPPPP0 `AAAAAA рWIDE1 - 1bџџ№`vXl [/`_$ mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGROUP 01џџџџџџџџGROUP 02џџџџџџџџGROUP 03џџџџџџџџGROUP 04џџџџџџџџGROUP 05џџџџџџџџGROUP 06џџџџџџџџGROUP 07џџџџџџџџGROUP 08џџџџџџџџGROUP 09џџџџџџџџGROUP 10џџџџџџџџџџG1-1џџG1-2џџG1-3џџG1-4џџG1-5џџG2-1џџG2-2џџG2-3џџG2-4џџG2-5џџG3-1џџG3-2џџG3-3џџG3-4џџG3-5џџG4-1џџG4-2џџG4-3џџG4-4џџG4-5џџG5-1џџG5-2џџG5-3џџG5-4џџG5-5џџG6-1џџG6-2џџG6-3џџG6-4џџG6-5џџG7-1џџG7-2џџG7-3џџG7-4џџG7-5џџG8-1џџG8-2џџG8-3џџG8-4џџG8-5џџG9-1џџG9-2џџG9-3џџG9-4џџG9-5џџG0-1џџG0-2џџG0-3џџG0-4џџG0-5џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџпmд-џchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQzRCIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJGVDNEIiwgInZhcmlhbnQiOiAiUiJ9chirp-20240224/tests/images/Retevis_RB627B.img0000644000175000017500000001035114411666130017510 0ustar hibbyhibby%`D%`Du`Du`D%1`D%1`DuC`DuC`D%V`D%V`Duh`Duh`D%`D%`Du“`Du“`D%aD%aDuaDuaD%1aD%1aDuCaDuCaD%VaD%VaDuhaDuhaD%aD%aDu“aDu“aDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџˆџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjYyN0IiLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIxMTIxMyIsICJyY2xhc3MiOiAiUmV0ZXZpc1JUNjI3QiIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Jetstream_JT220M.img0000644000175000017500000002000014411666130020027 0ustar hibbyhibbyЅfU™Ї w‰ШЇ™D7рџџџџџџџџџџџџџџџџЅfU™Ї w‰ШЇ™D7рџџџџџџџџџџџџџџџџ20090410000000142009-4-102009-4-10ЅЅЅЅЅЅЅЅџџ№$8`P #P#P#P$dKLLBF$dKLLBF$8` K:<>L#R:KLBF#PG:MLBF$TLCLBF1#HLCLBF2#†` :KERF:G#”`:KARLMD$$` :K;ERG$f` :K@HE=$`FHGKH>$(`>O>K>MM$8` F:KRLOE$T`$x` ERF:G$P` MB@>KFM#˜` >MB@>K$` FBD>D>R$h` L>:MME>™3  ююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююююф4^ююююююююх4^ююююююююchirp-20240224/tests/images/Icom_IC-T7H.img0000644000175000017500000000166014411666130017010 0ustar hibbyhibbyDIPR0` fZ`p`` D$D` D$ e `D`QP`DEz QP`QP`QP`QP`QP`b e ` DR D$ DzD0P D z DHP D ` P C0 P ` Dz Dz Dz Dz Dz Dz Dz Dz Dz D Q`s` D0zQp`TP` D7z 8 @ F˜ b DR C™` D ` @@ 2D™` E P`:``€` G @` rP` I0`P`U` `0` `` D e `0 Dz€ XPPX€€€HH€€€€€€€€€€€X€€€€€€€€€€€€€€€€€€XPYXPQX€€€€€€€€€€€€€€€€€€€HXџџџџџџ€џџџџџ!@џџXDuPџџџџџџџџџџџџ IcomCloneFormat3chirp-20240224/tests/images/Retevis_RT622.img0000644000175000017500000000224514411666130017426 0ustar hibbyhibbyP3207!јџџџџџџ%`D%`D|| u`Du`D||%1`D%1`D||'uC`DuC`D||4%V`D%V`D||Auh`Duh`D||N%`D%`D||[u“`Du“`D||h%aD%aD((uuaDuaD((‚%1aD%1aD((uCaDuCaD((œ%VaD%VaD((ЉuhaDuhaD((Ж%aD%aD((Уu“aDu“aD((аџџџџџџџџP3207!јџџџџџџ%`D%`D|| u`Du`D||%1`D%1`D||'uC`DuC`D||4%V`D%V`D||Auh`Duh`D||N%`D%`D||[u“`Du“`D||h%aD%aD((uuaDuaD((‚%1aD%1aD((uCaDuCaD((œ%VaD%VaD((ЉuhaDuhaD((Ж%aD%aD((УP3207!јџџџџџџ%`D%`D|| u`Du`D||%1`D%1`D||'uC`DuC`D||4%V`D%V`D||Auh`Duh`D||N%`D%`D||[u“`Du“`D||h%aD%aD((uuaDuaD((‚%1aD%1aD((uCaDuCaD((œ%VaD%VaD((ЉuhaDuhaD((Ж%aD%aD((УRT622 џchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDYyMiIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjAxMDE0IiwgInJjbGFzcyI6ICJSVDYyMiIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Baofeng_UV-3R.img0000644000175000017500000000710014411666130017376 0ustar hibbyhibbyџџџџџџџџџџРџџџџAТQ`DРEџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџaРaџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAТA@Р3Ц•yDLISTENINv•‰R џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРџџџџAТQ`DРEџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџџџџџџџџџџџРџџџџaРachirp-20240224/tests/images/Retevis_RB17P.img0000644000175000017500000001424514411666130017445 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџі:џџџџMDбџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%@%@џџџџ ўџ%@%@џџџџ ўџџџџџџџџџџџџџџ?џџџ?ŽSБ;ŽSБ;"nnŽSБ;ŽSБ;"nnџџXTџџŽSБ; ?p``p?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ::>>>BUU22222222ЭЭввввззШШШШШШШШdFLxLxXoozzz…ŠŠddddddddррррррррррррррррррррррррррррррррррррррррррррррррџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@GџџџџџџџџџџџџџPb%FPb%FppjџмP‡%FP‡%FˆˆjџмP&FP&FssjџмP7&FP7&FjџмPb&FPb&FeejџмP‡&FP‡&FjџмP'FP'FbbjџмPbuFPbuFC‚C‚hџмP‡uFP‡uF2€2€hџмPvFPvFG€G€hџмP7vFP7vFQ€Q€hџмPbvFPbvFS€S€hџмP‡vFP‡vFe€e€hџмPwFPwFhџмP%FP%F00jџмu%Fu%FCЧCЧjџм&F&F2У2Уjџм%&F%&FssjџмP&FP&FCТCТjџмu&Fu&F††jџм'F'F1Ч1Чjџм%'F%'FeejџмP%FPuFeejџмu%FuuFeejџм&FvFeejџм%&F%vFeejџмP&FPvFeejџмu&FuvFeejџм'FwFeejџм%'F%wFeejџмџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjE3UCIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwMTE4IiwgInJjbGFzcyI6ICJSMTdQUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Retevis_RT24V.img0000644000175000017500000000225514473333172017476 0ustar hibbyhibbyџџџџџџџџџџџџыџџџ%%џџџџїP7P7P7џџџџїPPPџџџџїP‡P‡P‡џџџџї‘‘‘џџџџїP‘P‘P‘џџџџїџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹џјџџSMџP558џџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSZXRldmlzUlQyNFYiLCAidmVuZG9yIjogIlJldGV2aXMiLCAibW9kZWwiOiAiUlQyNFYiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMwODIzIn0=chirp-20240224/tests/images/Yaesu_FT2D_R.img0000644000175000017500000037671314411666130017312 0ustar hibbyhibbyAH60Mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ'QW4PCN KILLDHџџџџ '  џџџџџџџџџџџџџџџџ ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџ C0Pџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ% ЈBŽЈџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒџџџџџУџџџџџџRƒџџџџџУџџџџџџRџџџџ Pџџџџџџџџџџџџџџџџ p@P€ wџџџџ Pџџџџџџџџџџџџџџџџ p@P€ w џџџџ C0Pџџџџџџџџџџџџџџџџ BGC0€   џџџџ C0Pџџџџџџџџџџџџџџџџ BGC0€  Уџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€€ tУџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€€ tџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBANK 1џџџџџџџџџџBANK 2џџџџџџџџџџBANK 3џџџџџџџџџџBANK 4џџџџџџџџџџBANK 5џџџџџџџџџџBANK 6џџџџџџџџџџBANK 7џџџџџџџџџџBANK 8џџџџџџџџџџBANK 9џџџџџџџџџџBANK10џџџџџџџџџџBANK11џџџџџџџџџџBANK12џџџџџџџџџџBANK13џџџџџџџџџџBANK14џџџџџџџџџџBANK15џџџџџџџџџџBANK16џџџџџџџџџџBANK17џџџџџџџџџџBANK18џџџџџџџџџџBANK19џџџџџџџџџџBANK20џџџџџџџџџџBANK21џџџџџџџџџџBANK22џџџџџџџџџџBANK23џџџџџџџџџџBANK24џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ e Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ D`РџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0РџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0РџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPРџџџџџџџџџџџџџџџџ СWB5IUZ ABQџџџџџџ %PСKX4KDH NC SIMPLX 2СK4OBXџџџџџџџџџџџ QСW4PCN KILLDHџџџџ Q0СK5BIQ ABQџџџџџџџ QPСK5BIQ ABQџџџџџџџ R0СKB7ZIH PINEDALEџ RСNM5ML ABQџџџџџџџ RСK4OBX Bodie Islџ SСW7EH Eagar AZџџџ S0СW5CSY ABQџџџџџџџ SpСNM5HD ABQџџџџџџџ fСW7OTA AZџџџџџџџџ f СN7QVU Azџџџџџџџџ fUСWA4VTX LizNCџџџџ gСKC5OUR BelenNMџџ gСK7EAR EagarAzџџџ g СK5CQH TijerasNMџ g СW7ARA EagarAzџџџ g@СKD5MHQ ABQџџџџџџ hСW7RIM AZџџџџџџџџ g`СAD7W PinetopAzџџ h РN7KQ AZџџџџџџџџџ h5СKX4NC ColumbiaNC iСK5FIQ ABQџџџџџџџ i СKF5ERC ABQџџџџџџ i`СK5URR BelenNMџџџ #p@СAB1Q ABQџџџџџџџџ #p€СNM5SC ABQџџџџџџџ $qСNM5RR NMџџџџџџџџ $rСN5BGC SF NMџџџџџ #s СK5LXP ABQџџџџџџџ #s0СWA4VTX NCџџџџџџџ #s@СNM5MLџџџџџџџџџџџ #s`СKB5XEџџџџџџџџџџџ #s`СW7ARA SunflowAZџ #s€РN5GU ABQџџџџџџџџ teСW5MHG ABQџџџџџџџ "8 РWA5VJY ABQџџџџџџ "9РKB5UGU ABQџџџџџџ "@СK5CQHџџџџџџџџџџџ "E€СK6LIE ABQџџџџџџџ "I@РN7KQ AZџџџџџџџџџ "I@РW5AOX ABQџџџџџџџ $D PСK5BIQ ABQџџџџџџџP $D!СKB5GAS ABQџџџџџџP Х$D!PёAB1Q ABQџџџџџџџџP РХ$D"№K5RM ABQџџџџџџџџP РХ$D"%№N5CUL NMџџџџџџџџP РХ$D"P№WA5IHLџџџџџџџџџџP РХ$D#ёAD5MO ABQџџџџџџџP РХ$D&ёK5FSB ABQџџџџџџџP РХ$D#PёWA5OLD ABQџџџџџџP РХ$D'%ёK4OBX NCџџџџџџџџP РХ$D'PёKC5IPK ABQџџџџџџP РХ$D(ёN7KQ AZџџџџџџџџџP РХ$D)№KA8JMW ABQџџџџџџP РХ$D0ёNM5RR ABQџџџџџџџP РХ$D3ёWA6CCB ABQџџџџџџP РХ$D4ёKX4NC NCџџџџџџџџP РХ$D6№WA5OIP ABQџџџџџџP РХ$D6PёK5LXP ABQџџџџџџџP РХ$D7PёWA6CCB ABQџџџџџџP РХ$D8№W5MPZ SNL ABQџџџP РХ$D@ёW5CSY ABQџџџџџџџP РХ$DA%ёWA5TSV LL NMџџџџP РХ$DA%ёK4OBX NCџџџџџџџџP РХ$DAPёW5AOX ABQџџџџџџџP РХ$DCёWA4VTX NCџџџџџџџP РХ$DC%ёNM5ML ABQџџџџџџџP РХ$DEёW7ARA AzџџџџџџџџP РХ$DE%№K5URD NMџџџџџџџџP РХ$DF№N5GUџџџџџџџџџџџџP РХ$DF%ёW4NV MoyockNCџџџP РХ$DGёK5CPU ABQџџџџџџџP РХDfёN7QVU AzџџџџџџџџP РХDruёKB5VPZ NMџџџџџџџP РХDsuёK7FQ SnowflakeAZP РХDtuёW7NAZ PaysonAzџџP РХDwuёKF5SGT SF NMџџџџP РХDƒuёW7ARA EagarAZџџџP РХDˆPёN7OEI EagarAzџџџP РХDPёAD7W PinetopAzџџP РХD‘PёW7EH ShowLowAZџџP РХD’uёK9GAJ SF NMџџџџџP РХD“PёN7QVU Greer AZџџP РХD”P№K5URR ABQџџџџџџџP РХD•PёK5FIQ ABQџџџџџџџP РХD˜ёK5FIQ ABQџџџџџџџP РХ’qbёW7ARA EagarAzџџџP РХ’vPёKC5ZXW ABQџџџџџџP РХ’wёWB5EZO ABQџџџџџџP* РР%%№6m Callџџџџџџџџџ РРe №2m Callџџџџџџџџџ РХ"5№220 Callџџџџџџџџ РХD`№.7m Callџџџџџџџџ РРe€№ABQ simplexџџџџџ РџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC˜џџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCРџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCџџџџџџџџџџџџџџџџP DџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФџџџџџџz?ТYYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******CQ*******QST******YAESU****џџџџџџџџџBLN******BLN*џџџџџBLN*џџџџџFxx  xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:A? џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ******џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWD5EQY џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<ePDeџџџџџq{џ0AZazi9**џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS5PURS `KG5ELE- 9ђSANDIA рџџMOSC р№`r;io6c>/]"F.}145.330MHz T100 -060= ŠL0r000h36b10131OD1wxЄџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS5PQSU `K5LGF - 9ђELKMTN `SANDIA р№`pD_o+Vj/`"D+}146.520MHz Green Jeep - Larry_% о www.urfmsi.org b4 i—џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRS `KF5GRI- 1bCAPILA `SANDIA р№@042022z3519.43N/10528.18W_326/003g008t077r000p000P000h41b10182.DsVP џЎџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSUQQUW `KE7ETB- 7юSANDIA `LAMOSC р№`rG^oqkk/`"F&}_% АA80MHz ToffSOTA WAGON IS GO!= p_igi Gruhlke УTx. W5GAFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSS5SUX `WB5USB- 7юLAMOSC `SANDIA р№`s9En"sk\`"Su}_ #р919.23W_133/001g007t073r000p000P000h24b08122.DsVPЄџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS5PSUS `WA5SJW- 9ђSANDIA рџџNDIA р№'r=]l"Kj/]"Ew}Goodie-9 Tsx ј7360/ *PCG* Digi Gruhlke УTx. W5GAF›k {UIV32} œџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRS `BENRDG `CAPILA `SANDIA р№_06041859c...s000g001t059h46e1w H000h07b.....tU2kЎ3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPT311 `K7DON - 5jSANDIA рџџNDIA р№/202306h3514.88N\10634.03Wv190/055/A=005124/Don- Tucson, AZcаџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPK102 `K5MTS рCAPILA `SANDIA р№=3500.04N/10620.91W_344/005g t078r000p000P h23b10059KDvs 4Œ.DsVP iEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPOTC1 рKF5EFR рSANDIA сџџNDIA р№!3509.07N/10632.97W_180/000g008t083P000r000h25b10137OD1wсў.org”NџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPZ186 рLUERA `LAMOSC рџџMOSC р№!3346.41NS10751.40W#PHG5630/W4,NMn/W5DIG-2 DIGI www.urfmsi.org#˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRX28 `KC5EVE-15~DURNGO `LAMOSC р№!3735.23NI10748.68W#KC5EVE-15 I-Gate/Digi Needles, CO -40b10177.DsVP+нџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWX `ELPASO `BENRDG `SANDIA р№_06042049c188s000g000t089h23e1w ю8Wr_100.0Tone_Mega-Link сџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS1USPQ `AA5EP - 9ђCABALL `SANDIA р№`r>smKEM94PQ - (FBB BBS) (AC4ZR-1) 7-PORT BPQ NODE/APRS-IS DIGI"oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS6TT9W `KV4HB -14|KE4KDY- 5jWIDE2 с№`h[JnAk/'"4&}TinyTrak3 Jud!wcx!|3ўќngo,CO Missionary Ridge N0GIO3Linami TOKYO {UIV32} #џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN382 `RAVEN `CAPILA `SANDIA р№!3459.19NS10620.70W#PHG5630/W4,NMn/K5CQH-15 Digi www.urfmsi.org ‰њџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPMI06 `N5QHO - 1bCAPTAN `LAMOSC р№@181237z3051.61NI10035.99W&N5QHO-1 Widen-n Digi U=13.9V,T=0.0C aNџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPOT21 рN5FAZ рELPASO `SANDIA р№!3146.20N/10620.91W>223/000/A=003937EPE005 ~уџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPTW14 `KJ7AZ - 3fGALPK `SANDIA р№!3359.51N/10549.42W_278/008g005t065r000p003P000h..b.....tU2ku˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPJI42 `KM5VY -10tCAPILA `SANDIA р№!3458.19NT10618.30W&PHG2400javAPRSigate - tom.km5vy@gmail.com/A=007286WЎџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS5PYVQ `K9WLF - 7юSANDIA рџџNDIA р№`r"FZ}= М620MHz Saikai city_" љВџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWX `ELPASO `BENRDG `LAMOSC р№_06010129c090s000g000t076h23e1w —ЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPX209 рKM5VY `GALPK `SANDIA р№@310155z3458.19N/10618.29W_180/000g...t064r000p000h37b10217С џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSR2STX `KG5FCO- 9ђCABALL `SANDIA р№`rEnr"Kk/`"Bp}146.640MHz T100 -060 Monitoring_% ЅъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSSQPUP `WA9JMU рCABALL `SANDIA р№`s)*l#D-/`"Bo}mon 146 52 223 500 446 000 HI GUYS_" dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPHH2 `WD9CMS- 3fTESQUE `SANDIA р№=3553.80N/10616.23W> Р AN CEDRIC, RX 433.00 MHz / D-STAR FJ43_" ƒ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN382 `ROSWEL `GALPK `SANDIA р№!3323.83NS10422.58W#PHG4430/W4,NMn/W5DIG-7 Digi www.urfmsi.org Еœџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ3U1URP `K8TE - 1тSANDIA рџџNDIA р№`rB?l k/]"Ea}[scanning]Bill NERD 1= дџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN382 `LAMOSC `SANDIA рџџNDIA р№!3515.14NS10735.79W#PHG5930/W4,NMn/K5DIG-4 Digi www.urfmsi.org CџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN832 `GALPK `SANDIA рџџNDIA р№!3414.82NS10547.31W#PHG6830/W5,NMn/W5DIG-5 Digi www.urfmsi.org  šџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN382 `TAPIA `SANDIA рџџNDIA р№!3506.00NS10537.51W#PHG4630/W4,NMn/K5DIG-10 Digi www.urfmsi.org rшџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN391 `PARRTT `LAMOSC `SANDIA р№!3722.34N110806.06W#PHG3820 W2,COn /A=011450 PARROTT PEAK N0GIO ЌОџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBEACON `CABALL `SANDIA сџџNDIA р№;147.26+ML*000000z3258.27N/10713.44Wr_100.0Tone_Mega-Link ўПMA_$ >лџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN382 `CABALL `SANDIA рџџNDIA р№!3258.27NS10713.44W#PHG7830/W4,NMn/W5DIG-8 Digi urfmsi.org pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN382 `ELKMTN `SANDIA рџџNDIA р№!3546.00NS10533.27W#PHG4830/W4,NMn/W5SF-1 Digi www.urfmsi.org “gџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS55QUY `KF5REI- 2dTESQUE `SANDIA р№`r)Lp!\v/"Ia}сœha@9158-ROOM RX PSE CALL ME!_$ ‚‡џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSU1UST `WD5IDL рSANDIA рџџNDIA р№`rBU RPk/]"EF} г#МЇrvice= $§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPN382 `HARRIS `DEZA `SANDIA р№!3638.34NS10746.50W#PHG4740/W4,NMn/N5DIG-3 Digi www.urfmsi.org i2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPRX29 `W5PDO - 1bSANDIA рџџNDIA р№!3554.05NS10619.30W#Tx-iGate + Digipeater in Los Alamos, NM (managed by N3XKB)-эџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPNU19 рMALJAM `BENRDG `SANDIA р№!3252.00NS10345.38W#PHG6330/W4,NMn/W5DIG-15 UIDIGI www.urfmsi.org ўцџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSUPVXY `KM5VY - 9ђLAMOSC рџџMOSC р№'r@8l!&k/]"E9} tфћES5587/0699= ц0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSU1VRT `KD5HEH- 9ђSANDIA рџџNDIA р№`rA.l lK\]"E6}= ЈfYUSYU (1734) T77= Ь9џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSUPYSS `N4TCW рSANDIA рџџNDIA р№`rDql >/]"Dh}= JNS KANSAI/TEAM0949_% &›џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS5TWVW `N0WJE - 9ђELKMTN `SANDIA р№`qCFm{rk/>146.52-simplex ыhRS-JP* 9K6BPS 144.640MHZ= ,DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS5PYVP `WA5SJW- 9ђSANDIA рџџNDIA р№'r9k *&j/]"H$}Goodie-9 Tsx Ђ­ JA6JQZ ..PLEASE CALL ME !!!!!_% 5'џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSRPQVU `KG5DRT- 9ђCABALL `SANDIA р№`pL.l bk/]"LH}144.000MHz ToffRoad Trip=  [џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSU0STX `N5DGC рSANDIA рџџNDIA р№`r;zlJwk/]"F5}= !XC DM6PE= рFmode MONITOR NOW v(^^)v_% АџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS5SXST `N621TM `SANDIA рџџNDIA р№`rXDl!h'/'"Iz} KF5DUN |$L%C'v|!wx0!|3Ќ1AN City {ISIKAWA) * CALL ME_" ѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS4UYPY `N5GPN - 9rSANDIA рџџNDIA р№`rCfl#V>/"DO}~з# ЌБџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPOT21 рKE5TBF- 9ђSANDIA рџџNDIA р№!3538.98N/10603.05Wk235/054/A=006489Monitoring voice alert 144.39ЙџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSVPPU3 `JH1SPN рJQ1YFT- 2хџџ1YZZ-10ѕ№`C@:l h\`_% ъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS4TRW5 `JG3RQO- 7nTCPIP `JQ1YZZ-10ѕ№`?5Ql!u>/`"3L}433.00MHz Call now_# Œ­џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS3PWR1 `JA6DWF- 9rTCPIP `JQ1YZZ-10ѕ№`9Mbn^.>/`"4Y}438.920MHz FTM400DH WiRES RED CROSS NAGASAKI 0852 / C4FM D/A_% pтџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџS2UUU0 `JA6JSY- 9rTCPIP `JQ1YZZ-10ѕ№`9T~nH8>/`"4%}432.400MHz nagasaki mobil_" TџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSV1RW5 `JH1QMX- 9rTCPIP `JQ1YZZ-10ѕ№`C*[n_*v/`"4E}_% ШѕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЋchirp-20240224/tests/images/Wouxun_KG-UV920P-A.img0000644000175000017500000006335114411666130020122 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџ'%(%PP%&  ]X98c(XSssE„&#&PPBFp@BFp@`fgihijmmss‚šŸOOQSVWYZZ\`gqz{//00/.-+-,/39?Aljfd_^WZhnl\TI>ДЏЊЊЅЅ  ЊЙДЃ –‘<<<<<<<<<<<<<<<2222222222222..KKKKKKKKKKKHFFF777777777777400'5EO_p|‡‘›ЅЏЙУџџџџџџџџџџџџџџџџZˆ\ ШKqBv‡  ›››–– jjlonqotxz<=>@BA?ACD‡nZF??KZinцвОЗВДСШзмxxvvvvvvxxPPNNNNNNNNVVRPPPPPRRA<<<<<<<<<'?KXhxŠ˜mlFС08@q`%&  ]E91>PP!E1>*8?E#*&PP<<<===<:52TR><'&SQ -џџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJCRlQyMEZSU1JhZGlvIiwgInZlbmRvciI6ICJCYW9mZW5nIiwgIm1vZGVsIjogIkJGLVQyMEZSUyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzEyMTMifQ==chirp-20240224/tests/images/Hiroyasu_HI-8811.img0000644000175000017500000013170114437323351017733 0ustar hibbyhibby%pF%pFџџџџџџџџџџџџџџџџuqFuqFџџџџџџџџџџџџџџџџ%sF%sFџџџџџџџџџџџџџџџџutFutFџџџџџџџџџџџџџџџџ%vF%vFџџџџџџџџџџџџџџџџuwFuwFџџџџџџџџџџџџџџџџ%yF%yFџџџџџџџџџџџџџџџџu€Fu€Fџџџџџџџџџџџџџџџџ%‚F%‚FџџџџџџџџџџџџџџџџuƒFuƒFџџџџџџџџџџџџџџџџ%…F%…Fџџџџџџџџџџџџџџџџu†Fu†Fџџџџџџџџџџџџџџџџ%ˆF%ˆFџџџџџџџџџџџџџџџџu‰Fu‰Fџџџџџџџџџџџџџџџџ%‘F%‘Fџџџџџџџџџџџџџџџџu’Fu’Fџџџџџџџџџџџџџџџџ%@%@џџџџџџџџџџџџџџџџuAuAџџџџџџџџџџџџџџџџ%C%CџџџџџџџџџџџџџџџџuDuDџџџџџџџџџџџџџџџџ%F%FџџџџџџџџџџџџџџџџuGuGџџџџџџџџџџџџџџџџ%I%IџџџџџџџџџџџџџџџџPPPPџџџџџџџџџџџџџџџџ…Q…Qџџџџџџџџџџџџџџџџ…S…Sџџџџџџџџџџџџџџџџ%U%UџџџџџџџџџџџџџџџџuVuVџџџџџџџџџџџџџџџџ%X%XџџџџџџџџџџџџџџџџuYuYџџџџџџџџџџџџџџџџ%a%aџџџџџџџџџџџџџџџџububџџџџџџџџџџџџџџџџ%@$%@$џџџџџџџџџџџџџџџџPA$PA$џџџџџџџџџџџџџџџџ%C$%C$џџџџџџџџџџџџџџџџuD$uD$џџџџџџџџџџџџџџџџ%F$%F$џџџџџџџџџџџџџџџџuG$uG$џџџџџџџџџџџџџџџџ%I$%I$џџџџџџџџџџџџџџџџPP$PP$џџџџџџџџџџџџџџџџuQ$uQ$џџџџџџџџџџџџџџџџuS$uS$џџџџџџџџџџџџџџџџ%U$%U$џџџџџџџџџџџџџџџџuV$uV$џџџџџџџџџџџџџџџџ%X$%X$џџџџџџџџџџџџџџџџuY$uY$џџџџџџџџџџџџџџџџ%a$%a$џџџџџџџџџџџџџџџџub$ub$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџ2љџџџџџџџџџџџџџџџџџџ‰Оџџџџџџџџџџџџџџџџџпџџџџџџџџџ џџџџџџџџйБџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ* џџџџџџџџџџџџџџџЄYџ* xеџ* о џ* xеџ* ч™џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      NUM.31NUM.32NUM.33NUM.34NUM.35NUM.36NUM.37NUM.38NUM.39NUM.40NUM.41NUM.42NUM.43NUM.44NUM.45NUM.46NUM.47NUM.48NUM.49NUM.50NUM.51NUM.52NUM.53NUM.54NUM.55NUM.56NUM.57NUM.58NUM.59NUM.60џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJISTg4MTFSYWRpbyIsICJ2ZW5kb3IiOiAiSGlyb3lhc3UiLCAibW9kZWwiOiAiSEktODgxMSIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzA1MTUifQ==chirp-20240224/tests/images/Icom_IC-W32E.img0000644000175000017500000000774114411666130017074 0ustar hibbyhibbyd`146415 d0`146430 dE`146445 d``146460 du`146475 d`146490 e`146505 e `N-SIMP e5`146.535 eP`146550 ee`146565 e€`146580 e•`146595 p`HGN 09 q `W3ACH r%`N3NRI t`147405 t `147420 t5`147435 tP`147.450 te`147465 t€`147480 t•`147495 u`147510 u%`147525 u…`147585 SP` W3KGN T0`N3TWT P NO NAMEP NO NAMEU€`NO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO AMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAME`NO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMEDNO NAMES@NO NAMEPNO NAMEPNO NAMEPNO NAMEPNO NAMEPNO NAMEPNO NAME@џџџџџџџџ€џџџџџџџџ`NO NAMECNO NAME@NO NAME€NO NAMENO NAMENO NAMEB NO NAMENO NAMED N3LTQ/R D0PW3BD/R DP%CR1 DPPCR2 DPuCR3 DQCR4 DQ%CR5 D`NATL SMPD`P446.050 D`u446.075 Da446.100 D@NO NAMEENO NAMEC@NO NAMEDNO NAME€NO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMEDNO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMEC0@NO NAMEC0 NO NAMEC0NO NAMEC0`NO NAMEC0`NO NAMECџџџџџџџџEџџџџџџџџ0NO NAME™™‡NO NAMENO NAMENO NAMEC‰€NO NAMECNO NAME0NO NAME™™‡NO NAME ,((€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€<, €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€< € №q ` 0D`@0`0DW%`d€``DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџMain File IcomCloneFormat3chirp-20240224/tests/images/Retevis_RB27.img0000644000175000017500000001034514411666130017323 0ustar hibbyhibbyPb%FPb%FP‡%FP‡%FP&FP&FџџџP7&FP7&FџџџPb&FPb&FџџџP‡&FP‡&FџџџP'FP'FџџџPbuFPbuF&&џџџP‡uFP‡uFџџџPvFPvFџџџP7vFP7vFџџџPbvFPbvF  џџџP‡vFP‡vF  џџџPwFPwFџџџP%FP%Fџџџu%Fu%Fggџџџ&F&F88џџџ%&F%&FџџџP&FP&F&&џџџu&Fu&FWWџџџ'F'Fddџџџ%'F%'FџџџP%FPuFџџџu%FuuFџџџ&FvFџџџ%&F%vFџџџP&FPvFџџџu&FuvFџџџ'FwFџџџ%'F%wFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCH--1џџџCH--2џџџCH--3џџџCH--4џџџCH--5џџџCH--6џџџCH--7џџџCH--8џџџCH--9џџџCH-10џџџCH-11џџџCH-12џџџCH-13џџџCH-14џџџCH-15џџџCH-16џџџCH-17џџџCH-18џџџCH-19џџџCH-20џџџCH-21џџџCH-22џџџRPT-1џџџRPT-2џџџRPT-3џџџRPT-4џџџRPT-5џџџRPT-6џџџRPT-7џџџRPT-8џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjI3IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMTEyMTMiLCAicmNsYXNzIjogIlJldGV2aXNSVDI3IiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_FTM-3200D_R.img0000644000175000017500000017731314411666130017722 0ustar hibbyhibbyAH52Nџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ S•џџџџџџџџџџџџџџџџ Уџџџџџџ `џџџџџџџџџџџџџџџџ ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ% ЈBŽ Ј%(EdџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУџџџџџџвџџџџџУџџџџџџвяџџџџ Pџџџџџџџџџџџџџџџџ `@P ряџџџџ Pџџџџџџџџџџџџџџџџ `@P р џџџџ C0Pџџџџџџџџџџџџџџџџ BG ­ џџџџ C0Pџџџџџџџџџџџџџџџџ BG ­Уџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€ єУџџџџџџ `џџџџџџџџџџџџџџџџ ˜`€ єџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBANK 1џџџџџџџџџџBANK 2џџџџџџџџџџBANK 3џџџџџџџџџџBANK 4џџџџџџџџџџBANK 5џџџџџџџџџџBANK 6џџџџџџџџџџBANK 7џџџџџџџџџџBANK 8џџџџџџџџџџBANK 9џџџџџџџџџџBANK10џџџџџџџџџџBANK11џџџџџџџџџџBANK12џџџџџџџџџџBANK13џџџџџџџџџџBANK14џџџџџџџџџџBANK15џџџџџџџџџџBANK16џџџџџџџџџџBANK17џџџџџџџџџџBANK18џџџџџџџџџџBANK19џџџџџџџџџџBANK20џџџџџџџџџџBANK21џџџџџџџџџџBANK22џџџџџџџџџџBANK23џџџџџџџџџџBANK24џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ e Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ D`РџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0РџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ PРџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ C0РџџџџџџџџџџџџџџџџP GРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPРџџџџџџџџџџџџџџџџ fU€K1RKџџџџџџџџџџџџ  su‚џџџџџџџџџџџџџџџџ  sEџџџџџџџџџџџџџџџџ e•Рџџџџџџџџџџџџџџџџ guРџџџџџџџџџџџџџџџџ e €џџџџџџџџџџџџџџџџ FPТ CH- 8   FPУ CH- 9  FPУ CH-10  FPР CH-11 R@ CH-12 @@ CH-13 `@ CH-14 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџˆP@џџџџџџџџџџџџџџџџ bP€џџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФџџџџџџ?€YYџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALL******CQ*******QST******YAESU****џџџџџџџџџBLN******BLN*џџџџџBLN*џџџџџFxx  xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ:A? џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ******џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<ePDeџџџџџq{џ0AZazi9**џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџ7chirp-20240224/tests/images/Retevis_RT76.img0000644000175000017500000000120514411666130017344 0ustar hibbyhibbyPb%FPb%Fžž`P‡%FP‡%FЄЄ`P&FP&Fљљ`=P7&FP7&F&&`Pb&FPb&FUU`P‡&FP‡&F……`ˆфP'FP'FЖЖ`PbuFPbuFЃ(Ѓ(@P‡uFP‡uF((@PvFPvF'('(@P7vFP7vF)()(@PbvFPbvF+(+(@P‡vFP‡vF5(5(@PwFPwFN(N(@P%FP%FЮЮ`u%Fu%FуЉуЉ`&F&FкЈкЈ`%&F%&Fљљ`P&FP&FЃЈЃЈ`u&Fu&F†)†)`'F'FйЉйЉ`%'F%'FUU`P%FPuFUU`u%FuuFUU`&FvFUU`%&F%vFUU`P&FPvFUU`u&FuvFUU`'FwFUU`%'F%wFUU`џchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDc2IiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIkR5bmFtaWNSYWRpb0FsaWFzIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_VX-8DR.img0000644000175000017500000017731314411666130017255 0ustar hibbyhibbyAH29Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ @џџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ# ЈТЮЈџџџџџџџџџџџџџџџџM1Уџџџџџџѕ1Уџџџџџџѕ@s`1? # $8%'$џџ p@s`€&/ ?pO'@s`1? # $8%'$џџ p@s`€&/ ?pO' C $ џџџџџџџџp@C€? Ž C $ џџџџџџџџp@C€? Ž@ џџџџџџџџџџџџџџџџ ˜p@€ К@ џџџџџџџџџџџџџџџџ ˜p@€ Кџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $"џџџџџџџџ $"џџџџџџ $"$џџџџџџ%77%9џџџџџџџџџџ9**30/џџџџџџџџџ%2,%88%2џџџџџџџ9))27џџџџџџџџџџ 633/0=2џџџџџџџџ1)6+)2'=џџџџџџџ30-')$$-6)џџџџ :-%8-32џџџџџџџџ6%**-'џџџџџџџџџ"$30-')G-6)G G )78',)78)6џџ$398,џџџџџџџџ $џџџџџџџџџ $џџџџџџџџџ $џџџџџџџџџ $ џџџџџџџџџ $џџџџџџџџџ $џџџџџџџџџ $џџџџџџџџџ" $  $G$ " џџџџџџџџ@C@Рџџџџџџџџџџџџџџџџ ˜E@Рџџџџџџџџџџџџџџџџ E@Рџџџџџџџџџџџџџџџџ Eˆ`Рџџџџџџџџџџџџџџџџ ˜Eˆ WPРџџџџџџџџџџџџџџџџ ˜EG€Рџџџџџџџџџџџџџџџџ @e Рџџџџџџџџџџџџџџџџ Eˆ@Рџџџџџџџџџџџџџџџџ E" Рџџџџџџџџџџџџџџџџ ED`Рџџџџџџџџџџџџџџџџ EˆGРџџџџџџџџџџџџџџџџ E†Рџџџџџџџџџџџџџџџџ ECPРџџџџџџџџџџџџџџџџ ˜E@Рџџџџџџџџџџџџџџџџ EHРџџџџџџџџџџџџџџџџ EˆРџџџџџџџџџџџџџџџџ ˜Eˆ WPРџџџџџџџџџџџџџџџџ ˜EGPРџџџџџџџџџџџџџџџџ @e%Сџџџџџџџџџџџџџџџџ Eˆ Рџџџџџџџџџџџџџџџџ E"(PРџџџџџџџџџџџџџџџџ C€PСџџџџџџџџџџџџџџџџP1 EHH"PРџџџџџџџџџџџџџџџџ E#bРџџџџџџџџџџџџџџџџ @C@Рџџџџџџџџџџџџџџџџ ˜E@Рџџџџџџџџџџџџџџџџ E@Рџџџџџџџџџџџџџџџџ E`Рџџџџџџџџџџџџџџџџ E WPРџџџџџџџџџџџџџџџџ EG€Рџџџџџџџџџџџџџџџџ @PpРџџџџџџџџџџџџџџџџ E@Рџџџџџџџџџџџџџџџџ E" Рџџџџџџџџџџџџџџџџ EF%Рџџџџџџџџџџџџџџџџ EGРџџџџџџџџџџџџџџџџ E†Рџџџџџџџџџџџџџџџџ 7>‹“˜›Імтчшщьюђіћќ§ў  #'(),-/37:<=ACDGKNOPQRVWXZ]cfqsvwz{|~„†ˆ‰Š‹Ž’“”–—™›žЃЅІЊ­АБЕЖЗМРџџџџџџџџџџ#7>ast€“ ІСпсфцъюѓѕїјљњ  !$%&+.124569>BEFHJTUY\]_adegjkqru}€‚…‡˜šœŸ ЄЇЉЎЏВГТУџџ>Z[f‚‹“клноуыэёі "*0IL]`bmnoptxyƒ‘ЁЂЈЛНПСџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ>ITXuˆŒ’“™ЕУєќ #',<ADRZ[]fwˆ‰ŠŒŽЅЌИЙџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  "$&+=>EILOV`knz|†Œ’“™ЄЙКНХрхє  8;@S]hilŒ’”–—žІЋДКХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!07>afx‚‹“”›œŸІЌБТочщэії§*+0IL]`ceopqvx†‘•ЁЂЈ­АЗМНПСџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%)>HNXВУл№ё3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ^џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“­ЎЏАБВГДЕЖЙКЛМНОПРСТУФХЦЧШЩЪ&@B(((џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“­ЎЏАБВГДЕЖСЮЯабвгдежзийклмнпруфхцчшђѓєѕії§ў  ((џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&'()*+,-./012346789:;<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ !@ABџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“”•–—˜™š›žŸ ЁЂЅІЇЈЉЊЋџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ fsx‹“ЌВі-03;KN]aqƒ†ŠЂЦЧШЩЪЫЬЭЮЯабвгдежзийкнџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ1234ЭЮЯабвгдежзийџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒƒƒƒƒƒƒƒƒƒУУУƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒCР $ џџџџџџџџ  С5? #џџџџџџџџ0 С2.? џџџџџџџџE%%Р2%8?$1$'%00-2+џ 1С79**?  џџџџџ1pС2=? "џџџџџџџ3С2=? џџџџџџџџ3pС;'? џџџџџџџџ3С2.? џџџџџџџџџ4С1? $6<$320=џ4pС2.?  #џџџџџџџ4Р2.?  #џџџџџџџ @7С79**? џџџџџA8PС79**? џџџџџџ8pС2=?џџџџџџџџ QС2.?џџџџџџџџџQТ;'? џџџџџџџџџQ0Т2=?48?џџџџџ@Q@Р/(-+џџџџџџџџџџџ  QPС2.? џџџџџџџџ&%QPТ79**?  џџџџџџџQpТ2.?џџџџџџџџQpТ2=?6/?џџџџџQС2=?36?џџџџџRР2.? џџџџџџџџџ RС79**?  џџџџџџџ@RТ79**?  ?&%'/94R0Т&406IЎ„dŒЈА`@k(Ў„dД’’`! S1œ’dž@@`>4080–†dЄЈЄр`-!–†d˜ Њr! B3ЎdЈЄЄ@d=40V2ЎhЄŒ”@ф'F'–„d„І˜т`40R3ЎdšŠЄ@`=e5œ`’Žˆ@т<:%Ў‚dŽЊŽ~W402'œdš@@! 40]8–†dŠ„ˆђ`.8Ўd‚ˆ @b! A œdš@@y! 40MA–„dЌЌ‚ќ'BB–fŽœД@р>P$–†dˆЊ`@40’S–„b’ŒАц'40J2ЎdЈЄЄ@r/40IE–dˆ˜І@р@yH–„dЎŠ˜b! FHЎ„dД’’~! Y WB2QBP ; @ pQ–dВВˆ@d@ ~"IRLP-47;4@0aWЎdЄ†Ј@ю`409œd‚Є†@`=40aЎАb†Ј@р@40yœdš@@z! 40[ –„bЄžžt=40I$–dВВˆ@ў! 40B%Ў„dŒЈА~! 40c'œdœІ‚@`=40V'–dŽŠ@@~! 40S2ЎЂdЂ@@ђ`40.2–†d„Д„ъ'40)2–dŽŠ@@j=40RџџџџџџџџџџџџџџџџџџџџџџџџЈ hЌbА`Ў‚d†„ІтЄŠ˜‚В@`џџ№'eWGl #/]in progress q'џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЄІ@@рЎd‚ŠŠ@`Ў’ˆŠd@eџџˆŠd@с№!4048.56N/07357.61W#PHG5430 Columbia University WIDEn-n/TRACEn-n n2ygk@columbia.edužrџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЄІ@@рЎd˜Ќ@@`œdš@@~Ў’ˆŠd@с№!!000000FF02C1052E2638033E0197----0083041100000000Hнџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈdbрЌŠf’ˆ@ђœdš@@~Ў’ˆŠb@с№/122121z4044.73N/07415.40W>281/000HDOP02.2 SATS06 VE3ID OT2 QSX VE3RPT 147.06 1286.0 224.86 444.400 145.41Ж 145.41ЉFџџџџџџџџџџџџџЈЂd lЄ`‚†dކ@ђЎ„dД’’~Ў’ˆŠd@с№`eIYlR^>/`"5r}Mutt Moble_" гџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈ ЊЊfД`–dЄ Œ@ў–b’šˆ@|œdš@@ў№'dC-n\<>/]"3k} ФQџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЎdpjрЎ„dДŠА`œdš@@ўџџˆŠb@р№_05122227c150s002g003t057r141p141P000h00b10165wHKT xЖLYN-285-<630> ™[џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈ ЄІp `–„f †Вr–‚dЄ˜š~Ў’ˆŠd@с№`fNjl 0>/'"5.}/TinyTrak4 Alpha!wO\!|4Ÿќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈ†bр‚„p’Њ@№œdš@@~Ў’ˆŠb@р№/122122z4039.79N\07410.60Wu040/000/A=000034 11.7V 19C Voice:446.000mhzјnџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ўdnj`Ўdœ Ј@`œdš@@ўџџˆŠb@р№=4055.98N/07407.16WoPHG5230/WinAPRS 2.7.5 -NJBERFAIR LAW-275-<630> fЧџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœр–dВВˆ@bЎ„dŒЈА~Ў’ˆŠd@с№>220323zUI-View32 V2.03 !VK2YYD@arrl.net {UIV32N} Щџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ў@@@`Ў„dŒЈА`Ў„dŒЈА~Ў’ˆŠd@с№@122147z4059.35N/07420.83W_002/000g000t069r000p000P000b10130h48FWX/ {UIV32N} ƒtџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЄІ@@рЎ„dД’’`œdš@@ўџџˆŠd@с№!4104.67N/07348.25WmPHG7450/W-R-T+147.06 www.weca.orgˆІџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Јfbb`œ’dž@@`œdš@@~Ў’ˆŠb@р№>G7LTT's $100 APRS TrackerHQџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈbЄ j `–†dЄЈЄрЎ„dД’’~Ўd‚ŠŠ@с№`eSP KEv/>"59} Йџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Јfbb`–†d˜ ЊrЎd˜Ќ@@`Ў’ˆŠd@с№!4051.75N/07438.88W>339/021/A=000747Ц–ttp://KC2LPU.AJoiner.netmФџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЊdjœрЎdЈЄЄ@dЎ’ˆŠd@dџџˆŠd@с№=4047.91N/07405.50WrPHG71103/ 50W Digi, I-gate {UIV32N} ‡џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІВjЎlІ`ЎhЄŒ”@фЄŠ˜‚В@`œdš@@џ№'g'6m+ v/]"49}Monitoring 446.00 Simplex –џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈ`ІЄfІ`–„d„І˜тœdš@@~Ў’ˆŠb@р№`faflKB>/]"4:}[Freq Mhz]*Hello from Staten Island!= Eџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ўdlb`ЎdšŠЄ@`–dŽŠ@@~Ў’ˆŠd@с№=4016.43N/07440.91WoPHG5200/Mercer County EOC -NJMERLAWRENCE-261-<530> Qџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœ`œ`’Žˆ@тœdš@@~Ў’ˆŠd@с№/]"4>}= Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„Š‚†žœ`Ўd‚ˆ @bœdš@@~Ў’ˆŠd@с№!4048.92N/07418.57W-ADP RADIO CLUB Пџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ”’df`œdš@@yџџš@@~џџˆŠd@с№!4047.56NI07415.09W&javAPRSIgate - www.n2mh.netcЇџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈ`ЄЊ`Ђ`–„dЌЌ‚ќœdš@@ўџџˆŠd@с№'f5#l o/]East Brunswick Twp NJ OEM жтџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Іddn`–fŽœД@р–dŽŠ@@~Ў’ˆŠd@с№>062235z[227]APRS+SA Skip from Manalapan, NJ FN20 aџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœр–†dˆЊ`Ў„dД’’~œdš@@ў№@122221z4116.00N/07358.61W_115/003g006t062r000p000P000h67b10183Davis WMII & Weather Display WWW.KC2EHA.com {UIV32N} GъџџџџџџџџџџџџЈb ІbЄ`–„b’ŒАцœdš@@~Ў’ˆŠd@с№'e<1l #/]RED CROSS STAMFORD,CT [Freq MHz]= шџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Јfbb`ЎdЈЄЄ@rЎ„dŒЈА~Ў’ˆŠd@с№/122230z4050.01N/07356.99W>012/025/A=000059к џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœ`–dˆ˜І@рœdš@@~Ў’ˆŠd@с№@122142z4023.75N/07412.52W_001/000g000t065r000p000P000h56b10158/_ Ivy Hill Weather Station YЮџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„Š‚†žœ`–„dЎŠ˜bœdš@@џџџš@@ў№!4038.82N/07415.02WoPHG5160/Roselle OEM Nџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЄІ@@рЎ„dД’’~œdš@@~Ў’ˆŠd@с№!4116. N/07348. W#PHG7300 fill-in digipeater www.weca.org­ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЄІ@@`œdš@@yџџš@@~џџˆŠd@с№;WB2QBP *122218z4042.51N/07349.13W+ Queens ARC www.arcecs.org Mtg: 1st Tue 19:30nџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœр–dВВˆ@dЎ„dŒЈА~œdš@@ў№@122148z4047.33N/07330.36W_125/005g003t062r000p000P000h44b10070Syosset Weather - K2YYD@arrl.net ‰џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЌЄf``œdš@@yџџ˜‚В@`џџˆŠd@с№;IRLP-4740*122220z4047.56NI07415.09W0442.600MHz T141 R20m OFFLINE •=џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈ`ЈЈnЄ`ЎdЄ†Ј@юœdš@@~Ў’ˆŠd@с№`fXUl [/`w2rct@arrl.net_ dќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ўdph`œd‚Є†@`–dŽŠ@@~Ў’ˆŠb@с№=4019.40N/07438.28W+PHG7200/WinAPRS 2.8.4 -NJMERPRINCETO-284-<630> „џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœ`ЎАb†Ј@рœdš@@~Ў’ˆŠd@с№@122214z4107.95N/07323.13W_063/000g001t061r000p000P000h69b10158norwalkweather.net {UIV32N} уŽџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œЊbrрœdš@@z–dŽŠ@@~Ў’ˆŠd@с№!4052.12NS07446.07W#PHG7630/W2,NJn Budd Lake, NJ www.n2mh.netsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœр–„bЄžžt–d ЊЈ@~Ў’ˆŠd@с№=/9\cm<"v?# B...IT'S ALL ABOUT THE ROO!!! эњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈd‚р–dВВˆ@ў–dВВˆ@fЎ’ˆŠd@с№!4047.92N/07330.97W>299/012/A=000224˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfrb`Ў„dŒЈА~œdš@@~Ў’ˆŠd@с№!4103.63NS07415.28W#PHG3530 W2,NJn-N,10-70 Repeater Assn,Wanaque, NJ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ўdpj`œdœІ‚@`œdš@@~Ў’ˆŠd@с№=4051.25N/07353.25W-PHG5280/ n2nsa@n2nsa.com -285-<630> пџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfrb`–dŽŠ@@~œdš@@~Ў’ˆŠd@с№!4016.82NS07419.80W#PHG3340/W3,NJn Manalapan NJ K2GE —TџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈ`ЄЂfЂ`ЎЂdЂ@@ђ–‚dЄ˜š~Ў’ˆŠd@с№`fCDl"!>/]"4I}= ZѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈ`ІВjА`–†d„Д„ъœdš@@ўџџˆŠd@с№'eEQl -/] X'џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ŒŽdb`–dŽŠ@@jЎ„dІœœ~Ў’ˆŠd@с№=4027.33N\07422.28Ww>T+068F+000V057 FloodAdvisor -03˜пџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p`‚‚‚‚‚‚рЎ’ˆŠb@bџџ№:BBBBBB :1{71 ЗЊџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p`‚‚‚‚‚‚рЎ’ˆŠb@bџџ№:BBBBBB :1{72 п€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  N040445300W074000400  N040447200W074005700џџџџџџ  N040463600W072436500  N040486900W072386700џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџюchirp-20240224/tests/images/Wouxun_KG-UV9G_Pro.img0000644000175000017500000010027514430171343020404 0ustar hibbyhibbyІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІ000000џџ000000џџKG-UV9PX 8  Ќ–X&„ќ Ф  Pњ8P џџџџџџџ>HR\fpz„Ž˜ЌРдш#-7AKZdnx‚Œ– ЅІІІІІІІІІІІІІІІІcWK=3/-*.1œ—ŒˆŠŠ”šЧХТСІЃІВХЭІІІІІІІІІІІІІІІPG<<62($*+0}wqhb[XXSQSTW_`мммммммммммммммІІІІІІІІІІІІІІІІ8  Ќ–X&„Ž ФP PІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІfpz„Ž˜ЌОд&0:DS]gq{…™ЃІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІqsuwy{}ƒ…‡‰‹‘“•—јјІІІІІІІІІІІІІІІІІІІІлУФP*„PІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІлУФP @PРС,€С^ѓРРІІІІІІІІІІІІІІІІџџ ч 8&zP' №№џџџџџџџџ(<PZBetterSafeRadio ІІІІІІІІІІІІІІІІWOUXUN20220609ИЃНЈЪЁШЊжнЪа000000B4_PX3.0deШЩ ,Шс‘єѕМН !RSдџџџџџџџџGMRSMUMMS-CGHAMSATRACINGDTWLMRISRSHTFMDCORDLSMARSCAAARAILІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІСаzСаzуРќџСк>Ск>уРќџСфСфуРќџСэЦСэЦуРќџСїŠСїŠуРќџТNТNуРќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІGMRS 1GMRS 2GMRS 3GMRS 4GMRS 5GMRS 6ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІAAAAAAќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќІІІІІІІІІІІІІІІІІІІІІІІІ  №№  №№  №№  №№  №№  №№  №№  №№ №№ №№ №№ №№ №№ №№ №№ №№ №№ №№ №№ №№U 101џџU 102џџU 103џџU 104џU 105џџU 106џџU 107џџU 108џџU 109џџU 110џџU 111U 112U 113џџU 114џџU 115џџU 116џџU 117џџU 118џџU 119џџU 120џ  !"#$%&'()*+,-./0123456789:;<=>?ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJLR1VWOUdQcm9SYWRpbyIsICJ2ZW5kb3IiOiAiV291eHVuIiwgIm1vZGVsIjogIktHLVVWOUcgUHJvIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Icom_ID-5100.img0000644000175000017500000052203514411666130017000 0ustar hibbyhibbyrx €ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ џџџџџџџџџџџџџџџџџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџсџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@7P­Аџџ m`u0џџ O№_џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ џџ јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџ@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ CALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGN џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№џŒџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџ‹Ÿ__ˆˆ++џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњNEџџџ API510,DSTAR* />/v/k/- \Y NEџџџ \Y NEџџџџ/_ џџџџџџџџџџџџџџџџџџџџџ‘нР"3@ €Гя 'Р@ €9оLK@@ €‘нР"3@ €Гя 'Р@ €9оLK@@ €CQCQCQ CQCQCQ CQCQCQ CQCQCQ џџ NEџџџџџџџџ REF000ALREF000AL CQCQCQ NEџџџџџ NEџџџџџџџџ REF000ALREF000AL CQCQCQ NEџџџГя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџ9оLK@@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќџџџџџџџџџџўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џchirpюimgeyJ2ZW5kb3IiOiAiSWNvbSIsICJtb2RlbCI6ICJJRC01MTAwIiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIklENTEwMFJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Icom_IC-2300H.img0000644000175000017500000001424014411666130017100 0ustar hibbyhibbyrx ‚qxKB6LEDŠqxK6POU ЊqxWA6HAM–rxW6BUR ЎrxW6TP КrxK6LNK РrxWB6NDJсrxW6SRR !sxWB6TCS !sxW6RGG !}sxKF6ALAvqxN6NFI №‡x  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№‡x џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџrx џџџџџџџџџџџџџџџџ‚}˜ M- 1 P ъy˜ M- 1AP Œ}˜ M- 2 P –}˜ M- 3 P ўy˜ M- 3AP  }˜ M- 4 P z˜ M- 4AP Њ}˜ M- 5 P z˜ M- 5AP z˜ M- 6 P О}˜ M- 7 P &z˜ M- 7AP 0z˜ M- 8 P :z˜ M- 9 P Dz˜ M-10 P Nz˜ M-11 P Xz˜ M-12 P bz˜ M-13 P lz˜ M-14 P vz˜ M-15 P €z˜ M-16 P Šz˜ M-17 P ,~˜ M-18 P ”z˜ M-18AP 6~˜ M-19 P žz˜ M-19AP @~˜ M-20 P Јz˜ M-20AP J~˜ M-21 P Вz˜ M-21AP J~˜ M-21BP T~˜ M-22 P Мz˜ M-22AP ^~˜ M-23 P Цz˜ M-23AP h~˜ M-24 P r~˜ M-25 P r~˜ M-25BP |~˜ M-26 P †~˜ M-27 P ~˜ M-28 P ~˜ M-28BP }}˜ M-60 P ‡}˜ M-61 P яy˜ M-61AP ‘}˜ M-62 P љy˜ M-62AP ›}˜ M-63 P z˜ M-63AP Ѕ}˜ M-64 P  z˜ M-64AP Џ}˜ M-65 P z˜ M-65AP Й}˜ M-66 P !z˜ M-66AP +z˜ M-67 P 5z˜ M-68 P ?z˜ M-69 P Iz˜ M-70 P Sz˜ M-71 P ]z˜ M-72 P gz˜ M-73 P qz˜ M-74 P z˜ M-77 P 1~˜ M-78 P ™z˜ M-78AP ;~˜ M-79 P Ѓz˜ M-79AP E~˜ M-80 P ­z˜ M-80AP O~˜ M-81 P Зz˜ M-81AP Y~˜ M-82 P Сz˜ M-82AP c~˜ M-83 P Ыz˜ M-83AP c~˜ M-83BP m~˜ M-84 P еz˜ M-84AP w~˜ M-85 P пz˜ M-85AP ~˜ M-86 P щz˜ M-86AP ‹~˜ M-87 P ѓz˜ M-87AP •~˜ M-88 P §z˜ M-88AP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::џџ J J :::::::::::::џџџџџџџџџџџџ N N N N N N N N N N яГР' яГР' яГР'     џџџџџџџџџџџџџџџџџџяГР' џџџџџџџџџџџџяГР' џџџџџџџџџџџџяГР' џџџџџџџџџџџџяГР'  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   џџџџџџџџџџџџџџџџџџяГР'  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   џџџџџџџџџџџџџџџџџџяГР'  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   џџџџџџџџџџџџџџџџџџџџџџџџџ32510001џџџџџџџџџџџџџџџџchirp-20240224/tests/images/Yaesu_FT-65E.img0000644000175000017500000002076114411666130017165 0ustar hibbyhibby4123џџџџџџџџџџџџC ˜S% 9•bUQ%229•Q%%hh%@UD%G™•@UD%22G™•D%B%hhG%bUQ%9•@UD%G™•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC ˜@   P @  C ˜ P @  C ˜џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ---------..------------------------------------------------------------------------------------------------------------------------------------------------------S% S%  S% џchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIllhZXN1IiwgIm1vZGVsIjogIkZULTY1RSIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Yaesu_FT-7100M.img0000644000175000017500000001740014411666130017326 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџx‚x‚‚€№џџџџџџџџџџџџџџџџ UUџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџРЗЛРЗЛ<  џџ€LщЈLщЈ<  ‚@РЯ@РЯ,R OEFVERѓoѓo< ƒ џџџџџџР-)9Р-)9є"  џџџџџџ‚LщЈLщЈ< HOME џџџџџџ‚ шЈ шЈјR HOME џџџџџџРЗЛРЗЛ< VHOME €k•€k•єU  Vertex Standard AH003M Backup DT‚D•D•< 144000‚ˆW•ˆW•< 144005‚@†Є@†Є< 145000‚€ШГ€ШГ< 146000‚D•@Œ< 144-06‚D•Рkž< 144+06‚D•@†Єd 144145‚D•D•< ƒAM ‚D•D•< NAME €D•D•< NONAMEƒD•k•< SPLIT ‚D•D•< TNONE ‚D•D•< TONE ‚D•D•< TSQL ‚D•D•< CTCBEL‚D•D•< DCS23 ‚D•D•< DCS25 ‚D•D•< gDCS754€D•D•<  ‚D•D•< T100 ‚D•D•<T67 ‚D•D•<1T254-1€D•D•<  ‚D•D•< 5K ‚D•D•< 10K ‚D•D•< 12K5 ‚D•D•< 15K ‚D•D•< 20K ‚D•D•< 25K ‚D•D•< 50K €D•D•<  ‚D•D•< HIGH ‚D•D•< LOW3 ‚D•D•< LOW2 ‚D•D•< LOW €D•D•<  ‚D•D•< SKIPOFЂD•D•< SKIPON‚D•D•< MASKOFТD•D•< MASKON€D•D•<  ‚ѓoѓo 108 ‚•К •К 180 €D•D•<  €D•D•<  ‚ > > <EKANAL‚xr„ xr„ <HELI1 ‚‡ ‡ <HELI2 ‚3} 3} <REBERG‚шlt шlt <RKOORDƒ@†ЄP­Є< SPLIT2РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  ‚D•D•< VHF120РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  РЗЛРЗЛ<  ‚€GЁ€GЁјU 430 ‚ааP ƒ320AM ‚8œ8œ,V 480FM ƒ€žG0Р‡‹;Ф R 810999‚Р‡‹;Р‡‹;Ф R 999 €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  €k•€k•єU  ‚8І%ИЎБјR HUNEBE‚8І%ИЎБјR!MUTTEN‚8І%ИЎБјR! MT-BAR‚8І%ИЎБјR MOSALP‚р&`ВјR!WEISST‚ˆi&rВјR"CHASRL‚0Ы&АгВјR!SANTIS‚и,'X5ГјR SISACH‚и,'X5ГјR! CIMETA‚и,'X5ГјR ATTING‚€Ž'—ГјR!PILATU‚(№'ЈјГјR"RIGI ‚аQ(PZДјR LAPRAZ‚xГ(јЛДјR!LUZERN‚Шv)HЕјR! BERN-W‚Шv)HЕјR WNKDRF‚pи)№рЕјR STRIHE‚:*˜BЖјR! INTERL‚:*˜BЖјR MOLLIS‚Р›*@ЄЖјR!GIBLOU‚h§*шЗјR BASEL ‚h§*шЗјR!BCHSBR‚h§*шЗјR SCHAFF‚h§*шЗјR!LA-BRN‚_+gЗјR! NIESEN‚_+gЗјR"ANDERM‚_+gЗјR MALMER‚ИР+8ЩЗјR!GRENCH‚`",р*ИјR PLANCY‚„,ˆŒИјR!BASEL ‚Ах,0юИјR!WINTER‚Ах,0юИјR!VAIRAN‚Ах,0юИјR!ZOFING‚XG-иOЙјR!ETZEL ‚Љ-€БЙјR THUN ‚Ј .(КјR!GOSSAU‚Ј .(КјR!CHASRO‚Pl.аtКјR BDRAMS‚Pl.аtКјR!WILISA‚јЭ.xжКјR!FRONAL‚јЭ.xжКјR!GENF ‚ // 8ЛјR NIEDHR‚H‘/Ш™ЛјR!GEMPEN‚№ђ/pћЛјR!WEISSF‚№ђ/pћЛјR! AFFOLT‚˜T0]МјR!LOVRES‚˜T0]МјR"ZURICH‚@Ж0РОМјR"BACHTE‚@Ж0РОМјR!RECKIN‚@Ж0РОМјR!LUTRY ‚ш1h НјR! V-SCUR‚ш1h НјR!GENF ‚ш1h НјR!VALENS‚МH1Ѓb>Ѓbџџ Јb Јbџџ ­b­bџџ фБbфБbџџ ЦЖbЦЖbџџ ЈЛbЈЛbџџ ŠРbŠРbџџ lХblХbџџ NЪbNЪbџџ 0Яb0Яbџџ дbдbџџ єиbєиbџџ жнbжнbџџ ИтbИтbџџ šчbšчbџџ |ьb|ьbџџ ^ёb^ёbџџ @іb@іbџџ "ћb"ћbџџ ccџџ цcцcџџ Ш cШ cџџ ЊcЊcџџ ŒcŒcџџ ncncџџ PcPcџџ 2"c2"cџџ 'c'cџџ і+cі+cџџ и0cи0cџџ К5cК5cџџ œ:cœ:cџџ ~?c~?cџџ `Dc`Dcџџ BIcBIcџџ $Nc$Ncџџ ScScџџ шWcшWcџџ Ъ\cЪ\cџџ ЌacЌacџџ ŽfcŽfcџџ pkcpkcџџ RpcRpcџџ 4uc4ucџџ zczcџџ ј~cј~cџџ кƒcкƒcџџ МˆcМˆcџџ žcžcџџ €’c€’cџџ b—cb—cџџ DœcDœcџџ &Ёc&Ёcџџ ІcІcџџ ъЊcъЊcџџ ЬЏcЬЏcџџ ЎДcЎДcџџ ЙcЙcџџ rОcrОcџџ TУcTУcџџ 6Шc6Шcџџ ЭcЭcџџ њбcњбcџџ мжcмжcџџ ОлcОлcџџ  рc рcџџ ‚хc‚хcџџ dъcdъcџџ FяcFяcџџ (єc(єcџџ љc љcџџ ь§cь§cџџ ЮdЮdџџ АdАdџџ ’ d’ dџџ tdtdџџ VdVdџџ 8d8dџџ  d dџџ ќ$dќ$dџџ о)dо)dџџ Р.dР.dџџ Ђ3dЂ3dџџ „8d„8dџџ f=df=dџџ HBdHBdџџ *Gd*Gdџџ Ld Ldџџ юPdюPdџџ аUdаUdџџ ВZdВZdџџ ”_d”_dџџ vddvddџџ XidXidџџ :nd:ndџџ sdsdџџ ўwdўwdџџ р|dр|dџџ ТdТdџџ Є†dЄ†dџџ †‹d†‹dџџ hdhdџџ J•dJ•dџџ ,šd,šdџџ ŸdŸdџџ №Ѓd№Ѓdџџ вЈdвЈdџџ Д­dД­dџџ –Вd–Вdџџ xЗdxЗdџџ ZМdZМdџџ <Сd<Сdџџ ЦdЦdџџ ЫdЫdџџ тЯdтЯdџџ ФдdФдdџџ ІйdІйdџџ ˆоdˆоdџџ jуdjуdџџ LшdLшdџџ .эd.эdџџ ђdђdџџ ђіdђіdџџ дћdдћdџџ ЖeЖeџџ ˜e˜eџџ z ez eџџ \e\eџџ >e>eџџ e eџџ eeџџ ф"eф"eџџ Ц'eЦ'eџџ Ј,eЈ,eџџ Š1eŠ1eџџ l6el6eџџ N;eN;eџџ 0@e0@eџџ EeEeџџ єIeєIeџџ жNeжNeџџ ИSeИSeџџ šXešXeџџ |]e|]eџџ ^be^beџџ @ge@geџџ "le"leџџ qeqeџџ цueцueџџ ШzeШzeџџ ЊeЊeџџ Œ„eŒ„eџџ n‰en‰eџџ PŽePŽeџџ 2“e2“eџџ ˜e˜eџџ іœeіœeџџ иЁeиЁeџџ КІeКІeџџ œЋeœЋeџџ ~Аe~Аeџџ `Еe`Еeџџ BКeBКeџџ $Пe$Пeџџ ФeФeџџ шШeшШeџџ ЪЭeЪЭeџџ ЌвeЌвeџџ ŽзeŽзeџџ pмepмeџџ RсeRсeџџ 4цe4цeџџ ыeыeџџ јяeјяeџџ кєeкєeџџ МљeМљeџџ žўežўeџџ €f€fџџ bfbfџџ D fD fџџ &f&fџџ ffџџ ъfъfџџ Ь fЬ fџџ Ў%fЎ%fџџ рС—рС—ш lмlмu lмlмu lмlмu dJнdJнџџ`ъ зu зuџџ`ъ@ЅЎ@ЅЎџџ`ъdJнdJнџџ`ъА6wА6wџџ`ъф Їф Їџџ`ъ 5!BррёAё рС5V99 %‘@ЦB000000rIѓёAџџџџџџџџџџџџџџџџџџџџџџџџџёšМо№4Vx'24W˜4P4Vx24W˜4_4VxB4ex4P4VxB4ex4_4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx4VxšМо№4Vx Уi№ №Vx 4VxšМо№4Vx ˜vT2Мо№4Vx 24W˜4_B4ex4_ рС—рС—rIѓёAё рСVЬ2T-01  VЬyOжP  4Vx 5T-01  4Vx 5T-02  4Xx123456 5T-03  ‡eC!123456 5T-04  5W„123456 5T-05  4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx 4Vx `а4Vx‡eC!F 4VxšМ5T-01  4V‡ŠМ 5T-02  ‡eC!šМ5T-03  5W„šМ5T-04  4VxšМ 4VxšМ 4VxšМ 4VxšМ …ЯР€ …ЯР€ џџџџџџџџџџџџџџџџZblмZblмџџџџџџџџџррSпџџ5ћџџџ3%!44,џџџџџџџооџџџџћџџџ3)-0џџџџџџџp0сp0сџџџџћџџџ!2#џџџџџџџ`ŒрРvсџџ5ћџџџ"%,(!-џџџџџџџаЃр0Žсџџsћџџџ7()$"9џџџџџџџаЃр0Žсџџpћџџџ1.!,4џџџџџџџ@Лр Ѕсџџ0ћџџџ&/2+3џџџџџџџhsн‰мџџHћџџџ6)# џџџџџџџрЪр@Есџџ…ћџџџ3!,4"#џџџџџџџHЂншЗмџџpћџџџ1.!,4џџџџџџџ`о`оџџџџћџџџ3)-0џџџџџџџ`’п`’пџџџџћџџџ.#!,,џџџџџџџ0с0сџџџџћџџџ/! џџџџџџџссџџџџћџџџ/! џџџџџџџа са сџџџџћџџџ/! џџџџџџџ (с (сџџџџћџџџ/! џџџџџџџ№ёр№ёрџџџџћџџџ/! џџџџџџџ˜kн8мџџ0ћџџџ1.!,4џџџџџџџа&рp<пџџ…ћџџџ1.!,4џџџџџџџ€Эїџџџџџџџџџџџџ78 џџџџџџџDзїџџџџџџџџџџџџ78 џџџџџџџсїџџџџџџџџџџџџ78 џџџџџџџЬъїџџџџџџџџџџџџ78 џџџџџџџTўїџџџџџџџџџџџџ78 џџџџџџџјџџџџџџџџџџџџ78 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ yоhyмџџ…ћџџџ.!33џџџџџџџŠДэџџџџџџџџџџџџ31- &$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBяBяџџџџћџџџ-!2џџџџџџџ0Зя0Зяџџџџћџџџ-!2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџzаСzаСџџџџџџџџ&23 џџџџџџџ>кС>кСџџџџџџџџ&23 џџџџџџџфСфСџџџџџџџџ&23 џџџџџџџЦэСЦэСџџџџџџџџ&23 џџџџџџџŠїСŠїСџџџџџџџџ&23 џџџџџџџNТNТџџџџџџџџ&23 џџџџџџџ Т Тџџџџџџџџ&23 џџџџџџџšqЩšqЩџџџџџџџџ&23 џџџџџџџ^{Щ^{Щџџџџџџџџ&23 џџџџџџџ"…Щ"…Щџџџџџџџџ&23 џџџџџџџцŽЩцŽЩџџџџџџџџ&23 џџџџџџџЊ˜ЩЊ˜Щџџџџџџџџ&23 џџџџџџџnЂЩnЂЩџџџџџџџџ&23 џџџџџџџ2ЌЩ2ЌЩџџџџџџџџ&23 џџџџџџџ˜ЫС˜ЫСџџџџџџџџ&23 џџџџџџџ\еС\еСџџџџџџџџ&23 џџџџџџџ пС пСџџџџџџџџ&23 џџџџџџџфшСфшСџџџџџџџџ&23 џџџџџџџЈђСЈђСџџџџџџџџ&23 џџџџџџџlќСlќСџџџџџџџџ&23 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџФlŸф ЇџџHћџџџ8"!.$џџџџџџџШƒЂш$Њџџ5ћџџџ+/)џџџџџџџP—Ђp8Њџџћџџџ",9.џџџџџџџP—ЂP—Ђџџџџћџџџ",9//3џџџџџџџDЃdЗЊџџ5ћџџџ703%џџџџџџџріЃ˜ЋџџHћџџџ##2042џџџџџџџ‘Ѕ(2­џџ5ћџџџ-4#/.џџџџџџџLгІltЎџџrћџџџ6)# џџџџџџџнІ0~Ўџџћџџџ+-"9џџџџџџџРŠЈРŠЈџџџџћџџџ.#!,,џџџџџџџ˜ЄИ Ќџџћџџџ!.!#/2џџџџџџџдЂєЅЉџџ5ћџџџ703%џџџџџџџ8Гž8Гžџџџџћџџџ/! 5џџџџџџџРЦžРЦžџџџџћџџџ/! 5џџџџџџџHкžHкžџџџџћџџџ/! 5џџџџџџџXŸXŸџџџџћџџџ/! 5џџџџџџџрŸрŸџџџџћџџџ/! 5џџџџџџџшяшяџџџџћџџџ/!5"+џџџџџџџpžpžџџџџћџџџ/!5"+џџџџџџџјžјžџџџџћџџџ/!5"+џџџџџџџ€*ž€*žџџџџћџџџ/!5"+џџџџџџџQžQžџџџџћџџџ/!5"+џџџџџџџдцІє‡Ўџџћџџџ6)# џџџџџџџЄЁФ0Љџџ ћџџџ7()$"џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџшЪИшЪИџџџџџџџџ2!0%2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ №п`ъџџџџїџџџџџџџџџџџџџџџџџџ@œqџџџџџџџ"џџџџџџџџџџџџџџџџL4,фєdџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€9џџАџџўџеџ;џџџџџПЯџџРџџџџџџџt}ОђєƒД6 ѕѕџ!!2$џџџџџџё2рŽѕџџџџџџџџџџџџџџџџџџџџџџџџџџPTC88ЊЏZblм…ЯР€ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџу 5џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTH-UV8000џџchirpюimgeyJ2ZW5kb3IiOiAiVFlUIiwgIm1vZGVsIjogIlRILVVWODAwMCIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Radioddity_GS-5B.img0000644000175000017500000001641114430171343020075 0ustar hibbyhibby e Yf`%P%DP9P3%@%@Ч Ч %PC%PCЖЖ•F•Fžž%A%APEPQ%b%hPRBPRBuBuBP„BP„BPCPC%aC%aCP…CP5D%D%QDPDEPƒDP3DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGeneral џџџџџџLew Rptrџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ џџџџџџџџџџџџџџџџџџџџџг  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџœœџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSYWRpb2RkaXR5R1M1QlJhZGlvIiwgInZlbmRvciI6ICJSYWRpb2RkaXR5IiwgIm1vZGVsIjogIkdTLTVCIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDIzMDMwNCJ9chirp-20240224/tests/images/BTECH_MURS-V1.img0000644000175000017500000002001014411666130017113 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ  žž€€žž@@žžpEpEžžFFžž  э э €€э э @@э э pEpEэ э FFэ э   €€@@pEpEFFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFANGXIAODONGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸpџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ FM 65-75Mn FM 76-108MџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџMurs1-1џџџџџџџџџMurs1-2џџџџџџџџџMurs1-3џџџџџџџџџMurs1-4џџџџџџџџџMurs1-5џџџџџџџџџMurs2-1џџџџџџџџџMurs2-2џџџџџџџџџMurs2-3џџџџџџџџџMurs2-4џџџџџџџџџMurs2-5џџџџџџџџџMurs3-1џџџџџџџџџMurs3-2џџџџџџџџџMurs3-3џџџџџџџџџMurs3-4џџџџџџџџџMurs3-5џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ140902N WELCOME USM2402USM2402џџssssssssssttuuvvrrrrqqpoonnnnдедeeeeeeeeeeeeeeeeiiiiiiiiiiiii‚stNNNNNNNNNOOOPPQQEFHJKJIIIIIIIŒŽ/ <џpsv}‡  *4>HT_ju џ€0y џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ123456BF9166Њ0y нchirp-20240224/tests/images/Icom_IC-2720H.img0000644000175000017500000001204014411666130017102 0ustar hibbyhibbyЛЗР 'Р Цf 'Р  УЇ 'Р  Чž  'Р  Њ+ 'Р ЋВ0 'Р У Р 'Р Ч` 'Р П 'Р 9оLK@ Мр 'Р МT 'Р ЈVа 'Р Уѕ 'Р Іа0 'Р  Х{Р 'Р Їс )Ј Гя 'Р ЧьР 'Р УXр 'Р# Рчр 'Р# Њ+ 'Р Тn€ 'Р С„ 'Р ЈА 'Р ЊyА 'Р НP 'Р Ш‰ 'Р Шз 'Р Х{Р 'Р Ч` 'Р Нк  'Р Пa@ 'Р ЈЄ№ 'Р Шз 'Р Ћd 'Р Т ` 'Р Т• 'Р ЦлP 'Р Оvр 'Р Шз 'Р НP 'Р ПЏ` 'Р РK  'Р Нк  'Р НQш 'Р С6 'Р ЇP 'Р Ћd 'Р ФC@ 'Р  П 'Р НŒ€ 'Р Х-  'Р Ш:р 'Р Ф‘` 'Р  Ц 'Р НŒ€ 'Р ЉP 'Р  ЊЧа 'Р НQш 'Р Оvр 'Р Св@ 'Р Ц 'Р Ф‘` 'Р Фп€ 'Р ЊЧа 'Р ЌP 'Р ЧP€ 'Р ТМ  'Р Їlp 'Р ЉA0 'Р ЊyА 'Р ЙР'Р Т ` 'Р Тn€ 'Р Щ­јЪј  С„ 'Р Јѓ 'Р ЉP 'Р# Љнp 'Р НQш 'Р П 'Р Є­P 'Р Єћp 'Р ЅI 'Р Ѕ—А 'Р Ѕха 'Р ›7p 'Р Џї№ 'Р cд0LK@ GћHLK@  ‚КXLK@ <‰˜LK@  L№аLK@  ‚XАLK@ aŠ@LK@  G™ LK@ AрШLK@  зrАLK@  tLK@ ]XLK@ PС`LK@  ƒ}ЈLK@  bЏ8LK@  ~&xLK@  ~ˆ LK@  MД LK@  hЩИLK@% gCLK@  KpLK@ …Ч˜LK@  lћ№LK@ DŒ`LK@ ~ˆ LK@ fШLK@( iюАLK@ НлLK@ ЙЈиLK@ виLK@ W=ˆLK@ :ЁPLK@ =ЎLK@ KˆLK@ ZJШLK@  sйРLK@ a(˜LK@  ]XLK@ ЦЁ(LK@ cрLK@ ƒLK@ FtЈLK@ •`LK@ }€LK@ D*ИLK@ DŒ`LK@ DюLK@ FtЈLK@ \і`LK@ ` LK@ sйРLK@ xm LK@  yє@LK@  {zрLK@  {мˆLK@  ~ˆ LK@  ‚XАLK@ ƒ}ЈLK@  …Ч˜LK@  FжPLK@ bЏ8LK@  zUшLK@ ZЌpLK@ xЯHLK@  qёxLK@ >qрLK@ @ЛаLK@ XФ(LK@ [бhLK@ hhLK@ nф8LK@ pjиLK@  ВИLK@ Ш'ШLK@ ЮЃ№LK@ NйLK@ UЖшLK@ rДШLK@ zЗLK@  …e№LK@  ;ЦHLK@ WŸ0LK@ ` LK@ Гя 'Р 9оLK@ ‘нРРМЂ 'Р ;s€ 'Р Z РР 9оLK@ ЭeР ‘нРРУЇ 'Р  Z РР <ы@LK@ ЭeР 5ЄщР №џ€€џџ№ Њ""""""""""""""""""""""""""""""""ЊЊЊЉ™™™Ё333333333333333333333333333333ЊЊЊЊЊЊЊЊЊЊЊЊЊЊЊЊ№€€џџџѓЊ+ 'Р УЇ 'Р  nUTrP Гя 'Р 9оLK@ Цf 'Р  Гя 'Р Гя 'Р  9оLK@  Гя 'Р  9оLK@  Гя 'Р  9оLK@  24920001chirp-20240224/tests/images/SenhaiX_8800.img0000644000175000017500000001624114430171343017163 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%b%b%P%PP9P9%@%@%PC%PC•F•Fџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIlNlbmhhaVgiLCAibW9kZWwiOiAiODgwMCIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/Baofeng_UV-17ProGPS.img0000644000175000017500000010211414527622514020403 0ustar hibbyhibbyPP`џџџџVHF 1џџџџџџџaџџџџVHF 2џџџџџџџPPaџџџџVHF 3џџџџџџџbџџџџVHF 4џџџџџџџPPbџџџџVHF 5џџџџџџџccџџџџVHF 6џџџџџџџP PcџџџџVHF 7џџџџџџџddџџџџVHF 8џџџџџџџPdPdџџџџVHF 9џџџџџџџeeџџџџVHF 10џџџџџџPePeџџџџVHF 11џџџџџџffџџџџVHF 12џџџџџџPfPfџџџџVHF 13џџџџџџggџџџџVHF 14џџџџџџPgPgџџџџVHF 15џџџџџџhhџџџџVHF 16џџџџџџPhPhџџџџVHF 17џџџџџџiџџџџVHF 18џџџџџџPPiџџџџVHF 19џџџџџџpџџџџVHF 20џџџџџџPPpџџџџVHF 21џџџџџџqџџџџVHF 22џџџџџџPPqџџџџVHF 23џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPsPsџџџџVHF 27џџџџџџttџџџџVHF 28џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP!PuџџџџVHF 31џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%%`џџџџVHF 60џџџџџџuu`џџџџVHF 61џџџџџџ%%aџџџџVHF 62џџџџџџuuaџџџџVHF 63џџџџџџ%%bџџџџVHF 64џџџџџџuubџџџџVHF 65џџџџџџ% %cџџџџVHF 66џџџџџџucucџџџџVHF 67џџџџџџ%d%dџџџџVHF 68џџџџџџededџџџџVHF 69џџџџџџ%e%eџџџџVHF 70џџџџџџueueџџџџVHF 71џџџџџџ%f%fџџџџVHF 72џџџџџџufufџџџџVHF 73џџџџџџ%g%gџџџџVHF 74џџџџџџugugџџџџVHF 75џџџџџџ%h%hџџџџVHF 76џџџџџџuhuhџџџџVHF 77џџџџџџ%%iџџџџVHF 78џџџџџџuuiџџџџVHF 79џџџџџџ%%pџџџџVHF 80џџџџџџuupџџџџVHF 81џџџџџџ%%qџџџџVHF 82џџџџџџuuqџџџџVHF 83џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџususџџџџVHF 87џџџџџџ%t%tџџџџVHF 88џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%`D%`D@џџџџPMR 1џџџџџџџu`Du`D@џџџџPMR 2џџџџџџџ%1`D%1`D@џџџџPMR 3џџџџџџџuC`DuC`D@џџџџPMR 4џџџџџџџ%V`D%V`D@џџџџPMR 5џџџџџџџuh`Duh`D@џџџџPMR 6џџџџџџџ%`D%`D@џџџџPMR 7џџџџџџџu“`Du“`D@џџџџPMR 8џџџџџџџ%aD%aD@џџџџPMR 9џџџџџџџuaDuaD@џџџџPMR10*џџџџџџ%1aD%1aD@џџџџPMR11*џџџџџџuCaDuCaD@џџџџPMR12*џџџџџџ%VaD%VaD @џџџџPMR13*џџџџџџuhaDuhaD&&@џџџџPMR14*џџџџџџ%aD%aD//@џџџџPMR15*џџџџџџu“aDu“aD66@џџџџPMR16*џџџџџџ%`D%`DДД@џџџџKEN 1џџџџџџџu“`Du“`Duu@џџџџKEN 2џџџџџџџ%1`D%1`D  @џџџџKEN 3џџџџџџџuh`Duh`D@џџџџKEN 4џџџџџџџuC`DuC`DЄЄ@џџџџKEN 5џџџџџџџu`Du`DЮЮ@џџџџKEN 6џџџџџџџPb%FPb%F@џџџџFRS 1џџџџџџџP‡%FP‡%F@џџџџFRS 2џџџџџџџ%CC%CC@џџџџLPD 1џџџџџџџPCCPCC@џџџџLPD 2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%`D%`DDџџџџPMR 1џџџџџџџu`Du`DDџџџџPMR 2џџџџџџџ%1`D%1`DDџџџџPMR 3џџџџџџџuC`DuC`DDџџџџPMR 4џџџџџџџ%V`D%V`DDџџџџPMR 5џџџџџџџuh`Duh`DDџџџџPMR 6џџџџџџџ%`D%`DDџџџџPMR 7џџџџџџџu“`Du“`DDџџџџPMR 8џџџџџџџ%aD%aDDџџџџPMR 9џџџџџџџuaDuaDDџџџџPMR 10џџџџџџ%1aD%1aDDџџџџPMR 11џџџџџџuCaDuCaDDџџџџPMR 12џџџџџџ%VaD%VaDDџџџџPMR 13џџџџџџuhaDuhaDDџџџџPMR 14џџџџџџ%aD%aDDџџџџPMR 15џџџџџџu“aDu“aDDџџџџPMR 16џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPb%FPb%FDџџџџFRS 1џџџџџџџP‡%FP‡%FDџџџџFRS 2џџџџџџџP&FP&FDџџџџFRS 3џџџџџџџP7&FP7&FDџџџџFRS 4џџџџџџџPb&FPb&FDџџџџFRS 5џџџџџџџP‡&FP‡&FDџџџџFRS 6џџџџџџџP'FP'FDџџџџFRS 7џџџџџџџPbuFPbuFDџџџџFRS 8џџџџџџџP‡uFP‡uFDџџџџFRS 9џџџџџџџPvFPvFDџџџџFRS 10џџџџџџP7vFP7vFDџџџџFRS 11џџџџџџPbvFPbvFDџџџџFRS 12џџџџџџP‡vFP‡vFDџџџџFRS 13џџџџџџPwFPwFDџџџџFRS 14џџџџџџP%FP%FDџџџџFRS 15џџџџџџu%Fu%FDџџџџFRS 16џџџџџџ&F&FDџџџџFRS 17џџџџџџ%&F%&FDџџџџFRS 18џџџџџџP&FP&FDџџџџFRS 19џџџџџџu&Fu&FDџџџџFRS 20џџџџџџ'F'FDџџџџFRS 21џџџџџџ%'F%'FDџџџџFRS 22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџu0Cu0CџџџџLPD 01џџџџџџ1C1CџџџџLPD 02џџџџџџ%1C%1CџџџџLPD 03џџџџџџP1CP1CџџџџLPD 04џџџџџџu1Cu1CџџџџLPD 05џџџџџџ2C2CџџџџLPD 06џџџџџџ%2C%2CџџџџLPD 07џџџџџџP2CP2CџџџџLPD 08џџџџџџu2Cu2CџџџџLPD 09џџџџџџ3C3CџџџџLPD 10џџџџџџ%3C%3CџџџџLPD 11џџџџџџP3CP3CџџџџLPD 12џџџџџџu3Cu3CџџџџLPD 13џџџџџџ4C4CџџџџLPD 14џџџџџџ%4C%4CџџџџLPD 15џџџџџџP4CP4CџџџџLPD 16џџџџџџu4Cu4CџџџџLPD 17џџџџџџ5C5CџџџџLPD 18џџџџџџ%5C%5CџџџџLPD 19џџџџџџP5CP5CџџџџLPD 20џџџџџџu5Cu5CџџџџLPD 21џџџџџџ6C6CџџџџLPD 22џџџџџџ%6C%6CџџџџLPD 23џџџџџџP6CP6CџџџџLPD 24џџџџџџu6Cu6CџџџџLPD 25џџџџџџ7C7CџџџџLPD 26џџџџџџ%7C%7CџџџџLPD 27џџџџџџP7CP7CџџџџLPD 28џџџџџџu7Cu7CџџџџLPD 29џџџџџџ8C8CџџџџLPD 30џџџџџџ%8C%8CџџџџLPD 31џџџџџџP8CP8CџџџџLPD 32џџџџџџu8Cu8CџџџџLPD 33џџџџџџ9C9CџџџџLPD 34џџџџџџ%9C%9CџџџџLPD 35џџџџџџP9CP9CџџџџLPD 36џџџџџџu9Cu9CџџџџLPD 37џџџџџџ@C@CџџџџLPD 38џџџџџџ%@C%@CџџџџLPD 39џџџџџџP@CP@CџџџџLPD 40џџџџџџu@Cu@CџџџџLPD 41џџџџџџACACџџџџLPD 42џџџџџџ%AC%ACџџџџLPD 43џџџџџџPACPACџџџџLPD 44џџџџџџuACuACџџџџLPD 45џџџџџџBCBCџџџџLPD 46џџџџџџ%BC%BCџџџџLPD 47џџџџџџPBCPBCџџџџLPD 48џџџџџџuBCuBCџџџџLPD 49џџџџџџCCCCџџџџLPD 50џџџџџџ%CC%CCџџџџLPD 51џџџџџџPCCPCCџџџџLPD 52џџџџџџuCCuCCџџџџLPD 53џџџџџџDCDCџџџџLPD 54џџџџџџ%DC%DCџџџџLPD 55џџџџџџPDCPDCџџџџLPD 56џџџџџџuDCuDCџџџџLPD 57џџџџџџECECџџџџLPD 58џџџџџџ%EC%ECџџџџLPD 59џџџџџџPECPECџџџџLPD 60џџџџџџuECuECџџџџLPD 61џџџџџџFCFCџџџџLPD 62џџџџџџ%FC%FCџџџџLPD 63џџџџџџPFCPFCџџџџLPD 64џџџџџџuFCuFCџџџџLPD 65џџџџџџGCGCџџџџLPD 66џџџџџџ%GC%GCџџџџLPD 67џџџџџџPGCPGCџџџџLPD 68џџџџџџuGCuGCџџџџLPD 69џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%`D%`DДДDџџџџKEN 1џџџџџџџu“`Du“`DuuDџџџџKEN 2џџџџџџџ%1`D%1`D  DџџџџKEN 3џџџџџџџuh`Duh`DDџџџџKEN 4џџџџџџџuC`DuC`DЄЄDџџџџKEN 5џџџџџџџu`Du`DЮЮDџџџџKEN 6џџџџџџџ%`D%`DљљDџџџџKEN 7џџџџџџџ%V`D%V`DVVDџџџџKEN 8џџџџџџџ%`D%`D00DџџџџKEN 9џџџџџџџu“`Du“`DUUDџџџџKEN 10џџџџџџ%1`D%1`D||DџџџџKEN 11џџџџџџuh`Duh`D99DџџџџKEN 12џџџџџџuC`DuC`DDџџџџKEN 13џџџџџџu`Du`DDџџџџKEN 14џџџџџџ%V`D%V`DDџџџџKEN 15џџџџџџ%`D%`D''DџџџџKEN 16џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPb%FPb%FџџџџGMRS 1џџџџџџP‡%FP‡%FџџџџGMRS 2џџџџџџP&FP&FџџџџGMRS 3џџџџџџP7&FP7&FџџџџGMRS 4џџџџџџPb&FPb&FџџџџGMRS 5џџџџџџP‡&FP‡&FџџџџGMRS 6џџџџџџP'FP'FџџџџGMRS 7џџџџџџPbuFPbuFDџџџџGMRS 8џџџџџџP‡uFP‡uFDџџџџGMRS 9џџџџџџPvFPvFDџџџџGMRS 10џџџџџP7vFP7vFDџџџџGMRS 11џџџџџPbvFPbvFDџџџџGMRS 12џџџџџP‡vFP‡vFDџџџџGMRS 13џџџџџPwFPwFDџџџџGMRS 14џџџџџP%FP%FџџџџGMRS 15џџџџџu%Fu%FџџџџGMRS 16џџџџџ&F&FџџџџGMRS 17џџџџџ%&F%&FџџџџGMRS 18џџџџџP&FP&FџџџџGMRS 19џџџџџu&Fu&FџџџџGMRS 20џџџџџ'F'FџџџџGMRS 21џџџџџ%'F%'FџџџџGMRS 22џџџџџP%FPuFџџџџGMRS 550/15Ru%FuuFџџџџGMRS 575/16R&FvFџџџџGMRS 600/17R%&F%vFџџџџGMRS 625/18RP&FPvFџџџџGMRS 650/19Ru&FuvFџџџџGMRS 675/20R'FwFџџџџGMRS 700/21R%'F%wFџџџџGMRS 725/22Rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  DџџџџMURS 1џџџџџџ€€DџџџџMURS 2џџџџџџ@@DџџџџMURS 3џџџџџџpEpEџџџџBlue DotџџџџFFџџџџGreen Dotџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџjџџџџџџџџџџџр џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГЩдБ1џџџџџџџџГЩдБ2џџџџџџџџГЩдБ3џџџџџџџџГЩдБ4џџџџџџџџГЩдБ5џџџџџџџџГЩдБ6џџџџџџџџГЩдБ7џџџџџџџџГЩдБ8џџџџџџ џџГЩдБ9џџџџџџџџГЩдБ10џџџџџџџГЩдБ11џџџџџџџГЩдБ12џџџџџџџГЩдБ13џџџџџџџГЩдБ14џџџџџџџГЩдБ15џџџџџџџГЩдБ16џџџџџџџГЩдБ17џџџџџџџГЩдБ18џџџџџ џџГЩдБ19џџџџџџџГЩдБ20џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџJMџџГœњ1}џџџџџJџџГœњ2tџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџГЩдБ19џџџџџџџГЩдБ20џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџMarifoon џџџџPMR Dorus џџџџPMR џџџџFRS џџџџLPD џџџџKENWOOD џџџџGMRS џџџџMURS џџџџZONE 9 џџџџZONE 10 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Welcome џџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџUV-17ProGPSџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjE3UHJvR1BTIiwgInZlbmRvciI6ICJCYW9mZW5nIiwgIm1vZGVsIjogIlVWLTE3UHJvR1BTIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDIzMTEwOCJ9chirp-20240224/tests/images/Icom_IC-V80.img0000644000175000017500000000745514551723752017004 0ustar hibbyhibbyHq №‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџ№‡  џџџџќџџHq ўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ @†Є џџџџџџџџџџџџ@†Є  џџџџџџџџџџџџ32540001џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJJQ1Y4MFJhZGlvIiwgInZlbmRvciI6ICJJY29tIiwgIm1vZGVsIjogIklDLVY4MCIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogInB5M2RldiJ9chirp-20240224/tests/images/QYT_KT-8R.img0000644000175000017500000004023114411666130016505 0ustar hibbyhibby%F%F%V$%V$%5%5%C%Cџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%C%Cџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Model:KT-8R  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ& 000000. z  *4>HT_juKT-8R MCB264  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000MCB264000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJ2ZW5kb3IiOiAiUVlUIiwgIm1vZGVsIjogIktULThSIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMDEwMTQiLCAicmNsYXNzIjogIktUOFIiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Yaesu_FT-8900.img0000644000175000017500000003471114411666130017226 0ustar hibbyhibbyAH008$$F’ Р0@€@&А!"`zЊ)@ P G  Р# €P D  @€@P FhР0@€@џџџџџџџџџџџџџџџџџџџџџџdN$йџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)@ P D Р# €P 0 @€@P џџџџџџџџџџџџџџџџ)@ P D Р# €P 0 @€@P D Р0 @€@0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)@ P D Р# €P 0 @€@P D Р0 @€@0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)@ P D Р# €P 0 @€@P D Р0 @€@0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)@ P D Р# €P 0 @€@P D Р0 @€@0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)@ P D Р# €P 0 @€@P D Р0 @€@0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)@ P D Р# €P 0 @€@P D Р0 @€@0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDFР“G&Р’F!€и“G  Р“„Ag @€@DFР’Fh $$$$ф$0 @€@0 @€@@5$$dЄd$„H7$$dЄd$„E’$$dЄd$“D  $$dЄd$FD$$$$ф$0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@0 @€@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџПchirp-20240224/tests/images/Kenwood_TM-D710G_CloneMode.img0000644000175000017500000027667114411666130021641 0ustar hibbyhibbyџџџџџџџџџџџџџџџ000џџџџџџ54121џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF9999E999џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDTMF-009џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKC7MOF џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgg €‰D•Р' РЕJ §Cо9@KLD•Р' РЕJ §Cо9@KL€d=Feb 2020 €‰22Ты Ты ЃсЃс„з„з›;2Ты Ты ЃсЃс„з„з›;Џ/m|Mџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ gg €‰D•Р' РЕJ §Cо9@KLD•Р' РЕJ §Cо9@KL€d=12/2019џ €‰22Ты Ты ЃсЃс„з„з›;2Ты Ты ЃсЃс„з„з›;Џ/m|MџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSgg €‰D•Р' РЕJ §Cо9@KLD•Р' РЕJ §Cо9@KLцшIA:TNCџџџџџџџџџџџџџ€‰22Ты Ты ЃсЃс„з„з›;2Ты Ты ЃсЃс„з„з›;Џ/m|M  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџzg' €‰D•Р' РЕJ §Cо9@KLD•Р' РЕJ §Cо9@KLцшIXBANDџџџџџџџџџџџџџ€‰22Ты Ты ЃсЃс„з„з›;2Ты Ты ЃсЃс„з„з›;Џ/m|M  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџg €‰D•Р' РЕJ §Cо9@KLD•Р' РЕJ §Cо9@KLцшIPM 4џџџџџџџџџџџџџџ€‰22Ты Ты ЃсЃс„з„з›;2Ты Ты ЃсЃс„з„з›;Џ/m|M  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџg €‰D•Р' РЕJ §Cо9@KLD•Р' РЕJ §Cо9@KLцшIPM 5џџџџџџџџџџџџџџ€‰22Ты Ты ЃсЃс„з„з›;2Ты Ты ЃсЃс„з„з›;Џ/m|M  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSSџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚І‚ Р' 0аІ‚Р' plЇ‚Р' АЈ‚ Р' КЇ€ ѓЈ‚Р' PЉ‚Р' №Ћ‚ Р' 0ВЋ‚Р' €uЌраЏР‚ЏЎ­А П‚ Р' @aП‚ Р' @aП‚ Р' @aП€ КЇ‚ Р' ЙЂ Р' рvО‚Р' @вС‚Р' €nТ‚ Р' 0oЫ PІК Р{Х Р' fЦР' fЦР' €PЧР' ‚І‚Р' РьЧР' аVЈ‚Р' @%Щ РЗЛ рЋЪњЪ HЫ@–Ы`sЩ№3ІР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€9ЖР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџА&Ѓ №ТЃ Є pћЄ IЅ А—Ѕ ахЅ 0#Ў  Џ p7› 0_Є џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџшІB@KLЈ?:@KLа%Y @KL щY @KL щY€ Јо^ @KLРЄg@KLPЊw @KLј@„@KLH… @KL€k• №ћl @KLH0T @KL03€У3а†4p 6Ра6_+`",Ах,Љ- // Ђ„@KLhœO@KLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрiР' Рkž‚Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРo[@KL€}@KL№PА Ў ј+Џ ЈhЎ PЪЎ  Џ HяЏ P•Ђ ˜}Є ј`Л џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРЗЛ Р' €k• џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWF7WџџџџPTOWNVџџSKAGITџџBLAINEџџFKSOOSџџVIC-1џџџISAQUAџџVIC-2џџџDUNCBCџџOA-1BKџџOA-2BKџџOA-3BKџџOA-4BKџџOA-5BKџџMTCON1џџCARLSBџџSTRIPEџџST-OOSџџFORKS1џџVIC-3џџџFRIDAYџџSNOHOMџџSEATTLџџSIMP1џџџARCџџџџџBELHAMџџWHIDBYџџQNALT1џџFORKS2џџVIC-4џџџSALTBCџџQNALT2џџSIMP2џџџNCALL1џџOA-2џџџџOA-4џџџџOA-3џџџџOA-5џџџџOA-1џџџџQNALT3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџST-INPTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDIGI-1џџDIGI-2џџDIGI-3џџDIGI-4џџDIGI-5џџDIGI-6џџDIGI-7џџDIGI-8џџDIGI-9џџAPRS-1џџAPRS-2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџREV-XBNDX-BANDџџKO6IџџџџBLYNџџџџBLYOOSџџW7PSE1џџCCRPTRџџMTCON2џџVIC-5џџџVIC-6џџџNCALL2џџANACORџџW7PSE2џџOA-1UџџџOA-2UџџџOA-3UџџџOA-4UџџџOA-5UџџџOA1UBKџџOA2UBKџџOA3UBKџџOA4UBKџџOA5UBKџџK6MBYџџџWHIDB2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџScan0LџџScan0HџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSCAN9LOWSCAN9HIGWX 1 WX 2 WX 3 WX 4 WX 5 WX 6 WX 7 WX 8 WX 9 WX 10 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџARES StdџџџџџџџџARES TNCџџџџџџџџCROSS BANDџџџџџџDefaultџџџџџџџџџDefaultџџџџџџџџџARES Standard Channel Layout џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ33џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOCALL\Kџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ TEMP*ALL,QST,CQ,KWD‚000Fxџџџџџџџџџџџџџџџџџџџџџџџџџџ ыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8NOCALLNOCALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOCALL\Kџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ TEMP*ALL,QST,CQ,KWD‚000Fxџџџџџџџџџџџџџџџџџџџџџџџџџџ ыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8NOCALLNOCALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOCALL\Kџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ TEMP*ALL,QST,CQ,KWD‚000Fxџџџџџџџџџџџџџџџџџџџџџџџџџџ ыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8NOCALLNOCALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOCALL\Kџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ TEMP*ALL,QST,CQ,KWD‚000Fxџџџџџџџџџџџџџџџџџџџџџџџџџџ ыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8NOCALLNOCALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOCALL\Kџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ TEMP*ALL,QST,CQ,KWD‚000Fxџџџџџџџџџџџџџџџџџџџџџџџџџџ ыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8NOCALLNOCALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOCALL\Kџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ TEMP*ALL,QST,CQ,KWD‚000Fxџџџџџџџџџџџџџџџџџџџџџџџџџџ ыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ8NOCALLNOCALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџVE7CRP-7Network Node (569CRP)ЕџџџџABaъщџџџџaъeџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџР№x ўў€РРРРР€ўўўў€РРРРР€РР€РРРР€€РРРЈйx €€РРРРР€€РРРРРР€РРРР€РРјјРРР@РРРРрј<јРќќ ј№ќќ №јœ №Р€€€€€РРџџpљœŒŒŒЬџџџџџџpљœŒŒŒЬџџџџџџџџ№Р€€€€€РР>џС€€€€€Сџ>џР€€€Рџџџџџџџџ€€€~№€№~Рј??јРџџ?ћр€џџƒƒƒƒƒ€РСƒƒ†Юќxрр `Р€РР€р`р€№№рр РР` `РРРР` @џџ |ўƒƒў|џџџџ€№|/# #/|№€џџўќ^џЁЁЁПŸ|ў“žџџ|ў“žŽ1ётџџ?џР€€Рџ??џР€€џџџџџџџџPA_EOCџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiS2Vud29vZCIsICJtb2RlbCI6ICJUTS1ENzEwR19DbG9uZU1vZGUiLCAiY2hpcnBfdmVyc2lvbiI6ICIwLjMuMGRldiIsICJyY2xhc3MiOiAiS2Vud29vZFRNRDcxMEdSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/QYT_KT8900D.img0000644000175000017500000004000014551723752016646 0ustar hibbyhibby%f%f%f%f%D%D%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџшХ    џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџшшшш WELCOME KT-8900Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2 VC2002  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000VC2002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000chirp-20240224/tests/images/Radioddity_GA-510.img0000644000175000017500000001626114411666130020117 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%!E%!EЕЕ%2E%2E““%CE%CEUU%TE%TEъъ%eE%eEˆˆ%vE%vEr r %‡E%‡E%˜E%˜E%F%F33%"F%"F;; %3F%3FPP %DF%DFxx %UF%UFЫЫ %"@%"@ %tC%tCu™Gu™GP…P…uuP'P'…C…CWWџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJyY2xhc3MiOiAiUmFkaW9kZGl0eUdBNTEwUmFkaW8iLCAidmVuZG9yIjogIlJhZGlvZGRpdHkiLCAibW9kZWwiOiAiR0EtNTEwIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYifQ==chirp-20240224/tests/images/Wouxun_KG-UV8E.img0000644000175000017500000010026514430171343017560 0ustar hibbyhibbyннннннннннннннннŸЉ<ннннннннннннннннннннннннннннOБ€ŒЙ†OБ€ŒЙ†мbZtbZtЯ… fЯ… fнннннРЭў`OБ€ нннннннннннннŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ$$џџџџџџџџ444444444445566bZџџџнннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн &5AMWgv…–ЉЗСУ_nv~†ŽœннннннннннннннннннннннннннннннннннннннннннннннннРЭў`OБ€ нннннннннннннˆˆˆ‡ŒŒ‘‘“‘kaнннннннннннннннн2;>AACEB@>>==?Эў`нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн"2?KXbu}‹–БК_nv~†Ž–ŒŒŒŒŒŒŒ†††€„„’нннннннннннннннн0(&&*2:BJPX]ds’OБ€нннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннWOUXUNSVИЃНЈЪЁWOШЊжнЪаИЃ01000001UV8E(3TX)V1.01н20160722ннKG-UV8TннннннннннннннннннннннннннннннннннннннннннннннннннннннcdЧШ+,ѓєWXЛМ ƒ„чннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнннннннн•З-їјјјјјјјјјјјјјјјјннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннAaron - N3MBH <000000000000№№2• џџнннннннннннннннЩШqƒшннннннннннннннннннннннннннннннннннннннннннннннннПЯШqннннннннннннннннннннннннннннннннннннннннннннннннџџџџџџџџџџџџџџџџЃМHЋ]hƒшƒш1BЊB4ЂЁ„Ю„ЮGІ8­ЇXƒшƒшRІ№˜Ў‘И„Ю„ЮAЄEЋц „Ю„Ю бџЃ3ЊдА„Ю„ЮOV9`SШ`ƒшƒш бџV5xSФx…&…&‘8р6pпLƒшƒш‘3н{8ми‡‡Б3рБ|с›м„ЮёџЃn(ЋHƒƒ ёџЅ/`Ќа€ƒƒ‘Oр6pпLƒш Б3рqс[hƒшƒш ёџЋŽ<Ѓэƒшƒш ёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџп’`п’`Б4пœ$пœ$Б2лн(лн(Б4UАUА ёџTщpTщp ёџЈŠРЈŠР ёџЈžH §( Б4џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџнрШміh„|„| ёџЎtlІгL„љ„љ БMр$мп:| БAрН4сЇ” ёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєlєl бџѕщ ѕщ бџєЯрєЯр бџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЫ ­lРƒшƒш ‘RџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџД4џџџџ бџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјџџџџ бџїЭ€џџџџ бџїъЬџџџџ бџїзDџџџџ бџїсџџџџ бџїєџџџџ бџїўTџџџџ бџіЈˆџџџџ бџій\џџџџ бџіЯ˜џџџџ бџї1@џџџџ бџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчЈАчЈА аџчР чР аџчзчз аџыкшыкш бџыц ыц 3СаЌСаЌ3СкpСкp бџСф4Сф4 бџСэјСэј бџСїМСїМ бџТ€Т€ бџТ DТ D бџЩqЬЩqЬ бџЩ{Щ{ бџЩ…TЩ…T бџЩЩ бџ٘м٘м бџЩЂ ЩЂ  бџЩЌdЩЌd бџСۘСۘ бџСе\Се\ бџСп Сп бџСшфСшф бџСђЈСђЈ бџСќlСќl бџТ0Т0 бџТєТє бџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩqЬЩqЬџџџџ бџыц ыц †Ъ†ЪБAџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџMBURGHGRTWNFREDRKCACAPNCP SPGSџMOOREFLDLINDENџFRKBURGџW3CWCџW8ORSџWB8YZVџN3UHDџN3TIAџW3CWCџW3CWCџW3CWCџџџџ146.52џ146.545џ144.09џ223.5џ223.42џ446.0џ446.05џџџџWMSTR1џџџџWMSTR2џMANCHSTџSYKSVLLџџџџџџџџCSX 1џCSX 2џNSџџџџџџџOR444.2џџџџџџџџџџџџџџџџџџџџBERK-FRџџџџџџџџџџџWX1џWX2џWX3џWX4џWX5џWX6џWX7џWX8џWX9џWX10џWX11џџџџџMURS-1џMURS-2џMURS-3џMURS-4џMURS-5GMRS1GMRS2џGMRS3џGMRS4џGMRS5џGMRS6џGMRS7џFRS8џFRS9џFRS10џFRS11џFRS12џFRS13џFRS14џGMRS15џGMRS16џGMRS17џGMRS18џGMRS19џGMRS20џGMRS21џGMRS22џџџџFRS8DCSџWALMARTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJLR1VWOEVSYWRpbyIsICJ2ZW5kb3IiOiAiV291eHVuIiwgIm1vZGVsIjogIktHLVVWOEUiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Yaesu_FT-4VR.img0000644000175000017500000002077114411666130017242 0ustar hibbyhibby4123џџџџџџџџџџџџ@ he f… gEf… V… g0 s0D Y he sfU pE TP su RP g p0 q• g i@r% guqe fpfq€SpS0 h D 4fq€q€q€SpSpSpS0 h D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4D 4e @ @  P @ @  P @ @  @hef…gEf…V…g0s0DYhesfUpETPsuRPgp0q•gi@r%guqefpfq€SpS0hDfq€q€q€SpSpSpS0hDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDe ---------..------------------------------------------------------------------------------------------------------------------------------------------------------@ @  P@џchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQtNFZSIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMDAxMDciLCAicmNsYXNzIjogIllhZXN1RlQ0UmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/BTECH_GMRS-20V2.img0000644000175000017500000004024514411666130017254 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%FP‡%FP‡%FP&FP&FP7&FP7&FPb&FPb&FP‡&FP‡&FP'FP'FPbuFPbuFP‡uFP‡uFPvFPvFP7vFP7vFPbvFPbvFP‡vFP‡vFPwFPwFP%FP%Fu%Fu%F&F&F%&F%&FP&FP&Fu&Fu&F'F'F%'F%'FP%FPuFu%FuuF&FvF%&F%vFP&FPvFu&FuvF'FwF%'F%wFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШпџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBTECH GMRS-25V2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS01џџџџџџџџџџGMRS02џџџџџџџџџџGMRS03џџџџџџџџџџGMRS04џџџџџџџџџџGMRS05џџџџџџџџџџGMRS06џџџџџџџџџџGMRS07џџџџџџџџџџGMRS08џџџџџџџџџџGMRS09џџџџџџџџџџGMRS10џџџџџџџџџџGMRS11џџџџџџџџџџGMRS12џџџџџџџџџџGMRS13џџџџџџџџџџGMRS14џџџџџџџџџџGMRS15џџџџџџџџџџGMRS16џџџџџџџџџџGMRS17џџџџџџџџџџGMRS18џџџџџџџџџџGMRS19џџџџџџџџџџGMRS20џџџџџџџџџџGMRS21џџџџџџџџџџGMRS22џџџџџџџџџџREPT15џџџџџџџџџџREPT16џџџџџџџџџџREPT17џџџџџџџџџџREPT18џџџџџџџџџџREPT19џџџџџџџџџџREPT20џџџџџџџџџџREPT21џџџџџџџџџџREPT22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ &!#000000&!#))))))&!#))))))&!#))))))-   2 BTECH  WP4204 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000WP4204000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJ2ZW5kb3IiOiAiQlRFQ0giLCAibW9kZWwiOiAiR01SUy0yMFYyIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjAxMTUiLCAicmNsYXNzIjogIkdNUlMyMFYyIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Retevis_RT29_VHF.img0000644000175000017500000000225514411666130020053 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%e%e  0ј%f%f- - 0ј%g%gM M 0ј%h%hR R 0ј%i%iY Y 0ј%q%qŠ Š 0ј%r%r• • 0ј%s%s­ ­ 0ј%t%tЙ Й 0ј%u%uк к 0ј%…%…щ щ 0ј%–%–ѕ ѕ 0ј%% ! !0ј%%љ љ 0ј%'%'!!0ј%8%8S!S!0ј  џџ џ000џџџџџџџџџ12345џџџџџџџџџџџџџџџџџџџџџџџџџџџџ3џџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP2207јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџррррррррр€€€€€€€ѕѕѕѕѕѕѕѕѕѕѕѕѕѕѕѕ___ddddiiiiiQQQQ ########џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџdFЬ џџџџџџЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDI5X1ZIRiIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwNzAzIiwgInJjbGFzcyI6ICJSVDI5VkhGUmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/WACCOM_MINI-8900.img0000644000175000017500000004000014551723752017331 0ustar hibbyhibby%F%FџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPHPHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШџџџџџџџџџџџЧџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&!#%00000&!#%)))))-  €22880џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000M288540000000000000000000000HHTYHTY288M28854U880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000chirp-20240224/tests/images/Kenwood_TH-D72_clone_mode.img0000644000175000017500000020000014411666130021652 0ustar hibbyhibbyџџџџџџџџџџџџ000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp7› Р' РЗЛР' `  џџџРЗЛР' о9@KL€‰(}ЛР' §Cо9@KL2€_ €p€Ё€‰22€_ а„з„з›;џџџџџџџџџџџџџџџџTHaywardџџџџџџџџџџ!џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKD7LXLџџџџџџџџ џџџџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/[џџxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTEMPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ*џџџџџџџџџALL,QST,CQ,KWDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ000џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOCALLџџџџNOCALLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўџўџџџџџџџџџџџџџџџџџџџџўџџўўџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџўўўўўўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўџўџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџўўўџџџџџџџџџџџџџџўўўўўўўўџўўџўџџџџџџџџџџџџџџўўўўўўўўўўўўўџџџўџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўџџўўўўўўўўџџўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўџџџџџџўўўўџџџџџџџџџџџџўўўџџџџџџџџџџџџџџўўўџџџџџџџџџџџџџџўўўўџџџџџџџџџџџџўўўўўџџџџџџџџџџўўўўўџџџџџџџџџџўўўўўџџџџџџџџџџўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚‚џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0›š Р' p7› Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@aП‚ Р'  KР‚ Р' шыa @KL žЧР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€§П‚Р' Аюi@KL(љd@KL0ВЋ‚ Р' PЉ‚Р' x‡Y@KLв€@KL`ЧР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ žЧР' џџџџџџџџџџџџџџџџXnN Р' XШ? Р' ˆ=@ Р' x@ Р' ИВ@ Р' ш'A Р' €bA A x~ „`IM x~ €Р' Р? @Ц@ € АA €ТB №PА џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ E Р' %9 Р' РрF Р' pY< Р' а,, Р' XnN Р' ТB Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp7›Р' П‚ Р' рz{ @KL ЂМР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ KР‚ Р' €—d@KLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ зШР' ‰ШР' €PЧР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ю< „h$L  Ю< „h$L  Ю< „h$L  Ю< „h$L  Ю< €Р'  Ю< „h$L №@ Р' x$ „ ИQe и-‰„ и6Цш'A €Р' Р? €Р' xm@KLA Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€bA Р' Ћ1 Р' а2 Р' @Э* „ hК3 „0- ш0 Р' аC= Р' HП: Р' ЈЉ; Р' РрF Р' HЊ| Р' №@ Р' P“O Р' xJr@KLиУp @KL@n @KLиqC Р' рžo@KLpos@KLџџџџџџџџџџџџџџџџh‚њ@KLлn@KLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџИ›/ Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ tšР' p7›Р' xGІ‚ Р' ЇЇ€ Р'  сЇ‚ Р' џџџџџџџџџџџџџџџџ˜Љ‚ Р' `ЖЉ‚ Р' Р Њ‚Р' №Ћ‚ Р' ‹Ћ‚Р' РЗЛР' №,МР' ЂМР' џџџџџџџџџџџџџџџџ€ŒНР' ` Т‚ Р' ЈyЦР' ‰Ш Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџИвЅ‚@KLАїІ‚@KLјпЈ‚ @KL‹Ћ‚@KLрИФ@KLˆХ‚ @KLhЎЩ‚ @KLЪ‚ @KLЪB @KL№ЃЮ‚ @KLшШЯB @KL*а‚ @KLџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџш'A Dрт) ш'A €ˆ=@ €hК3 @Р' Р? €Р? €8Ёw @рLB €0б  Р' АLъ „ ptѓ АLъ €8\D €ШЛE @? D№Џ8 №UG $Аo| ИВ@ €!!Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ О „$$€f в… €((X‰ €џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”ш€ Џю€ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXnN € %9 €џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџИJ{ Р' ТB Р' XnN Р' чC Р'  !D Р' ащK Р' Pš9 Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ E Р' ЈЉ; Р' @ф; Р' %9 Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`іE Р' Р:8 Р' №@ Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ E Р' @ф; Р' pёv Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(8 Р' HП: Р' ЈЉ; Р' ащK Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџР:8 Р' Р:8 Р' И_9 Р' Pš9 Р' J Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPš9 Р' Р:8 Р' J Р' и< Р' hбD Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџИ_9 Р' XG Р' hбD Р' и< Р' И_9 Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPš9 Р' (8 Р' Xu8 Р' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрНD ˆE (ІF №H hГI рђP иR €yR (лR а43J%^7bC `+:[Hc9T @&.X/W!AU] џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKG7V-9џџџџ /A=000055џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/0| И ћ/Uџ­щщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџNB7O-11џџџ /A=001479out n aboutџџџџџџџџџџџџџџџџџџџџџџџ-)H v2ф ћ/kџУщщџџџџaъџџџџџWA2WAџџџџKOPEAKџџџџџџџџџџџџџџџW7KJ-9џџџџ   146.520MHzџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/рz%( ћ/ka ]щщџџџџaъџџџџџBALDIџџџџSNOPASџџџџџџџџџџџџџџџNETџџџџџџџ Network Node ()џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџABщщџџџџaъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWA7NWP-9џџ   http://www.nwaprs.infoџџџџџџџџџџџџџџџџџџџџџ/)Ф"zˆћ/>ABщщџџџџaъџџџџџSOMTNџџџџSNOPASџџџџџџџџџџџџџџџSNOVALџџџџ   CN97DL/w1 Fill-In North Bend W7RTYџџџџџџџџ/Ьy+Ќ&ћ/-џџџџџABщщџџџџaъџџџџџSNOPASџџџџџџџџџџџџџџџџџџџџџџџџKD7ITS-11џ 1%TT3+EVERETT, WAџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/5ЬzШћ/>џ2 •щщџџџџaъџџџџџWW7RAџџџџSNOPASџџџџџџџџџџџџџџџNG7Nџџџџџџ  p000P000h60b10182.DsVPџџџџџџџџџџџџџџџџџџџџџ/'шz€ ћ/_џџџџџAB)ІЦ'<џџџџN7QNMџџџџW7PFR-1џџџџџџџџџџџџџџK7FZOџџџџџ :€446.525MHz Toff Simplex - k7fzo@arrl.netџџџ/(#y(шћ/;џџџџџABщщџџџџaъџџџџџSNOPASџџџџџџџџџџџџџџџџџџџџџџџџW7RAKџџџџџ  Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ. l{H&ћ/k#щщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџWB7AYU-1џџ  / Marine - Home Port Ballard, WA {UIV32N}џџ/'@z,ћ/sџџџџџABщщџџџџaъџџџџџSOMTNџџџџџџџџџџџџџџџџџџџџџџџџџTWOODSџџџџ kd7isz testing new firmware 54746џџџџџџџџџџ.-иz ћ/#џџџџџABщщџџџџaъџџџџџW7PFR-1џџSOMTNџџџџџџџџџџџџџџџџBETHALџџџџ W2,WAn,Bethal-N7HHUџџџџџџџџџџџџџџџџџџџџџџџџ.*`"yћS#џџџџџABщщџџџџaъџ5730YAKIMAџџџCLEELMџџџџџџџџџџџџџџџRODDHUџџџџ  $13.8V 30C VA7YLW a OCARC digi near Grand џ1 рv$ ћ/#џџџџџABщщџџџџaъџџџџџMISIONџџџCLEELMџџџџџџџџџџџџџџџN6NBN-7џџџ  PN6NBN__Mobileџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/%Ф zАћ/vzщщџџџџaъџџџџџVCAPHџџџџSOMTNџџџџџџџџџџџџџџџџKOPEAKџџџџ W2,WAn,KOPEAK WA7RWџџџџџџџџџџџџџџџџџџџџџџџџ.Ш{ €%ћS#џџџџџABщщџџџџaъџ5660SNOPASџџџџџџџџџџџџџџџџџџџџџџџџNN7Uџџџџџџ  Chuck, Ft. Clatsop Rd. AstoriaџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџABщщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџAC7KPџџџџџ  WinAPRS 2.5.1 -WAPIEEATONVIL-251-<530>џџџџџ.6Œ#z ћ/_џџџџџAB#0000SOMTNџџџџџџџџџџџџџџџџџџџџџџџџџHAM4X4џџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/Lz„ћ/jі щщџџџџaъџџџџџBALDIџџџџSNOPASџџџџџџџџџџџџџџџW7NW-8џџџџ TinyTrak3 v1.1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/04!zДћ/>џч8jщщџџџџaъџџџџџERINBџџџџџџџџџџџџџџџџџџџџџџџџџMEGLERџџџџ 94_PHG5768/W2,WAn,Chinook WIDE-KB7ADOџџџџџџџџ.@{5l ћS#џџџџџABщщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџBALDIџџџџџ  h00b00000T2WXџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/ y2дћ/_џџџџџABaъ\7830SOMTNџџџџџџџџџџџџџџџџџџџџџџџџџKC0EVP-9џџ 0 440.450MHzџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ-Јz*јћ/k%­щщџџџџaъџџџџџLARCHџџџџSNOPASџџџџџџџџџџџџџџџCLEELMџџџџ /W2,WAn,Cle Elum W7HNHџџџџџџџџџџџџџџџџџџџџџџ/ Œ x:ДћS#џџџџџABщщџџџџaъџ5830џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSSADDLџџџџ  &KK7DS viscous digi and igate - South Saddlџ- X{(#ћ/#џџџџџABщщџџџџaъџџџџџSOMTNџџџџџџџџџџџџџџџџџџџџџџџџџK7WJV-9џџџ  441.625MHzџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/ Ќ&y:Аћ/kцщщџџџџaъџџџџџSOMTNџџџџџџџџџџџџџџџџџџџџџџџџџN7QOB-8џџџ  Jeff D710 Mobile 442.300/Rџџџџџџџџџџџџџџџџџ/$T z Ф ћ\K щщџџџџaъџџџџџKE7ARH-5џW7PFR-1џџџџџџџџџџџџџџN7FWZ-1џџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/$Œ#z4!ћ/v'щщџџџџaъџџџџџVCAPHџџџџSOMTNџџџџџџџџџџџџџџџџSOMTNџџџџџ .W2,WAn South Mtn KB7UVCџџџџџџџџџџџџџџџџџџџџ/а{„ћS#џџџџџABщщџџџџaъџ2860џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKE6WHN-2џџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/lzxћ/>­щщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџVE7BX-9џџџ Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ1z%Рћ/k.ABщщџџџџaъџџџџџVE7RNA-10SOMTNџџџџџџџџџџџџџџџџVSOMTNџџџџ 0W2,WAn VSOMTN 144.350MHz @ 9600Baud KB7UVCџ/Ш{ˆћS#џџџџџABщщџџџџaъџ2860BALDIџџџџџџџџџџџџџџџџџџџџџџџџџK7DU-7џџџџ  $џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/($zH ћ/kџ„ ABщщџџџџaъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSKAGITџџџџ  ;OpenWRT digined - n7ipb@wetnet.netџџџџџџџџџ0єzPћS#џџџџџABщщџџџџaъџ4466ERINBџџџџVCAPHџџџџџџџџџџџџџџџџN7TQZџџџџџ   WinAPRS 2.5.1 -WAPIETACOMA -251-<630>џџџџ/Јzаћ/_џџџџџAB%™ (0000SOMTNџџџџSNOPASџџџџџџџџџџџџџџџN7GME-1џџџ 1 >George's RAM diesel 1 tonџџџџџџџџџџџџџџџџџ/lz$єћ/kД}щщџџџџaъџџџџџSOMTNџџџџSNOPASџџџџџџџџџџџџџџџWZ5I-7џџџџ  147.300MHz + T88џџџџџџџџџџџџџџџџџџџџџџџџџџџ/z$ћ/jVщщџџџџaъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKC8IKWџџџџ  146.520MHzџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/ px5 ћ/u7BщщџџџџaъџџџџџCLEELMџџџџџџџџџџџџџџџџџџџџџџџџK1OQ-10џџџ  |!%&8'\|!wb9!|3џџџџџџџџџџџџџџџџџџџџџџџџџџџџ-(№#z!@ћ/>SKщщџџџџaъџџџџџLARCHџџџџSNOPASџџџџџџџџџџџџџџџVCAPHџџџџџ ,VCAPH/UCAPH (K7OFT-1) 144.39/440.80 1k2/9kџ/$T$zрћU#џџџџџABщщџџџџaъџ7660KOPEAKџџџSNOPASџџџџџџџџџџџџџџџKC7TDG-9џџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/<zћ/jV –щщџџџџaъџџџџџW7PFR-1џџSOMTNџџџџџџџџџџџџџџџџKC7RAS-8џџ ! h36b10437OTW1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/$Œ z ћ/_џџџџџABaъ2Х($џџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџKC7OHYџџџџ NO FIX 14.0V 21C****** Live from MEGA WACHџ/„zЌ ћ/sџОABщщџџџџaъџџџџџSOMTNџџџџџџџџџџџџџџџџџџџџџџџџџW9BFP-2џџџ  :A=000450Test Re-installed Sys.џџџџџџџџџџџџџ/4Ќ z `"ћ/-џџџџџ‰щщџџџџaъџ3260WW7RAџџџџSOMTNџџџџџџџџџџџџџџџџN7AAM-9џџџ & џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ- xz.` ћ/j ХщщџџџџaъџџџџџSSADDLџџџSOMTNџџџџџџџџџџџџџџџџKG6JNY-14џ 7 truckin in circlesџџџџџџџџџџџџџџџџџџџџџџџџџ.:lwДћ/uZwщщџџџџaъџџџџџMISIONџџџCLEELMџџџџџџџџџџџџџџџN7SI-9џџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/&ќ!z,@ћџџџ+ABщщџџџџaъџџџџџERINBџџџџџџџџџџџџџџџџџџџџџџџџџKC7DX-10џџ   00.0V 79F CNT00012 џџџџџџџџџџџџџџџџџџџџџџџ- Ьz;ћ/-џџџџџABщщџџџџaъџџџџџSSADDLџџџSOMTNџџџџџџџџџџџџџџџџKC7YRS-10џ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/#˜zћ/jcщщџџџџaъџџџџџN7QNMџџџџSOMTNџџџџџџџџџџџџџџџџERINBџџџџџ  W2,WAn-N OIDARHILL K7IDXџџџџџџџџџџџџџџџџџџџ/(z7 ћS_џџџџџABщщџџџџaъџџџџџVCAPHџџџџW7PFR-1џџџџџџџџџџџџџџKE7EZJ-14џ ) TRUCKINGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ- Мz(8ћ/uD8щщџџџџaъџџџџџSSADDLџџџSOMTNџџџџџџџџџџџџџџџџOLYџџџџџџџ W2,WAn Tumwater Hill Olympia W7SIXџџџџџџџџџ/”z6ћS#џџџџџABщщџџџџaъџ5660SOMTNџџџџџџџџџџџџџџџџџџџџџџџџџW7AUWџџџџџ LinuxXastir1.9.7 IGATE/145.63 AUW-2џџџџџџџџ.:`"{3%ћ/xџџџџџABщщџџџџaъџ7250KOPEAKџџџSNOPASџџџџџџџџџџџџџџџMSVLџџџџџџ / WA7HYD Marysville FIll Inџџџџџџџџџџџџџџџџџ0dz ћ/#џџџџџABщщџџџџaъџџџџџERINBџџџџџџџџџџџџџџџџџџџџџџџџџSNOPASџџџџ 22,WAn-n,Snoqualmie Pass KC7JLUџџџџџџџџџџџџџ/yРћS#џџџџџABщщџџџџaъџ4540џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKR7W-7џџџџ  146.520MHz Now QRT Enroute from Summitџџџџџ/y-` ћ/[ѕђщщџџџџaъџџџџџSNOVALџџџSNOPASџџџџџџџџџџџџџџџASTRWXџџџџ 4 p000P000h..b10169.U21hџџџџџџџџџџџџџџџџџџџџџ.{5˜ћ/_џџџџџAB(p Й'џџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџKD7YTJ-14џ  ./A=000833 11.8V HDOP00.8 SATS09uot on the џ.дx#`"ћ/kџVўщщџџџџaъџџџџџYAKIMAџџџCLEELMџџџџџџџџџџџџџџџKD7MQM-1џџ  : p000P000h90b10356South Kennwick ele.1400 fџ. Pwˆћ/_џџџџџABTt(ZџџџџWA2WAџџџџSNOPASџџџџџџџџџџџџџџџETIGERџџџџ  147080t103.5 ETIGER Mnt W7GLBџџџџџџџџџџџџџџ/И y8а ћS#џџџџџABщщџџџџaъџ6730џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAD7AB-9џџџ  TM-D700A at conference.џџџџџџџџџџџџџџџџџџџџ/ ˜zћ/>љTщщџџџџaъџџџџџBALDIџџџџSNOPASџџџџџџџџџџџџџџџKE7WKM-9џџ &џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ-z48ћ/vџЏABщщџџџџaъџџџџџSSADDLџџџSNOPASџџџџџџџџџџџџџџџKB7QWZ-7џџ  MONITOR 146.520џџџџџџџџџџџџџџџџџџџџџџџџџџџџ-%ќ{Мћ/v(qщщџџџџaъџџџџџSSADDLџџџSOMTNџџџџџџџџџџџџџџџџMISIONџџџџ 'W2,WAn,Mission Ridge-WR7ADXџџџџџџџџџџџџџџџџ/0xићS#џџџџџABщщџџџџaъџ6860YAKIMAџџџSNOPASџџџџџџџџџџџџџџџW7OOF-9џџџ   The Husky Hamџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/.xzФ"ћ/k€щщџџџџaъџџџџџSNOVALџџџSNOPASџџџџџџџџџџџџџџџN7QXO-9џџџ  3W2,WAN,VANCOUVERџџџџџџџџџџџџџџџџџџџџџџџџџџџ-:( z;%ћS#џџџџџABщщџџџџaъџ7650KOPEAKџџџSNOPASџџџџџџџџџџџџџџџKC7VQD-2џџ ;312218 WIDE1-1 HOME DIGIџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџABщщџџџџaъџџџџџSOMTNџџџџџџџџџџџџџџџџџџџџџџџџџN7RIG-5џџџ UI-View32 V2.03џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџABщщџџџџaъџџџџџWW7RAџџџџSOMTNџџџџџџџџџџџџџџџџW7PFR-1џџџ  W2,WAn,Pack Forest - W7PFRџџџџџџџџџџџџџџџџџ.2tzˆћS#џџџџџABщщџџџџaъџ5660SOMTNџџџџџџџџџџџџџџџџџџџџџџџџџN7QXO-14џџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ-*z!И ћ/vbщщџџџџaъџџџџџLARCHџџџџSNOPASџџџџџџџџџџџџџџџNG7N-2џџџџ  WX - Magnolia Bluff (AS437)џџџџџџџџџџџџџџџџ/'шzф ћ/-ABщщџџџџaъџџџџџBALDIџџџџSNOPASџџџџџџџџџџџџџџџUSEAџџџџџџ  USEA - Seattle,WA WIDE N7FSPџџџџџџџџџџџџџџџ/ 4zdћ/#ABщщџџџџaъџџџџџBALDIџџџџџџџџџџџџџџџџџџџџџџџџџW7PKTџџџџџ  7 DXalert 145.73 w7pkt.net7300џџџџџџџџџџџџџџџ/@z Мћ/-ABщщџџџџaъџџџџџBALDIџџџџSNOPASџџџџџџџџџџџџџџџW7RTY-1џџџ PKCSO SAR VANџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/y-€%ћ\v^†щщџџџџaъџџџџџN7QNMџџџџW7PFR-1џџџџџџџџџџџџџџN7GMEџџџџџ N7GME/R NONE/D DISABL/BџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAB"=(OџџџџW7PFR-1џџSOMTNџџџџџџџџџџџџџџџџDGDAVEџџџџ >DIGI_NED: digipeater W7AUW in S.E. Hoquiaџ.:t{4АћD#џџџџџABщщџџџџaъџ7350KOPEAKџџџSNOPASџџџџџџџџџџџџџџџN7URW-8џџџ )џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/ z ћYYщщџџџџaъџџџџџBALDIџџџџSNOPASџџџџџџџџџџџџџџџWB7VLW-7џџ  Ralph's mobileџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/  z”ћ/>‚щщџџџџaъџџџџџSOMTNџџџџSNOPASџџџџџџџџџџџџџџџW7AUX-9џџџ 1SHORELINE FIRE "COMM 61" 442.825 MHz 103.џџџџџџџџџџџџџџџџџџABщщџџџџaъџџџџџWW7RAџџџџERINBџџџџџџџџџџџџџџџџHAM4X2џџџџ  de K7MCRџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/#H y6` ћ/>’0щщџџџџaъџџџџџPRESTNџџџBALDIџџџџџџџџџџџџџџџџN7OFWџџџџџ ) 010222 drnichol@msn.comџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAB#-џџџџLARCHџџџџSNOPASџџџџџџџџџџџџџџџWB7OR-14џџ  Enroute from MT to Sumner WA 146.52џџџџџџџџ/ (#zєћ/uС щщџџџџaъџџџџџW7PKTџџџџSOMTNџџџџџџџџџџџџџџџџALAKESџџџџ 5 h35b10173T2WXџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ,9ьvєћ/_џџџџџABaъ @Н'#џџџџYAKIMAџџџCLEELMџџџџџџџџџџџџџџџKA7IJU-12џ .PMT-RTGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ.$x"` ћ/>Z4їщщџџџџaъџџџџџYAKIMAџџџCLEELMџџџџџџџџџџџџџџџTIGERџџџџџ  .K7NWS WA TIGER MTN APRSџџџџџџџџџџџџџџџџџџџџ/Py;LћN#џџџџџABщщџџџџaъџ3860KOPEAKџџџSNOPASџџџџџџџџџџџџџџџWW7RAџџџџџ  ' >WW7RA Digi & Remote Wx Staџџџџџџџџџџџџџџџџ/ `"z0”ћ/_џџџџџABщщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџN9VW-7џџџџ  Happy Trailsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/(Аz  ћ\KX€щщџџџџaъџџџџџVCAPHџџџџSOMTNџџџџџџџџџџџџџџџџSEDROџџџџџ  OpenWRT digined - kg7hq@arrl.netџџџџџџџџџџџ0Аz ћS#џџџџџABщщџџџџaъџ5470SKAGITџџџERINBџџџџџџџџџџџџџџџџWA7RW-9џџџ   HAVING FUNџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ.*${;@ћ/ky!ўџџџщщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџK2SARџџџџџ 7122024 monitoring 441.700 103.5џџџџџџџџџџџџ.;dz.,ћ/-џџџџџABщщџџџџaъџ2000KOPEAKџџџSNOPASџџџџџџџџџџџџџџџK7PAL-9џџџ  444.700 103.5 QAџџџџџџџџџџџџџџџџџџџџџџџџџџџ/&рz`"ћ/kЧ%щщџџџџaъџџџџџWW7RAџџџџSOMTNџџџџџџџџџџџџџџџџKC7ILKџџџџ  9@KC7ILK/R WIDE1-1/D KC7ILK-1/Bџџџџџџџџџџџџџџџџџџџџџџќџ џџџџџABщщџџџџaъџџџџџSSADDLџџџSNOPASџџџџџџџџџџџџџџџW7HR-9џџџџ /$Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ.5Xz9ћ/v B5щщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџAK9Eџџџџџџ  |!#&@'=|!waJ!|3џџџџџџџџџџџџџџџџџџџџџџџџџџџџ. {Xћ/kвщщџџџџaъџџџџџKOPEAKџџџSNOPASџџџџџџџџџџџџџџџSEAџџџџџџџ  SEA - Seattle, WA WIDE n7fspџџџџџџџџџџџџџџџ/ 4zdћ/#ABщщџџџџaъџџџџџSOMTNџџџџџџџџџџџџџџџџџџџџџџџџџW7JKH-9џџџ  KC4X4SAR H-1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/&ШzДћ/kd1щщџџџџaъџџџџџVCAPHџџџџSOMTNџџџџџџџџџџџџџџџџWA7BVQ-7џџ  ; џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/„z„ћ/-ABщщџџџџaъџџџџџVCAPHџџџџSNOPASџџџџџџџџџџџџџџџN7QNMџџџџџ  P000p000h54b10177џџџџџџџџџџџџџџџџџџџџџџџџџџ/%ЄzXћ/_џџџџџAB'&С'6џџџџSOMTNџџџџџџџџџџџџџџџџџџџџџџџџџBULLMTџџџџ KB7WUK OR Bull Mt Fill inџџџџџџџџџџџџџџџџџџ-z1,ћF#џџџџџABщщџџџџaъџ2667N7QXO-9џџSNOPASџџџџџџџџџџџџџџџK7TMF-9џџџ  6 444.700MHz On the move!џџџџџџџџџџџџџџџџџџџџ/ zH ћ/j щщџџџџaъџџџџџBALDIџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџsoК}{ЖВА555БЉЂ664Б­Ћ655­ІŸ653_N1479cc`dcfЃ—31-УauЄwˆ‡AuЄ8e€™Я$&%) N j J f0N0 k 00I00  d  Щџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ'chirp-20240224/tests/images/BTECH_GMRS-50X1.img0000644000175000017500000004000014411666130017245 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%FP‡%FP‡%FP&FP&FP7&FP7&FPb&FPb&FP‡&FP‡&FP'FP'FPbuFPbuFP‡uFP‡uFPvFPvFP7vFP7vFPbvFPbvFP‡vFP‡vFPwFPwFP%FP%Fu%Fu%F&F&F%&F%&FP&FP&Fu&Fu&F'F'F%'F%'FP%FPuFu%FuuF&FvF%&F%vFP&FPvFu&FuvF'FwF%'F%wFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS01џџџџџџџџџџGMRS02џџџџџџџџџџGMRS03џџџџџџџџџџGMRS04џџџџџџџџџџGMRS05џџџџџџџџџџGMRS06џџџџџџџџџџGMRS07џџџџџџџџџџGMRS08џџџџџџџџџџGMRS09џџџџџџџџџџGMRS10џџџџџџџџџџGMRS11џџџџџџџџџџGMRS12џџџџџџџџџџGMRS13џџџџџџџџџџGMRS14џџџџџџџџџџGMRS15џџџџџџџџџџGMRS16џџџџџџџџџџGMRS17џџџџџџџџџџGMRS18џџџџџџџџџџGMRS19џџџџџџџџџџGMRS20џџџџџџџџџџGMRS21џџџџџџџџџџGMRS22џџџџџџџџџџREPT15џџџџџџџџџџREPT16џџџџџџџџџџREPT17џџџџџџџџџџREPT18џџџџџџџџџџREPT19џџџџџџџџџџREPT20џџџџџџџџџџREPT21џџџџџџџџџџREPT22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџНd­ћNІhгD`ЂЧп>Нd­ћNІhгD`ЂЧп>Нd­ћNІhгDЂ`п>`$ˆіxњ†&а˜№*Ъu(Ј`$ˆіxњ†&а˜u*фЈЪ(˜Ъ$ˆіxњ†&аu``$ˆіxњ†&а˜Ъ*№u(Ј˜Ъ$ˆіxњ†&а9ф(u`Ј˜Ъ$ˆіxњ†&а9v(X`Нd­ћNІhгDЂ`п>ЧXхrџŒІ3РMgкєЫCг‡@џУŒY*ўж&ЙT­Й7Хalа4˜ќawЙT­Й8ХЫ;… †‘Љ?еk—-Учџџџџџџџџџџџџџџџџ                   џџџџџџџџџџџџџџџџ‹„ 9и|&жП­C‡‹„ 9и|&жП­C‡‹„ 9и|&ж’­ПCП}Тmсcы6G+v<П}Тmсcы+)ŸwщАqН‚џМIщ‚CщАЇqМ‚УБќWАm™FE|кUх‡vџџџџџџџџџџџџџџџџ                            џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ÿџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШпџџџџџџџџџџџџџ>џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ BTECH џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2 BTECNC1932  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000NC1932280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000chirp-20240224/tests/images/Radioddity_UV-5G.img0000644000175000017500000001477114411666130020134 0ustar hibbyhibbyЊDFpнџџџџџџџџџџџџџџџџPb%FPb%FDP‡%FP‡%FDP&FP&FDP7&FP7&FDPb&FPb&FDP‡&FP‡&FDP'FP'FDPbuFPbuFP‡uFP‡uFPvFPvF P7vFP7vF PbvFPbvF P‡vFP‡vF PwFPwF P%FP%FDu%Fu%FD&F&FD%&F%&FDP&FP&FDu&Fu&FD'F'FD%'F%'FDP%FPuFDu%FuuFD&FvFD%&F%vFDP&FPvFDu&FuvFD'F2FD%'F%wFDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP%џџџџ$џџџџu$џџџџ%$џџџџP$џџџџ%џџџџ%%џџџџPџџџџuџџџџPџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ €џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ <џџџџџџџџ <џџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS1џџџџџџџџџџџGMRS2џџџџџџџџџџџGMRS3џџџџџџџџџџџGMRS4џџџџџџџџџџџGMRS5џџџџџџџџџџџGMRS6џџџџџџџџџџџGMRS7џџџџџџџџџџџGMRS8џџџџџџџџџџџGMRS9џџџџџџџџџџџGMRS10џџџџџџџџџџGMRS11џџџџџџџџџџGMRS12џџџџџџџџџџGMRS13џџџџџџџџџџGMRS14џџџџџџџџџџGMRS15џџџџџџџџџџGMRS16џџџџџџџџџџGMRS17џџџџџџџџџџGMRS18џџџџџџџџџџGMRS19џџџџџџџџџџGMRS20џџџџџџџџџџGMRS21џџџџџџџџџџGMRS22џџџџџџџџџџREPTR1џџџџџџџџџџREPTR2џџџџџџџџџџREPTR3џџџџџџџџџџREPTR4џџџџџџџџџџREPTR5џџџџџџџџџџREPTR6џџџџџџџџџџREPTR7џџџџџџџџџџREPTR8џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOAA1џџџџџџџџџџџNOAA2џџџџџџџџџџџNOAA3џџџџџџџџџџџNOAA4џџџџџџџџџџџNOAA5џџџџџџџџџџџNOAA6џџџџџџџџџџџNOAA7џџџџџџџџџџџNOAA8џџџџџџџџџџџNOAA9џџџџџџџџџџџNOAA10џџџџџџџџџџNOAA11џџџџџџџџџџAOFENG UV-5R 151123H џџBAOFENG UV-5R HN5RV011џџџџџџџџРРППППООРТТТРПООЕЕЕЖЖЖЕДГГЕГГџџџeeeeeeeeeeeeeeeeiiiiiiiiiiiiiџџџLLLKKKKKKJJJJJJJMMMMMMMMMMMMMџџџџџџџџ?џџџџџ?0 <џџpsv}‡Ђ1 џ€6t џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџUV-5G џchirpюimgeyJ2ZW5kb3IiOiAiUmFkaW9kZGl0eSIsICJtb2RlbCI6ICJVVi01RyIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Icom_ID-31A.img0000644000175000017500000025240014411666130016733 0ustar hibbyhibbyWРш €€ф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ H ш €€ф ‡FtP @ @ _ш €€ф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ ˜ €Pф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ џџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯџџџџџў0РРџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџ@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ CALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGNCALLSIGN џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџИ 3@ €LK@3@ € 2Р@ €‡Ћ" @ €‰€3@ €Є†@@ € Р€@ €9оLK@@ €2Љј€@ €џџџџџџџџџџџџџџџџџCQCQCQ CQCQCQ џџ NEџџџџџџџ  CQCQCQ NEџџџ9оLK@@ €CQCQCQ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџџџўўўўўўўўўў—_Ш+ „џџџџџџџџџњNEџџџ API31,DSTAR*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/[/b/>/-џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Retevis_RT23.img0000644000175000017500000001000014551723752017336 0ustar hibbyhibbyP31183џџџџџџџџџџ e eџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP`P`џџџџџP@P@џџџџџnNHРџ-------џ`@@Hџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‰џџџџџџџџџџџџџџU5FџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШШШУЙУУЭЭУУУУУУУУ_ZZUKUUUUPFKPPPAKџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЇЈџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Vertex_Standard_FTL-2011.img0000644000175000017500000000111514411666130021324 0ustar hibbyhibbyP!@ L@џ )$%RF  %QpEp C$$T0H0 ETPHP ITH 'RpFp QPEP #R0F0 aVV PUU P0P0 RRhumbeluiagrМџchirpюimgeyJ2ZW5kb3IiOiAiVmVydGV4IFN0YW5kYXJkIiwgIm1vZGVsIjogIkZUTC0yMDExIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAxOTA1MjQiLCAicmNsYXNzIjogImZ0bDIwMTEiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/BTECH_GMRS-V1.img0000644000175000017500000002001014411666130017075 0ustar hibbyhibbyPb%FPb%FP‡%FP‡%FP&FP&FP7&FP7&FPb&FPb&FP‡&FP‡&FP'FP'FP%FP%FDu%Fu%FD&F&FD%&F%&FDP&FP&FDu&Fu&FD'F'FD%'F%'FDP%FPuFDu%FuuFD&FvF%&F%vFDP&FPvFDu&FuvFD'FwFD%'F%wFDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFANGXIAODONGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŸpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ FM 65-75Mn FM 76-108MџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS01џџџџџџџџџџGMRS02џџџџџџџџџџGMRS03џџџџџџџџџџGMRS04џџџџџџџџџџGMRS05џџџџџџџџџџGMRS06џџџџџџџџџџGMRS07џџџџџџџџџџGMRS15џџџџџџџџџџGMRS16џџџџџџџџџџGMRS17џџџџџџџџџџGMRS18џџџџџџџџџџGMRS19џџџџџџџџџџGMRS20џџџџџџџџџџGMRS21џџџџџџџџџџGMRS22џџџџџџџџџџREPT15џџџџџџџџџџREPT16џџџџџџџџџџREPT17џџџџџџџџџџREPT18џџџџџџџџџџREPT19џџџџџџџџџџREPT20џџџџџџџџџџREPT21џџџџџџџџџџREPT22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ140902N WELCOME US32411USG2411џџssssssssssttuuvvrrrrqqpoonnnnдедeeeeeeeeeeeeeeeeiiiiiiiiiiiii‚stNNNNNNNNNOOOPPQQEFHJKJIIIIIIIŒŽ/ <џpsv}‡  *4>HT_ju џ€0y џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ123456BF9166Њ0y нchirp-20240224/tests/images/Retevis_RB17A.img0000644000175000017500000000164514411666130017426 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%FžžџџP‡%FP‡%FЄЄјP&FP&FљљџџP7&FP7&F&&џџPb&FPb&FUUџџP‡&FP‡&F……џџP'FP'FЖЖџџPbuFPbuFЃ Ѓ џџP‡uFP‡uF  џџPvFPvF' ' џџP7vFP7vF) ) џџPbvFPbvF+ + џџP‡vFP‡vF5 5 џџPwFPwFN N џџP%FP%FЮЮџџu%Fu%FуЁуЁџџ  џџ џ000џџџџџџџџџ12345џџџџџџџџџџџџџџџџџџџџџџџџџџџџ3џџџџџџџџ џџџџџ?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP3207sјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&F&Fк к џџ%&F%&FљљџџP&FP&FЃ Ѓ џџu&Fu&F†!†!џџ'F'FйЁйЁџџ%'F%'FUUџџP%FPuFUUџџu%FuuFUUџџ&FvFUUџџ%&F%vFUUџџP&FPvFUUџџu&FuvFUUџџ'FwFUUџџ%'F%wFUUџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjE3QSIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/QYT_KT7900D.img0000644000175000017500000004000014551723752016645 0ustar hibbyhibby%f%f%PP$%PP$%5%5%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ш9  џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџ WELCOME KT-7900Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2 VC4004  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000VC4004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000chirp-20240224/tests/images/Jetstream_JT270MH.img0000644000175000017500000002000014411666130020144 0ustar hibbyhibbyuџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЁџџџџџєЂџџџџџєџџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№ЊџџџџџєŠ‰Ÿџџџџѕџџџџџџџ№џџџџџџџ№?џџџџџѓ?џџџџџѓџџџџџџџџ™™џџ C$џџџџџџџџџџџџџџџџџ`@DC C$џLeixenџLX-‰……џџџџџџџџџcџџџ2џьѓђ‡D#7e№ќг <у3а ШШ 0Mc\В’аЁADJі`џџ њPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPO №№APRO ТjBC Lock ТBeep  CHASave 3DTMF Т @@@DW @@@DecType C  DecCode SEncType c EncCode s @@@FM ƒ@@@FM SCAN FM SQL №FM DW Font .RKeyLock   Keypad 'Lamp NameSYS   NameCHA в NamEdit #@@@OpenDIS Р6Р@P1 Long "№!№P1Short "TP2 Long !№!№P2Short !TP3 Long #№!№P3Short #TPower Т€Р@PTT ID Т €€€PTT SET oRoger ЦReverse Ѓ  RPT SET RPTType SaveBat SCAN “  SCNMode †  SCANADD Т SQL  Step ЦPd№Tail Т Talk Г  TOT † >TxStop @@@Vox ‚ Vox D 0:№Vox S VXB ЦWIDNAR Т  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ OFF ON OFF 10M 20M 30M 40M 50M 1H1.5H 2H 4H 6H 8H 10H 12H 14H 16HNarrWide OFF KeyCont Low MidHighHigh K+S PTT KEY ALL CO TO DC FMMONIMOLO SQMMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 5K6K25 10K12K5 25K ALLTimeUser SYS 1S 2S 3S 4S OFF 10S 20S 30S 40S 50S 60S 70S 80S 90S100S110S120SSING-RPT+RPT OFF CTCNDCSIDCSSMAL BIG DC FMBANDTIMEMOLOMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 2K5 5K6K25 10K12K5 25K OFFCompScraTXScRXScA!=B A=BџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџUSER џџџџџџџџ JET STREAM Waiting Debug Day CHA- Menu ( ) Vol Call Reset ? ALL RES FUN RES CHA DEL Send Error TX Stop KeyLock SEND Welcome DC џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ``џџџўАќ``џџџўАќ џџџўАќ џџџўАќ@@џџџўАќ@@џџџўАќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџ NameA01 џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Radioddity_R2.img0000644000175000017500000000223514411666130017604 0ustar hibbyhibbyu“aDu“aDџџџџuџџџ%`D%`Dџџџџuu`u`Du`Dџџџџu%1`%1`D%1`DџџџџuuC`uC`DuC`Dџџџџu%V`%V`D%V`Dџџџџuuh`uh`Duh`Dџџџџu%`%`D%`Dџџџџuu“`u“`Du“`Dџџџџu%a%aD%aDџџџџuuauaDuaDџџџџu%1a%1aD%1aDџџџџuuCauCaDuCaDџџџџu%Va%VaD%VaDџџџџuuhauhaDuhaDџџџџu%a%aD%aDџџџџuu“au“aDu“aDџџџџuџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹џџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџR2 џchirpюimgeyJ2ZW5kb3IiOiAiUmFkaW9kZGl0eSIsICJtb2RlbCI6ICJSMiIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJSYWRpb2RkaXR5UjJSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Feidaxin_FD-288B.img0000644000175000017500000000400014551723752017667 0ustar hibbyhibbyџюLџџџџџџџџџџџџџ`D`DџџџџћџџџPDPUDџџџџњџџџ%D%bDџџњџџџP7DP7fDџџџџњџџџPDPiDџџџџњџџџu$DutDџџ0њџџџu(DuxDџџ5 њџџџP7DP‡Dџџњџџџu7Du‡DџџњџџџP9DP‰Dџџ0њџџџDD”Dџџ%њџџџuDDu”Dџџ0њџџџPGDP—Dџџ0њџџџPHDP˜Dџџ0њџџџuHDu˜Dџџ0њџџџuHDu˜DџџњџџџID™DџџњџџџuIDu™DџџrњџџџPFDPFDџџџџњџџџ‘DADџџњџџџPb%FPb%FџџџџњџџџP‡%FP‡%FџџџџњџџџP&FP&FџџџџњџџџP7&FP7&FџџџџњџџџPb&FPb&FџџџџњџџџP‡&FP‡&FџџџџњџџџP'FP'FџџџџњџџџPbuFPbuFџџџџњџџџP‡uFP‡uFџџџџњџџџPvFPvFџџџџњџџџP7vFP7vFџџџџњџџџPbvFPbvFџџџџњџџџP‡vFP‡vFџџџџњџџџPwFPwFџџџџњџџџP%FP%Fџџџџњџџџu%Fu%Fџџџџњџџџ&F&Fџџџџњџџџ%&F%&FџџџџњџџџP&FP&Fџџџџњџџџu&Fu&Fџџџџњџџџ'F'Fџџџџњџџџ%'F%'FџџџџњџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџяЎџџџџџџџџџџџ@F џџџџџџџџџџџџchirp-20240224/tests/images/BTECH_UV-25X4.img0000644000175000017500000004000014551723752017045 0ustar hibbyhibby%f%f%PP$%PP$%5%5%D%D%f%f%@`Eџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   Ѕ  џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџ џџџџ WELCOME UV-25X4 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2 UV25X4UC4014  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000UC4014000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000chirp-20240224/tests/images/Talkpod_A36plus_8w.img0000644000175000017500000013240514564102745020507 0ustar hibbyhibbyPb%FPb%FDџџџџGMRS01џџџџџџP‡%FP‡%FDџџџџGMRS02џџџџџџP&FP&FDџџџџGMRS03џџџџџџP7&FP7&FDџџџџGMRS04џџџџџџPb&FPb&FDџџџџGMRS05џџџџџџP‡&FP‡&FuuDџџџџGMRS06џџџџџџP'FP'FuuDџџџџGMRS07џџџџџџPbuFPbuFuuDџџџџGMRS08џџџџџџP‡uFP‡uFuuDџџџџGMRS09џџџџџџPvFPvFuuDџџџџGMRS10џџџџџџP7vFP7vFuuDџџџџGMRS11џџџџџџPbvFPbvFuuDџџџџGMRS12џџџџџџP‡vFP‡vFuuDџџџџGMRS13џџџџџџPwFPwFuuDџџџџGMRS14џџџџџџP%FP%FuuDџџџџGMRS15џџџџџџu%Fu%FuuDџџџџGMRS16џџџџџџ&F&FuuDџџџџGMRS17џџџџџџ%&F%&FuuDџџџџGMRS18џџџџџџP&FP&FuuDџџџџGMRS19џџџџџџu&Fu&FuuDџџџџGMRS20џџџџџџ'F'FuuDџџџџGMRS21џџџџџџ%'F%'FuuDџџџџGMRS22џџџџџџP%FPuFžžџџџџRPT-15џџџџџџu%FuuFžžџџџџRPT-16џџџџџџ&FvFžžџџџџRPT-17џџџџџџ%&F%vFžžџџџџRPT-18џџџџџџP&FPvFžžџџџџRPT-19џџџџџџu&FuvFžžџџџџRPT-20џџџџџџ'FwFžžџџџџRPT-21џџџџџџ%'F%wFžžџџџџRPT-22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџзк џџџџџџџџџ џџџџџџџџџ(й џџџџџџџџџ џџџџџџџџџ(й џџџџџџџџџ џџџџџџџџџ(йџџџџџџџџџ џџџџџџџџџЈІџџџџџџџџџџџџџџџџџџ№џџџџџџџџџџџџџџџџџџ№џџџџџџџџџџџџџџџџџЪ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџTіџ Йџ lџ Йџ N#џ Йџ lџ Йџ lџ џџџџџџџџџџPЩџ џџџџџџџџџџіМџ џџџџџџџџџџPЩџ џџџџџџџџџџіМџ џџџџџџџџџџPЩџ џџџџџџџџџџіМџ џџџџџџџџџџPЩџ џџџџџџџџџџіМџ џџџџџџџџџџPЩџ џџџџџџџџv7џ џџџџџџџџџџџџџџm?џ џџџџџџџџџџџџџџЫJџ џџџџџџџџџџџџџџm?џ џџџџџџџџџџџџџџЫJџ џџџџџџџџџџџџџџm?џ џџџџџџџџџџџџџџЫJџ џџџџџџџџџџџџџџm?џ џџџџџџџџџџџџџџЫJџ џџџџџџџџџџџџџџm?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJBMzZwbHVzOHdSYWRpbyIsICJ2ZW5kb3IiOiAiVGFsa3BvZCIsICJtb2RlbCI6ICJBMzZwbHVzXzh3IiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDI0MDExMSJ9chirp-20240224/tests/images/Yaesu_FT-60.img0000644000175000017500000006771114411666130017061 0ustar hibbyhibbyAH017$ FV  ...ТAЊ FV ""@  P Фbh!dP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFR  P@  P FP dP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚EC  ‚E7 ƒG1 ‚Fe# ‚E!  ‚F…  ‚Fq ‚E ‚Fp ƒG0 ‚Fw ƒG ‚F€ ‚E9 ƒG9 ‚Fv ‚F‚ ‚Fˆ  ‚E  ‚E% ‚Ft  ƒG"  ‚EG  ‚E €FR €FU €FX €GB €GE €GH 0P 0P 0P  Q‚ € Qˆ € Q” €€TW €T` ƒTQ$ .f€Qƒ$ .€TQ$ .0P 0P 0P 0P 0P 0P ƒ„CQdƒ„CbQdƒ„D'QdƒBPd0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P €bU €„bW €b` €„bb €be €„bg €bp €„br 0P 0P  DbV € ФbX € Dba € Фbc € Dbf € Фbh € Dbq € DgV Œ€ ФgX Œ€ Dga Œ€ Фgc Œ€ Dgf Œ€ Фgh Œ€ Dgq Œ€0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P 0P  $€€  $€€"€€ €€ €€ €€  €€  €€€€ €€ €€  €€ $€€€€€€€€   $€€€€ €€   €€ €€ €€ €€  €€€€€€€€€€€€€€$$$$$$$$$$$$$$$$$$1€€1€€1€€1€€1€€ €€ €€ €€$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ ! €€ $€€ $€€ $$€€$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$€€€€€€€€ €€€€€€€€$$$$$$$$$$$$€€€€€€€€€€€€€€$$€€ $$€€$€€$€€$€€$€€$€€$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџjchirp-20240224/tests/images/TYT_TH-350.img0000644000175000017500000001031114411666130016517 0ustar hibbyhibbyTH350 Radio Program data v1.08%@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€eDPggAџ@…DPџџџџIџ€“DTЧTЧHџ€“DHџ€“Drџ€“D џ€“Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%•Fџџџџџ%UCџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЏЏЏЏЏЏЏЏЏЏЏЏЏЏЏџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ4шT€ DD џђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHKT511џџ"џ  $џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`@@G 'џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџгяуцъцєЊX[^a`caZџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџылеаулсуgaSOKIMWщтлноумн\_]QYVTLџchirpюimgeyJ2ZW5kb3IiOiAiVFlUIiwgIm1vZGVsIjogIlRILTM1MCIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJUaDM1MFJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Baojie_BJ-9900.img0000644000175000017500000001436114411666130017313 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџо{џџџнŒЬџџРISSAOSџоzџџџнЦџџРISSџџџџоy џџџнŽРџџРIR0ISSџоx&џџџнКџџРISSџџџџоw,џџџнДџџРISSLOSџнгџџџнгџџ@FDVHFџџ%Ђџџџ—ЦТџџ@RU0AVEџ*„џџџ’›„џџ@RU1VRxџ*„џџџ’›„џџ@RU1BLџџ4Hџџџ’ЅHџџ@RU2BLџџ4Hџџџ—п,Д@RU2VRџџ9*џџџ’Њ*џџ@RU2ABLџ> џџџ’Џ џџ@RU3VIxџBюџџџ’Гюџџ@RU3aTVџGаџџџ’Иаџџ@RU4BLџџGаџџџ’ИаД@RU4PDџџLВџџџ’НВџџ@RU4aVIџ[Xџџџ’ЬXџџ@RU6VEџџ`:џџџ’б:џџ@RU6aTVџiўџџџ’кўџџ@RU7aBLџnрџџџ’прЄ@RU8PDџџxЄџџџ’щЄџџ@RU9PDџџxЄџџџ’щЄџџ@RU9VEџџ}†џџџ’ю†Д@RU9aBLџ•№џџџ“№џџ@RU12VIџЄ–џџџ“–џџ@RU13aTVаˆџџџ˜qЈџџ@RUVRџџџ’ џџџ”zu@RU17TVџ’Ьџџџ”ƒЬџџ@RU18BLџ’Ьџџџ”ƒЬu@RU18BLџ’§,џџџŒ,Д@RU11TVџ“ вџџџšвџџ@RU12aRO“ZџџџЎZџџ@RU14aVI“)џџџИџџ@RU15aVIџџџџџџџџџџџџџџџџџџџџџџџ Рџџџ—Срџџ@RUPDџџџаˆџџџ˜qЈџџ@RUVRџџџ•sџџџ•sД@TBLџџџџ’ џџџ”zu@LNKNAZџџџџџџџџџџџџџџџџџџџџџџџџ”œ6џџџџџџџџџ@LNKNAZџџџџџџџџџџџџџџџџџџџџџџџџ”лАџџџ”лАџџ@DIR100џ”я8џџџ”я8џџ@DIR150џ•Рџџџ•Рџџ@DIR200џ•*џџџ•*џџ@DIR2625•Pрџџџ•Pрџџ@VOLO400•э џџџ•э џџ@LPDџџџџ•*џџџ•*џџ@DIRPDU1–6^џџџ–6^џџ@DIR9875‚hџџџ’ѓhД@RU10џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”лАџџџ”лАџџ@DIR-VEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘ыМџџџ‘ыМџџ@FDUHFџџоRџџџџB@тџџџџџџџџџџџџџџџџџџџџџџџ”р’џџџџB@тџџџџџџџџџџџџџџџџџџџџџџџ8жdџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWELCOME IU3BRKЁО@ ŽbZыЎ@chirp-20240224/tests/images/TYT_TH-7800.img0000644000175000017500000017742014411666130016625 0ustar hibbyhibbyTH9800џџV14xџџџџ@@#РvџџџџџџџџџџCC#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџџџџџџџџџ#Рvџџџџџџџџџџ@@#Рџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ d d#ШСџџVSST1џџџff#@џџVSEND1џџtt#РџџVSST2џџџvv#РџџVSEND2џџBB#РџџVHFS1џџџyy#РџџVHFE1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ``#Рџџџџџџџџџџpp#Рџџџџџџџџџџ``#Рџџџџџџџџџџ€€#Рџџџџџџџџџџ€h€t0#РŒџџџџџџџџџџ""#Рvџџџџџџџџџџ55#Р vџџџџџџџџџџ%sD%sD#РFvџџџџџџџџџџuu#Рvџџџџџџџџџџ q w0#РŒџџџџџџџџџџ%”D%DD#РLPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ…џџ€ ˆф 3#џџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџyќџ№џ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2T-S01џџ 2 џџ‘ A$yжOUџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2T-01џџџ‘ A$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF џџџР]h)P-œ1А6Ф;f™Ÿ0Ї7{PРџ` №0pА €№џџџџћ000ў00 @080908&:$p@+l§џsД§w$џrBѕЩўѕж]СIџьџџ Z џ‚’„…*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTH9800џџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџ€•9@@@5•™9@ Q@Hџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/BTECH_UV-50X2.img0000644000175000017500000004025514560403070017041 0ustar hibbyhibby%f%f%v%v%D%D%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  Шп  џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџ WELCOME UV-50X2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####џџџџџџџџ####;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2 UV50X2UC2M12  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000UC2M12000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjUwWDIiLCAidmVuZG9yIjogIkJURUNIIiwgIm1vZGVsIjogIlVWLTUwWDIiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Icom_ID-51.img0000644000175000017500000037550014411666130016643 0ustar hibbyhibby^ь ƒ€фMayDay ‡FtP @ @ d‚ ƒ€фPAE ATIS ‡FtP @ @ c ƒ€фPAE Clnc ‡FtP @ @ _( ƒ€фPAE Gnd ‡FtP @ @ ]ш ƒ€фPAE TwrE ‡FtP @ @ gо ƒ€фPAE TwrW ‡FtP @ @ dd ƒ€фSEA AppN ‡FtP @ @ cЮ ƒ€фBFI ATIS ‡FtP @ @ gp ƒ€фBFI Clnc ‡FtP @ @ _< ƒ€фBFI Gnd ‡FtP @ @ ^8 ƒ€фBFI Twr ‡FtP @ @ \0 ƒ€фSEA ATIS ‡FtP @ @ d ƒ€фSEA Clnc ‡FtP @ @ c ƒ€фSEA RmpN ‡FtP @ @ _‡ ƒ€фSEA RmpS ‡FtP @ @ _ ƒ€фSEA Gnd ‡FtP @ @ ]Ќ ƒ€фSEA TwrE ‡FtP @ @ ^~ ƒ€фSEA TwrW ‡FtP @ @ ] ƒ€фSEA App ‡FtP @ @ b\ ƒ€фSEA Dep ‡FtP @ @ bд ƒ€фSEA DepS ‡FtP @ @ ]д ƒ€фSEA DepW ‡FtP @ @ ^ ƒ€фSEA DepN ‡FtP @ @ c. ƒ€фRNT ATIS ‡FtP @ @ _ ƒ€фRNT Gnd ‡FtP @ @ al ƒ€фRNT Twr ‡FtP @ @ `T ƒ€фAcuWings ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ |Gx €фWsp-Air ‡FtP @ @ yM0фEvrt PD ‡FtP @ @ x €фEvrt FD ‡FtP @ @ yM0фSnoCom ‡FtP @ @ |YM0фSnoShf-E ‡FtP @ @ |M0фSnoShf-N ‡FtP @ @ |bM0фSnoShf-S ‡FtP @ @ y€a€фWsp-1F04 ‡FtP @ @ ya€фWsp-1F11 ‡FtP @ @ ya€фWsp-1F19 ‡FtP @ @ xфa€фWsp-1F31 ‡FtP @ @ yŒ0РфWsp-2F03 ‡FtP @ @ xи0РфWsp-2F07 ‡FtP @ @ yt €фWsp-2F12 ‡FtP @ @ y> €фWsp-2F22 ‡FtP @ @ xъ €фWsp-5F02 ‡FtP @ @ xиUPфWsp-5F07 ‡FtP @ @ yТ €фWsp-5F14 ‡FtP @ @ y›Y`фWsp-7F13 ‡FtP @ @ y Y`фWsp-7F17 ‡FtP @ @ y}Y`фWsp-7F18 ‡FtP @ @ xчY`фWsp-7F20 ‡FtP @ @ xъ<№фWsp-8F02 ‡FtP @ @ xе<№фWsp-8F15 ‡FtP @ @ xл €фWsp-8F16 ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ q^x4афN7HDH V ‡FtP @ @ qbxI фKF7JC V ‡FtP @ @ qfxAфW7JCR V ‡FtP @ @ qnxM0фN7UQA V ‡FtP @ @ qrxY`фN7QHX V ‡FtP @ @ qvx4афWR7JM V ‡FtP @ @ qzxM0фWA7NAN V ‡FtP @ @ q‚xI фW7UDI V ‡FtP @ @ q†x4афKC7IYE V ‡FtP @ @ qŠx†фK7NWS V ‡FtP @ @ q’xUPфWC7AAO V ‡FtP @ @ q–x4афKJ7YL V ‡FtP @ @ qžx†фAB7Y V ‡FtP @ @ qЊx4афAA7UJ V ‡FtP @ @ rd €фSmpx-1 V ‡FtP @ @ rx €фCallingV ‡FtP @ @ rŒx4афWW7RA-eV ‡FtP @ @ rx4афKB7CNN V ‡FtP @ @ rœxeф4W7FHZ V ‡FtP @ @ rЄx4афK7SKW V ‡FtP @ @ rЈx4афWA7FW V ‡FtP @ @ rЌx4афK7CHN-eV ‡FtP @ @ rДx4афK7LED V ‡FtP @ @ rМxM0фW7AVM V ‡FtP @ @ rРx €фK7PF V ‡FtP @ @ rФx4афW7SRZ V ‡FtP @ @ rШxI фWB7VYA V ‡FtP @ @ rЬx4афK7HW V ‡FtP @ @ rаx4афW7VHY V ‡FtP @ @ rдx0РфK7MMI V ‡FtP @ @ rиx4афW7DX V ‡FtP @ @ rмx4афW7TED V ‡FtP @ @ rрx4афWA7FW V ‡FtP @ @ rшx4афW7WWI V ‡FtP @ @ rьx4афWA7NAN V ‡FtP @ @ rјx]pфW7IAG V ‡FtP @ @ rќx4афWA7LAW V ‡FtP @ @ sxI фK7PP V ‡FtP @ @ sx €фK7OI V ‡FtP @ @ sx4афW7DK V ‡FtP @ @ sx €фK6RFK-eV ‡FtP @ @ s( €фSmpx2 V ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ Wуш4аPфKA7PMC U ‡FtP @ @ Wэш4аPфWR7HE U ‡FtP @ @ Wќш4аPфKC7ONX U ‡FtP @ @ XGш4аPфN6OBY U ‡FtP @ @ XLш €PфNV7P U ‡FtP @ @ X[ш €PфW7ACS U ‡FtP @ @ X’ш4аPфKC7MAP U ‡FtP @ @ XœшePфK7AAE U ‡FtP @ @ XЁшI PфWB0CZA U ‡FtP @ @ XІшI PфKD7BQH U ‡FtP @ @ XПш0РPфN7XOJ U ‡FtP @ @ Xгш4аPфW7NTF U ‡FtP @ @ Xиш4аPфNT7H U ‡FtP @ @ Xчш0РPфKB7TBF U ‡FtP @ @ Xћш4аPфN7PL U ‡FtP @ @ Y(шY`PфW7AW U ‡FtP @ @ Y2шЂ€PфN6TJQ U ‡FtP @ @ Y7ш4аPфNB7RZZ U ‡FtP @ @ Y<ш}№PфKB7RII U ‡FtP @ @ YAш0РPфW7UVH U ‡FtP @ @ YUшePфW7WWI U ‡FtP @ @ YZшAPфKA7PMC U ‡FtP @ @ Y_ш<№PфK7NWS U ‡FtP @ @ Ydш0РPфW5RFL U ‡FtP @ @ Yiш €PфNV7P U ‡FtP @ @ Ynш4аPфK7LWZ U ‡FtP @ @ Yxш8рPфW7UMH U ‡FtP @ @ Y‡ш4аPфWA7NAN U ‡FtP @ @ Y‘ш0РPфK7MMI U ‡FtP @ @ Y›ш4аPфK7NP U ‡FtP @ @ YЅш4аPфW7UDI U ‡FtP @ @ YЊш4аPфKE7LE U ‡FtP @ @ YДш4аPфKG7IK U ‡FtP @ @ YШшAPфK7DNR U ‡FtP @ @ YЭш4аPфW7NTF U ‡FtP @ @ Yвш4аPфWW7RA-eU ‡FtP @ @ Yцш4аPфW7UMH U ‡FtP @ @ Y№ш4аPфN7NFY U ‡FtP @ @ Yѕш4аPфWB7AHT U ‡FtP @ @ YњшY`PфW7MYR U ‡FtP @ @ Zш4аPфWA7LZO U ‡FtP @ @ Z ш €PфN7RET U ‡FtP @ @ Zш4аPфWA7FW U ‡FtP @ @ Zш4аPфW7ERH U ‡FtP @ @ Z"ш4аPфKA7PMC U ‡FtP @ @ Z1ш4аPфN7UMO U ‡FtP @ @ Z;ш8рPфN7SNK U ‡FtP @ @ Z@ш4аPфK7PAR U ‡FtP @ @ ZEш4аPфK7MJ U ‡FtP @ @ ZTш4аPфWA7NAN U ‡FtP @ @ ZYшM0PфWR7JM U ‡FtP @ @ Z^ш4аPфKA7BZA U ‡FtP @ @ Zcш4аPфN7IO U ‡FtP @ @ ZhшI PфK7PP U ‡FtP @ @ Zmш4аPфWO7O U ‡FtP @ @ Zrш4аPфW7JPH U ‡FtP @ @ Zwш €PфNN7N U ‡FtP @ @ Zш}№PфWB7DPF U ‡FtP @ @ Z†ш4аPфW7SRZ U ‡FtP @ @ Z•ш4аPфKC7JM U ‡FtP @ @ ZšшY`PфW7ACS U ‡FtP @ @ ZŸш4аPфW6TOZ U ‡FtP @ @ ZЉш4аPфN7BTI-eU ‡FtP @ @ ZЎш4аPфW7ISX U ‡FtP @ @ ZГш4аPфW6TOZ U ‡FtP @ @ ZНш €PфN7WGR U ‡FtP @ @ ZТшM0PфWB7DPF U ‡FtP @ @ ZЧш4аPфW7UFI U ‡FtP @ @ ZЬш €PфK7NWS U ‡FtP @ @ Zбш0РPфW7FLY U ‡FtP @ @ Zлшa€PфKD7DUJ U ‡FtP @ @ Zхш4аPфKB7ZTC U ‡FtP @ @ Zъш4аPфK7SKW U ‡FtP @ @ Zєш0РPфK7BZT U ‡FtP @ @ Zўш0РPфW7GVJ U ‡FtP @ @ [ш4аPфK7HW U ‡FtP @ @ [ш0РPфK7MLR U ‡FtP @ @ [ шI PфKC7LFW U ‡FtP @ @ [шY`PфWR7JM U ‡FtP @ @ [ш<№PфN7NVP U ‡FtP @ @ [шAPфWA7WKT U ‡FtP @ @ [&ш4аPфK7OET U ‡FtP @ @ [+ш4аPфK7YR U ‡FtP @ @ [0ш4аPфWA7NAN U ‡FtP @ @ [:ш0РPфK7CH U ‡FtP @ @ [?ш4аPфW7NPC U ‡FtP @ @ [Dш4аPфWA7ZUS U ‡FtP @ @ [Iш4аPфN7KGJ U ‡FtP @ @ [NшY`PфWW7SEA U ‡FtP @ @ [Sш4аPфWA7LAW U ‡FtP @ @ []шUPPфWC7AAO U ‡FtP @ @ [bшQ@PфWA7HTJ U ‡FtP @ @ [gшM0PфN7BUW U ‡FtP @ @ [lш4аPфWA7QIH U ‡FtP @ @ [qш €PфWB7UFR U ‡FtP @ @ [vш–PPфKB7CNN U ‡FtP @ @ [{ш4аPфKJ7XE U ‡FtP @ @ [Šш4аPфK7OV U ‡FtP @ @ \H €PфSmpx-1 U ‡FtP @ @ \k €PфSmpx-2 U ‡FtP @ @ qР …фD1 V ‡FtP @ @ qЮ …фD2 V ‡FtP @ @ qbx …фK7LWH V ^ –оeyC–оeyGrœx …фWC7SO V ^ Џ Н9шCЏ Н9шGrИx …фWA7FW V ^ ЏМjшCЏМjшGrx …фNW7DR V ^ ]МJHC]МJHGq‚x …фKF7CLD V ^ —М9‘C—М9‘GrjШ …фN7JN V ^ œоTфCœоTфGq‚x …фIcom V ^ œоL„CœоL„Grx €ф ‡FtP @ @ qXx …фVE7VIC V ^ ­Нi0аC­Нi0аGrмx …фVE7RAG V ^ ­Н(1аC­Н(1аGqPx …фVA7ICM V ^ ­̘sPC­̘sPGrx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ Xˆ …PфD1 U ‡FtP @ @ \. …PфD2 U ‡FtP @ @ \ …PфD3 U ‡FtP @ @ Y–ш …PфK7TUL U ‡FtP –оЅYˆB@ %к …PфW7NPC U ‡FtP ЎоuhB@ Xш …PфNR7SS U ^ IН:hBIН:hG%z …PфW7ACS U ^ Ўо :hBЎо :hGZш …PфK7LWH U ^ –оeyB–оeyGWРш …PфKF7UUY U ^ —НZЖPB—НZЖPGXш …PфWC7SO U ^ Џ Н9шBЏ Н9шGZТш …PфWA7FW U ^ ЏМjшBЏМjшG% …PфNW7DR U ^ ]МJHB]МJHGZOш …PфK7ISQ U ^ –оM:(B–оM:(GZmш …PфKF7CLD U ^ —М9‘B—М9‘GXш …PфKF7BFS U ^ —М(даB—М(даGXш …PфKF7BFT U ^ —М(еB—М(еG%ц …PфWA7HJR U ^ ЏМ‰TBЏМ‰TG% …PфWR7KCR U ^ ЏIМИtBЏIМИtGY­ш …PфN7JN U ^ œоTфBœоTфGYЭш …PфW7JD U ^ ЎоTDBЎоTDGYзш …PфKF7NPL U ^ —МъB—МъGZ‹ш …PфIcom U ^ œоL„BœоL„Grx €ф ‡FtP @ @ YPш …PфVE7VIC U ^ ­Нi0аB­Нi0аGZhш …PфVE7RAG U ^ ­Н(1аB­Н(1аGYPш …PфVA7ICM U ^ ­̘sPB­̘sPGrx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ p€x €ф ‡FtP @ @ _ш €€ф ‡FtP @ @ p€x €ф ‡FtP @ @ s x €ф ‡FtP @ @ O№ш €€ф ‡FtP @ @ _ш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ rx €ф ‡FtP @ @ rx €ф ‡FtP @ @ WРш €€ф ‡FtP @ @ WРш €€ф ‡FtP @ @ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџјџџџџ?€Рџџџџџџџ ў@ќџџџџџџџџџџџџџџџџџџќџџџџјўџџ №Рўџџ Рџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ     џџџџџ      !"#$%&'()џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcџ   џџџџџџџ   !џ"#$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2013-0208:19:30 Aeronautical D-Star Public UHF FM VHF FM џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџиу KING-FM џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSeattle џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџqдxDЌеtCWindhoek Namibia ˜vS*E<Р[`DЕMЕ PCPretoria S-AfricaЂDS8ЬExS8 DГ…ЊQBJakarta Indonesi3SjФрEЄVI8H­-)АаBMelbourne Victoria& S‘LšEX[…шˆ­ЕzSаBBanff National PAlberta 3*аNs†8Wў\[žшˆ­ДyBCalgary Alberta 3†Nr&\Wў\С ˆ­ДšаBCalgary Alberta 2с№Nr&Wў\[™шˆ­ЕzSBCalgary Alberta 3ВNr1tWў\XVш„­Д)BEdmonton Alberta 5lЎNqaАWў\[”ш ˆ­ДЙЈBEdmonton Alberta 5{fNqQ"Wў\[ш „­ДKBSherwood Park Alberta 5hLNq.,Wў\[]ш „­Н(rаBChilliwack BC 1жNyд‚Wў \Cш „­Мz(BDelta BC 1{N{ЫWў XQш „­Н:ГBDelta BC 1$œNzдІWў X~шˆ­МI1аBKelowna BC 1ЮNwkфWў X~ш„­Ми“BSalt Spring Isl BC 0ЩTN{wВWў YPшˆ­̘sPBVancouver BC 1+ŽNzУДWў Zhшˆ­Н(1аBVancouver BC 1TФNzп*Wў YPш@­Нi0аBVictoria BC NEў qXx€­Нi0аCVictoria BC NEў [Sшˆ­Ѕx”BWinnipeg Manitoba1гNa!HWў˜Zhшˆ­=KHBSt.Johns NL /{\N4Ц WџZєшˆ­œ4BAlmonte Ontario -%јNLDЂWўд[:шˆ­8‘аBCornwall Ontario -zNJ­„Wўд[Šш„­œј’BCumberland Ontario -v†NK_ВWўдСF ˆ­y2аBHamilton Ontario +W0NOфHWўдYPш„­œYвBLanark Ontario -?HNKз WўдYZшˆ­+BLittle Current Ontario -пŽNQоWўдYŒшˆ­J•BLondon Ontario *цДNQ9:WўдСb „­zеPBMindemoya Ontario -Ћ­NR'6Wўд[ш„­ ГаBMississauga Ontario +‰њNO—JWўдСb „­ZUPBMississauga Ontario +ŠќNOИјWўдСb „­*qBMississauga Ontario +ŠќNOИјWўдСb !„­ZUPBMississauga Ontario +ŠќNOИјWўдСв "„­šRаBNewmarket Ontario ,(NOfWўд\T#„­œ‰HBNorfolk Ontario *иоNPC’WўдС"$„­œјTBOakville Ontario +mьNOЂЈWўдVD%„­œ™“BOrangeville Ontario +д NPNWўд[Šш&ˆ­œј‘аBOttawa Ontario -`hNKЁ†Wўд\T'D­œjtBOttawa Ontario -BЂNKЦвWўд[&ш(ˆ­œЪtBSimcoe County Ontario ,|КNO›‚WўдYмш-ˆ­›6BToronto Ontario +˜NOY`WўдZEш.ˆ­*BToronto (UxbridgOntario ,lNOЈWўдYОш/„­•)ДBBlainville Quebec -ЁЪNIгhWўд^}ш0D­•šЕPBBlainville Quebec (ПИN6iH™i„JtBSofia Bulgaria*„кNCŠExWR№?HŸ-„*TPBBrno Czech 1,ЮN{ŽE<WR№@HŸ-„ˆtаBPraha Czech 28N[6E<WH№ADЇIЭZгPBKrakow / ChoragwPoland 2–NмPE<СЂРBHЇIZдаBSzczecin-Kolowo Poland 5kŠN}ZE<СІРCHЇI­ZаPBWarsaw Poland 46’Nъ.E<СС D„ЅUœѕаBMoscow Russia 7N%‘PE№V™№EDŸ5„љ0аBHigh Tatras Slovakia1!8N3BE<W№FDГ5”ЙhBIstanbul Turkey (мцN(2ExСж@GHŸi•(АPBCopenhagen Denmark 7vN zЈE<Р[`HDŸ!•(rCEspoo Finland <*іNЏјExСš@ID™”КHBKongsvinger Norway N LE<SƒJD™ŒњˆBOslo Norway ;цвN œТE<SƒKDЇ-…шBTyreso Sweden ;7 N9E<qХxLHk Є;(CNicosia City Cyprus "лиN ЩExV…№MHЇY”BMt.Parnitha Greece &*0NЊмExVј№NDЇYTBMt.Ymittos Greece %нжNОњExVž№OH‡E„I–BLisbon Portugal&І6N фWW №PHІеЌIЖBMaribor Slovenia.yNŠЌE<С ЎQ„ЈнЬJШBSan Marino SM +лjN iE<V№RH‹(pаBCastellar del VaSpain )”РNіE<V™№SHŸˆ”аBVienna Austria 03ЄNQ6E<V™№TDŸ‰5аBVienna Austria 0AЌNaPE<СЊРUDŸ9„JBBoom Belgium 3NVE<WR№VDŸ9„JuBDiest Belgium 3ўN˜E<Wa№WHŸ9…Y‘аBLiege Belgium 2‰XN…pE<Vl№XDŸ9„ЩђаBLokeren Belgium 3 NE<СJРYDŸ9„ШHBVreren Belgium 2ЌкNv˜E<С ърZ„ŒЦе ˆBCourbevoie France 0Ю@NTиE<W№[H‘ ЬшBWillisau Switzerl/ДNE<РZў`\H‘ ЬˆˆCSirnach Switzerl/mNцxE<Wf№]H‘ Ь„BM.Tamaro Switzerl.ˆNЩE<СОР^H‘ ܘ0аBLa Barillette Switzerl.dЊN~E<СЊР_H‰ „HШBBerlin BE 4}‚N qЪE<WW№`H‰ „9ѓPBHAM Radio BW /ŸN v˜E<WW№aH‰ …{HBWuerzburg BY 1З>N д”E<WЛXbH‰ „˜sPBBad Soden HE 2 NNwтE<WW№cH‰ „жBDARC HQ in BaunaHE 3>ŠN d E<Q!@dˆ“IY0BPordenone F-V-G .šN fE<С С eˆ“I„и(BRoma Lazio )ПИN ЇВE<P,@fˆ“IНXPPBBari Puglia )јNЬE<P@gˆ“IЭBPalermo Sicilia &)hN ?˜E<W.шhD•A™TPAInage Chiba #›dNŒъEW*шiH•A™RAHamFair Tokyo #“bN‹КaESЮшjˆ™Uœ№аBBuenos Aires Argentin"ŽаS:ZnWџLrоxkˆ™UЌhHCRosario Argentin!S<КWџLWfшlHЁe”ИpPBAmericana Brazil ЋрS/RЦWџLqvxlHЁe”ИpPCAmericana Brazil ЋрS/RЦWџLWfшnDЁe”ЙQBAmericana Brazil еHS/hWџLqvxn„Ёe”ЙQCAmericana Brazil еHS/hWџLWЂшpHЁeЅ(tBBelo Horizonte Brazil лLS+иИWџLrиxpˆЁeЅ(tCBelo Horizonte Brazil лLS+иИWџLrЊxrHЁeЅ)аCBelo Horizonte Brazil пРS+еWџLWЂшsHЁQ”I1аBBrasilia Brazil Ю,S/Р:WџLrŠxtDЁQ”к‘CBrasilia Brazil S0WџLW шuDЁe”И2BCabreuva Brazil МšS.ОјWџLrОxvDЁe”И0PCCampinas Brazil жS.ліWџLqЂxwHЁeМI1аCCaruaru Brazil 2S#кzWџLV”шxDЁe”ИЕBJundiai Brazil 6~S.мЊWџLWБшyHЁeŒzваBNiteroi Brazil а S+$WџLrІxyHЁeŒzваCNiteroi Brazil а S+$WџLWБш{DЁeŒzгBNiteroi Brazil а S+$WџLqžx{DЁeŒzгCNiteroi Brazil а S+$WџLW №}DЁeŒ8ЕPBRio de Janeiro Brazil Ш(S+TrWџLrІx}DЁeŒ8ЕPCRio de Janeiro Brazil Ш(S+TrWџLWЌшDЁeŒXєBRio de Janeiro Brazil хbS+5 WџLrІxDЁeŒXєCRio de Janeiro Brazil хbS+5 WџLWЂшDЁeZQPBRio de Janeiro Brazil йШS+pWџLVЦш‚DЁe”КTаBS.Rita do Passa Brazil ŸиS/cŠWџLrвxƒDЁeœщєCSao Francisco deBrazil NRS2nŒWџLWЛш„DЁe”ИVPBSao Paulo Brazil P@S.\ŽWџLršx…DЁe”ИДCSao Paulo Brazil €YS.•ХWџLWБш†HЁe”КPBSao Paulo Brazil bоS.ЅŒWџLWЛш‡HЁe”КBSao Paulo Brazil Ќ:S.4МWџLqšx‡HЁe”КCSao Paulo Brazil Ќ:S.4МWџLrќx‰ˆЁe”КRCSao Paulo Brazil T.S.{ЌWџLWБшŠDЁe”КBSorocaba Brazil vJS/wаWџLsxŠ„Ёe”КCSorocaba Brazil vJS/wаWџLqJŒHЕM„(“CTalagante Chile !Ÿ`SFЫ Wџrќxˆ‘-ДjPаCCali ColombiaaюNLкWўдRќшŽ„Ё)”BWillemstad Curacao аNDЧ8Wџs†ШDГMšhCSan Salvador El Salva ЎjNY< Wў˜q„xHБ(pаCCancun Mexico ,œNVР&Wў˜qx‘HБ”š–CChihuahua Mexico X Nj оWў˜rx’DБ(tаCMexico Mexico АrNbСHWў˜s x“„‘A(qCPANAMA Panama №NO}аWўд[{ш”„seЅJ“BArima ––N=AFWџrжx•DЉ„(CGuatemala [hNZYWў˜Vb№–HЁ%ŒˆѓBDelft ZH 4pN>DE<VЈш—HЕ1•iBUpper Hutt NZL )"œSЏ! EаСж ˜D Н8ШBSheffield NOR 5bfNgђWСЎ ™D НxhBWarrington NOR 5PZN•~WW„šD М8ˆBCardiff WM 3nRN'$WYШш›ˆЏU­ 1аBClarksville AR #ndN]n Wў˜[bшœ„ЎТltBCedar Falls IA *|8N\p€Wў˜YZшˆœТ‹BCedar Rapids IA *vN[–ШWў˜s)ЦHœТ‹CCedar Rapids IA *vN[–ШWў˜\дŸD—… uPBNew London IA (уXN[RWў˜[Xш „ЎТ”)hBReinbeck IA *IђN\ŒWў˜РZо` DЎТ”)hCReinbeck IA *IђN\ŒWў˜СQ ЂˆЎцZ(BBatavia IL )Щ,NXqќWў˜sxЂˆЎцZ(CBatavia IL )Щ,NXqќWў˜Сg ЄˆЎц™ˆBCadwell IL 'ŸNXz€Wў˜qoxЄHЎц™ˆCCadwell IL 'ŸNXz€Wў˜YiшІ„ЎцЌ™BCarbondale IL %І@NY3rWў˜С- ЇˆЎцЭ$BChampaign IL (jNXDHWў˜СO ЈˆMЭ(hBChicago IL )фшNW™zWў˜С1 ЉˆЏЬњPаBChicago IL )ЯbNW“”Wў˜YУшЊ„…(ˆBDanville IL (#(NW“ЈWў˜С Ћˆ— Э №аBDuPage County IL )йфNX Wў˜Сw Ќˆ— ЬљuаBLake County IL *7(NX2Wў˜С+ ­ˆЎц„˜(BPeoria IL (ЋТNYqдWў˜q]x­HЎц„˜(CPeoria IL (ЋТNYqдWў˜rџxЏˆЎц xЈCQuincy IL 'ф4N[MvWў˜Y№шАˆ— Э(PBRolling Meadows IL * ЪNXЮWў˜Р[Б„— ЭZQCSandoval IL &RNYNWў˜С] ВˆЎц%X(BSpringfield IL 'МРNY—@Wў˜[bшГˆ]„ДBColby KS '[ТNebWў˜YiшДˆ–ТDЈBLouisburg KS &‰bN^‘dWў˜q`xДH–ТDЈCLouisburg KS &‰bN^‘dWў˜ZEшЖˆЎТl”BScott City KS &oTNdз(Wў˜sxЗ„—­ 1PCAlexandria LA 7ђN\lTWў˜rиxИ„—­YsCCarencro LA JUN\ |Wў˜sPxЙDЎжt$CCarencro LA MОN\ шWў˜sxК„—­ 1CDelhi LA kSN[s~Wў˜sxЛˆ—­аPCLeesville LA КN]AŒWў˜С’ МˆœжlˆBMinden LA NN]9”Wў˜q8єМˆœжlˆCMinden LA NN]9”Wў˜[™шОˆЎж<ˆBNew Orleans LA х~NZ ЦWў˜rЩxОHЎж<ˆCNew Orleans LA х~NZ ЦWў˜qfxРH— ­ЉVPCPineville LA KњN\fјWў˜qdxСHœж HCRuston LA …„N\ЅмWў˜YPшТˆЎжœŠШBShreveport LA xdN]ЏdWў˜s xТˆЎжœŠШCShreveport LA xdN]ЏdWў˜YPшФˆЏ­{BWest Monroe LA yN\#ШWў˜YxшХˆœТ,єBDuluth MN .ИКN\ЬWў˜ZбшЦ„–кд4BFairmont MN +“ЈN^OАWў˜rвxЦD–кд4CFairmont MN +“ЈN^OАWў˜[!шШ„— …yBGem Lake MN -XN]8Wў˜ZршЩˆЎТ”X(BLittle Falls MN -фдN^TіWў˜q^xЪD—„ЉѕPCMinneapolis MN ,цшN]=дWў˜ZmшЫ„ЎТЬ4BMinneapolis MN ,хЎN]=еWў˜ZГшЬˆЎТ ш(BMounds View MN -4N].ЬWў˜q™xЬHЎТ ш(CMounds View MN -4N].ЬWў˜ZТшЮˆЎТmŠшBRochester MN ,2N\mWў˜ZхшЯˆ—„˜2PBWanda MN ,IЂN_2мWў˜Y‘шаˆЏa„(hBColumbia MO &у N\NWў˜Zhшб„ЎТtBKansas City MO 'ѓN^‹Wў˜^ЅшвHЎТ,XЈBRolla MO %риN[ДмWў˜rЋxгDЎТ|иˆCSpringfield MO %ДN])TWў˜YУшдˆ–ТlHшBSt Louis MO &žHNZ]zWў˜rлxдˆ–ТlHшCSt Louis MO &žHNZ]zWў˜YsшжˆЏ„9ѓBColumbus NE )GЎNaQжWў˜rЯxжHЏ„9ѓCColumbus NE )GЎNaQжWў˜Yiшиˆ—„8єBOmaha NE )HЎц%YhCMuncie IN (."NUa0Wўдqœx?D–вєCErlanger KY 'NTŒйWўдС" @„Ўв%9(BLexington KY &љNTsфWўдqЄx@DЎв%9(CLexington KY &љNTsфWўдС* BˆЏЅ›VPBMiddlesboro KY $ŠќNSЙŒWўдq„xBHЏЅ›VPCMiddlesboro KY $ŠќNSЙŒWўдСТ Dˆ—ЅšбBRichmond KY %ЅцNT?ЪWўдqtE–Ц”i(AFall River MA )žnNG*Wўд_1шEH–Ц”i(BFall River MA )žnNG*WўдqœxEH–Ц”i(CFall River MA )žnNG*Wўд^ышHHЎЦ\ДBFeeding Hills MA *иNHЄіWўдqfxHHЎЦ\ДCFeeding Hills MA *иNHЄіWўд]GшJHЎЦ%:HBHolliston MA *+HNGюWўдqdxJHЎЦ%:HCHolliston MA *+HNGюWўд]ƒшLDƒŒЙhBHolyoke MA *іNHž=WўдqдMˆ— 8RCWestford MA *ŽјNGmhWўд[€шNˆ— ˜RBFrederick MD 's№NMtъWўд[шOˆ—Yœ$BGermantown MD '(–NM?ЌWўд[шP„ЎЮ…)шBSalisbury MD &T‡NKŒzWўд[шQˆЎЦ,и(BBelfast ME ,zvNE.^WўдqšxQHЎЦ,и(CBelfast ME ,zvNE.^Wўд^џшSD— ˜0аBEast BridgewaterME *ЖNG0Wўдs)S„— ˜0аCEast BridgewaterME *ЖNG0Wўдs.xUˆ— hаPCTurner ME ,:pNFBJWўдСЊ Vˆ–т%ˆ(BAuburn Hills MI *аNS5дWўдqbxVH–т%ˆ(CAuburn Hills MI *аNS5дWўдY‡шX„Ўтl(BBenton Harbor MI * NV7‚WўдС& Yˆ–т-IШBCharlotte MI *ˆNTЦRWўдqpxYH–т-IШCCharlotte MI *ˆNTЦRWўд[qш[ˆ—-ФxhBGarden City MI *OЩNSK3WўдС† \ˆ—ХpаBGaylord MI - ДNTœWўдYОш]ˆЏaФzTBGrand Rapids MI *ЌЈNU‘–Wўдsx]ˆЏaФzTCGrand Rapids MI *ЌЈNU‘–Wўд[bш_ˆЏaФzSBGreenville MI +,ЏNUNчWўдСŠ `ˆ–тd8ˆBHell MI *eєNSпzWўдsx`ˆ–тd8ˆCHell MI *eєNSпzWўдС† bˆЎтdšШBHowell MI *ˆЬNSф˜WўдqˆxbHЎтdšШCHowell MI *ˆЬNSф˜WўдСі dˆ—ԘВаBIthaca MI +?ЖNTŽNWўдrіxdˆ—ԘВаCIthaca MI +?ЖNTŽNWўдСђ fˆЎтe(hBLowell MI +œNUQИWўдС‚ gˆЏФйqаBMuskegon MI +8@NV:˜WўдqxgHЏФйqаCMuskegon MI +8@NV:˜Wўд[шiˆЎтœ‰(BOwosso MI *хФNT(WўдqxxiHЎтœ‰(COwosso MI *хФNT(WўдršxkH–т (hCPort Huron MI *ф>NRdWўдZcшlˆЎт8ЈBStutsmanville MI -uјNUlWўд]eшmD9(BDerry NH *а*NG?ђWўд]шnD— I6BEast Kingston NH *з(NFр$Wўдq˜xnD— I6CEast Kingston NH *з(NFр$Wўд\ушpDŒJШBGoffstown NH *цŽNGŠWўд_'шqD–ЦD*HBHampton NH *лОNFФ Wўдq xqD–ЦD*HCHampton NH *лОNFФ Wўд_‹шsD— X4BHudson NH *ЖаNG]РWўдqвs„— X4CHudson NH *ЖаNG]РWўдY‚шu„— yвBLondonderry NH *Х NGRШWўдs.u„— yвCLondonderry NH *Х NGRШWўдY(шw„–ЦљЈBManchester NH + NGfWўдYвшxˆœЦ JШBOssipee NH +НœNG<ДWўдrчxxˆœЦ JШCOssipee NH +НœNG<ДWўд[&шzˆ–ЦE)шBSalem NH *ЙNG6œWўдq†xzH–ЦE)шCSalem NH *ЙNG6œWўдY‚ш|„— ZбPBTwin Mountain NH ,G|NG|рWўдСщ }ˆ— •H№BAtlantic City NJ 'XдNJhіWўдСB ~ˆ— •h0аBAtlantic County NJ ']ђNJ”RWўдqЂxD— •JPCBrigantine IslanNJ '^JNJXдWўд]—ш€H)”JhBCape May County NJ 'œNJСfWўдrЋx€H)”JhCCape May County NJ 'œNJСfWўдriШ‚ˆЎЪ$yˆCCedar Grove NJ (Щ@NJ90WўдС ƒ„— •xRBKendall Park NJ (bОNJ„œWўдС' „„–Ъ,јhBLindenwold NJ 'НиNJшWўдY ш…ˆ)”HшBMartinsville NJ (HNJ…„Wўдqdx…H)”HшCMartinsville NJ (HNJ…„WўдСU ‡D— •еBMount Laurel NJ 'уXNJвxWўдС ˆˆ)”9ЈBOceanview NJ '.рNJАўWўдС% ‰H)•8hBWoodstown NJ '”pNKTWўдZTшŠˆЏ•YЖBAlbany NY *“DNJМWўд\ш‹HЏ”кrаBBrooklyn NY (œжNIхLWўд\WшŒD–Ъ…ZˆBCARMEL NY )@тNIeўWўдZИш„— •kTаBFairport NY +NMixWўдСN Žˆ—•:”BGasport NY +!˜NN…WўдСІ ˆЏ”ы(BHauppauge NY (Н.NI*WўдqDєˆЏ”ы(CHauppauge NY (Н.NI*WўдZ|ш‘ˆ–ЪyhBHemlock NY *ДZNM€ Wўдs#x‘ˆ–ЪyhCHemlock NY *ДZNM€ Wўд[пш“D–Ъ$˜шBNew York NY (ЏnNIчWўдZ^ш”„–Ъ4BPotsdam NY ,šАNKWўд[vш•ˆ–ц•(ˆBTuxedo Park NY )0 NJ-њWўдС –HЎЪ,8(BValhalla NY )дNIНWўдYУш—ˆ—ФJQаBAkron OH ) ТNQšиWўдrЯx—H—ФJQаCAkron OH ) ТNQšиWўдZрш™ˆ–т˜шBCincinnati OH 'VNTtъWўдqŽx™H–т˜шCCincinnati OH 'VNTtъWўдY‘ш›ˆЏ ХIBCleveland OH )ulNQЂюWўдqŽx›HЏ ХICCleveland OH )ulNQЂюWўдZршˆЎтйBColumbus OH 'ъVNRъVWўдqЊxHЎтйCColumbus OH 'ъVNRъVWўдYвшŸˆЎт$˜шBColumbus OH (ЌNRжjWўдq–xŸHЎт$˜шCColumbus OH (ЌNRжjWўдСŽ ЁˆЎтDZ(BDayton OH 'ЦЪNTHWўдq~xЁHЎтDZ(CDayton OH 'ЦЪNTHWўдZ"шЃˆЎт•IˆBDayton OH '‹œNSбЮWўдrэxЃˆЎт•IˆCDayton OH '‹œNSбЮWўдС& Ѕ„ЏФI1аBElyria OH )UјNRМWўдYЭшІ„Ўт”щˆBHamilton OH '\NTŽWўдqhxІDЎт”щˆCHamilton OH '\NTŽWўдZ'шЈ„—Х*ђаBHillsboro OH '.рNS“ЈWўдZ•шЉˆ—QФBLima OH (Џ2NTцWўдСВ Њˆ]Х4BLorain OH )nЊNR(WўдZшЋ„Џ ФЪЕBLorain OH );ANRWўд[шЌˆ—ХёBOregon OH ) (NS`єWўдСв ­„–тЌ”BParma OH )VИNQЈРWўд[:шЎˆЎтdBParma OH )XдNQЈWўд[…шЏˆЎте„BStone Creek OH (ZZNQyšWўдСъ АˆЎтBStoutsville OH 'LNRЕWўдqbxАHЎтCStoutsville OH 'LNRЕWўдYцшВˆЎтDˆШBToledo OH )˜žNS}nWўдYnшГˆЎт<єBWilmington OH 'hNSФъWўдrіxДˆ–Ю zhCAtlantic PA )vЌNPHŠWўдPšшЕˆ— HГPBEast StroudsburgPA )FNK*lWўдq8xЕˆ— HГPCEast StroudsburgPA )FNK*lWўдYnшЗˆЏ  hBGreensburg PA (I NOsмWўдq xЗHЏ  hCGreensburg PA (I NOsмWўдqžxЙD— yгаCGreenville PA )Y.NP`иWўд[…шК„ЎтšhBGreenville PA )iоNP]вWўдqЦК„ЎтšhCGreenville PA )iоNP]вWўдq^xМHЎЮ|ДCNAZARETH PA (­оNKNшWўдZ'шН„— ˜PBNew Castle PA (шNPOАWўдС= ОD–Ю„JHBPhiladelphia PA (VNK*vWўдrŠxОD–Ю„JHCPhiladelphia PA (VNK*vWўд[&шРˆЎЮ-ŠшBPittsburgh PA (h’NOсњWўдrДxРHЎЮ-ŠшCPittsburgh PA (h’NOсњWўдС+ ТHЎЮ,јhBPocopson PA 'еNK™шWўдrrШТˆЎЮ,јhCPocopson PA 'еNK™шWўд[ешФDЎЮ-ЈBSchnecksville PA (Ё"NK‘€Wўдq’xХH–Ю$CUniversity Park PA (К^NMЪlWўдq„xЦHЎЦ ˆCPORTSMOUTH RI )†іNG7вWўдZhшЧˆ—:”BSalem RI )lzNH9žWўдrсxШˆЎЦDIШCWest Warwick RI )›ŒNGzŠWўдY\шЩˆЎвDiBAlexandria VA &РаNMКWўдq”xЩHЎвDiCAlexandria VA &РаNMКWўдС‚ Ы„œв­9(BHaymarket VA &еHNM˜XWўдqЂxЫDœв­9(CHaymarket VA &еHNM˜XWўдС’ ЭˆЎв}iBManassas VA &ЗЌNMzlWўдСR Ю„Ўв4ЄBRichmond VA %DNMmёWўдs xЮ„Ўв4ЄCRichmond VA %DNMmёWўд^\шаDЏ]ЄYАаBSpotsylvania VA &.XNM‰йWўдqxxаDЏ]ЄYАаCSpotsylvania VA &.XNM‰йWўд]oшвHЏMЅh(BStafford VA &QўNMoЎWўдqˆxвHЏMЅh(CStafford VA &QўNMoЎWўд^шдHYЄiЈBTysons Corner VA &д0NM2 WўдqŒxдHYЄiЈCTysons Corner VA &д0NM2 WўдY<шжˆЎв*HBVirginia Beach VA $ФрNKф WўдqŽxжHЎв*HCVirginia Beach VA $ФрNKф WўдYЅши„Џ ЄyаPBAnniston AL !qПNUНІWў˜q„xиDЏ ЄyаPCAnniston AL !qПNUНІWў˜Z@шкˆ–в%9шBBirmingham AL ![†NVœWў˜qšxкH–в%9шCBirmingham AL ![†NVœWў˜Zлшмˆ—%Ѕ8PBBirmingham AL !q„NVНКWў˜q@ємˆ—%Ѕ8PCBirmingham AL !q„NVНКWў˜ZYшоˆ—%Ѕ86PBFort Payne AL "p€NUŒ Wў˜q xоH—%Ѕ86PCFort Payne AL "p€NUŒ Wў˜[{шр„–в”(hBGadsden AL "ДNUщШWў˜qЊxрD–в”(hCGadsden AL "ДNUщШWў˜Y}штˆ–вЄъhBGreenville AL ТФNVŽфWў˜qnxтH–вЄъhCGreenville AL ТФNVŽфWў˜qdxфH—%Ѕ+6CGuntersville AL "\NV0Wў˜Zcшхˆ—%Ѕ BHuntsville AL "ЌЦNV|Wў˜qžxхH—%Ѕ CHuntsville AL "ЌЦNV|Wў˜[шчˆ—%Ѕ86BMagnolia SpringsAL YjNWПrWў˜q†xчH—%Ѕ86CMagnolia SpringsAL YjNWПrWў˜Zmшщ„—%Ѕ8PаBMentone AL "Ÿ`NV…˜Wў˜ZлшъˆЎв BMontgomery AL ^œNV."Wў˜rШxъHЎв CMontgomery AL ^œNV."Wў˜ZmшьˆЎвМ(hBSouth HuntsvilleAL "rіNVšWў˜qxьHЎвМ(hCSouth HuntsvilleAL "rіNVšWў˜qhxюDœвМщˆCTalladega AL !pNVXWў˜ZяшяˆЎв\:(BTuscaloosa AL !0 NW{ЌWў˜r‰xяHЎв\:(CTuscaloosa AL !0 NW{ЌWў˜rоxёˆ—)ЄћCCocoa FL Zˆ—)ЄЙ‘PBWarm Springs GA ЧКNTЄVWўдq8є>ˆ—)ЄЙ‘PCWarm Springs GA ЧКNTЄVWўд[…ш@ˆ–ж”ЙШBBrandon MS PnNYтšWў˜qjx@H–ж”ЙШCBrandon MS PnNYтšWў˜С" B„Ўж%((BClinton MS JNZM Wў˜s$xB„Ўж%((CClinton MS JNZM Wў˜[?шDˆ—%ЅIВBMcHenry MS ЏNY ЌWў˜qjxDH—%ЅIВCMcHenry MS ЏNY ЌWў˜^ШшFH–о,h(BBILLINGS MT -Е^Nl‡ Wў\С G„ƒ-ЄXшBBurlington NC #нрNOf9WўдqˆxGDƒ-ЄXшCBurlington NC #нрNOf9WўдС– I„—IЅ(•PBChapel Hill NC #ж NO WўдС~ J„—Ѕ™ЖBCharlotte NC #EЅNQWўдСj Kˆ—%Ѕ{аBCharlotte NC #;NP мWўдqdxKH—%Ѕ{аCCharlotte NC #;NP мWўдСЪ MˆЎв=9шBGreensboro NC $ NOТˆWўдYUшN„—)ЄЈ3BHendersonville NC #JГNRl Wўдs xN„—)ЄЈ3CHendersonville NC #JГNRl WўдСb P„—IЅ(3BRaleigh NC #ž„NN}–WўдСž Q„ЎвušHBShelby NC #D}NQ}–WўдqXQ„ЎвušHCShelby NC #D}NQ}–WўдС" Sˆ—IЄ2аBAiken SC !…„NQЈfWўдqhxSH—IЄ2аCAiken SC !…„NQЈfWўдqЈxUH—)ЄЩвCBeaufort SC ІрNPŸЮWўдq`xVHЏIЅ8hCCharleston SC ‚nNObЌWўдZ@шWˆ—)Є*ђаBColumbia SC " NVу&Wў˜s$xgˆ—1МhШCKetchikan AK 7P2Nƒ—rW§ф\\шhHЎо\JhBKingman AZ #S„NrWў\qcxhHЎо\JhCKingman AZ #S„NrWў\\kшjH—МЈвBMesa AZ !sxNo–(Wў\qaxjH—МЈвCMesa AZ !sxNo–(Wў\С‚ lˆЎоlњˆBPhoenix AZ !‡xNp†tWў\qcxlHЎоlњˆCPhoenix AZ !‡xNp†tWў\\RшnHœо”BPinal Mountain AZ !B,NnРŠWў\\fшoH—М:БBScottsdale AZ !zNoгЎWў\\fшpH—IН:ˆBTucson AZ &˜0NyHWў\q_xpH—IН:ˆCTucson AZ &˜0NyHWў\\\шrD–о•:ˆBTucson/Mt.LemmonAZ gмNnИЩWў\s*ШrD–о•:ˆCTucson/Mt.LemmonAZ gмNnИЩWў\^йшtHЎкE)шBAnaheim CA !Ц NuммWў sJџtHЎкE)шCAnaheim CA !Ц NuммWў \ДшvHЏ Д((BCorona CA !КrNu Wў s_xwH—MДŠTCFolsom CA &˜0NyHWў \,шxH–кœј(BLaguna Beach CA !€шNuАєWў r'xxˆ–кœј(CLaguna Beach CA !€шNuАєWў ]`шzH—%ДЉpPBLos Angeles CA "M&NvŒ№Wў \Sш{H—)Д*єBMalibu CA "кNvštWў Сю |ˆ–кe(шBMt.Allison CA %uNyЬjWў [€ш}ˆЎкDˆˆBMt.Bullion CA %}вNxФWў qbx}HЎкDˆˆCMt.Bullion CA %}вNxФWў s7ШH–кlHˆCMt.Diablo CA %бBNyг^Wў WЪш€ˆЎкєBNapa CA &Y`Nz]РWў \8шH—)ДЙ2PBNorth Hills CA "<(NvpюWў [ш‚ˆ—)ДЪеBOroville CA '|іNykЈWў ]TшƒH–кLjHBPalm Springs CA !Ы NteИWў \Uш„H—%ДиѓBPalomar Mtn. CA !IpNtЩ@Wў sJџ„H—%ДиѓCPalomar Mtn. CA !IpNtЩ@Wў X8ш†ˆЎк$ŠhBSacramento CA &rКNxŠ>Wў q@P†HЎк$ŠhCSacramento CA &rКNxŠ>Wў \ДшˆH—%Е{VBSan Bernardino CA "-№Nu šWў sDџˆH—%Е{VCSan Bernardino CA "-№Nu šWў ]сшŠH—%ДК5PBSan Diego CA !NtукWў \сш‹H—)ДhrBSan Diego CA !>Nu!zWў ]4шŒH—]ДŠSаBSan Diego CA ‹jNtХЦWў Сš „Ўк…tBSan Francisco CA %ЗZNzvPWў rэx„Ўк…tCSan Francisco CA %ЗZNzvPWў WќшˆЎкLњhBSan Jose CA %_(NyйNWў ZяшˆЏ]Д(6PBSan Jose CA %J8Nz^Wў Yш‘„–кЄBSanta Cruz CA $шNzWў \рш’H—)ДzTаBSantiago Peak CA !І|Nu}2Wў WЪш“„–кДšhBVisalia CA $ЉкNvн"Wў qЂx“D–кДšhCVisalia CA $ЉкNvн"Wў СJ •HЎТ$ДBBoulder CO (ЖNi6Wў\Р[`•HЎТ$ДCBoulder CO (ЖNi6Wў\СR —D— „:еPBColorado SpringsCO &УyNhР‚Wў\q“x—D— „:еPCColorado SpringsCO &УyNhР‚Wў\СZ ™HЎТJhBDenver CO 'бtNib*Wў\qzx™HЎТJhCDenver CO 'бtNib*Wў\СB ›DЎТhˆBFort Collins CO (Ni фWў\qdx›DЎТhˆCFort Collins CO (Ni фWў\СN HЎТЄЩЈBMonument CO 'юNhЩєWў\]3шžD—…аBSalida CO &j/NjWў\YPшŸ„—!ДŠBHonolulu HI >.NЛкW§ф[™ш ˆЏ!ДI1аBHonolulu HI PШNдXW§Јrќx ˆЏ!ДI1аCHonolulu HI PШNдXW§ЈYмшЂˆЏ!ДIBPearl Harbor HI ZdNлІW§ЈqЂxЂHЏ!ДICPearl Harbor HI ZdNлІW§Ј[&шЄˆЎоДљ(BBoise ID +НиNtвWў\qЌxЄHЎоДљ(CBoise ID +НиNtвWў\ZcшІ„—Нj“BCinnabar Mtn ID (ЌnN ЯWў q‚xЫHœоL„CBellevue WA /“фNz+>Wў XшЭ€Џ Н9шBBellingham WA NEџrœxЭ@Џ Н9шCBellingham WA NEџWРшЯ€—НZЖPBBothell WA NEў Zmшаˆ—М9‘BBurien WA /t|NzNоWў s<ШаH—М9‘CBurien WA /t|NzNоWў С вˆЏIМИtBCle Elum WA /'LNxГjWў q6г„—НXжCEdmonds WA /ЩNzGЌWў С дˆ]МJHBEdmonds WA /ЩNzGИWў rxдˆ]МJHCEdmonds WA /ЩNzGИWў ZТшжˆЏМjшBFederal Way WA /GЎNzKДWў rИxжHЏМjшCFederal Way WA /GЎNzKДWў Zrши„—МzгBGraham WA /ЬNzF2Wў ZOшй„–оM:(BIssaquah WA /|8Nz ИWў Yзшкˆ—МъBMaple Valley WA /ZвNz8Wў СТ л„Ўо”щhBNewcastle WA /|8Nz*0Wў Сњ мˆЎоЬ„BPullman WA .Њ(Nu#PWў ZшнˆœоTфBSan Juan Island WA 0Š N{ Wў rФxнHœоTфCSan Juan Island WA 0Š N{ Wў Сz п„Ўо :hBSeattle WA /Œ NzMXWў Сц рˆЏМ‰TBSeattle WA /sZNyрWў Xшс„IН:hBSnohomish WA /еѕNzWў YЭшт€ЎоTDBTacoma WA NEџWїшу„—М(даBTukwila WA /A Nz'иWў Xшф„—М(еBTukwila WA /B Nz#єWў Z1шхˆ— МPPBVeradale WA /\NuЮWў ]eшцH— Н9гаBCheyenne WY ),ˆNhЁИWў\q’xчDН{(CGillette WY ,1NimАWў\џџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџџџ‡dЪrcЮ NEџЌеtGЕMЕ PGГ…ЊQG­-)АаG­ЕzSаG­ДyG­ДšаG­ЕzSG­Д)G­ДЙЈG­ДKG­Н(rаG­Мz(G­Н:ГG­МI1аG­Ми“G­̘sPG­Н(1аG­Нi0аG@ ­Ѕx”G­=KHG­œ4G­8‘аG­œј’G­y2аG­œYвG­+G­J•G­zеPG­ ГаG­ZUPG­*qG­ZUPG­šRаG­œ‰HG­œјTG­œ™“G­œј‘аG­œjtG­œЪtG­›6G­œ‰№PG­pG­œЙpPG­›6G­*G­•)ДG­•šЕPG­•(ЖG­•9qаG­•*“аG­•)pPG­• ВаG­•)3аG­ŒipG­•*дG­•*5G­•)ЈG­”huG­”ЩsG­ЌJHG™i„JtGŸ-„*TPGŸ-„ˆtаGЇIЭZгPGЇIZдаGЇI­ZаPGЅUœѕаGŸ5„љ0аGГ5”ЙhGŸi•(АPGŸ!•(rG™”КHG™ŒњˆGЇ-…шGk Є;(GЇY”GЇYTG‡E„I–GІеЌIЖGЈнЬJШG‹(pаGŸˆ”аGŸ‰5аGŸ9„JGŸ9„JuGŸ9…Y‘аGŸ9„ЩђаGŸ9„ШHGŒЦе ˆG‘ ЬшG‘ ЬˆˆG‘ Ь„G‘ ܘ0аG‰ „HШG‰ „9ѓPG‰ …{HG‰ „˜sPG‰ „жG“IY0G“I„и(G“IНXPPG“IЭG•A™TPG•A™RG™Uœ№аG™UЌhHGЁe”ИpPG@ Ёe”ЙQG@ ЁeЅ(tG@ ЁeЅ)аGЁQ”I1аGЁQ”к‘GЁe”И2GЁe”И0PGЁeМI1аGЁe”ИЕGЁeŒzваG@ ЁeŒzгG@ ЁeŒ8ЕPG@ ЁeŒXєG@ ЁeZQPGЁe”КTаGЁeœщєGЁe”ИVPGЁe”ИДGЁe”КPGЁe”КG@ Ёe”КRGЁe”КG@ ЕM„(“G‘-ДjPаGЁ)”GГMšhGБ(pаGБ”š–GБ(tаG‘A(qGseЅJ“GЉ„(GЁ%ŒˆѓGЕ1•iG Н8ШG НxhG М8ˆGЏU­ 1аGЎТltGœТ‹G@ —… uPGЎТ”)hG@ ЎцZ(G@ Ўц™ˆG@ ЎцЌ™GЎцЭ$GMЭ(hGЏЬњPаG…(ˆG— Э №аG— ЬљuаGЎц„˜(G@ Ўц xЈG— Э(PG— ЭZQGЎц%X(G]„ДG–ТDЈG@ ЎТl”G—­ 1PG—­YsGЎжt$G—­ 1G—­аPGœжlˆG@ Ўж<ˆG@ — ­ЉVPGœж HGЎжœŠШG@ Џ­{GœТ,єG–кд4G@ — …yGЎТ”X(G—„ЉѕPGЎТЬ4GЎТ ш(G@ ЎТmŠшG—„˜2PGЏa„(hGЎТtGЎТ,XЈGЎТ|иˆG–ТlHшG@ Џ„9ѓG@ —„8єG@ –ж,ЩhG@ Ўж|КˆGЎжЄ4GЏЌ2PG@ ЎжLhGЏ]ЌYЈG@ — Ќљ“аGЎж\G@ — •KGЎжDˆG@ Ўж 4G—Ќк6G–жtYЈG–жЄšˆG@ Ўж44G@ ЎжtzЈG@ Ўж,ЪG— ЌJTG—ЌйЖGЎжœ„G–Ц%*GЎжD:ˆGЎжDJHG@ —­xаG@ œжlJhG@ ЌфGQ­)ШG@ —­˜4G@ Џ­YвGЏ­:”G@ —ЌЙPG@ –жKG@ Ўж-KG@ —­(tаG@ Џ Ьh–G–ц,ЈGЎцE;(G–ц ZhG— ЬЩvG@ Ўц„jG@ Џ%Э(0аG–ц„(G@ — Э9VPG@ Ўц8hG@ — I1G@ ЎЦMŠЈG@ –Ц$˜шG–ЦHшG— YаGЎЦ,:ШG@ ЎЦEG@ — Œ8’PGЎЦДШ(G@ Џ:”GœЦ<ЈG@ @ ƒŒˆˆG@ ЎЦ8шGЎЮ xHG@ ЏЅ:”G@ –цMTGЏIЬбGЎцЄTGЎцL8ЈG@ Ўц *G@ Ўц,)ШGЎц%YhG–вєGЎв%9(G@ ЏЅ›VPG@ —ЅšбG–Ц”i(G@ @ ЎЦ\ДG@ ЎЦ%:HG@ ƒŒЙhG— 8RG— ˜RG—Yœ$GЎЮ…)шGЎЦ,и(G@ — ˜0аG@ — hаPG–т%ˆ(G@ Ўтl(G–т-IШG@ —-ФxhG—ХpаGЏaФzTG@ ЏaФzSG–тd8ˆG@ ЎтdšШG@ —ԘВаG@ Ўтe(hGЏФйqаG@ Ўтœ‰(G@ –т (hGЎт8ЈG9(G— I6G@ ŒJШG–ЦD*HG@ — X4G@ — yвG@ –ЦљЈGœЦ JШG@ –ЦE)шG@ — ZбPG— •H№G— •h0аG— •JPG)”JhG@ ЎЪ$yˆG— •xRG–Ъ,јhG)”HшG@ — •еG)”9ЈG)•8hGЏ•YЖGЏ”кrаG–Ъ…ZˆG— •kTаG—•:”GЏ”ы(G@ –ЪyhG@ –Ъ$˜шG–Ъ4G–ц•(ˆGЎЪ,8(G—ФJQаG@ –т˜шG@ Џ ХIG@ ЎтйG@ Ўт$˜шG@ ЎтDZ(G@ Ўт•IˆG@ ЏФI1аGЎт”щˆG@ —Х*ђаG—QФG]Х4GЏ ФЪЕG—ХёG–тЌ”GЎтdGЎте„GЎтG@ ЎтDˆШGЎт<єG–Ю zhG— HГPG@ Џ  hG@ — yгаGЎтšhG@ ЎЮ|ДG— ˜PG–Ю„JHG@ ЎЮ-ŠшG@ ЎЮ,јhG@ ЎЮ-ЈG–Ю$GЎЦ ˆG—:”GЎЦDIШGЎвDiG@ œв­9(G@ Ўв}iGЎв4ЄG@ Џ]ЄYАаG@ ЏMЅh(G@ YЄiЈG@ Ўв*HG@ Џ ЄyаPG@ –в%9шG@ —%Ѕ8PG@ —%Ѕ86PG@ –в”(hG@ –вЄъhG@ —%Ѕ+6G—%Ѕ G@ —%Ѕ86G@ —%Ѕ8PаGЎв G@ ЎвМ(hG@ œвМщˆGЎв\:(G@ —)ЄћG–в5xHG@ —=ЄY№аG@ —)Ѕ+2GЎв $GЎв ЙGЏЅ„G@ ЎвXшG@ —)Ѕ+1GЎв”шшG—)Ѕ+1аG@ ЏЅx•аG—)ЄsG@ ЎвЄˆЈG–в• ˆG—%Ѕ{PPG@ —-ЄHааG–ЦФ4G@ —)ЄйАаG—)ЄњаPGЎв ZhG—Ѕ(ДаG—%ЅipаG@ œвЩˆG@ %Є8ЈGЎв„ШHG@ ЎвL;(G—)Ѕ+2PGЄHшG@ Ўв”ъˆG—)ЅIQGЎвДШшGЎв*ˆG—)ЄЙ‘G@ —)Ѕ PG@ Ўв$јhG@ Џ)ЄhˆG–Ю”8HG—)Є(‘GЎв5xˆG—%Ѕ8PPG@ —Ѕ*еGЏ ЄŠSаG—)Ѕ™дG@ ЎвD‰G—)ЅЉ“G@ ЏIЄIG@ ЎвI(G—)ЄxѕG@ –в­8ˆG@ ЏaЄzG@ —)Ѕ 0G@ Ўв…jшGЎвДШˆG—)ЄЙ‘PG@ –ж”ЙШG@ Ўж%((G@ —%ЅIВG@ –о,h(Gƒ-ЄXшG@ —IЅ(•PG—Ѕ™ЖG—%Ѕ{аG@ Ўв=9шG—)ЄЈ3G@ —IЅ(3GЎвušHG@ —IЄ2аG@ —)ЄЩвGЏIЅ8hG—)Є*ђаG@ —)ЄhtаG@ –ждјЈG@ Ѕ8hG@ —aЄIєG@ ЎТе{(GЎв„ФG@ ЎвdZˆG@ —%Ѕ8’PG—1МhШGЎо\JhG@ —МЈвG@ ЎоlњˆG@ œо”G—М:БG—IН:ˆG@ –о•:ˆG@ ЎкE)шG@ Џ Д((G—MДŠTG–кœј(G@ —%ДЉpPG—)Д*єG–кe(шGЎкDˆˆG@ –кlHˆGЎкєG—)ДЙ2PG—)ДЪеG–кLjHG—%ДиѓG@ Ўк$ŠhG@ —%Е{VG@ —%ДК5PG—)ДhrG—]ДŠSаGЎк…tG@ ЎкLњhGЏ]Д(6PG–кЄG—)ДzTаG–кДšhG@ ЎТ$ДG@ — „:еPG@ ЎТJhG@ ЎТhˆG@ ЎТЄЩЈG—…аG—!ДŠGЏ!ДI1аG@ Џ!ДIG@ ЎоДљ(G@ —Нj“G—Ми’PG—МйPPG–ж­*HGЎжm HGЎж­(ˆGЎж<$G5­zHGЎжœdGЎж (Gœо *HG@ Ўо ZhG@ —МШ‘аG—МЩvGЎо­(шG@ —МквPGЎо<4GЏ МKQаG@ ЏIМ0PG@ ƒ МєG@ –оЬ”G—Н™6G@ —Е(3G@ UНJhG—МщёG@ @ –оeyG@ œоL„G@ Џ Н9шG@ —НZЖPG—М9‘G@ ЏIМИtG—НXжG]МJHG@ ЏМjшG@ —МzгG–оM:(G—МъGЎо”щhGЎоЬ„GœоTфG@ Ўо :hGЏМ‰TGIН:hGЎоTDG—М(даG—М(еG— МPPG— Н9гаGН{(G@ @ @ @ @ @ Africa Asia Australia Canada Europe Eastern Europe Northern Europe Southern Europe Western Germany Italy Japan Latin America Netherlands Oceania United Kingdom USA Midwest USA Northeast USA Southeast USA West AE7Q ID51AE7Q PID51AE7Q TID51WA7RO ID51WA7RO PID51WA7RO TID51/ E I UK7VE N7SS WA7DAD KL7BB WA7NWP K6BIV WA7RO WA7RO HWA7RO MWA7RO NWA7RO PWA7RO TWA7RO XWA7RO YAE7Q AE7Q HAE7Q MAE7Q NAE7Q PAE7Q TAE7Q XAE7Q YREF001ALREF001BLREF001CLREF002ALREF002BLREF002CLREF003ALREF003BLREF003CLREF004ALREF004BLREF004CLREF005ALREF005BLREF005CLREF006ALREF006BLREF006CLREF007ALREF007BLREF007CLREF008ALREF008BLREF008CLREF009ALREF009BLREF009CLREF010ALREF010BLREF010CLREF011ALREF011BLREF011CLREF012ALREF012BLREF012CLREF013ALREF013BLREF013CLREF014ALREF014BLREF014CLREF015ALREF015BLREF015CLREF016ALREF016BLREF016CLREF017ALREF017BLREF017CLREF018ALREF018BLREF018CLREF019ALREF019BLREF019CLREF020ALREF020BLREF020CLREF021ALREF021BLREF021CLREF022ALREF022BLREF022CLREF023ALREF023BLREF023CLREF024ALREF024BLREF024CLREF025ALREF025BLREF025CLREF026ALREF026BLREF026CLREF027ALREF027BLREF027CLREF028ALREF028BLREF028CLREF029ALREF029BLREF029CLREF030ALREF030BLREF030CLREF031ALREF031BLREF031CLREF032ALREF032BLREF032CLREF033ALREF033BLREF033CLREF034ALREF034BLREF034CLREF035ALREF035BLREF035CLREF036ALREF036BLREF036CLREF037ALREF037BLREF037CLREF038ALREF038BLREF038CLREF039ALREF039BLREF039CLREF039DLREF040ALREF040BLREF040CLREF041ALREF041BLREF041CLREF042ALREF042BLREF042CLREF043ALREF043BLREF043CLREF044ALREF044BLREF044CLREF045ALREF045BLREF045CLREF046ALREF046BLREF046CLREF047ALREF047BLREF047CLREF048ALREF048BLREF048CLREF049ALREF049BLREF049CLREF049DLREF050ALREF050BLREF050CLREF051ALREF051BLREF051CLREF052ALREF052BLREF052CLREF053ALREF053BLREF053CLREF054ALREF054BLREF054CLREF056ALREF056BLREF056CLREF056DLVIS ONVIS OFFCALLSIGNCALLSIGNCALLSIGNCALLSIGNUse Repeater Echo Test Repeater Status Unlink Repeater John Hays Scott Honaker Steve Hatch Bill Balzarini Bill Vodall Tim Barrett Club: general Club: home Club: mobile Club: network Club: portable Club: temp Club: x-data Club: y-data Dean: general Dean: home Dean: mobile Dean: network Dean: portable Dean: temp Dean: x-data Dean: y-data link to REF001A link to REF001B link to REF001C link to REF002A link to REF002B link to REF002C link to REF003A link to REF003B link to REF003C link to REF004A link to REF004B link to REF004C link to REF005A link to REF005B link to REF005C link to REF006A link to REF006B link to REF006C link to REF007A link to REF007B link to REF007C link to REF008A link to REF008B link to REF008C link to REF009A link to REF009B link to REF009C link to REF010A link to REF010B link to REF010C link to REF011A link to REF011B link to REF011C link to REF012A link to REF012B link to REF012C link to REF013A link to REF013B link to REF013C link to REF014A link to REF014B link to REF014C link to REF015A link to REF015B link to REF015C link to REF016A link to REF016B link to REF016C link to REF017A link to REF017B link to REF017C link to REF018A link to REF018B link to REF018C link to REF019A link to REF019B link to REF019C link to REF020A link to REF020B link to REF020C link to REF021A link to REF021B link to REF021C link to REF022A link to REF022B link to REF022C link to REF023A link to REF023B link to REF023C link to REF024A link to REF024B link to REF024C link to REF025A link to REF025B link to REF025C link to REF026A link to REF026B link to REF026C link to REF027A link to REF027B link to REF027C link to REF028A link to REF028B link to REF028C link to REF029A link to REF029B link to REF029C link to REF030A link to REF030B link to REF030C link to REF031A link to REF031B link to REF031C link to REF032A link to REF032B link to REF032C link to REf033A link to REF033B link to REF033C link to REF034A link to REF034B link to REF034C link to REF035A link to REF035B link to REF035C link to REF036A link to REF036B link to REF036C link to REF037A link to REF037B link to REF037C link to REF038A link to REF038B link to REF038C link to REF039A link to REF039B link to REF039C link to REF039D link to REF040A link to REF040B link to REF040C link to REF041A link to REF041B link to REF041C link to REF042A link to REF042B link to REF042C link to REF043A link to REF043B link to REF043C link to REF044A link to REF044B link to REF044C link to REF045A link to REF045B link to REF045C link to REF046A link to REF046B link to REF046C link to REF047A link to REF047B link to REF047C link to REF048A link to REF048B link to REF048C link to REF049A link to REF049B link to REF049C link to REF049D link to REF050A link to REF050B link to REF050C link to REF051A link to REF051B link to REF051C link to REF052A link to REF052B link to REF052C link to REF053A link to REF053B link to REF053C link to REF054A link to REF054B link to REF054C link to REF056A link to REF056B link to REF056C link to REF056D ircDDB: on ircDDB: off џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџW7ACS B W7ACS BW7ACS BAE7Q PE€„1AK7LWH G K7LWH GK7LWH BAE7Q PgЄРHWA7HJR G WA7HJR GWA7HJR BAE7Q P€Ё<9AE7Q T880H CQCQCQ Ъ`2NR7SS B NR7SS BNR7SS BAE7Q P>гˆ1 €Ё<2Sџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ DEAN @MILL CREEK WA џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDean @Mill Creek WA Dean @Everett WA USADean dstar@ae7q.net Data only operationsD-StarLet operationsџџџџџџџџ"’ЗN‡…kEOsaka Head Offic/“ХNz+IWIcom America #“›N‹К,ETokyo Bigsite 'С)NTAГWDayton Hamventio#ŸДN‹ГŒETokyo Station #“JN‹­oEShinagawa Statio"ЋьN‡u9EShin Osaka Stati!ŠEGotenba guchi #nБNŠКEFuji Yoshida џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџICOM HAM festa Railroad Mt.Fuji џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчџџџџџџџџџџџџ>GMS_dhj–—˜›иgџџџџџџџџџџџџ  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№џџџџџџ?ќџџџџ?јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ†џџ ,џџџџџџџџџџџ‹__ШШ++џџњў /ЩуNz,wEЬ API51,DSTAR*џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ/[/-/>/'џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘нР3@ €Гя 'Р@ €9оLK@@ €‘нР3@ €Гя 'Р@ €9оLK@@ €>ЦИ CQCQCQ CQCQCQ CQCQCQ CQCQCQ џџ NEџџџџџџџ  CQCQCQ NEџџџГя 'Р@ €CQCQCQ џџџџџџџџџџџџџџџџ9оLK@@ €CQCQCQ џџџџџџџџџџџџџџџџ>ЦџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќџџџџџџџџџџўўўўўўўўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIcomCloneFormat3џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Retevis_RT619.img0000644000175000017500000000067514411666130017441 0ustar hibbyhibby%`D%`D||€џџџu`Du`D||€џџџ%1`D%1`D||€žuC`DuC`D||€%V`D%V`D||€џџuh`Duh`D||€%`D%`D||€u“`Du“`D||€%aD%aD((€uaDuaD((€%1aD%1aD((€uCaDuCaD((€%VaD%VaD((€uhaDuhaD((€%aD%aD((€u“aDu“aD((€џџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDYxOSIsICJjaGlycF92ZXJzaW9uIjogIjAuMy4wZGV2IiwgInJjbGFzcyI6ICJSVDYxOVJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Retevis_RT68.img0000644000175000017500000000222114411666130017344 0ustar hibbyhibby%'F%'FbФbФ§џPb%FPb%Fpp§P‡%P‡%FP‡%Fˆˆ§P&P&FP&Fss§P7&P7&FP7&F§Pb&Pb&FPb&Fee§%&%&F%&Fss§%'%'F%'F§P‡&P‡&FP‡&F§P'P'FP'Fbb§P%P%FP%F00§u%u%Fu%FCЧCЧ§&&F&F2У2У§P&P&FP&FCТCТ§u&u&Fu&F††§''F'F1Ч1Ч§%'%'F%'FbФbФ§џјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџџџџџџџџјџџ‹џјџџџџџџџџџџјџџјџџјџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDY4IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMTExMTgiLCAicmNsYXNzIjogIlJUNjhSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Yaesu_FT-818.img0000644000175000017500000001511214411666130017140 0ustar hibbyhibbyиП€Рbюf–ВBх2ˆВВ22222 bHП 'џџџџџџџџ`HW0'џџџџџџџџaH+h' `H Ў`' bHB@'џџџџџџџџaH\Р'џџџџџџџџaHw@' aH ' aH%bP' aH*Й€' AHLK@† џџџџџџџџEO†GџџџџџџџџDKЄЫ€џџџџџџџџEHрїЬъ`џџџџџџџџB˜lЁ џџџџџџџџdHу`'џџџџџџџџbHП 'џџџџџџџџ`HW0'џџџџџџџџaH+h'џџџџџџџџ`H Ў`'џџџџџџџџbHB@'џџџџџџџџaH\Р'џџџџџџџџaHw@' aH 'џџџџџџџџaH%bP'џџџџџџџџaH*Й€'џџџџџџџџAHLK@†  EO†GџџџџџџџџDKЄЫ€џџџџџџџџAHлКъ`џџџџџџџџENЈŠРЁ џџџџџџџџdHу`' eH-*€' EHP%”†  EHн@ ъ` EN”Д Ё EN”ЊмЁ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџeH Ў`'џџџџџџџџП  @LK@ReРIџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЅЄˆ мDъ`W6COH …Єˆ#нœъ`KF6ZTY …dˆнo€ъ`WA6ISG …dˆнwPъ`WD6AWP …dˆ톹ъ`KC6JTN …dˆ톹ъ`W6MPH …dˆнŽРъ`W6DRA …dˆ нŽРъ`N6AH …dˆнŽРъ`KD6KTQ …dˆн–ъ`N6SLD …dˆ нІ0ъ`N6FDR …dˆнІ0ъ`WA6FV …dˆнЎъ`WR6AZN …dˆ нЕаъ`K6CPT …dˆнН ъ`W6TRW …dˆнН ъ`WD8RCL …dˆ нЭ@ъ`K9KAO …dˆнеъ`K6SRT …dˆ неъ`WA6LA …dˆ нмръ`N6ME …dˆнфАъ`N7OD …dˆнфАъ`K6NBR …Єˆ п œъ`WA6AV …dˆ#нь€ъ`N6NIK …dˆнь€ъ`N6USO …dˆ нќ ъ`W6AM …dˆнќ ъ`W6DRA …Єˆобъ`K6SOA …Єˆ объ`WB6RSK …Єˆобъ`WB6ZTY …Єˆошtъ`KA6AMR …Єˆошtъ`WB6UBG …Єˆ оє,ъ`K7GIL …фˆ,н%Hс2dKD6QLT …Єˆ,пРъ`W7JAM …Єˆп œъ`N6FQ …Єˆп œъ`W6KAT …Єˆ п.Фъ`WA6AQQ …ЄˆпQьъ`KF6YLB …dˆ пЕˆъ`KD6DDM …dˆпС@ъ`W7BF …dˆпС@ъ`WA6FGK …dˆпЧъ`KE6UPA …dˆ пЧъ`AB6MV …dˆ%пЬјъ`KD6AFA …Єˆоџфъ`K6CHE …dˆпЬјъ`N6JMI …dˆпЬјъ`WA6HYQ …dˆпЬјъ`WB6RSM …dˆпиАъ`W6NWG …dˆпиАъ`WA6MTZ …dˆ пфhъ`K0JPK …dˆ пфhъ`W6CLA …dˆпфhъ`W6NWG …dˆ#п№ ъ`KC6ZQR …dˆп№ ъ`KI6ITV …dˆпћиъ`K6SYU …dˆ пћиъ`K6SYU …dˆпћиъ`W6JW …dˆпћиъ`WA6YVL …dˆрДъ`KJ6HCX …dˆ рДъ`W6GTR …dˆ рHъ`N6EVC …dˆръ`W6FNO …dˆрHъ`W6JBT …dˆръ`W6TJ …dˆр$мъ`W6KRW …dˆр*Иъ`W6CTR …dˆр6pъ`KE6FUZ …dˆ р6pъ`WA6EFW …dˆрB(ъ`K6QEH …dˆрB(ъ`W6JW …dˆрB(ъ`WA6TST …Єˆп]Єъ`KE6TZG …Єˆ рY˜ъ`K6RIF …ЄˆрY˜ъ`WD6BNG …ЄˆрePъ`W6PWT …Єˆрk,ъ`W6NWG …Єˆрqъ`AA6DP …Єˆ р|Ръ`K7GIL …Єˆр|Ръ`N6VGU …Єˆр€Јъ`W6NWG …Єˆ рˆxъ`WR6JPL …Єˆ#р”0ъ`KK6NJ …Єˆр”0ъ`W6LAR …Єˆр”0ъ`WA6TST …Єˆ рš ъ`W6NVY …Єˆ рŸшъ`K6JSI …Єˆ рЅФъ`K6DCS …ЄˆрЋ ъ`W6MEP …Єˆ рУъ`KA6OLD …ЄˆрУъ`WB6QHB …ЄˆрЮШъ`K6BB …eˆЇРЁ K6HOG …dˆ с„ъ`W6VLD …dˆ#с>ъ`KI6JVF …dˆсIдъ`K6RIA …dˆсIдъ`K6SOA …dˆ сIдъ`KC6OKB …dˆсaDъ`K6ECS …dˆсlќъ`K6LLU …dˆ сlќъ`KB6C …dˆсxДъ`W6QFK …dˆ с›мъ`WA6YNT …dˆ#с›мъ`WW6Y …dˆсЇ”ъ`N6JMI …dˆ сЇ”ъ`W6BII …dˆсГLъ`K6COV …dˆсГLъ`KE6GUC …dˆсГLъ`W6CDF …dˆсГLъ`K6ERN …dˆ рДъ`K6ERN …dˆсПъ`K6JTH …dˆсПъ`KF6JWT …dˆсЪМъ`WD6DPY …Ѕˆ  W$Ё W6SLZ …eˆЈcАЁ KC4OGF †eˆЈЂ0Ё N6GGS …Ѕˆ І#„Ё KG6KKV …eˆЇЁ KB6OZX …eˆ Ї+0Ё KI6DB …eˆ ЇR@Ё WR6JPL …eˆ ЇyPЁ W6CDF …eˆ ЇyPЁ W6JW …eˆЇЯ@Ё K6KBF …eˆЇЯ@Ё K6BDE …eˆЇорЁ K6OPJ …eˆ ЇорЁ W6KAT …eˆ ЇцАЁ K6ERN …eˆ ЇцАЁ W6VLD …eˆЇю€Ё K6LLU …eˆЈ РЁ KB6BZZ …eˆ Їю€Ё KJ6W …eˆЇю€Ё N6FQ …eˆЇіPЁ W6HA …eˆЇў Ё W6TOI …eˆЈcАЁ KA6GXY …eˆЈcАЁ KC6TKA …eˆЈcАЁ N6RPG …eˆ#Јk€Ё KD6AFA …eˆ Љ'Ё KD6PXZ …eˆ Љ'Ё WA6FZH …eˆЉ'Ё WA6ITC …eˆ Љ>pЁ K6JSI …eˆЉe€Ё WD8CIK …eˆЉУ@Ё KG6HSQ …eˆЉт€Ё KB6JAG …eˆЊ`Ё KC6OPU …eˆЊ`Ё KE6CPF …eˆЊ`Ё W6NWG …eˆ Њ`Ё W6TRW …eˆ Њ`Ё K6ERN …eˆЊ_€Ё K6ONT …eˆЊ_€Ё WB6EKU …eˆ Њ_€Ё WR6AZN …eˆЊŽ`Ё KA6GRF …eˆ ЊŽ`Ё N6GLA …eˆ Њѓ№Ё KI6DYV …eˆЋaPЁ KK6AC …eˆ ЋЏpЁ K6JSI …eˆ%ЌаЁ KB6MRC …eˆЌаЁ N6NMC …eˆ ­“аЁ W6ZN …eˆ ­“аЁ KD6JTU …eˆ%­с№Ё WA6GDF …eˆ ­с№Ё K9KAO …eˆЎ0Ё W6DRA …eˆЎ0Ё N6CIZ …eˆЋIрЁ K6RIF …ЅˆІ^Ё WA6CAM …eˆЇЈ0Ё WD6FZA …eˆЇзЁ WD6ABC …eˆЋЗ@Ё KD6ZLZ …eˆЎv`Ё K6TEM …eˆЇП Ё K6TEM …eˆЊ–0Ё W6FRT †eˆ#­Ћ@Ё N6WZK …dˆнwPъ`WD6AWP …dˆнž`ъ`K6SOA …eˆЎOPЁ K6CHE …dˆръ`W6FNO …dˆр*Иъ`W6IN …Єˆ рePъ`WB6HRO …Єˆрˆxъ`K0AKS …dˆс›мъ`W6LMU …Єˆп.Фъ`K6CF …eˆЎ0Ё W6NVY …Єˆрš ъ`W6NVY …eˆЉкАЁ N6LXX …`ˆ-A№'N6LIZ …aˆQбP† N6LXX …eˆЇю€Ё K6CCR …dˆнмръ`KI6ITV …Єˆ рц8ъ`AA7SQ …eˆЇ#`Ё KE6UPI …`ˆ-2P'NI8H …aˆPЯ€† WA6MDJ …aˆ PзP† W6CDF …dˆр0”ъ`WA6TFD …eˆЇ Ё WA6MDJ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџaHтŽ'џџџџџџџџ $u˜lЁ џџџџaH"а'џџџџџџџџaH)'џџџџџџџџaH-*'џџџџџџџџaH2д'џџџџџџџџaH?T'џџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQtODE4IiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIkZUODE4UmFkaW8iLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Yaesu_FT-450.img0000644000175000017500000003556014522657251017150 0ustar hibbyhibby˜ @кЁ"K 2 РХ0 Вф ј јEЂ€–ќ€џџџџџџџHЂ€–<Ÿˆџџџџџџџ@Ђ€–msˆџџџџџџџE@Ђ€–šЉРџџџџџџџE"€–жРџџџџџџџE"€–/ џџџџџџџEЂ–APџџџџџџџEЂ–|,8џџџџџџџMЂ€–Х/ џџџџџџџD • 2РџџџџџџџMЂ€–QНШџџџџџџџEЂH•Œџџџџџџџ@ H•6ƒџџџџџџџEЂH•kьшџџџџџџџEЂ€–šЅиџџџџџџџE"€–жМЈџџџџџџџEЂH•+8џџџџџџџEЂH•AY џџџџџџџEЂH•|,8џџџџџџџE"€–ўЌ\(џџџџџџџDA"–ї-r0B@џџџџџџџ@ H•QЛдџџџџџџџD H•П џџџџџџџD H• 2Рџџџџџџџ@"€–I8$џџџџџџџA"€–л9"џџџџџџџA"€–EF`R13 w@„€њ№€7љ€№< №~№_= p @рџџDA"–ї-r0B@џџџџџџџ"€–EF`S2 A"€–PЈpџџџџџџџDAЂH–)zB@џџџџџџџ@ H•еЦ† џџџџџџџB H•еЩL† џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCЂ€–<Ÿˆџџџџџџџ"€–&ђДR11 Ђ–2•8R12 "€–EF`R13 Ђ€–ќYrpR14 Ђ€–tnЄR15 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCЂ€–<ŸˆџџџџџџџDЂ€–<ŸˆџџџџџџџM –<Ÿˆ MЁ–<Ÿˆ @Ђ€–<ŸˆџџџџџџџAЂ€–<ŸˆџџџџџџџBЂ€–<ЂDџџџџџџџJЂ€–<ЂDџџџџџџџEЂ–<“а џџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–jР џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€"€–џ2VИR41 €"€–џJbјR42 "€–џtt€R43 Ђ€–Ž <R44 Ђ€–ЭіR45 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@"€–џKрџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@"€–џ2yрџџџџџџџ@"€–џ=Khџџџџџџџ@"€–џO!аџџџџџџџ@"€–џow(џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAЂ–FŒŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–okpџџџџџџџA"€–CгHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@"€–џ!д(џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAЂ€–ќhXџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAЂ–=~0џџџџџџџA"€–е„(џџџџџџџAЂ€–ќQVDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@"€–џrkџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@"€–џ1dˆџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–їејџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–їе„(џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–їЉTџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–н џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–єўРџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@"€–џЙѕxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA"€–џJмџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЂ€–3ОTGA Ђ€–E”€TGB Ђ€–JмTGC Ђ€–g`иTGD Ђ€–wѓTGE Ђ€–u0TGF Ђ€–Š иTGG Ђ€–ŒЃшTGH Ђ€–œЉxTGI Ђ€–нЊTGJ Ђ€–яПTGK Ђ€–ё$lTGL Ђ€–%]TGM Ђ€–+A`TGN Ђ€–l ЬTGO @ H–5gрџџџџџџџHЂ€–= џџџџџџџIЂ€–ЏврџџџџџџџIЂ€–Х/ џџџџџџџA H•NйŒџџџџџџџ1 2 3 š“‡BЁH•Q\ † џџџџџџџAЁH•Qš † џџџџџџџB H•QУЄ† џџџџџџџA H•QќH† џџџџџџџA H•RyH† џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9їš"–ї-r0B@R13  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abFT-450џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2ZW5kb3IiOiAiWWFlc3UiLCAibW9kZWwiOiAiRlQtNDUwIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAibmV4dC0yMDIzMTAyNyJ9chirp-20240224/tests/images/Radtel_RT-470L.img0000644000175000017500000013167514430171343017422 0ustar hibbyhibby%vF%vFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџuVuVџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГUшџџџџџџџџџџџџџџџџиBшџџџџџџџџџџџџџџџџвaшџџџџџџџџџџџ џџџџџЬшџџџџџџџџџџџџџџџџR шџџџџџџџџџџџџџџџџиBшџџџџџџџџџџџ0џџџџџЬпшџџџџџџџџџџџ џџџџџFJшџџџџџџџџџџџџџџџџX/шџџџџџџџџџџџ џџџџџFJшџџџџџџџџџџџџџџџџR шџџџџџџџџџџџџџџџџX/шџџџџџџџџџџџ џџџџџFJшџџџџџџџџџџџџџџџџR шџџџџџџџџџџџџџџџџиBшџџџџџџџџџџџџџџџџГUшџџџџџџџџџџџџџџџџ&шџџџџџџџџџџџџџџџџMшџџџџџџџџџџџџџџџџLfшџџџџџџџџџџџџџџџџ'qшџџџџџџџџџџџџџџџџВ&шџџџџџџџџџџџџџџџџй1шџџџџџџџџџџџџџџџџ ™шџџџџџџџџџџџџџџџџЫŽшџџџџџџџџџџџџџџџџ^йшџџџџџџџџџџџџџџџџ5Юшџџџџџџџџџџџџџџџџ4Ншџџџџџџџџџџџџџџџџ_ЊшџџџџџџџџџџџџџџџџЪ§шџџџџџџџџџџџџџџџџ_Њшџџџџџџџџџџџџџџџџ4Ншџџџџџџџџџџџџџџџџ5Юшџџџџџџџџџџџџџџџџ^йшџџџџџџџџџџџџџџџџЫŽшџџџџџџџџџџџџџџџџ ™шџџџџџџџџџџџџџџџџй1шџџџџџџџџџџџџџџџџВ&шџџџџџџџџџџџџџџџџ'qшџџџџџџџџџџџџџџџџLfшџџџџџџџџџџџџџџџџMшџџџџџџџџџџџџџџџџ&шџџџџџџџџџџџџџџџџГUшџџџџџџџџџџџџџџџџиBшџџџџџџџџџџџџџџџџёxшџџџџџџџџџџџџџџџџиBшџџџџџџџџџџџ џџџџџF‘шџџџџџџџџџџџџџџџџR џџџџџџџџџшџџџџџџџџ џџџџџџџџџшџџџџџџџџ#7џџџџџџџџџшџџџџџџџџ џџџџџџџџџшџџџџџџџџ.џџџџџџџџџшџџџџџџџџ+3џџџџџџџџџшџџџџџџџџоизкМЭзкОšѓrзкџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЄYџ  …џ  Ђ№џ  …џ  Ђ№џ  …џ  ѓПџ  UЪџ  ‰џ џ 1џ џ ЛDџ џ 1џ џ ЛDџ џ 1џ џ ЛDџ џ 1џ џ  џ џџџажџ џџџџ“ыџ џџџџџхУџ џ й`џ џ й`џ џ й`џ џ й`џ џ й`џ 8кžЏ8кџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      NUM.31NUM.32NUM.33NUM.34NUM.35NUM.36NUM.37NUM.38NUM.39NUM.40NUM.41NUM.42NUM.43NUM.44NUM.45NUM.46NUM.47NUM.48NUM.49NUM.50NUM.51NUM.52NUM.53NUM.54NUM.55NUM.56NUM.57NUM.58NUM.59NUM.60џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSVDQ3MExSYWRpbyIsICJ2ZW5kb3IiOiAiUmFkdGVsIiwgIm1vZGVsIjogIlJULTQ3MEwiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMwNDI3In0=chirp-20240224/tests/images/AnyTone_5888UVIII.img0000644000175000017500000010026114411666130020022 0ustar hibbyhibbyЅЅz~P3™ГЏ7LEIyВK/…›’rƒ‹ eO>)- MRUX[_cfjKNQTW[^`g  є588UVPANYTONE-226569212019-9-4 Š DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDE`  ч#`  чP`  ч5  чE`  ч5  чE`  ч#`  чP`  ч5  чE`  ч5  чE`  ч#`  чP`  ч5  чE`  ч5  чE`  ч#`  чP`  ч5  чE`  ч5  чd  3#D$   2dD`  ч"`  ч   ч < џchirpюimgeyJ2ZW5kb3IiOiAiQW55VG9uZSIsICJtb2RlbCI6ICI1ODg4VVZJSUkiLCAiY2hpcnBfdmVyc2lvbiI6ICIwLjMuMGRldiIsICJyY2xhc3MiOiAiQW55VG9uZTU4ODhVVklJSVJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/TDXone_TD-Q8A.img0000644000175000017500000002001014551723752017264 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџџџџџџџџџџџџџПџџџ e eџџџџ—џџџ`D`DџџџџŸџџџ$џџџџџџџџŸџџџ%$џџџџџџџџŸџџџP$џџџџџџџџŸџџџu$џџџџџџџџŸџџџ%џџџџџџџџŸџџџ%%џџџџџџџџŸџџџP%џџџџџџџџŸџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‡џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ x €xџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџppџџџџŸџџџ%C%CџџџџŸџџџжжжжммееппппггбб7>3>3>?24>HR\fpz„Ž˜ЌРдш#-7AKZdnx‚Œ– ЅІІІІІІІІІІІІІІІB>;97775ZXSQOMLJŒˆ„‚€~xІІІІІІІІІІІІІІІKB>>?@@@@=73.-,dXRSVY[\WQMJFDA‘‘‘‘‘‘Œ‡‚‚‡Œ‘ІІІІІІІІІІІІІІІ8  Ќ–X&„ќ ФPЬ PЬІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІcmw„Ž˜ЌОд&0:DS]gq{…™ЃІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІјјјјјјјјјјјјјјјјјјјјјјјІІІІІІІІІІІІІІІІІІн;ОP­ОPІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІн<ИP­ОP„P@ФИтP^јЂPІІІІІІІІІІІІІІІІ  PЬјџџџџџџџџ(<Px Powerwerx ІІІІІІІІІІІІІІІІWOUXUN20171102ИЃНЈЪЁШЊжнЪаІІІІІІІІB4_R1.0cdЧШ+,ѓєWXЛМ ƒ„чІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІп’`п’`PќЈŠРЈŠРPќјџџџџутќџјјутќџїЭ€їЭ€утќџїъЬїъЬутќџїзDїзDутќџїсїсутќџїєїєутќџїўTїўTутќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІVHF SIMPUHF SIMPWX PDXWX1PA7WX2PA1WX3PA4WX4PA2WX5PA3WX6PA5WX7PA6ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІ<<}||||||}ќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќќІІІІІІІІІІІІІІІІІІІІІІІ                    џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ џџџџџџ   !"#$%&'()*+,-./0123456789:;<=>ІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІІchirp-20240224/tests/images/Retevis_RB75.img0000644000175000017500000000222114411666130017320 0ustar hibbyhibbyP‡uFP‡uFџџџџџџџPb%FPb%FppяџџџP‡%FP‡%FˆˆяџџџP&FP&FssяџџџP7&FP7&FяџџџPb&FPb&FeeяџџџP‡&FP‡&FяџџџP'FP'FbbяџџџPbuFPbuFC‚C‚чџџџP‡uFP‡uF2€2€чџџџPvFPvFG€G€чџџџP7vFP7vFQ€Q€чџџџPbvFPbvFS€S€чџџџP‡vFP‡vFe€e€чџџџPwFPwFчџџџP%FP%F00яџџџu%Fu%FCЧCЧяџџџ&F&F2У2Уэјџџ%&F%&FssэјџџP&FP&FCТCТэјџџu&Fu&F††эјџџ'F'F1Ч1Чэјџџ%'F%'FeeэјџџP%FPuFeeэјџџu%FuuFeeэјџџ&FvFeeэјџџ%&F%vFeeэјџџP&FPvFeeэјџџu&FuvFeeэјџџ'FwFeeэјџџ%'F%wFeeэјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџџџџџџџџџјџџ‹ SMџP558џјџџјџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjc1IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMTEyMjEiLCAicmNsYXNzIjogIlJCNzVSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Q-MAC_HF-90_v300_or_earlier.img0000644000175000017500000002031114430171343021512 0ustar hibbyhibbyЭџџ4џ’€! ”Х@Y LlСФј–†ЈА­лцIbЈ$џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJFYXJseUhGOTBSYWRpbyIsICJ2ZW5kb3IiOiAiUS1NQUMiLCAibW9kZWwiOiAiSEYtOTAiLCAidmFyaWFudCI6ICJ2MzAwIG9yIGVhcmxpZXIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Wouxun_KG-816.img0000644000175000017500000002000014411666130017335 0ustar hibbyhibbyџџџџџџџџџџџџџџџџˆCCџџџџ•џџџPb’CPbCџџž•џџџ“CCџџД•џџџPb†CPbCџџЕ•џџџ%‰C%Cџџџџ•џџџ‘CCџџџџ•џџџPˆCPCџџџџ•џџџ‰CCџџž•џџџP“CPCџџџџ•џџџPCPCџџџџ•џџџP‡‰CP‡CџџЮ•џџџP7ˆCP7CџџД•џџџP…CP Cџџџџ•џџџ„CCџџџџ•џџџP‰CPCџџџџ•џџџP”CPCџџш•џџџPb‡CPbCџџž•џџџ‡CCџџž•џџџP(CP(Cџџџџ•џџџu1Cu1Cџџџџ•џџџ’CCџџџџ•џџџu‡CuCџџџџ•џџџu†CuCџџž•џџџCCџџџџ•џџџ%†C%Cџџž•џџџu‰CuCџџџџ•џџџP’CPCџџ&•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCCџџџџ•џџџPCPCџџџџ•џџџ%C%Cџџџџ•џџџP7CP7Cџџџџ•џџџPCPCџџџџ•џџџPbCPbCџџџџ•џџџuCuCџџџџ•џџџP‡CP‡Cџџџџ•џџџCCџџџџ•џџџPCPCџџџџ•џџџ%C%Cџџџџ•џџџP7CP7Cџџџџ•џџџPCPCџџџџ•џџџPbCPbCџџџџ•џџџuCuCџџџџ•џџџP‡CP‡Cџџџџ•џџџCCџџџџ•џџџPCPCџџџџ•џџџ%C%Cџџџџ•џџџP7CP7Cџџџџ•џџџPCPCџџџџ•џџџPbCPbCџџџџ•џџџuCuCџџџџ•џџџP‡CP‡Cџџџџ•џџџCCџџџџ•џџџ(C(Cџџџџ•џџџP(CP(Cџџџџ•џџџ%(C%(Cџџџџ•џџџP7(CP7(Cџџџџ•џџџP(CP(Cџџџџ•џџџPb(CPb(Cџџџџ•џџџu(Cu(Cџџџџ•џџџ%`D%`Dџџџџ•џџџu`Du`Dџџџџ•џџџ%1`D%1`Dџџџџ•џџџuC`DuC`Dџџџџ•џџџ%V`D%V`Dџџџџ•џџџuh`Duh`Dџџџџ•џџџ%`D%`Dџџџџ•џџџu“`Du“`Dџџџџ•џџџ%9C%9Cџџџџ•џџџP5CP5Cџџџџ•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџu1Cu1Cџџџџ•џџџP†CPCџџџџ•џџџPb†CPbCџџЕ•џџџu†CuCџџџџ•џџџP‡†CP‡Cџџџџ•џџџ‡CCџџž•џџџP‡CPCџџџџ•џџџ%‡C%Cџџџџ•џџџP7‡CP7Cџџџџ•џџџP‡CPCџџџџ•џџџPb‡CPbCџџџџ•џџџu‡CuCџџџџ•џџџP‡‡CP‡Cџџџџ•џџџˆCCџџџџ•џџџPˆCPCџџџџ•џџџ%ˆC%Cџџџџ•џџџP7ˆCP7CџџД•џџџPˆCPCџџџџ•џџџPbˆCPbCџџџџ•џџџuˆCuCџџџџ•џџџP‡ˆCP‡Cџџџџ•џџџ‰CCџџž•џџџP‰CPCџџџџ•џџџ%‰C%Cџџџџ•џџџP7‰CP7Cџџџџ•џџџP‰CPCџџџџ•џџџPb‰CPbCџџџџ•џџџu‰CuCџџџџ•џџџP‡‰CP‡CџџЮ•џџџCCџџџџ•џџџPCPCџџџџ•џџџ%C%Cџџџџ•џџџP7CP7Cџџџџ•џџџPCPCџџџџ•џџџPbCPbCџџџџ•џџџuCuCџџџџ•џџџP‡CP‡Cџџџџ•џџџ‘CCџџџџ•џџџP‘CPCџџџџ•џџџ%‘C%Cџџџџ•џџџP7‘CP7Cџџџџ•џџџP‘CPCџџџџ•џџџPb‘CPbCџџџџ•џџџu‘CuCџџџџ•џџџP‡‘CP‡Cџџџџ•џџџ’CCџџџџ•џџџP’CPCџџџџ•џџџ%’C%Cџџџџ•џџџP7’CP7Cџџџџ•џџџP’CPCџџ&•џџџPb’CPbCџџž•џџџu’CuCџџџџ•џџџP‡’CP‡Cџџџџ•џџџ“CCџџД•џџџP“CPCџџџџ•џџџ%“C%Cџџџџ•џџџP7“CP7Cџџџџ•џџџP“CPCџџџџ•џџџPb“CPbCџџџџ•џџџu“CuCџџџџ•џџџP‡“CP‡Cџџџџ•џџџ”CCџџџџ•џџџP”CPCџџш•џџџ%”C%Cџџџџ•џџџP7”CP7Cџџџџ•џџџP”CPCџџџџ•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP9CP9Cџџџџ•џџџu1Cu1Cџџџџ•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP”CP”CџџДјџџPb†CPb†CџџДјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ””ŸŸ““‘ž’›™š   ­ІЌЈЈЅЄЏЃЁОЖ.-я04№ѓіNLR\юџюџєџєџєџџџџwuЗПs%ЄЇsz~{wrџџџџџџџџџџџџџџџџ{w{{w{{w{{w{ЋЇнsz~Нd­ћNІhгD`ЂЧп>Нd­ћNІhгDЂ`п>`$ˆіxњ†&а˜№*Ъu(Ј`$ˆіxњ†&а˜u*фЈЪ(˜Ъ$ˆіxњ†&аu``$ˆіxњ†&а˜Ъ*№u(Ј˜Ъ$ˆіxњ†&а9ф(u`Ј˜Ъ$ˆіxњ†&а9v(X`Нd­ћNІhгDЂ`п>ЧXхrџŒІ3РMgкєЫCг‡@џУŒY*ўж&ЙT­Й7Хalа4˜ќawЙT­Й8ХЫ;… †‘Љ?еk—-Учџџџџџџџџџџџџџџџџ                   џџџџџџџџџџџџџџџџ‹„ 9и|&жП­C‡‹„ 9и|&жП­C‡‹„ 9и|&ж’­ПCП}Тmсcы6G+v<П}Тmсcы+)ŸwщАqН‚џМIщ‚CщАЇqМ‚УБќWАm™FE|кUх‡vџџџџџџџџџџџџџџџџ                            џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Oџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ#4EVgx‰0528џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   & #&(%00000&!#%)))))&!#%)))))-  2 MIN125M3G201џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 280528џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000M3G201000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000chirp-20240224/tests/images/Baofeng_UV-17Pro.img0000644000175000017500000010207114527622514020033 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPP`џџџџVHF 1џџџџџџџaџџџџVHF 2џџџџџџџPPaџџџџVHF 3џџџџџџџbџџџџVHF 4џџџџџџџPPbџџџџVHF 5џџџџџџџccџџџџVHF 6џџџџџџџP PcџџџџVHF 7џџџџџџџddџџџџVHF 8џџџџџџџPdPdџџџџVHF 9џџџџџџџeeџџџџVHF 10џџџџџџPePeџџџџVHF 11џџџџџџffџџџџVHF 12џџџџџџPfPfџџџџVHF 13џџџџџџggџџџџVHF 14џџџџџџPgPgџџџџVHF 15џџџџџџhhџџџџVHF 16џџџџџџPhPhџџџџVHF 17џџџџџџiџџџџVHF 18џџџџџџPPiџџџџVHF 19џџџџџџpџџџџVHF 20џџџџџџPPpџџџџVHF 21џџџџџџqџџџџVHF 22џџџџџџPPqџџџџVHF 23џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPsPsџџџџVHF 27џџџџџџttџџџџVHF 28џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP!PuџџџџVHF 31џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%%`џџџџVHF 60џџџџџџuu`џџџџVHF 61џџџџџџ%%aџџџџVHF 62џџџџџџuuaџџџџVHF 63џџџџџџ%%bџџџџVHF 64џџџџџџuubџџџџVHF 65џџџџџџ% %cџџџџVHF 66џџџџџџucucџџџџVHF 67џџџџџџ%d%dџџџџVHF 68џџџџџџededџџџџVHF 69џџџџџџ%e%eџџџџVHF 70џџџџџџueueџџџџVHF 71џџџџџџ%f%fџџџџVHF 72џџџџџџufufџџџџVHF 73џџџџџџ%g%gџџџџVHF 74џџџџџџugugџџџџVHF 75џџџџџџ%h%hџџџџVHF 76џџџџџџuhuhџџџџVHF 77џџџџџџ%%iџџџџVHF 78џџџџџџuuiџџџџVHF 79џџџџџџ%%pџџџџVHF 80џџџџџџuupџџџџVHF 81џџџџџџ%%qџџџџVHF 82џџџџџџuuqџџџџVHF 83џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџususџџџџVHF 87џџџџџџ%t%tџџџџNawakaџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%`D%`DDџџџџPMR 1џџџџџџџu`Du`DDџџџџPMR 2џџџџџџџ%1`D%1`DDџџџџPMR 3џџџџџџџuC`DuC`DDџџџџPMR 4џџџџџџџ%V`D%V`DDџџџџPMR 5џџџџџџџuh`Duh`DDџџџџPMR 6џџџџџџџ%`D%`DDџџџџPMR 7џџџџџџџu“`Du“`DDџџџџPMR 8џџџџџџџ%aD%aD@џџџџPMR 9џџџџџџџuaDuaD@џџџџPMR10*џџџџџџ%1aD%1aD@џџџџPMR11*џџџџџџuCaDuCaD@џџџџPMR12*џџџџџџ%VaD%VaD @џџџџPMR13*џџџџџџuhaDuhaD&&@џџџџPMR14*џџџџџџ%aD%aD//@џџџџPMR15*џџџџџџu“aDu“aD66@џџџџPMR16*џџџџџџ%`D%`DДД@џџџџKEN 1џџџџџџџu“`Du“`Duu@џџџџKEN 2џџџџџџџ%1`D%1`D  @џџџџKEN 3џџџџџџџuh`Duh`D@џџџџKEN 4џџџџџџџuC`DuC`DЄЄ@џџџџKEN 5џџџџџџџu`Du`DЮЮ@џџџџKEN 6џџџџџџџPb%FPb%F@џџџџFRS 1џџџџџџџP‡%FP‡%F@џџџџFRS 2џџџџџџџ%CC%CC@џџџџLPD 1џџџџџџџPCCPCC@џџџџLPD 2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џ@џџџџ џџџџџрџџџџџџџџџџџџџџџџџџџџџџџџџџџџГЩдБ1џџџџџџџџГЩдБ2џџџџџџџџГЩдБ3џџџџџџџџГЩдБ4џџџџџџџџГЩдБ5џџџџџџџџГЩдБ6џџџџџџџџГЩдБ7џџџџџџџџГЩдБ8џџџџџџ џџГЩдБ9џџџџџџџџГЩдБ10џџџџџџџГЩдБ11џџџџџџџГЩдБ12џџџџџџџГЩдБ13џџџџџџџГЩдБ14џџџџџџџГЩдБ15џџџџџџџГЩдБ16џџџџџџџГЩдБ17џџџџџџџГЩдБ18џџџџџ џџГЩдБ19џџџџџџџГЩдБ20џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ7SKџџс‹д‡c{џџџџџ7Pџџс‹д‡`rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџГЩдБ19џџџџџџџГЩдБ20џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ7SKџџс‹д‡c{џџџџџ7Pџџс‹д‡`rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџГЩдБ19џџџџџџџГЩдБ20џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ7SKџџс‹д‡c{џџџџџ7Pџџс‹д‡`rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Welcome џџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџUV-17ProџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjE3UHJvIiwgInZlbmRvciI6ICJCYW9mZW5nIiwgIm1vZGVsIjogIlVWLTE3UHJvIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Retevis_RB26.img0000644000175000017500000000170514411666130017322 0ustar hibbyhibbyPb%FPb%Fžž P‡%FP‡%FЄЄ P&FP&Fљљ P7&FP7&F&& Pb&FPb&FUU P‡&FP‡&F…… P'FP'FЖЖ PbuFPbuFЃ(Ѓ(P‡uFP‡uF((PvFPvF'('(P7vFP7vF)()(PbvFPbvF+(+(P‡vFP‡vF5(5(PwFPwFN(N(P%FP%FЮЮ u%Fu%FуЉуЉ &F&FкЈкЈ %&F%&Fљљ P&FP&FЃЈЃЈ u&Fu&F†)†) %V'F'FйЉйЉ F%'F%'FUU P%FPuFUU u%FuuFUU &FvFUU %&F%vFUU P&FPvFUU u&FuvFUU 'FwFUU %'F%wFUU 0џџџџ282626џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000џchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjI2IiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIkR5bmFtaWNSYWRpb0FsaWFzIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_FT-450D.img0000644000175000017500000003526014411666130017242 0ustar hibbyhibby9#`ёСFU R…2 , ' x С УЊ` ” ћ і@ˆ ”xШ† џџџџџџџ@‚€ –<Юh† џџџџџџџ@ •oD†  E‚€ •šЅи† џџџџџџџEЂ•жА№†  @0” "х†  C:ЈˆXу|@–P†  A˜X”і<uрф†  C H•О † џџџџџџџDA ˆ•  H№  @ •оПp†  @ˆ ”xШ† џџџџџџџ@<“аARES80M@ •o2†  B •˜–€†  @ •жлш†  A •Ј€†  A •@o@†  A •uз †  A •Ћ?†  DAЂH… "‘† BLYN @ •оПp†  DЁ•УЉ†  DЁ•!wШB@ @ •"х†  @ •јСаB@ @0” "х†  w@„€њ№€7љ€#|№уџ|№|№уџР|ј€ • <Юh† ARES80M„AЂˆ• .\№ BLYN „Ђˆ• !wШ№ RESRCS „AЂˆ• *а№ LYMAN „AЂˆ• 1З№№ CULTUS „AЂˆ• &0№ VCTORIA„AЂˆ– 5§А№ ENMCLAWџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„ @@”ћ † TSTSPLXџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ H•<Юh† ARES80M€ •o#,† N-NET40€ <“а† N-NET80€ •nкш† NNET40A€ •<Ѓp† TUNE-80€ •oј† TUNE-40џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC а•џ&% † џџџџџџџ@ H•jЯР† џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@ H˜•џo#,† џџџџџџџ…0ВШжА№П 20M-PSK…Ђ•kс0† 40M-PSK…Ђ•šЙ`† 30M-PSK…Ђ–/ † 17M-PSK…Ђ–A€А† 15M-PSK…Ђ•­Р† 10M-PSKџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ…Ђ•lmа† WMR-40C…Ђ@•6ор† WMR-80C…Ђ•6Гш† WMR-80A…Ђ•šЩ† WMR-30A…Ђ•l)t№ WMR-40A…Ђ•6фМ† WMR-80D…Ђ•N`† WMR-17A…Ђ•l^0† WMR-40B…Ђ•зф† WMR-20A…Ђ•6кј† WMR-80B…Ђ•6е† WMR-80EџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDЂJ• ,IP№ VIC-6M DЁАHа… ЦФ#Д VIC-6M EЂH˜•џkљГ† џџџџџџџDЁАHа… ЦФ#Д VIC-6M џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒЂH•&% † WWV-2.5ƒЂH•LK@† WWV-5.0ƒЂH•˜–€† WWV-10.ƒЂH•фсР† WWV-15.ƒЂH•1-† WWV-20.@ H•jЯР† џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ H•uз † ACH-500@ •lИ†  @ •oc †  @ •6ю€†  @ •= †  A H•NйŒ† џџџџџџџAA0RD CN88JD QTH IS SEQUIM WA USA HANDLE IS RICK RICK 듇A H•Q\ † џџџџџџџA H•Qš † џџџџџџџA H•QУЄ† џџџџџџџA H•QќH† џџџџџџџA H•RyH† џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9ї л H•  H№ VIC-6M  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^FT-450Dchirp-20240224/tests/images/Lanchonlh_HG-UV98.img0000644000175000017500000002026114411666130020141 0ustar hibbyhibby%@%@џџџџ%a%aџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%a%aџџџџ%@%@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 0000008888џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџxm\QJGD?<>@Rdh3  ‚Œ– ЊДОШвмц№њџџџ @I[& 66tp6tpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKF7HVM-7џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT`fffijj[YTTTQX4.-89:<9'''''3MHnx‚Œ– ЊДОШвмц№њџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџ0ўџchirpюimgeyJ2ZW5kb3IiOiAiTGFuY2hvbmxoIiwgIm1vZGVsIjogIkhHLVVWOTgiLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIyMTAyNSIsICJyY2xhc3MiOiAiTGFuY2hvbmxoSEdfVVY5OCIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Baofeng_BF-A58S.img0000644000175000017500000002025114411666130017531 0ustar hibbyhibbyџ%E џџ????%!E%!EЕЕD%2E%2E““D%CE%CEUUD%TE%TEээD%fE%fE;;D%vE%vEr r D%‡E%‡ED%˜E%˜ED%F%F33D%"F%"F;; D%3F%3FPP D%DF%DFxx D%UF%UFЫЫ D%"@%"@ D%tC%tCDu™Gu™GDP…P…DPvPvDP'P'D% % D%R#%R#D%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџ%‰%%‰%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`<џџџџџџџџ`<џџџџџџџџџџџџџџŠџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ001џџџџџџџџџџџџџ002џџџџџџџџџџџџџ003џџџџџџџџџџџџџ004џџџџџџџџџџџџџ005џџџџџџџџџџџџџ006џџџџџџџџџџџџџ007џџџџџџџџџџџџџ008џџџџџџџџџџџџџ009џџџџџџџџџџџџџ010џџџџџџџџџџџџџ011џџџџџџџџџџџџџ012џџџџџџџџџџџџџ013џџџџџџџџџџџџџ014џџџџџџџџџџџџџ015џџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџnnnnnnnmlkkkkџџџ____^________џџџFFFFFFFGHHIJJџџџџџџџџџџџџџџџџџџџџџџ190105NџџџџџџџџџWELCOME џџ???????џџџџџџџџџkkkkkklllkkkkkkkllkjiiiiihhgfџџџ]]]\ZXXXXWWXYYYYUUUSRUVVVVVVVџџџGGGHIJJJKKKKKKKKIIHGHIJKKJIIIџџџ џџџџџ?џџ џџџџџ1 <џџџks{ƒŠŸ1 џ€6t `џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ123456BF9166Њ0y нџchirpюimgeyJ2ZW5kb3IiOiAiQmFvZmVuZyIsICJtb2RlbCI6ICJCRi1BNThTIiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAxOTA5MjUiLCAicmNsYXNzIjogIkJGQTU4UyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Radtel_RT-470X.img0000644000175000017500000013167514466370044017446 0ustar hibbyhibby%pF%pFџџџџџџџџџџџџџџџџuqFuqFџџџџџџџџџџџџџџџџ%sF%sFџџџџџџџџџџџџџџџџutFutFџџџџџџџџџџџџџџџџ%vF%vFџџџџџџџџџџџџџџџџuwFuwFџџџџџџџџџџџџџџџџ%yF%yFџџџџџџџџџџџџџџџџu€Fu€Fџџџџџџџџџџџџџџџџ%‚F%‚FџџџџџџџџџџџџџџџџuƒFuƒFџџџџџџџџџџџџџџџџ%…F%…Fџџџџџџџџџџџџџџџџu†Fu†Fџџџџџџџџџџџџџџџџ%ˆF%ˆFџџџџџџџџџџџџџџџџu‰Fu‰Fџџџџџџџџџџџџџџџџ%‘F%‘Fџџџџџџџџџџџџџџџџu’Fu’Fџџџџџџџџџџџџџџџџ%@%@џџџџџџџџџџџџџџџџuAuAџџџџџџџџџџџџџџџџ%C%CџџџџџџџџџџџџџџџџuDuDџџџџџџџџџџџџџџџџ%F%FџџџџџџџџџџџџџџџџuGuGџџџџџџџџџџџџџџџџ%I%IџџџџџџџџџџџџџџџџPPPPџџџџџџџџџџџџџџџџ…Q…Qџџџџџџџџџџџџџџџџ…S…Sџџџџџџџџџџџџџџџџ%U%UџџџџџџџџџџџџџџџџuVuVџџџџџџџџџџџџџџџџ%X%XџџџџџџџџџџџџџџџџuYuYџџџџџџџџџџџџџџџџ%a%aџџџџџџџџџџџџџџџџububџџџџџџџџџџџџџџџџ%@$%@$џџџџџџџџџџџџџџџџPA$PA$џџџџџџџџџџџџџџџџ%C$%C$џџџџџџџџџџџџџџџџuD$uD$џџџџџџџџџџџџџџџџ%F$%F$џџџџџџџџџџџџџџџџuG$uG$џџџџџџџџџџџџџџџџ%I$%I$џџџџџџџџџџџџџџџџPP$PP$џџџџџџџџџџџџџџџџuQ$uQ$џџџџџџџџџџџџџџџџuS$uS$џџџџџџџџџџџџџџџџ%U$%U$џџџџџџџџџџџџџџџџuV$uV$џџџџџџџџџџџџџџџџ%X$%X$џџџџџџџџџџџџџџџџuY$uY$џџџџџџџџџџџџџџџџ%a$%a$џџџџџџџџџџџџџџџџub$ub$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџ2љџџџџџџџџџџџџџџџџџџ‰ОџџџџџџџџџџџџџџџџџШŸџџџџџџџџџ џџџџџџџџИЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ( џџџџџџџџџџџџџџџЄYџ( goџ( Сџ( goџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      NUM.31NUM.32NUM.33NUM.34NUM.35NUM.36NUM.37NUM.38NUM.39NUM.40NUM.41NUM.42NUM.43NUM.44NUM.45NUM.46NUM.47NUM.48NUM.49NUM.50NUM.51NUM.52NUM.53NUM.54NUM.55NUM.56NUM.57NUM.58NUM.59NUM.60џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJSVDQ3MFhSYWRpbyIsICJ2ZW5kb3IiOiAiUmFkdGVsIiwgIm1vZGVsIjogIlJULTQ3MFgiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJuZXh0LTIwMjMwODEwIn0=chirp-20240224/tests/images/Retevis_RB85.img0000644000175000017500000000222114411666130017321 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%C%CppщCPbCPbCˆˆщbC%C%CssщCPbCPbCщbC% C% Ceeщ CPb%CPb%Cssщb%C%0C%0Ceeщ0CPb5CPb5Cщb5C%@C%@Cbbщ@CPbECPbEC00щbEC%PC%PCCЧCЧщPCPbUCPbUC2У2УщbUCPbeCPbeCCТCТщbeCPbuCPbuC††щbuCPb…CPb…C1Ч1Чщb…CPb•CPb•CbФbФщb•Cџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹љџџSM-5558џџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjg1IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMTEyMjEiLCAicmNsYXNzIjogIlJCODVSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Leixen_VV-898S.img0000644000175000017500000002027514562116574017472 0ustar hibbyhibbyuџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЁџџџџџєЂџџџџџєџџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№џџџџџџџ№ЊџџџџџєŠ‰Ÿџџџџѕџџџџџџџ№џџџџџџџ№ŠџџџџџѓŠџџџџџѓџџџџџџџџ™™џџ  S4џџџџџџџџџџџџџџџџџ`@DC  S4џLeixenџLX-‰…uџџџџџџџџџЧ џqџЄCђ‡c" џйбc№б <ч<џ@S->3а •Œ 4>YQ„Šа‡.FBѕ`џџ њPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAPO №№APRO ТjBC Lock ТBeep  CHASave 3DTMF Т @@@DW @@@DecType C  DecCode SEncType c EncCode s @@@FM ƒ@@@FM SCAN FM SQL №FM DW Font .RKeyLock   Keypad 'Lamp NameSYS   NameCHA в NamEdit #@@@OpenDIS Р6Р@P1 Long "№!№P1Short "TP2 Long !№!№P2Short !TP3 Long #№!№P3Short #TPower Т€Р@PTT ID Т €€€Roger ЦReverse Ѓ  RPT SET RPTType SaveBat SCAN “  SCNMode †  SCANADD Т SQL  Step цPd№Tail Т Talk Г  TOT † >TxStop @@@Vox ‚ Vox D 0:№Vox S VXB ЦWIDNAR Т  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ OFF ON OFF 10M 20M 30M 40M 50M 1H1.5H 2H 4H 6H 8H 10H 12H 14H 16HNarrWide OFF KeyCont Low MidHighHigh K+S PTT KEY ALL CO TO DC FMMONIMOLO SQMMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 5K6K25 10K12K5 25K ALLTimeUser SYS 1S 2S 3S 4S OFF 10S 20S 30S 40S 50S 60S 70S 80S 90S100S110S120SSING-RPT+RPT OFF CTCNDCSIDCSSMAL BIG DC FMBANDTIMEMOLOMUTESCAN LOW EMG V/MDTMFCALL1750 A/BTalk REV 2K5 5K6K25 10K12K5 25K OFFCompScraTXScRXScџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџUSER џџџџџџџџ LEIXEN Welcome Waiting Debug Day CHA- Menu ( ) Vol Call Reset ? ALL RES FUN RES DEL B Send Error TX Stop KeyLock SEND џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%%%%џџџўАќ"3Cu"3CuџџџўАќ@@џџџўАќ@@џџџўАќCQCQџџџўАќF™F™џџџўАќ@@џџџўpќF™F™џџџўpќ@@џџў0ќF™F™џџў0ќaaџџџўАќQQџџџўАќ@@џџџўАќaaџџџўpќ@@џџџўpќaaџџў0ќ@@џџў0ќCQCQџџџ~Аќ@@џџџо0ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Name001 Name002 Name003 Name004 Name005 Name006 Name007 Name008 Name009 Name010 Name011 Name012 Name013 Name014 Name015 Name016 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJMZWl4ZW5WVjg5OFNSYWRpbyIsICJ2ZW5kb3IiOiAiTGVpeGVuIiwgIm1vZGVsIjogIlZWLTg5OFMiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/CRT_Micron_UV.img0000644000175000017500000003150514411666130017520 0ustar hibbyhibbyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџQP ђCPP ђWELCOMEџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ dd–88888 12345 23456 34567 45678 FFFd–d 2F4^ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 123456   QPCP  ђџchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIkNSVCIsICJtb2RlbCI6ICJNaWNyb24gVVYiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Yaesu_VX-5.img0000644000175000017500000001767314411666130017026 0ustar hibbyhibby  $р$рџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џўџўџўџўџўџўџўџўџўџўџў1234џўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўcdefghijklџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўџўКЛМНПРСХЦЧШЩЪЫЬЭЯабвгдежџџџџџџџџS2KJ6VU/r  r@0W6RGG/r u0SCARES/s U…0SPACE/s  R00N6NFI/r  Rp0W6ASH/r  f@0WR6ABD/rt0simpl1/s a0AA6BT/r  i…0W6UU/r p`0W6CX/atv S0K6ARC/r Qp0K6GLares a0џџџџџџџџ` џџ pE0K6LRG/r  a0џџџџџџџџ`? џџ…d70AMBDISP1 …t70AMBDISP2 …„70AMBDISP3 BP0CTYFIRE1 R00N6NFI/r  D0CTYFIRE3 ƒU0CTYFIRE4 FV0CTYFIRE5P 90FCMD-CUP QE0FCMD-SJ1 W`0FCMD-SJ2 Y…0FCMD 2  E10AMBULNCEP G@0TRANSTPD W0CITYPD-1 XP0CITYPD-2 aP0CITYPD-3 b0CITYPD-4 –0CITYPD-5 ™u0CITYPD-6 U0CITYPD-7 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџd0simpl1/1 d00simpl1/2 dE0simpl1/3 d`0simpl1/4 e 0simpl1/5 e•0simpl1/6 tP0simpl1/7 u0simpl1/8 up0simpl1/9 u…0simpl1/a "D 0KB6LCS/r"B€0WA6GFY/r "A@0W6ASH/r  "@@0KU6V/r  џџџџџџџџџџџџџџџџџџџџџPP0џџџџџџџџ0 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC0P0џџџџџџџџP0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"40simpl2/1 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ"5 0simpl2/2 D)0WR6ABD/rPD2%0KJ6K/r P D4P0K9GVF/r PD7%0K9GVF/r PD9u0KJ6VU/r P D2u0K6SNY/r PD7u0WA6GFY/rP DP0W6JWS/rTP DF%0N6NAC/r PDGu0W6YOP/r PџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD0simpl4/1P D`0simpl4/2P De0simpl4/3P џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 0KU6V/r &`0KD6AOG/rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ†2PAO TWR P1PAO GRND 0simpl5/1 0simpl5/2 90simpl5/3 †1PAO TWR iP1SJC ATIS 1SJC 1129 Au1MOF ATIS P1PAO GRND 1PAO ATIS •P1MOF TOWR @1SJC 1230 …d70AMBDISP1 …t70AMBDISP2 …„70AMBDISP3 BP0CTYFIRE1 B€0CTYFIRE2 D0CTYFIRE3 ƒU0CTYFIRE4 FV0CTYFIRE5P 90FCMD-CUP QE0FCMD-SJ1 W`0FCMD-SJ2 Y…0FCMD 2  E10AMBULNCEP G@0TRANSTPD W0CITYPD-1 XP0CITYPD-2 aP0CITYPD-3 b0CITYPD-4 –0CITYPD-5 ™u0CITYPD-6 U0CITYPD-7 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@   @   @  C P € 8 †   … wwu €@ d` D7… P. ""% †    … pP   u  C3u P `% 0 X џџџџџџџџџџџџџџџџ ••–––———џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчb€ в|јBџџџџџџџџџџџџџџџџџџџџ> D2%PKJ6K/r d  э€Ъџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ chirp-20240224/tests/images/Alinco_DJ-G7EG.img0000644000175000017500000032414514411666130017425 0ustar hibbyhibbyddШ22ddddddШdddџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@†ЄР' їан @Я€їs ЈЫ@B Р!0M-1 Р2 @B џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€Ћ8 @B џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€‰@B џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@†ЄР' џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџАЦ  €[ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€п@T‰ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWІ Хћ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@Я€їs џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџА j €[ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€%л3Р;G џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџp89-1 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџР!0M-1 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџT Р' > Simplex 144.725XL­Р'  > Moleson 9PEXL­Р' !!> Cari 9EIЎ­Р'  > R0 145.6000Ў­Р'  > Les PleiadesЎ­Р' > Gempen HB9BSЎ­Р' > Luzern HB9LUЎ­Р'  > Motto RottondoЎ­Р'  > Parpaner RothornЎ­Р' > Stollenhaeusernдо­Р'  > R0X 145.6125ЈЎР'  > R1 145.6250ЈЎР' > Eglisau HB9EEЈЎР' > Geneve HB9GEЈЎР' > Poschiavo 9OKЈЎР'  > MoosalpЈЎР'  > Petit Ballon|@ЎР'  > R1X 145.6375|@ЎР' > Rigi ScheideggPqЎР'  > R2 145.6500PqЎР'  > Magglingen$ЂЎР'  > R2X 145.6625$ЂЎР' > WeissfluhgipfelјвЎР'  > R3 145.6750јвЎР'  > Hoechensch.DB0YHЬЏР'  > R3X 145.6875 4ЏР'  > R4 145.7000 4ЏР'  > Schilthorn HB9FteЏР'  > R4X 145.7125teЏР'  > Homberg DB0XRH–ЏР'  > R5 145.7250H–ЏР'  > Poele Chaud 9GH–ЏР'  > Zugspitze DB0ZUteЏР'  > Wildberg 9ZЧЏР'  > R5X 145.7375ЧЏР'  > Bad RamsachЧЏР' > Zuerich HB9SP№їЏР'  > R6 145.7500№їЏР'  > Kaiserst. DB0ZF№їЏР'  > Sex CarroФ(АР'  > R6X 145.7625Ф(АР' > Bachtel HB9ZFФ(АР' > Mt. Tamaro HB9HФ(АР'  > Zermatt HB9Y˜YАР'  > R7 145.7750˜YАР'  > Laegern HB9AGlŠАР'  > R7X 145.7875@ЛАР'  > R8 145.8000@ЛАР'  > ISS SpacestationџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPФЬ€їs> Simplex 432.850<љ€їs> Hoernli 9NF*€їs> Iddaburg 9IDфZ€їs> BrienzwilerŒМ€їs> Uetliberg 9KW,C!€їs> Rigi 9RFt!€їs> Lehn 9LUЈе!€їs> NuetziweidЈе!€їs > Oerliken 9ZRH|"€їs> Scheidegg 9FBЬЩ"€їs> Mellingen 9NAВ$€їs> Falkenfluh 9BGD%€їs > RU692 438.650D%€їs > Roc Blanc 9YD%€їs> Uetliberg8І%€їs > RU694 438.6758І%€їs> Mt.Bar8І%€їs > Moosalp8І%€їs> Muttenz8І%€їs> Zug 9RFр&€їs > RU696 438.700р&€їs> Weissensteinˆi&€їs > RU698 438.725ˆi&€їs> Chasseralˆi&€їs > Grellingen0Ы&€їs > RU700 438.7500Ы&€їs> Saentisи,'€їs > RU702 438.775и,'€їs > Attinghausenи,'€їs> Cimettaи,'€їs > SissacherfluhЌ]'€їs > RU703 438.7875Ќ]'€їs > Friedrichshafen€Ž'€їs > RU704 438.800€Ž'€їs> Pilatus(№'€їs > RU706 438.825(№'€їs> Rigi ScheideggаQ(€їs > RU708 438.850аQ(€їs > Kaiserst. DB0ZFаQ(€їs > La PrazxГ(€їs > RU710 438.875xГ(€їs > HofberglixГ(€їs> Luzern 9LU )€їs > RU712 438.900 )€їs > FeldbergШv)€їs > RU714 438.925Шv)€їs > Bern WBankdorfШv)€їs> Braunau TGШv)€їs > Gerlisbergpи)€їs > RU716 438.950pи)€їs> Strihen:*€їs > RU718 438.975:*€їs > Interlaken:*€їs > MollisР›*€їs > RU720 439.000Р›*€їs> Le GiblouxР›*€їs> Zuerich HB9SPh§*€їs > RU722 439.025h§*€їs> Buchserbergh§*€їs > Schaffhausen_+€їs > RU724 439.050_+€їs> Andermatt_+€їs > Niesen_+€їs > San SalvatoreИР+€їs > RU726 439.075ИР+€їs > Grenchenberg`",€їs > RU728 439.100`",€їs > Bachtel 439.100`",€їs > Petit Lancy„,€їs > RU730 439.125„,€їs> Basel 9FMАх,€їs > RU732 439.150Ах,€їs > BurgdorfАх,€їs> Locarno 9UFАх,€їs > WinterthurАх,€їs> ZofingenXG-€їs > RU734 439.175XG-€їs > Blauen DB0YEXG-€їs> Etzel-Klm. HB9DCЉ-€їs > RU736 439.200Љ-€їs > Kuessabrg DB0HRHЉ-€їs > Thun HB9TЈ .€їs > RU738 439.225Ј .€їs > Le ChasseronЈ .€їs> Gossau 9ZOPl.€їs > RU740 439.250Pl.€їs > Bad RamsachPl.€їs> WillisauјЭ.€їs > RU742 439.275јЭ.€їs> FronalpstockјЭ.€їs > Geneve HB9GE //€їs > RU744 439.300 //€їs > NiederhornH‘/€їs > RU746 439.325H‘/€їs> Gempenfluh 9BS№ђ/€їs > RU748 439.350№ђ/€їs> Affoltern 9RF№ђ/€їs> Weissfluhgipfel˜T0€їs > RU750 439.375˜T0€їs > Loveresse˜T0€їs> Zuerich HB9GL@Ж0€їs > RU752 439.400@Ж0€їs> Bachtel 439.400@Ж0€їs> Reckingn HB9GOMSш1€їs > RU754 439.425ш1€їs > Bad Saeck.DB0SACш1€їs> Genfш1€їs> Valscura HB9EIy1€їs > RU756 439.450y1€їs > Belpy1€їs> Gerlisberg8л1€їs > RU758 439.4758л1€їs > Schilthorn 9Fр<2€їs > RU760 439.500ˆž2€їs > RU762 439.52503€їs > RU764 439.55013€їs > Poschiavo 9OKиa3€їs > RU766 439.575Ќ’3€їs> St.Gallen 9SGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`GVM > SpxCall 1297.500А WM > Simplex 1297.550ž[M > Simplex 1297.850` J?Ћ > Augsburg DB0UAA А?cM?Ћ > Blauen DB0YEИbM?Ћ > Chestenberg 9AM`|bM?Ћ > Durlach DB0UX J KР > Jungfraujoch№LfM?Ћ > Kaiserst. DB0ZFРw J?Ћ > La BariletteX| KР > Lohn HB9SHXЁcM?Ћ > Reutlingn DB0REUxФJ?Ћ > Schauinsl DB0FRGPЦdM?Ћ > St.Georgn DB0STGHыeM?Ћ > Tegelberg DB0PFRhWaM?Ћ > Trogen`"KР > Uetliberg 1750рІK@Šї > Uetliberg Traeg. 1M@Šї > Uetliberg ReversdM?Ћ > Uplamoer DB0ACA€ЪbM?Ћ > Villingen DB0SWB0KР > Weissensteinpи§JР > Zofingen@gM?Ћ > Zugspitze DB0ZUИЊJM > Bake Stra. F5ZBSрЧKM > Bake P.Bal.F1ZBI€бLM > Bake Frei.DB0FREˆЌKM > Bake Tref.DB0RIGP'@M > Bake HB9BBD$LM > Bake Neuc.HB9EMEOIM > Bake HB9SHјНLM > Bake Mt.S.HB9OKјНLM > Bake Land.DB0FAIЈkNM > Bake Rosnh.DB0AS`ƒLM > Bake Stutg.DB0LBАFMM > Bake Karls.DB0UXџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@†ЄР' @Я€їs Р!0M-1 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШ:Т 3Я аХW №ЖШ „з а­ ;X }б €УТ €­ќ PЬ РAШ  i  РžW € R @с ш‘ јe И ˜!$ џchirpюimgeyJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmVuZG9yIjogIkFsaW5jbyIsICJtb2RlbCI6ICJESi1HN0VHIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Icom_IC-E90.img0000644000175000017500000002675514411666130016757 0ustar hibbyhibbyЌqЅ 2MFM ЌqЌq€ 2MCALLЌRЌR€ 70CM CРq!x  GB3WR Рq!x@ GB3CF [!xа GB3VM Хq!x GB3NW [!x GB3BM йq!x!GB3CG [!x!GB3ZA оq!x  GB3BC уq!x GB3WK [!x!GB3KD •PA№!UGB3WUЎPA№ UGB3WLЉPA№а UGB3VNMRA@а UGB3HNJ A№а UGB3RCZ A№ UGB3EHzRA@ UGB3MWRRA@ UGB3WM„RA@ UGB3GBќD€ BBCR2 АJ€ BBCWM PK€ BRMB |L€ BBCR1 АO€ BEAR PP€ WYVRN Q€ BBCWM @Q€ BBCHWW@Q€ BBCHWRь6 ђ+ ё6 ђ+ і6 ћ+ ћ6 ў+ 7 , 7 , 7 4MCALL , 7 , 7 xUKC01 ’xUKC02 ”xUKC03 ExUKC04 ˜xUKC05 šxUKC06 œxUKC07 žxUKC08 MxUKC09 ЂxUKC10 ЄxUKC11 ІxUKC12 ЈxUKC13 UxUKC14 ЌxUKC15 ЎxUKC16 АxUKC17 ВxUKC18 ]xUKC19 ЖxUKC20 ИxUKC21 КxUKC22 МxUKC23 exUKC24 РxUKC25 ТxUKC26 ФxUKC27 ЦxUKC28 mxUKC29 ЪxUKC30 ЬxUKC31 ЮxUKC32 аxUKC33 uxUKC34 дxUKC35 жxUKC36 иxUKC37 кxUKC38 }xUKC39 оxUKC40 xEUC01 xEUC02 xEUC03 xEUC04 xEUC05 xEUC06 xEUC07 #xEUC08 %xEUC09 'xEUC10 )xEUC11 -xEUC12 /xEUC13 1xEUC14 3xEUC15 7xEUC16 9xEUC17 ;xEUC18 =xEUC19 AxEUC20 CxEUC21 ExEUC22 KxEUC23 GxEUC24 IxEUC25 MxEUC26 OxEUC27 QxEUC28 SxEUC29 UxEUC30 WxEUC31 YxEUC32 [xEUC33 ]xEUC34 _xEUC35 axEUC36 cxEUC37 exEUC38 gxEUC39 ixEUC40 ѓƒ РW№ˆ 'd‡  (d‡ €pxˆ rxˆ №O№ˆ РW№ˆ ŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ?????????????????????ŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ?ŸŸŸŸŸ????????????????????????????????????????????????????????????????????????????????ŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸџџŸŸџџџџџџџџ‡$ƒ Еx  ,… Q€ `h€ pZp­xˆ Ш… дR… Рд… ѓƒ ш€ ќ&d… Q€ :\ˆ Ќqxˆ p­xˆ !… ЇRУўp … и'd‡ Hqxˆ №O№ˆ кt21CH{22CHZ23CHš‡24CHк25CH”26CHZš27CHš 28CHкІ29CH­30CHZГ31CHšЙ32CHкП33CHЦ34CHZЬ35CHšв36CHки37CHп38CHZх39CHšы40CHкё41CHј42CHZў43CHš44CHк 45CH46CHZ47CHš48CHк#49CH*50CHZ051CHš652CHк<53CHC54CHZI55CHšO56CHкU57CH\58CHZb59CHšh60CHкn61CHu62CHZ{63CHš64CHк‡65CHŽ66CHZ”67CHšš68CHк 69CHџџџџџџџєџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџM1CFK џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP№ё˜ NEIL IcomCloneFormat3џchirpюimgeyJ2ZW5kb3IiOiAiSWNvbSIsICJtb2RlbCI6ICJJQy1FOTAiLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIyMDYyMCIsICJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Retevis_RB29.img0000644000175000017500000000222114411666130017317 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%Fppїb%FP‡%FP‡%Fˆˆї‡%FP&FP&Fssї&FP7&FP7&Fї7&FPb&FPb&Feeїb&F%&F%&Fssї%&F%'F%'Feeї%'FP‡&FP‡&Fї‡&FP'FP'Fbbї'FP%FP%F00їP%Fu%Fu%FCЧCЧїu%F&F&F2У2Уї&FP&FP&FCТCТїP&Fu&Fu&F††їu&F'F'F1Ч1Чї'F%'F%'FbФbФї%'Fџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‹џјџџSMP5558џџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjI5IiwgImNoaXJwX3ZlcnNpb24iOiAiZGFpbHktMjAyMjA4MjMiLCAicmNsYXNzIjogIlJCMjlSYWRpbyIsICJ2YXJpYW50IjogIiJ9chirp-20240224/tests/images/Icom_IC-W32A.img0000644000175000017500000000774014411666130017067 0ustar hibbyhibbyd`146415 d0`146430 dE`146445 d``146460 du`146475 d`146490 e`146505 e `N-SIMP e5`146.535 eP`146550 ee`146565 e€`146580 e•`146595 p`HGN 09 q `W3ACH r%`N3NRI t`147405 t `147420 t5`147435 tP`147.450 te`147465 t€`147480 t•`147495 u`147510 u%`147525 u…`147585 SP` W3KGN T0`N3TWT P NO NAMEP NO NAMEU€`NO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO AMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAME`NO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMEDNO NAMES@NO NAMEPNO NAMEPNO NAMEPNO NAMEPNO NAMEPNO NAMEPNO NAME@џџџџџџџџ€џџџџџџџџ`NO NAMECNO NAME@NO NAME€NO NAMENO NAMENO NAMEB NO NAMENO NAMED N3LTQ/R D0PW3BD/R DP%CR1 DPPCR2 DPuCR3 DQCR4 DQ%CR5 D`NATL SMPD`P446.050 D`u446.075 Da446.100 D@NO NAMEENO NAMEC@NO NAMEDNO NAME€NO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMEDNO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMENO NAMEC0@NO NAMEC0 NO NAMEC0NO NAMEC0`NO NAMEC0`NO NAMECџџџџџџџџEџџџџџџџџ0NO NAME™™‡NO NAMENO NAMENO NAMEC‰€NO NAMECNO NAME0NO NAME™™‡NO NAME ,((€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€<, €€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€€< € №q ` 0D`@0`0DW%`d€``DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџMain File IcomCloneFormat3chirp-20240224/tests/images/Retevis_RT668.img0000644000175000017500000000222514411666130017436 0ustar hibbyhibbyu“aDu“aD&€&€ѕџ%`D%`DHHѕu`u`Du`DHHѕ%1`%1`D%1`DHHѕuC`uC`DuC`DHHѕ%V`%V`D%V`DHHѕuh`uh`Duh`DHHѕ%`%`D%`DHHѕu“`u“`Du“`DHHѕ%a%aD%aD&€&€ѕuauaDuaD&€&€ѕ%1a%1aD%1aD&€&€ѕuCauCaDuCaD&€&€ѕ%Va%VaD%VaD&€&€ѕuhauhaDuhaD&€&€ѕ%a%aD%aD&€&€ѕu“au“aDu“aD&€&€ѕџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџјџџџџџџџџџјџџ‹џјџџSMџP558џјџџјџџјџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDY2OCIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjExMTE4IiwgInJjbGFzcyI6ICJSVDY2OFJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Wouxun_KG-1000G_Plus.img0000644000175000017500000010031514411666130020521 0ustar hibbyhibby†A9e’X'?E>PP%& "PџџџџџџџџџџџџX9c(Sss„S`0`@{wa```w[џџџџџџџџ€@G`029p˜P`@@G`0`@џџџџ(3џю3+Žj-Дi1223457јЃрљЃрњЃр€`@`2pp AFP_s‚Œ– Œ(,048=@DHLPTX\`dџџџџџџџџџџџџџџџџ&-4AKU_n‚‘ ЊЊ(,048<@DHLPPTX^bџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€@G`029p˜P`@@G`0`@B xxxxxxssnnMNOSSMMKII8::<=:8765&'())'&&$$nnssddhilpsx––}}AAAAAAAAAAAAEE<<-------------.--Œ‘‘‘baaaKKKK5555}}}}UUUT9???*+,,Ѕ  ЇБОЭвџџ––––––––––––ІІ––ЏОвцЙвцњЊДОвKKKKPZbm}‘FFFFFFFFFFFFFKKKU_is@HNR]j7777777777777777вцџџ ‚‡Œ‘ААААААААААААААААААААААџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ”Eџџџџf/џџi\PEџџџџџџџџџџџџџџџџA%PZF%…Pa%PZP2%PZp%PZA%PZp чЬ  џџџ#&"P#Pџшџџџџџџџџ'%(%PPE91>PP!E1>*8?EPP*&"PcdЧШ+,ѓєWXЛМ ƒ„чџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF%bPF%bPТF%‡PF%‡PТF&PF&PТF&7PF&7PТF&bPF&bPТF&‡PF&‡PТF'PF'PТFubPFubPйFu‡PFu‡PйFvPFvPйFv7PFv7PйFvbPFvbPйFv‡PFv‡PйFwPFwPйF%PF%PкF%uF%uкF&F&кF&%F&%кF&PF&PкF&uF&uкF'F'кF'%F'%кF%PFuPšF%uFuušF&FvšF&%Fv%šF&PFvPšF&uFvušF'FwšF'%Fw%šџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS-01GMRS-02GMRS-03GMRS-04GMRS-05GMRS-06GMRS-07GMRS-08GMRS-09GMRS-10GMRS-11GMRS-12GMRS-13GMRS-14GMRS-15GMRS-16GMRS-17GMRS-18GMRS-19GMRS-20GMRS-21GMRS-22RPT-15RPT-16RPT-17RPT-18RPT-19RPT-20RPT-21RPT-22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPPPPPPPPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJLRzEwMDBHUGx1c1JhZGlvIiwgInZlbmRvciI6ICJXb3V4dW4iLCAibW9kZWwiOiAiS0ctMTAwMEcgUGx1cyIsICJ2YXJpYW50IjogIiIsICJjaGlycF92ZXJzaW9uIjogIm5leHQtMjAyMzAxMjEifQ==chirp-20240224/tests/images/Retevis_RT22.img0000644000175000017500000000201014411666130017326 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%!F%!FЕЕ0€%"F%"Fџџџџ0%#F%#Fџџџџ0%$F%$F  0%%F%%F||0%&F%&Fљљ0%'F%'FUU0%(F%(FVV0%)F%)F((0%0F%0F)()(0%1F%1FU(U(0%2F%2FmЈmЈ0%5F%5F5Љ5Љ0%E%E((0%F%Fџџџџ0P™FP™Fѓѓ0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ<<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP32073јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџRT22 chirp-20240224/tests/images/Retevis_RT40B.img0000644000175000017500000000100514411666130017433 0ustar hibbyhibbyPb%FPb%Fžž(P‡%FP‡%FЄЄ(P&FP&Fљљ(P7&FP7&F&&(Pb&FPb&FUU(P‡&FP‡&F……(P'FP'FЖЖ(PbuFPbuFЃ(Ѓ(FP‡uFP‡uF((PvFPvF'('(%VP7vFP7vF)()(џџџPbvFPbvF+(+(282P‡vFP‡vF5(5(PwFPwFN(N(P%FP%FЮЮ(626u%Fu%FуЉуЉ(&F&FкЈкЈ(%&F%&Fљљ(P&FP&FЃЈЃЈ(u&Fu&F†)†)('F'FйЉйЉ(%'F%'FUU(џchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDQwQiIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwOTE3IiwgInJjbGFzcyI6ICJSVDQwQlJhZGlvIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Yaesu_FT-817ND.img0000644000175000017500000001457114411666130017371 0ustar hibbyhibbyиП@ƒрЬ(–ВB&х2K2…€В22222=`HС'џџџџџџџџaH|L'џџџџџџџџbH Е'џџџџџџџџbHB@'џџџџџџџџaHaЂ'џџџџџџџџaHw@'џџџџџџџџaH 'џџџџџџџџaH%bP'џџџџџџџџaH*Й€'џџџџџџџџAHLK@† џџџџџџџџEO…ƒАџџџџџџџџDKЄЫ€џџџџџџџџBKоъ`џџџџџџџџEЅNС GаqџџџџџџџџdH)2р'џџџџџџџџbHП 'џџџџџџџџ`HW0'џџџџџџџџbH Д<'џџџџџџџџbHB@'џџџџџџџџaH\Р'џџџџџџџџaHw@'џџџџџџџџaH 'џџџџџџџџaH%bP'џџџџџџџџbH*ЙМ'џџџџџџџџAHUs† џџџџџџџџEOЄЫ€џџџџџџџџDKб  џџџџџџџџEO€оxџџџџџџџџEN•ŽЁ џџџџџџџџbHцx'џџџџџџџџeH-*€'џџџџџџџџEHP%”† џџџџџџџџEHн@ ъ`џџџџџџџџEN”Д Ё џџџџџџџџ…хЃ<ффRU GE џџџџџџџџџџџџџџџџџџџџџџџџџџE%Ѓ<ффRU GE П  @LK@ReРgџџџџџџџџџџџџ?џџџџџџџџџџџџ?ЅH€•*'ARI PD U…K€(нЂH145.250 …K€н№h145.450 …K€˜qЈ435.450 …dc( оRъ`R4 PD ЅЅH( GаqRU+4 PD ЅЅH(nрqRU+8 PD …K(”бьLPD 1 …K€•dhLPD 16 …ЅK(“нШЮxRU3T ‡K€мђ€APRS …фc€,оy о 0ISS …KмќDI3ITX-6 †K€м‡IK6EDJ-6…KмŸ~RU3T VHF…eK(’ѓhqTRASPOND…dc€(о+ъ`R0 TN …dc(о/тъ`R0a …dc€(о4Фъ`R1 VE …dK( о9Іъ`R1a …dc(о>ˆъ`R2 TV …dc€(оCjъ`R2a …dc( оHLъ`R3 VI …dc(оM.ъ`R3a BL …dc(оRъ`R4 …dc(оVђъ`R4a …dc(о[дъ`R5 VR …dc(о`Жъ`R5a VR …dc(оe˜ъ`R6 TN …dc(оjzъ`R6aBL TN…dc( оo\ъ`R7 VR …dc€(оt>ъ`R7a TN …dK( о&ъ`MARMOL …Ѕc%ЂqRU+0A …ЅK(*„qRU+1VR …Ѕc/fqRU+4A BO…ЅK( 4HqRU+2 VR …ЅK(9*qRU+2a BL…ЅK(> qRU+3 FC …ЅcBюqRU+3A TV…ЅK( GаqRU+4 ……KMоqRU+4A TN…Ѕc(Q”qRU+5 TV …Ѕc€VvqRU+5A …ЅK([XqRU+6 VE …ЅK( `:qRU+6aTV …ЅK(eqRU+7 …ЅK(iўqRU+7a Bl…ЅKnрqRU+8 PD …ЅcsТqRU+8A TN…ЅK(xЄqRU+9 …Ѕc}†qRU9A …Ѕc€‚hqRU+10TN …Ѕc(•*qRU10A …Ѕc(Œ,qRU+11 BG…Ѕc(‘qRU+11A …Ѕc(•№qRU+12 ……K(š qRU+12A …Ѕc(ŸДqRU+13 …Ѕc( Є–qRU+13A …ЅcЉxqRU+14 …Ѕc(ЎZqRU+14AVI…Ѕc€(Г<qRU+15 …ЅcИqRU+15A …Ѕc€‘џDqRU+16 BL…Ѕc’&qRU+16A …Ѕc’ qRU+17 …Ѕc’ЬqRU+18 BL…Ѕc’ЎqRU+18A …Ѕc’qRU+19 …Ѕc€’!rqRU+19A …Ѕc’&TqRU+20 …Ѕc’+6qRU+20A …Ѕc’0qRU+21 …Ѕc€’4њqRU+21A …Ѕc’9мqRU+22 …Ѕc’>ОqRU+22A …Ѕc’C qRU+23 TN…Ѕc’H‚qRU+23A …Ѕc’MdqRU+24 BZ…Ѕc€(’RFqRU+24A …Ѕc(’W(qRU+25 …Ѕc(’W(qRU+25 ……K’]ўqRU+25A …Ѕc’`ьqRU+26 …Ѕc€’eЮqRU+26A …Ѕc’ttqRU+28 …Ѕc’~8qRU+29 …Ѕc’‡ќqRU+30 …eK€((’ѓhqRU-10 …ec’јJqRU-10A …eK( ’§,qRU-11 TV…eK€(“ вqRU-12ARO…eK€“ДqRU-13 …eK€“xqRU-14 …ec€“$<qRU-15 …ec“)qRU-15A …Ѕc9*qRU BL …Ѕc€-‰^qDB0FIG …K“)T Marmol…ec˜J˜qRU CO …хc-ф˜…0RU GE …хЃ-ффRU GE …хЃ-ффCH-104 ПфOˆџљш€оRLK@splittedџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџaHтŽ'џџџџџџџџ" $$U@ƒЃ<ффRU GE џџџџaH"а'џџџџџџџџaH)'џџџџџџџџaH0р'џџџџџџџџaH2д'џџџџџџџџaH?T'џџџџџџџџchirp-20240224/tests/images/BTECH_UV-25X2_G2.img0000644000175000017500000004026514430171343017375 0ustar hibbyhibby%f%f%v%v%D%D%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%D%Dџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШпџџџџџџџџџџџџ=џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWELCOME UV-25X2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ÿџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ----------------2222222222222222 &!#000000&!#))))))&!#))))))&!#))))))-   2 UV-25XUCB282  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000UCB282000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJVVjI1WDJfRzIiLCAidmVuZG9yIjogIkJURUNIIiwgIm1vZGVsIjogIlVWLTI1WDJfRzIiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Icom_IC-P7.img0000644000175000017500000007240014551723752016705 0ustar hibbyhibbyР’эфв€ќ Р*mMРсффв€ќ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ €пфВ€ќ `sфВ€ќ @!фВ€ќ ›%фВ€ќ /*фВ€ќ рТ.фВ€ќ РV3фВ€ќ  ъ7фВ€ќ €~<фВ€ќ `AфВ€ќ @ІEфВ€ќ :JфВ€ќ ЮNфВ€ќ рaSфВ€ќ РѕWфВ€ќ  ‰\фВ€ќ €aфВ€ќ `БeфВ€ќ @EjфВ€ќ йnфВ€ќ msфВ€ќ рxфВ€ќ Р”|фВ€ќ  (фВ€ќ €М…фВ€ќ `PŠфВ€ќ @фŽфВ€ќ x“фВ€ќ ˜фВ€ќ рŸœфВ€ќ Р3ЁфВ€ќ  ЧЅфВ€ќ €[ЊфВ€ќ `яЎфВ€ќ @ƒГфВ€ќ ИфВ€ќ ЋМфВ€ќ р>СфВ€ќ РвХфВ€ќ  fЪфВ€ќ €њЮфВ€ќ `Žгф€ќ @"иф€ќ Жмф€ќ Jсф€ќ рнхф€ќ Рqъф€ќ  яф€ќ €™ѓф€ќ `-јф€ќ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ШЈфв€ќ 9ЯВфв€ќ ЬПфв€ќ €Yфв€ќ €жуLРсффв€ќ š­NРсффв€ќ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџ ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџ˜:h§›џџџџџџџџџџџџР’эфв€ќ Р*mMРсффв€ќ P 1аО1 2PgD 3P2m 4ак  5Pƒ’! 6а+Ѕ" 7аF\# 8Pяn$ 9а—%10P@”&11ашІ'12PU13аУ$V14Pl7W15аJX16PН\Y17аeoZ18P‚[19аЖ”\20P_Ї]21аК^22PАЬ_23аXп`24Pђa25аЉc26PRd27ањ)e28PЃПm36Pчбn37афo38P8їp39ар r40P‰s41а1/t42PкAu43а‚Tv44P+gw45агyx46P|Œy47а$Ÿz48PЭБ{49аuФ|50Pз}51аЦщ~52Poќ53а54PР!‚55аh4ƒ56PG„57аЙY…58Pbl†59а ‡60PГ‘ˆ61а[Є‰629ЯВџ 9ЯВџ 9ЯВџ 9ЯВџ 9ЯВџ 9ЯВџ 9ЯВџ 9ЯВџ ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРџџџџџчџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРџџџџџџ?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРџ№џџџџџџ?џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`(Jфв€ќРсффв€ќ@˜ фв€ќ— фв€ќ€œфв€ќР’эфв€ќ€A)Bфв€ќР*mMРсффв€ќвIkфв€ќ€щ§—фв€ќР’эфв€ќ рђџџШџ џџџ џџџIcomCloneFormat3chirp-20240224/tests/images/QYT_KT-WP12.img0000644000175000017500000004024514411666130016712 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ%CuGџџџџџџџџџџџџџџџџ%v%vЮЮ%T%T%C%C%UC%UCљљ%wC%wC %˜C%˜CввP'GP'Gџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   <џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШџџџџџџџџџџџџџ/џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџModel-KT9900D  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgx џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ &!#000000&!#))))))&!#))))))&!#))))))-   2KT-WP1WP3094 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000WP30940000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJ2ZW5kb3IiOiAiUVlUIiwgIm1vZGVsIjogIktULVdQMTIiLCAiY2hpcnBfdmVyc2lvbiI6ICIwLjMuMGRldiIsICJyY2xhc3MiOiAiS1RXUDEyIiwgInZhcmlhbnQiOiAiIn0=chirp-20240224/tests/images/Alinco_DR235T.img0000644000175000017500000001000014411666130017302 0ustar hibbyhibbyЅfU3Ѕf0…=CHMWvqlgb]XRMHC>94/)$Ь3 (€"%#P`P`P`P`Ѕ џџ№$` #P#P#P$d KLTLBF$dKLTLBF$8` ?BK>MKE#R:KTLBF#PG:MTLBF$TLCTLBF1#HLCTLBF2#†` :KERF:G#”`:KARLMD$$` :KT;ERG$f` :KT@HE=$`FHGKH>$(`>O>K>MM$8` F:KRLOE$T`$x` ERF:G$P` MB@>KFM#˜` >TMB@>K$` FBD>D>R$h` L>:MME>#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P#P224380џџџџџџџџџџџџџџџџchirp-20240224/tests/images/Q-MAC_HF-90_v301_or_later.img0000644000175000017500000002030514430171343021202 0ustar hibbyhibbyЭwџџ4џ’€! ”Х@Y LlСФј–†ЈА­лцIbЈ$џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJMYXRlSEY5MFJhZGlvIiwgInZlbmRvciI6ICJRLU1BQyIsICJtb2RlbCI6ICJIRi05MCIsICJ2YXJpYW50IjogInYzMDEgb3IgbGF0ZXIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Retevis_RT87.img0000644000175000017500000002022514411666130017351 0ustar hibbyhibbyџџџџџџџџџџџџџџџџCxPCxPџџџџFVPVPџџџџFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`%`%џџџџџџ@%@%џџџџџџ7‘&PџџџџџџџџџџџџPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ%%%%%--Zdddddddd-----::::::::::::::::щцммШШШввввыыыыы@@@@@@@@@@@@@@@@F2и@џџџџџџ:"##! !!77777722////////MMMMMMMMMMMMMMMM–ЊОООШОООУОУУУШвNNNNNNNNNNNNNNNNdFP   џџџџџџџ1100.+(%%%%%%%%%---+***---------ccccccccccccccccмммммцыыыыыыыыыыRRRRRRRRRRRRRRRRdFP   џџџџџџџ %%%%%%%ddddddZZZ-------eeeeeeeeeeeeeeeeссссссссзыыыыыыы@@@@@@@@@@@@@@@@dFP  џџџџџџЅџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`@`@џџџџџџџ 0 0џџџџџџџ0@0@џџџџџџџ@H@Hџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $Adџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ`7џџџџџџџџџџџџ@џџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџdЎFЎFЎ(Ў!ЎFЎFЎFЎџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSVDg3IiwgImNoaXJwX3ZlcnNpb24iOiAiMC4zLjBkZXYiLCAicmNsYXNzIjogIlJUODciLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/Yaesu_VX-8R.img0000644000175000017500000017731314411666130017151 0ustar hibbyhibbyAH029џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ iџџџџџџџџџџџџџџџџ џџџџ `џџџџџџџџџџџџџџџџ ˜зџџџџ Cџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџ# шТЮЈџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУџџџџџџдУџџџџџџд џџџџD0Pџџџџџџџџџџџ BGD0Р  PF2 џџџџD0Pџџџџџџџџџџџ BGD0Р  PF2џџџџ t@џџџџџџџџџџџџџџџџ p@t@€ $ Ÿџџџџ t@џџџџџџџџџџџџџџџџ p@t@€ $ Ÿ џџџџ `џџџџџџџџџџџџџџџџ ˜p@`€  џџџџ `џџџџџџџџџџџџџџџџ ˜p@`€ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $џџџџџџџџџџ $ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ  џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџ џџџџџџџџџџC@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G€Рџџџџџџџџџџџџџџџџ e Рџџџџџџџџџџџџџџџџ ˆ@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ D`РџџџџџџџџџџџџџџџџP ˆGРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ‰gРџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜‡CРџџџџџџџџџџџџџџџџ t Сџџџџџџџџџџџџџџџџ ˆ@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ DbџџџџџџџџџџџџџџџџP ˆGРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ C@Рџџџџџџџџџџџџџџџџ ˜@Рџџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ ˆ`Рџџџџџџџџџџџџџџџџ ˜‰ WPРџџџџџџџџџџџџџџџџ ˜G%Рџџџџџџџџџџџџџџџџ e Рџџџџџџџџџџџџџџџџ ˆ@Рџџџџџџџџџџџџџџџџ " Рџџџџџџџџџџџџџџџџ 'D %СџџџџџџџџџџџџџџџџP ˆGРџџџџџџџџџџџџџџџџ †Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУУУƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒƒe С %6#џџџџџџџџџџџџP 'DPТџџџџџџџџџџџџџџџџP iР   џџџџџџ  s Р $ џџџџџџџџџ  s`Сџџџџџџџџџџџџџџџџ 'DuС џџџџџџџџџџџP U@џџџџџџџџџџџџџџџџ U€џџџџџџџџџџџџџџџџ CUРџџџџџџџџџџџџџџџџP CUџџџџџџџџџџџџџџџџP CU@џџџџџџџџџџџџџџџџP CU€џџџџџџџџџџџџџџџџP "5Рџџџџџџџџџџџџџџџџ "5џџџџџџџџџџџџџџџџ "5@џџџџџџџџџџџџџџџџ "5€џџџџџџџџџџџџџџџџ @Рџџџџџџџџџџџџџџџџ %Рџџџџџџџџџџџџџџџџ UРџџџџџџџџџџџџџџџџ CEРџџџџџџџџџџџџџџџџP CEТџџџџџџџџџџџџџџџџP CEУџџџџџџџџџџџџџџџџP "5Рџџџџџџџџџџџџџџџџ CРџџџџџџџџџџџџџџџџ ˜ˆРџџџџџџџџџџџџџџџџ ˜…™Рџџџџџџџџџџџџџџџџ "%Рџџџџџџџџџџџџџџџџ DРџџџџџџџџџџџџџџџџ ˆ€Рџџџџџџџџџџџџџџџџ ˜%Рџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCТџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF%bРFGFџџџџP F%‡РџџџџџџџџџџџџџџџџP F6РџџџџџџџџџџџџџџџџP F67РџџџџџџџџџџџџџџџџP F6bРџџџџџџџџџџџџџџџџP F6‡РџџџџџџџџџџџџџџџџP F7РџџџџџџџџџџџџџџџџP FubРF$џџџџџџџџџџP Fu‡РџџџџџџџџџџџџџџџџP FvРџџџџџџџџџџџџџџџџP Fv7РџџџџџџџџџџџџџџџџP FvbРџџџџџџџџџџџџџџџџP Fv‡РџџџџџџџџџџџџџџџџP FwРџџџџџџџџџџџџџџџџP F%PРFџџџџџџџџџP F%uРџџџџџџџџџџџџџџџџP F&РџџџџџџџџџџџџџџџџP F&%РџџџџџџџџџџџџџџџџP F&PРџџџџџџџџџџџџџџџџP F&uРџџџџџџџџџџџџџџџџP F'РџџџџџџџџџџџџџџџџP F'%РџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџC3ЧџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCР $џџџџџџџџ C3ЧџџџџџџџџџџџџџџџџP џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ "џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2џ2 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ› |z? YYWIDE1џWIDE2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџALLџџџџџџCQџџџџџџџQSTџџџџџџYAESUџџџџџџџџџџџџџBLN*џџџџџBLN*џџџџџBLN*џџџџџT–rŽ І@`@z3TœpЂŒ@@т=[3TЎpšЄŽ@ђ! _TЎpŽЊ†@r`Q2W –ŒhЄŠœ№`J3U–ŠhœВЌ~=9W–„pІІr`2U Ў`–Ўš@r! B-Wœrˆ–ž@z! e2X–rІŽЄ@p`92V–†pЈА‚р=iWœpˆ Ў@b'4GVЎpЊ–Š@b! \V –„rŽВžf! R2V ЎpŽЊ†@`=PW–„r˜ŽІю! V2W‚„p”˜@ђ`=3WЎ‚hД–žр=T.WЎpšЄŽ@`=f2X–”hŽ@@`':џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœ`–rŽ І@`Ўp„˜Ќ@рЎ’ˆŠd@c№@141019z3906.39N/08452.83W_339/000g000t067r000p000P000h00b10193/Lawrenceburg, IN - 147.285+ мLИ№ WX Station ЪˆИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ –b`d`œpЂŒ@@тЎp„˜Ќ@рЎ’ˆŠb@с№=3930.00N/08421.48W_000/000g000t069r p P000h98b10209KU2k taИ№96k {UIV32N} pИ№ ч И№И№ рИ№implex\ŒИ№ ізИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈ†bрЎpšЄŽ@ђЎ’ˆŠb@тЎp„˜Ќ@р–’lІД@фЎ’ˆŠd@с№!3914.09N/08421.94W(325/000Bob's Mobile Ham Station95И№ncouver, WA {UIV32N} -§И№ WX Station ?И№UIV32N} аaИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџfВjЄf `ЎpŽЊ†@rЎ‚pДЎ”тЎp„˜Ќ@рЎ’ˆŠd@с№`p(Qm6Ok/"7A}TinyTrak4 4.06, Reuben's Red-PU [И№7VJD-10 ‰И№<530> k И№И№<530> žИ№№285-<630> +№И№N} ˆyИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІpЊЂhІ`–ŒhЄŠœ№–pІ†@єЎ’ˆŠb@р–†pЄВЎц–’lІД@фЎp„˜Ќ@рЎ’ˆŠh@с№`pA@"-Rk/]"6g}= ѕ€И№! ƒИ№> •ЛИ№42BAB0012EC46 іИ№И№et 1юИ№> }ZИ№ ЂЕИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ d@`–ŠhœВЌ~œp–Аš@тЎ†pŠš‚с№=3951.14N/08411.59W>175/000 ЏИ№0ёИ№№14.26W_349/000g000t046h82e1w lUИ№ -284-<630> §ШИ№И№> З‚И№ ЂЕИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІВjАl `–„pІІrœpЎ†Ј@тЎ’ˆŠb@рЎ†pŠš‚с№`o_Oqhcv/"6_}-;И№} %И№}Г$И№И№ ўZИ№№D ’1И№1-<530> ё}И№%005 FИ№И№И№ Heights WX Station цйИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Јfbb`Ў`–Ўš@r–’lІД@фЎ†pŠš‚с№!3957.74N/08411.48Wv335/000/A=000862иИ№2 РИ№/UCAPH (K7OFT-1) Seattle, WA. M”И№№hes Heights WX Station DИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈd‚`œrˆ–ž@zЎ‚pДЎ”тЎp„˜Ќ@рЎ’ˆŠd@с№! / >/A=000908via RF..listening to 146.52 (no pl)ФИ№){BИ№ ЇИ№80-<630> iИ№===================================ЕИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІВЊЂhВ`–rІŽЄ@p–’lІД@фЎ’ˆŠb@рЎp„˜Ќ@рЎ’ˆŠd@с№`p-l!^[/"8u}ЅИ№иДИ№r000p000P000h62b09990wRSW xОИ№И№ GˆИ№RLP 3881 ю>И№0> ,}И№===================================‡5И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ –b`d`–†pЈА‚рЎp„˜Ќ@рЎ’ˆŠb@р–’lІД@фЎ’ˆŠd@с№=3931.35N/08420.39W_000/000g000t068r p P000h00b10206KU2k яЦИ№es Heights WX Station eєИ№ ѕЌИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІВЊЂ`І`œpˆ Ў@bЎ’ˆŠb@bЎ’ˆŠd@e№'p'Pl k/N8DPW@AOL.COM%мИ№№И№770/W2,ORn,LaGrande,OR W4PJS И№ OИ№276-<530> SѕИ№ШИ№ghts WX Station ћtИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œЊbrрЎpЊ–Š@bЎp„‚ @тœpЎ†Ј@т–’lІД@фЎ’ˆŠf@с№!3921.35NS08205.44W# W3 OHn Athens OH ac-ara.orgњИ№-276-<520> ’№И№ed іСИ№ghts WX Station й И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfrb`–„rŽВžfЎp„˜Ќ@рЎ’ˆŠd@c№!3907.60NS08453.29W#PHG3230 W2, INn-N www.lvarc.net бИ№70 0.0 0.0 mПИ№ 100.0 0.0 …ёИ№И№lex+PИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ ЊdjœрЎpŽЊ†@`–’lІД@фЎ’ˆŠd@c№=3952.42N/08412.56W#PHG55604/Vandalia,OH {UIV32N} ь–И№їИ№2v5 3И№eWeather.net eэИ№И№И№668,W,003.0,313.0,150909,018.9,E*6C Ш#И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈd‚р–„r˜ŽІюЌ‚f †@ђЎ’ˆŠb@р–’lІД@фЎp„˜Ќ@рЎ’ˆŠd@с№!3951.58N/08423.08Wjkb9lgs@kiva.netгЪИ№03] For information send message to n7bcp@gmail.com гOИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІВjЂhЄ`‚„p”˜@ђЎp„˜Ќ@рЎ’ˆŠb@рЎ’ˆŠd@e№`p/sl!l>/]"7&}Dayton OH ћИ№y me on VOICE ALERT KE7HTZ vjИ№ams Nov11 7pm kИ№ Heights WX Station •ŽИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ўdpj`Ў‚hД–žрЎ‚hД–žўЎ†pŠš‚с№=3839.65N/08434.60W-PHG3020/444.425+ PL107 -285-<630> уЙИ№nacres {UIV32} ИИ№} :ВИ№И№HITE SW-284-<630> O(И№E*63 •wИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfpd`ЎpšЄŽ@`–r”Ќ‚@рЎp„˜Ќ@рЎ’ˆŠd@с№=3914.08N/08421.91WrPHG2130 W2, OHn-N, W8MRG in Montgomery, Ohio }ЗИ№anadaћХИ№ ф.И№№0> ,}И№e|И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџІВЈВdІ`–”hŽ@@`œp–Аš@тЎpŽЊ†@р–’lІД@фЎ’ˆŠd@с№'p+4l jv/]"75}ЩGИ№Red BMW 325i&,И№HDO ЭLИ№V HDOP00.8 SATS09uot on the REZвИ№4И№ И№ЕИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊІЂАЂ`–†`ŠЌ ђ„Њ˜˜šЈрЎ’ˆŠd@c№`2H.o?)k/]"6"}440.450MHz= G[И№40/W2,WAN,SPOKANE œƒИ№ W7VOI ЄДИ№•ЛИ№№ED000AEC45 &ШИ№И№:W7GC-7 ЏИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈjІЄЈІ`–nŠА@@b„Њ˜˜šЈрЎ’ˆŠd@c№`2Usl!qk/"4S}K7EX Tiny TrakлИ№ZPHG3000/WinAPRS 2.5.1 -WAGRAOTHELLO -251-<530> ™#И№hes Heights WX Station Љ—И№ БLИ№№====‘оИ№=!MИ№=”=И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ўdnl`ЎnˆŽ@@`„Њ˜˜šЈрd@@@@@e№_01202009c000s000g000t000r000p000P000h00b00000wRSW lюИ№ -WACOWLONGVIEW-276-<530> ъzИ№s Heights WX Station iдИ№  3И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊdВЎЎ`œnˆ˜š@р„Њ˜˜šЈрЎ’ˆŠd@c№`2QNmIf>/]"4[}443.425MHz= § И№endleton OR {UIV32N}zИ№И№-<530> ё}И№1h ЦіИ№50Naches Heights WX Station bоИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ žЈ`fрœn’šŠ@ф„Њ˜˜šЈрЎ’ˆŠd@e№/290112z4536.87N/12241.84WY228/000 13.9V Blue Ecstacy GИ№A 0ˆИ№2N} UvИ№tes LИ№И№И№И№ts WX Station sŠИ№ ЕИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈjЄВІЊ`–b„Є†@р„Њ˜˜šЈрЎ’ˆŠd@c№`2K/]"4V}zest g<И№60/W2,ORn,Prineville KG6QHD ’1И№VOI :И№9.U21h ™…И№.netЮ*И№ ўИ№ WX Station І`И№ KцИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Ўdjb`–ˆnŒ„Ј`–ž Š‚–р„Њ˜˜šЈс№=4659.00N/12349.65W_PHG7490/WinAPRS 2.5.1 -WAGRAABERDEEN-251-<530> ё}И№0 ХМИ№И№NET ШnИ№И№И№ }ZИ№ aИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ œfrb`„Њ˜˜šЈ`œnЂАž@s№!4525.00NF12249.67W#PHG2667/KB7WUK OR Bull Mt Fill in „oИ№ )IИ№000h95b10050uRSW Kennewick WX hИ№ 146.860_ аDИ№2N} ‘И№==== ЏШИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Јfbb`Ў‚n–Єœn„Њ˜˜šЈрЎ’ˆŠd@e№/201650z4529.86N/12249.45Wk319/013/A=000200кХИ№И№TЗЯИ№ lЪИ№DX „ЇИ№И№T ыyИ№И№immyЁИ№0> ѓјИ№ +№И№.9,E*66 ŽИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊfЂІА`–ˆnВ’рЎ’ˆŠb@bЎ’ˆŠd@c№`2Ql#/>/]"4T}147.500MHz= аZИ№30/W2,ORn,...Salem.OR..N7IFJ Ÿ‡И№ridian, ID nwzimm@cableone.netvšИ№И№ +№И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊІЄ Ј`œn‚‚š@ю„Њ˜˜šЈрЎ’ˆŠd@c№`2Jhl#=R/`"5d}_ ОИ№57304/W2,WAn,Yakima-N7HHU AwИ№И№И№0> ДИ№Weather.net 7лИ№ Ц§И№> }ZИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊfЂЊ `–nЈ‚В@nЎ’ˆŠd@c№`2Rum,@(/"4S}ЏƒИ№OИ№3.60N/12125.45W_228/009g013t042OD1w=‘И№И№136.5 -WAPIEPUYALLUP-280-<630> 0И№И№ЏИ№ ОИ№UIV32N} \И№============Џ`И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Јfbb`–n† Њ@b„Њ˜˜šЈрЎ’ˆŠd@c№/112313z4532.50N/12257.69Wv116/000/A=000246/TM-733, TT3+, GPS2 OjИ№ хnИ№№И№И№ www.ocrg.org:W7GC-7 ЏИ№№И№N} fЧИ№============ЬцИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈjІІВЌ`–Šn˜Є„`„Њ˜˜šЈрЎ’ˆŠd@c№`2OQl!rk\"4b}hИ№И№050r000p000P000h..b.....wUII ‹ЗИ№z ,‘И№ ЬёИ№-<520> ’№И№XNET jŒИ№И№№2N} "<И№UIV32N} h—И№============ёИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЌbЄ Ј`–ˆnœЌ„ќ„Њ˜˜šЈрЎ’ˆŠd@c№`2QT!Imu/]"4.} црИ№ D700 IN SERVICE юИ№/003 [ъИ№Blue Ecstacy 0 И№r T88.5 AрИ№И№И№285-<630> ЂЕИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ „˜b`р–nЄ–Ј@„Њ˜˜šЈрЎ’ˆŠd@№!4525.93N\12244.28WO115/012/A=000360KўИ№BeeŠ'И№calnet.com WИ№RSW пИ№0> тИ№И№И№ ЯdИ№285-<630> ЂЕИ№ {UIV32N}  И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊfЂЊЈ`–nЈ‚В@№„Њ˜˜šЈрЎ’ˆŠd@c№`2Sl_>v/`"4*}Dan_ /СИ№~И№860/W2,WAn,Mission Ridge-WR7ADX f=И№ ІKИ№-<530> ъzИ№1 ю>И№s WX Station 7И№150909,019.0,E*6D §ВИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊІЊЂЂ`–ŒnŒ‚Ію„Њ˜˜šЈрЎ’ˆŠd@c№`2VzqJ~[/`"4E}_ 5БИ№43.350 PL82.5 * Juniper APRS KF7LN ”"И№F7LN Q И№№nitor 146.520 73 de Myles /A=005551Ф№И№1OyИ№3RИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЈЊf ЈЎ`–ˆn’œŒ`„Њ˜˜šЈрЎ’ˆŠd@c№`2FRo*Du/"5^}ЋRИ№ ŠИ№30/W2.IDn,WEST TWIN 1LИ№ ]yИ№V32N} БИ№11 7pm ЁИ№ ЉАИ№t ЕGИ№№TыBИ№> +№И№1,W,001.6,090.1,150709,018.9,E*62 ЬQИ№џџџџџџџџџџџџџџџџџџџџџџџЈЊjЈІ `œnœ”ž@ќ„Њ˜˜šЈрЎ’ˆŠd@c№`2HP!SVu/]"4#}Seattle, WA. to Salem, OR. and back.= .;И№106 In 10 Minutes К И№ёИ№№COMCAST.NETgЈИ№№ wШИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ –b`b`ЌŠnš˜АќЌŠnœžЄтЌ‚n˜ЎтЈВœœŠрˆžŽšЈœрЌŠnЄœ‚є„‚˜ˆ’@рœnЂАž@ђЎ’ˆŠf@c№:CQ :Hi from VE7MLX Matt in Armstrong BC{R шВИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ Њdjœр–Šn”ŒŒ`Ў’ˆŠb@bЎ’ˆŠd@g№:KK7DS-7 :?APRSS ŒZИ№џџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЎ’ˆŠd@ф–„nˆДЄ`Ў’ˆŠb@bЎ’ˆŠd@c№:KK7DS-7 :Wellcome to Wallowa co, and the 2010 ECX. Thanks for helping.{25 №И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p`‚b‚b‚bрЎ’ˆŠb@bЎ’ˆŠd@c№:BBBBBB :1{22 Ч‚И№џџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p‚‚‚‚‚‚№:BBBBBB :1{75 хяИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p‚‚‚‚‚‚№:BBBBBB :1{76 ХИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p‚‚‚‚‚‚№:BBBBBB :1{78 _И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p‚‚‚‚‚‚№:BBBBBB :1{79 EFИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ 1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p‚‚‚‚‚‚№:BBBBBB :1{80 šлИ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚ В``p‚‚‚‚‚‚№:BBBBBB :1{40 9~И№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAAAAA1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџХchirp-20240224/tests/images/Quansheng_UV-K5.img0000644000175000017500000002035114560403070017761 0ustar hibbyhibbyzаС>кСфСЦэСŠїСNТ ТšqЩ ^{Щ "…Щ цŽЩ Њ˜Щ nЂЩ 2ЌЩ ˜ЫС\еС пСфшСЈђСlќС0ТєТ˜ЫС Ё\еС Ё пС ЁфшС ЁЈђС ЁlќС Ё0Т ЁєТ ЁџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNTNT(-Ѕ(-ЅHЂнHЂнШ8vШ8vРЈВ%ˆ#˜ˆ#˜шьшьЯЯЯЯЯФХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џЬЭЯЯџџџџџџџџџџџџџџџџџџџџџџџџLogo 1џџџLogo 1џџџ*# џџџџџ1027777788888123456џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGMRS 1 GMRS 2 GMRS 3 GMRS 4 GMRS 5 GMRS 6 GMRS 7 GMRS 8 GMRS 9 GMRS 10 GMRS 11 GMRS 12 GMRS 13 GMRS 14 GMRS 15 GMRS 16 GMRS 17 GMRS 18 GMRS 19 GMRS 20 GMRS 21 GMRS 22 GMRS 550/1GMRS 575/1GMRS 600/1GMRS 625/1GMRS 650/1GMRS 675/2GMRS 700/2GMRS 725/2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCALL1101CALL2102CALL3103CALL4104CALL5105џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ KSVY\_bdfџџџџџџFPSVY\_bdџџџџџџZ-)&# џџџџџџd0-)&# џџџџџџZ џџџџџџd џџџџџџ2hknoruwy{џџџџџџ(dgjlnqsvxџџџџџџA2-($!џџџџџџF72-(%"џџџџџџZ џџџџџџd џџџџџџnx‚ŒДОШв222dddŒŒŒџџџџџџџ222dddŒŒŒџџџџџџџ222ZZZxxxџџџџџџџ222dddŒŒŒџџџџџџџ<<&€hJЈ^Ј^Ј^Ј^Ј^Ј^Ј^Ј^џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirpюimgeyJ2ZW5kb3IiOiAiTFVJVE9OIiwgIm1vZGVsIjogIkxULTU4MF9WSEYiLCAiY2hpcnBfdmVyc2lvbiI6ICJkYWlseS0yMDIxMDgxNCIsICJyY2xhc3MiOiAiRHluYW1pY1JhZGlvQWxpYXMiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/images/BTECH_GMRS-50V2.img0000644000175000017500000004026114411666130017255 0ustar hibbyhibbyџџџџџџџџџџџџџџџџPb%FPb%FP‡%FP‡%FP&FP&FP7&FP7&FPb&FPb&FP‡&FP‡&FP'FP'FPbuFPbuFP‡uFP‡uFPvFPvFP7vFP7vFPbvFPbvFP‡vFP‡vFPwFPwFP%FP%Fu%Fu%F&F&F%&F%&FP&FP&Fu&Fu&F'F'F%'F%'FP%FPuFu%FuuF&FvF%&F%vFP&FPvFu&FuvF'FwF%'F%wFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$$D%$%$DP$P$Du$u$D%%D%%%%DP%P%DџџџџџџџџџџџџџџџџGMRS01џџџџџџџџџџGMRS02џџџџџџџџџџGMRS03џџџџџџџџџџGMRS04џџџџџџџџџџGMRS05џџџџџџџџџџGMRS06џџџџџџџџџџGMRS07џџџџџџџџџџGMRS08џџџџџџџџџџGMRS09џџџџџџџџџџGMRS10џџџџџџџџџџGMRS11џџџџџџџџџџGMRS12џџџџџџџџџџGMRS13џџџџџџџџџџGMRS14џџџџџџџџџџGMRS15џџџџџџџџџџGMRS16џџџџџџџџџџGMRS17џџџџџџџџџџGMRS18џџџџџџџџџџGMRS19џџџџџџџџџџGMRS20џџџџџџџџџџGMRS21џџџџџџџџџџGMRS22џџџџџџџџџџREPT15џџџџџџџџџџREPT16џџџџџџџџџџREPT17џџџџџџџџџџREPT18џџџџџџџџџџREPT19џџџџџџџџџџREPT20џџџџџџџџџџREPT21џџџџџџџџџџREPT22џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOAA01џџџџџџџџџџNOAA02џџџџџџџџџџNOAA03џџџџџџџџџџNOAA04џџџџџџџџџџNOAA05џџџџџџџџџџNOAA06џџџџџџџџџџNOAA07џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ Ÿџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ   џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџШпџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ BTECH GMRS-50V2џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ #4EVgxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ-------+,-------  &!#%00000&!#%)))))&!#% ))))&!#%)))))-   2  BTECHNC1932  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0000000000000000NC1932290000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJHTVJTNTBWMiIsICJ2ZW5kb3IiOiAiQlRFQ0giLCAibW9kZWwiOiAiR01SUy01MFYyIiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/Kenwood_TK-272G.img0000644000175000017500000010000014551723752017566 0ustar hibbyhibby #џџZ џџџџџџ2џєа00џџёџџ‘ б Q A$ћ$‡#yё џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўћџџџџџџџџџџџџџџэџџџџџџџџџџ џџџџ TONI џџџџџџџџџџџP2720ћёџџџџџџџџџџџџChirpџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ#џџdd 222џџѓ !"#$%&'()*+,-./H<:FGAOOOOOOOOOOOOOOЁOџџџџџџџџџџOOOOOOOOOOOOOOOOPP52PTPH52џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџEste radio es propiedad de TONI CM7AEH џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ      џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘ A$CODE 1 џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџCAMAGUEYџpQpE63џџџџџџџџџџћџџџџџџџџџџџџџџџFLORIDA џpRpF41џџџџџџџџџџћџџџџџџџџџџџџџџџNUEVITASџSG41џџџџџџџџџџћџџџџџџџџџџџџџџџGUAIMAROџPTPH52џџџџџџџџџџћџџџџџџџџџџџџџџџ145_000 џPP52џџџџџџџџџџлџџџџџџџџџџџџџџџ145_500 џUU63џџџџџџџџџџћџџџџџџџџџџџџџџџ145_700 џWW52џџџџџџџџџџћџџџџџџџџџџџџџџџPAVEL_INџџ%B%B52Ч Ч џџџџџџћџџџџџџџџџџџџџџџ145_600 џџVV52џџџџџџџџџџћџџџџџџџџџџџџџџџ 145_100 џџQQ52џџџџџџџџџџћџџџџџџџџџџџџџџџ 145_250 џџPRPR52џџџџџџџџџџћџџџџџџџџџџџџџџџ C_AVILA џџPSPG52џџџџџџџџџџћџџџџџџџџџџџџџџџ CIENFUEGџџ0Q0E52џџџџџџџџџџћџџџџџџџџџџџџџџџ C_HABANAџџQE52џџџџџџџџџџћџџџџџџџџџџџџџџџS_CLARA џџTH52џџџџџџџџџџћџџџџџџџџџџџџџџџINT_FLRDџџDD52џџџџџџџџџџћџџџџџџџџџџџџџџџSAT-VOZ џџXX52џџџџџџџџџџћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ145 370 џpSpG41џџџџџџџџџџџџџџџџџџџџџџџџџџ145 390 џSG41џџџџџџџџџџџџџџџџџџџџџџџџџџ145 410 џTH63џџџџџџџџџџџџџџџџџџџџџџџџџџ145 430 џ0T0H41џџџџџџџџџџџџџџџџџџџџџџџџџџ145 450 џPTPH52џџџџџџџџџџџџџџџџџџџџџџџџџџ145 470 џpTpH63џџџџџџџџџџџџџџџџџџџџџџџџџџ145 490 џTH41џџџџџџџџџџџџџџџџџџџџџџџџџџSO50 ACTџPXPX52џџшџџџџџџџџџџџџџџџџџџџџџџSO50 UP џPXPX52џџžџџџџџџџџџџџџџџџџџџџџџџKASA џ5I5I11ѓ џџџџџџџџџџџџџџџџџџџџџџNOAA-19 џqџџџџ6џџџџџџџџџџџџџџџџџџџџџџџџџџџAO-85 RXџ€Yџџџџ1џџџџџџџџџџџћџџџџџџџџџџџџџџџQT 670 џPP52žžџџџџџџњџџџџџџџџџџџџџџџQT 693 џPP52ЕЕџџџџџџўџџџџџџџџџџџџџџџQT 719 џPP52ЯЯџџџџџџџџџџџџџџџџџџџџџџQT 744 џPP52шшџџџџџџџџџџџџџџџџџџџџџџQT 770 џPP52џџџџџ0џџџџџџџџџџџџџџџџQT 797 џPP52џџџџџ1џџџџџџџџџџџџџџџџR54NT54IџPP52,(,Јџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ056K44160112џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTK-272GџџџџџK1џџ30401887џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџ№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Yaesu_FT-2800M.img0000644000175000017500000001700014411666130017324 0ustar hibbyhibbye e  e e  e e  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџe e # џџџџџџџџџџe e  џџџџџџџџ e e  ƒР€Gџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/AnyTone_TERMN-8R.img0000644000175000017500000010000014411666130017743 0ustar hibbyhibbyЅЅs 5.. ""#TERMN8Rє2015-2-10ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџџџџџџџџџџџџџџџџџџџџџџџџџ#Pd0` 0E` 0”ўџџџџџџџџџџџџџџџ 2d‘ A$H:3 dF2d 2ўџџџўџџџўџџџџџџџўџџџџџџџџџџџџџџџ < жt"D%P(Ђ+:/3F7Ю;К@ОKўVєQњ_Fe•P'PP •PџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџI†‘ A$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџF4Pџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ` 0E` 0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ'P'0џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHelloџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘ A$H:3џџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџџџџџммџbV% GMRS010bXu GMRS020ba% GMRS030bcu GMRS040bf% GMRS050bhu GMRS060bq% GMRS070bU GMRS150bWP GMRS160b` GMRS170bbP GMRS180be GMRS190bgP GMRS200bp GMRS210brP GMRS220bU REPT150bWP REPT160b` REPT170bbP REPT180be REPT190bgP REPT200bp REPT210brP REPT220Q‚ MURS 10Qˆ MURS 20Q” MURS 30TW MURS 40T` MURS 50џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџchirp-20240224/tests/images/Alinco_DJ175.img0000644000175000017500000001536014411666130017167 0ustar hibbyhibbyЅЊUЊЅЊ!p57LM€F` KIMˆ G2`KIM2E`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`џџџџџџE`chirp-20240224/tests/images/TIDRADIO_TD-H8-GMRS.img0000644000175000017500000001770114430171343017760 0ustar hibbyhibbyP31184џџџџџџџџџџџџџџџџџџPb%FPb%FџџџџP‡%FP‡%FџџџџP&FP&FџџџџP7&FP7&FџџџџPb&FPb&FџџџџP‡&FP‡&FџџџџP'FP'FџџџџPbuFPbuFџџџџP‡uFP‡uFџџџџPvFPvFџџџџP7vFP7vFџџџџPbvFPbvFџџџџP‡vFP‡vFџџџџPwFPwFџџџџP%FP%Fџџџџu%Fu%Fџџџџ&F&Fџџџџ%&F%&FџџџџP&FP&Fџџџџu&Fu&Fџџџџ'F'Fџџџџ%'F%'FџџџџP%FPuFџџџџu%FuuFџџџџ&FvFџџџџ%&F%vFџџџџP&FPvFџџџџu&FuvFџџџџ'FwFџџџџ%'F%wFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџP%P%џџџџ$$џџџџu$u$џџџџ%$%$џџџџP$P$џџџџ%%џџџџ%%%%џџџџPPџџџџuuџџџџPPџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЪE(@џџџџџџџџџџџџџџџџ`@@Rџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?№џџџ?№‰P`P`џџџџP@P@џџџџџџџџџchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJUREg4X0dNUlMiLCAidmVuZG9yIjogIlRJRFJBRElPIiwgIm1vZGVsIjogIlRELUg4LUdNUlMiLCAidmFyaWFudCI6ICIiLCAiY2hpcnBfdmVyc2lvbiI6ICJweTNkZXYifQ==chirp-20240224/tests/images/Retevis_RB28.img0000644000175000017500000000103114411666130017314 0ustar hibbyhibbyPb%FPb%F P‡%FP‡%F P&FP&F P7&FP7&F Pb&FPb&F P‡&FP‡&F P'FP'F PbuFPbuFGGGGP‡uFP‡uF****PvFPvF,,,,cP7vFP7vF----PbvFPbvF....P‡vFP‡vF////PwFPwF6666P%FP%F џџџu%Fu%Fwwww &F&FQQQQ %&F%&F P&FP&FGGGG u&Fu&Fiiii 'F'Ftttt %'F%'F џchirpюimgeyJtZW1fZXh0cmEiOiB7fSwgInJjbGFzcyI6ICJEeW5hbWljUmFkaW9BbGlhcyIsICJ2ZW5kb3IiOiAiUmV0ZXZpcyIsICJtb2RlbCI6ICJSQjI4IiwgInZhcmlhbnQiOiAiIiwgImNoaXJwX3ZlcnNpb24iOiAicHkzZGV2In0=chirp-20240224/tests/images/TYT_TH-UV3R.img0000644000175000017500000000442014411666130016753 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ?џџџџќ иZ>џџpќ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџф ќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџр р§џДщeє$ !№р џџџџџџџџџџџџџџџџџџP400DЊџџџџџџџџZbР)Э…ЯР€ џџџџџџџџџџџџџџџџм џџџџџџџџџchirp-20240224/tests/images/Puxing_PX-2R.img0000644000175000017500000000774014411666130017315 0ustar hibbyhibbyџџџџџџџџџџџџџџџџP%FPKu%FPKџџџџ%&FPKP&FPKu&FPK'FPK%'FPKџџџџџџџџџџџџџџџџDџџџџџDџџџџџD3џџџџџD33џџџџџD33џџџџџDџџџџџDџџџџџD џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџPb7EPb7Š џPb6EPb6ŠџџP‡5EP‡5Š"џPb5EPb5‚џџџџџP74EP74ŠџџPb%HPb%)ŠџџџџџџџџџџџџџџџџџџD џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџD џџџџџџџџџџџџџџџџOKџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџv•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ@PHџџџџџџџџџџџџLISTENIGџџџџџџџџv•Ш`€ џ chirp-20240224/tests/images/Yaesu_VX-6.img0000644000175000017500000007751314411666130017026 0ustar hibbyhibbyAH021рџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџi`Рџџџџџџ `s…Сџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ..џџџџЌТЮYŠџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџf  D0Pџџџџџџ h@џџџџџџ џџџџ џџџ‹f  D0Pџџџџџџ h@џџџџџџ џџџџ џџџ‹џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ $ $ $ $ $ $ $ $ $               A@Рџџџџџџ @Рџџџџџџ @Рџџџџџџ †Рџџџџџџ †@Рџџџџџџ E€Рџџџџџџ e Рџџџџџџ †@Рџџџџџџ " Рџџџџџџ D`РџџџџџџP †GРџџџџџџ †Рџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџA@Рџџџџџџ @rРџџџџџџ @uРџџџџџџ ‡)Рџџџџџџ †@Рџџџџџџ E“Рџџџџџџ g`Рџџџџџџ FcPРџџџџџџ "9@Сџџџџџџ %DI%СџџџџџџP †HPРџџџџџџ †Рџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333T€Сџџџџџџ i@Сџџџџџџ "I Сџџџџџџ "C Сџџџџџџ DV@СџџџџџџP @DV€СџџџџџџP %D0УџџџџџџP %DPСџџџџџџP iРџџџџџџ %DPСџџџџџџP tРџџџџџџ "@`Р$ DfџџџџџџP "9@Рџ tРџџџџџџ "I€Сџџ"F@С $$"I@Р$ "@`Р$ $D7%Р џџџP %D0uС  џџP$DPР  P %DPС  P%D#%Р џџP $DB%Р џџP $D9%С  џP $D1%С  џP $D7%Р џџџP t€Р  џџ W0Р  џџ t€Р  џџ i`Рџџџџџџ %DСџџџџџџP %DСџџџџџџP u@Рџџџџџџ DfџџџџџџP t%Рџџџџџџ uUРџџџџџџ u%Рџџџџџџ TPРџџџџџџ i€Рџџџџџџ T0Рџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџEРџџџџџџ u@Рџџџџџџ iРџџџџџџ s Рџџџџџџ s`Сџџџџџџ %D0УџџџџџџP %D1PСџџџџџџP DfџџџџџџP p@Рџџџџџџ i`Рџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩџ6chirp-20240224/tests/images/BTECH_MURS-V2.img0000644000175000017500000002025114411666130017123 0ustar hibbyhibbyџџџџџџџџџџџџџџџџ  žž€€žž@@žžpEpEžžDFFžžD  э э €€э э @@э э pEpEэ э DFFэ э D  €€@@pEpEDFFDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$$D%$%$DP$P$Du$u$D%%D%%%%DP%P%DџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџFANGXIAODONGџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџMurs1-1џџџџџџџџџMurs1-2џџџџџџџџџMurs1-3џџџџџџџџџMurs1-4џџџџџџџџџMurs1-5џџџџџџџџџMurs2-1џџџџџџџџџMurs2-2џџџџџџџџџMurs2-3џџџџџџџџџMurs2-4џџџџџџџџџMurs2-5џџџџџџџџџMurs3-1џџџџџџџџџMurs3-2џџџџџџџџџMurs3-3џџџџџџџџџMurs3-4џџџџџџџџџMurs3-5џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNOAA01џџџџџџџџџџNOAA02џџџџџџџџџџNOAA03џџџџџџџџџџNOAA04џџџџџџџџџџNOAA05џџџџџџџџџџNOAA06џџџџџџџџџџNOAA07џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ140902N џџWELCOME џџUSM2403USM2403џџ ----777772333337eeeee77777777eeeiiiiiiiiiџџџ-(((((((((  џџџџџ џџџџџ( <~юџpsv}‡ 1 џ€0y џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ123456BF9166Њ0y нџchirpюimgeyJ2ZW5kb3IiOiAiQlRFQ0giLCAibW9kZWwiOiAiTVVSUy1WMiIsICJjaGlycF92ZXJzaW9uIjogImRhaWx5LTIwMjIwODIzIiwgInJjbGFzcyI6ICJNVVJTVjIiLCAidmFyaWFudCI6ICIifQ==chirp-20240224/tests/model_stats.tsv0000644000175000017500000002364214411666130016263 0ustar hibbyhibbymodel count Baofeng_UV-5R 1700672 Baofeng_UV-82 541174 Baofeng_UV-82WP 19912 Baofeng_BF-888 915735 Generic_CSV 556432 Baofeng_UV-9R 155694 AnyTone_5888UV 8643 RepeaterBook_ 297088 Radioddity_UV-5G 28679 BTECH_GMRS-20V2 1550 TYT_TH-UV8000 19137 Baofeng_BF-A58S 23694 Baofeng_BF-F8HP 317609 Baofeng_UV-5X 49662 Icom_IC-7000 2122 Yaesu_FT-60 30100 TYT_TH-UV88 31727 Radioddity_UV-5RX3 55501 Puxing_PX-777 6549 Baofeng_UV-82HP 145843 Baofeng_UV-5XP 31311 QYT_KT8900D 31240 Retevis_RT22 32979 Baofeng_UV-6R 44014 Baofeng_GT-3WP 26303 Wouxun_KG-UV9D Plus 24244 Baofeng_UV-9G 40164 Wouxun_KG-816 4537 TYT_TH-9800 39903 Baofeng_UV-82III 12429 Wouxun_KG-UVD1P 21369 Yaesu_FT-7800/7900 8326 Retevis_RT95 VOX 9028 Radioddity_GA-510 25695 Baofeng_UV-3R 27672 Baofeng_BF-T1 47089 Yaesu_FT-70D 16467 Radio Reference LLC_RadioReference.com 19825 Icom_IC-E90 1372 Baofeng_BF-U9 12688 AnyTone_778UV 10285 BTECH_UV-25X2 9206 QYT_KT8900 21417 Radioddity_UV-5R EX 6050 BTECH_UV-5X3 26484 TID_TD-M8 2241 TIDRADIO_TD-UV5R TriPower 21391 TIDRADIO_TD-H6 26254 Radioddity_GA-2S 11555 Wouxun_KG-UV8D Plus 5195 Yaesu_FTM-350 972 Kenwood_TK-8180 953 AnyTone_778UV VOX 14394 Kenwood_TK-7102 1494 AnyTone_5888UVIII 2407 Tenway_UV-5R Pro 12896 Baofeng_UV-B5 21750 Retevis_RT95 5162 Kenwood_TK-7180 731 Yaesu_FT-50 2292 Zastone_ZT-X6 6562 Baojie_BJ-218 17702 Zastone_MP-300 1923 Kenwood_TK-7108 690 Yaesu_FT-817ND 4131 KYD_IP-620 1226 KYD_NC-630A 988 QYT_KT7900D 14065 Alinco_DJ-G7EG 27316 Powerwerx_DB-750X 867 Baofeng_BF-A58 36184 Kenwood_TM-281 951 Yaesu_FT-4XE 8817 Retevis_RB26 2512 Retevis_RT16 1195 Retevis_RT5R 9343 Rugged_RH5R-V2 2882 Rugged_RH5R 2262 Retevis_RT85 13450 Yaesu_VX-170 2076 Icom_IC-91/92AD 1614 Retevis_RB17A 700 Retevis_RT9000D_400-490 741 Retevis_H777 23777 Baofeng_GT-5R 41759 Retevis_H777 Plus 3470 Retevis_RT1 4651 Retevis_RT21 12241 Retevis_RT22FRS 2475 Retevis_RT22S 2652 Retevis_RT23 2461 BTECH_UV-25X4 7089 Retevis_RT24 19182 Yaesu_FT-1802M 1310 Retevis_RT26 1882 QYT_KT8900R 7816 Retevis_RT5 4622 Retevis_RT5(tri-power) 1654 Retevis_RT5RV 2644 Retevis_RT6 2281 QYT_KT-8R 5833 Retevis_RT622 5317 Wouxun_KG-UV6 11828 BTECH_GMRS-50X1 8315 BTECH_UV-5001 1544 Wouxun_KG-UV8D 14808 Retevis_RT76 1178 Retevis_RT76P 2417 Retevis_RT87 2131 WACCOM_MINI-8900 6247 TYT_TH-UVF8D 2830 TYT_TH-UV3R 2662 TYT_TH-7800 8003 TYT_TH-UVF1 3560 TYT_TH-UV3R-25 1238 TYT_TH-350 4157 TYT_TH9000_144 3402 TYT_TH9000_220 2516 TYT_TH9000_440 2450 BTECH_GMRS-V1 9901 Yaesu_VX-5 4009 Baofeng_UV-6 28285 Baofeng_BF-T8 12864 AnyTone_OBLTR-8R 1437 AnyTone_TERMN-8R 1475 Icom_IC-T70 1669 Yaesu_FT-65R 10824 Retevis_RT98 3060 CRT_Micron UV V2 6030 Kenwood_TK-860 838 Baofeng_F-11 7356 Kenwood_TM-V7 597 QYT_KT980PLUS 5417 Kenwood_TK-3180K 1952 Icom_IC-2720H 1508 Yaesu_FT-857/897 15692 BTECH_UV-50X2 8054 Retevis_RT68 2077 Baojie_BJ-9900 1430 Retevis_RT668 1785 Radioddity_DB25-G 10359 Intek_KT-980HP 2762 MTC_UV-5R-3 1103 Kenwood_TS-480_LiveMode 86 Yaesu_VX-6 9975 Kenwood_TK-8108 456 Kenwood_TM-D710G 529 WLN_KD-C1 106730 Icom_ID-800H 741 Icom_IC-V82/U82 1974 Arcshell_AR-5 7729 Radioddity_R2 2741 Icom_IC-V86 2752 Icom_IC-7100 3601 Kenwood_TK-360G 716 Icom_746 927 Midland_DBR2500 3278 Yaesu_FT-4XR 6788 Icom_IC-2300H 4889 Icom_IC-T90 1095 Alinco_DJ175 1940 Alinco_DJ596 1445 Alinco_DR03T 624 Alinco_DR06T 639 Retevis_RB18 2205 Alinco_DR135T 2433 Alinco_DR235T 1015 Alinco_DR435T 1029 Ansoko_A-5R 1361 Ansoko_A-8S 2254 Arcshell_AR-6 3011 Arcshell_AR-8 531 BTECH_MURS-V1 2441 BTECH_UV-2501 1176 BTECH_UV-2501+220 1474 BTECH_UV-50X3 3527 Yaesu_FT-857/897 (US) 4812 Baojie_BJ-318 6130 Baojie_BJ-UV55 1671 Boblov_X3Plus 999 CRT_Micron UV 5176 Radtel_T18 4114 Feidaxin_FD-150A 1285 Retevis_RB85 1289 Feidaxin_FD-160A 518 Feidaxin_FD-268A 495 Feidaxin_FD-268B 387 Feidaxin_FD-288A 371 Kenwood_TS-2000 1568 Kenwood_TK-360 983 Kenwood_TK-370 1000 Yaesu_FT-90 1236 QYT_KT-UV980 2068 Puxing_PX-888K 4268 Yaesu_VX-3 4754 Puxing_PX-2R 2874 Kenwood_TM-V71 2625 Kenwood_TK-762G 854 Icom_IC-2730A 13133 Kenwood_TH-G71 312 Yaesu_FT-2900R/1900R 2959 Leixen_VV-898 9789 Yaesu_FT-8800 5190 Yaesu_FTM-7250D 2222 Retevis_RB27 5705 Radioddity_QB25 5820 Yaesu_FT-65E 4793 Tenway_TW-325 1864 Kenwood_TH-D7G 161 Kenwood_TK-2180 2361 Kenwood_TK-260G 1135 Yaesu_FT3D 2050 Icom_IC-7300 2131 Kenwood_TK-270 987 Yaesu_VX-8DR 2069 Surecom_S-KT8900D 2711 ITWeRKS_RFinder 965 Vertex Standard_VXA-700 1439 Kenwood_TK-762 426 QYT_KT5800 844 Yedro_YC-M04VUS 1158 Yaesu_FT-2800M 1957 LUITON_LT-588UV 874 Yaesu_VX-8R 1638 Yaesu_VX-2 2551 Radioddity_GA-5S 2159 Kenwood_TM-D700 757 Motorola_Waris Tuning 3331 Yaesu_VX-7 5606 Plant-Tours_MT-700 538 LUITON_LT-898UV 1463 Icom_IC-208H 3033 Yaesu_FT-1500M 1476 Kenwood_TH-F6 1766 Wouxun_KG-818 2161 Yaesu_FT-818ND (US) 1265 Kenwood_TK-3180K2 870 Jetstream_JT270MH 763 Kenwood_TK-8102 1125 Kenwood_TK-862G 833 Kenwood_TK-862 315 Icom_IC-W32A 1262 Greaval_GV-8S 2412 TechSide_TI-F8+ 1592 TDXone_TD-Q8A 1235 Kenwood_TK-760G 1713 LUITON_LT-725UV 1408 Radioddity_UV-82X3 3357 Kenwood_TK-760 1365 Kenwood_TK-270G 1222 Vertex Standard_FTL-2011 2965 HobbyPCB_RS-UV3 1463 LUITON_LT-316 2509 Kenwood_TK-370G 1090 Yaesu_FT-817 2163 Yaesu_FT-1D 1957 Kenwood_TK-260 1495 Yaesu_FT-450D 636 LUITON_LT-580_UHF 605 Kenwood_TK-278 977 Kenwood_TS-480_CloneMode 248 Icom_IC-P7 597 Retevis_RB618 9747 Retevis_RB617 1497 Kenwood_TM-271 644 Juentai_JT-6188 Mini 1618 Sainsonic_GT-890 1183 Yaesu_FT2D 954 Retevis_RT-5R 499 Retevis_RT-5RV 198 Polmar_DB-50M 1616 Juentai_JT-6188 Plus 878 Icom_ID-51 Plus 1080 Icom_ID-51 1080 Kenwood_TH-F7 1749 Yaesu_FT-8100 423 Yaesu_VX-8GE 850 Retevis_RT9000D_66-88 256 Yaesu_FT-817ND (US) 1176 Kenwood_TM-D710_CloneMode 172 Kenwood_TH-D72 (clone mode) 1399 Wouxun_KG-UV8E 3039 Yaesu_FT-25R 664 Yaesu_FT-2900R/1900R(TXMod) 1317 Yaesu_FT-4VR 764 Yaesu_FT-818 3080 Vertex Standard_FTL-1011 1344 Tenway_UV-82 Pro 733 Rugged_RH5X 655 Retevis_RB17 980 Retevis_RB17V 841 Retevis_RB27V 609 Retevis_RB627B 3119 Retevis_RB75 978 Retevis_RT9000D_136-174 438 Kenwood_TK-272 579 Kenwood_TK-272G 1213 OTGSTUFF_OTG Radio v1 667 Kenwood_TK-278G 388 Leixen_VV-898E 1526 LUITON_LT-580_VHF 316 Kenwood_TK-372 566 Kenwood_TK-372G 496 Yaesu_FT-8900 6781 Kenwood_TK-378 585 Kenwood_TK-388G 291 Jetstream_JT220M 688 Kenwood_TK-868G 526 Intek_HR-2040 949 Kenwood_TH-K2 119 Vertex Standard_FTL-8011 369 Vertex Standard_FTL-7011 1542 Yaesu_FTM-3200D 1347 Icom_ID-880H 1535 Icom_IC-T8A 495 Icom_IC-T7H 971 Kenwood_TM-G707 415 Icom_IC-Q7A 759 Kenwood_TM-D710G_CloneMode 286 Kenwood_TK-860G 987 Jetstream_JT270M 613 Leixen_VV-898S 4641 Icom_IC-2100H 2419 Icom_IC-2200H 3083 Icom_ID-80H 363 Icom_ID-31A 415 Icom_IC-W32E 517 Icom_IC-2820H 2349 Icom_7200 716 Kenwood_TK-868 635 Kenwood_TK-378G 386 Retevis_RT9000D_220-260 334 TYT_TH-9800 File 112 Feidaxin_FD-460UH 511 Feidaxin_FD-460A 387 Feidaxin_FD-288B 387 Greaval_GV-9S 726 Quansheng_UV-R50 39 Kenwood_TH-D72 (live mode) 254 Kenwood_TM-D710 560 przemienniki.net_ 370 Motorola_PR860 31 TechSide_TS-T9+ 1742 Jetstream_JT2705M 284 Kenwood_TK-768G 345 Yaesu_FT-2900E/1900E 11 Yaesu_FT-2900/1900 (Modded) 30 Retevis_RB27B 984 Kenwood_TK-768 242 Icom_IC-910 294 Kenwood_TS-590S_CloneMode 99 Wouxun_KG-UV8H 582 Wouxun_KG-UV9K Plus 10 Kenwood_TH-D7 181 Yaesu_FT-7100M 1681 Motorola_CDM1250 593 Leixen_VV898SDualBank 809 Feidaxin_FD-450A 460 BTECH_FRS-B1 2546 Kenwood_TS-850 24 Motorola_HT1250 433 Generic_XML 85 RT Systems_CSV 82 Kenwood_TS-590SG_CloneMode 102 Yaesu_FT5D 1 Icom_7000 23 Wouxun_KG-UV920P 277 ARRL_Travel Plus 35 Kenwood_ITM 38 Quansheng_TG-UV2+ 2982 BTECH_FRS-A1 831 Retevis_RT29 3 Wouxun_KG816 9 AnyTone_779UV 34 Retevis_RT29_VHF_Test 2 Radioddity_DB20-G 32 Wouxun_KG-UV920P-A 2660 Retevis_RT24v 23 Retevis_RB17P 1033 Yaesu_FTM-400 6 BTECH_GMRS-V2 9964 Retevis_RA685 15414 Retevis_RA85 2780 Yaesu_VX-8 41 Kenwood_HMK 27 Yaesu_FT-857 20 Retevis_RB26x 3 Sainsonic_AP510 10 Leixen_VV-898S107 54 Kenwood_TM-471 14 Icom_ID-51A 3 Kenwood_TS-590S/SG_LiveMode 98 Anysecu_WP-9900 2041 Wouxun_KG-819 138 Acme_Template 6 Retevis_RA685 LTX 8 BTECH_UV-82X3 8 Quansheng_TG-UV2+FIX 52 CSV_Generic 22 Baofeng_UV-8 77 Pofung_F17 178 Quansheng_TG-UV2+TEST 5 Baofeng_UV-S9 Plus 100 Baofeng_UV-82HP Triforce 80 Yaesu_FT-857 (US Version) 31 Baofeng_UV-9RPRO 3 Baofeng_UV-9R Pro 53167 Radtel_RT-490 4851 Commander_KG-UV 8 Jianpai_8800 Plus 558 Socotran_FB-8629 172 MMLradio_JC-8629 433 Retevis_RT21V 13 Wouxun_KG-935G 3240 HYS_TC-8900 9 Lanchonlh_HG-UV98 264 Baofeng_P15UV 20 Retevis_RB27A 5 Icom_IC-F520 2 Kenwood_TH-K20 4 Boristone_8RS 94 Abbree_AR-869 447 Icom_ID-52 2 Kenwood_TH-D700 11 QYT_KT-WP12 1436 Kenwood_TK-880 1 Kenwood_TK-280 11 SenHaiX_8800 206 Retevis_RB619 429 Retevis_RB19 289 Retevis_RB19P 401 Retevis_RT28 10 Yaesu_FT-2900 EU 4 Retevis_RT29 VHF 4 Retevis_RT29_VHF 1137 Retevis_RT29_UHF 1626 Baofeng Hack_UV-5R 3 HamGeek_HG-590 16 Abbrree_AR-63 8 Abbree_AR-63 1772 Abbree_AR-518 14516 Retevis_RB15 532 Retevis_RB615 371 Kenwood_TH-D74 (clone mode) 67 Baofeng_GT-22 21 Wouxun_KG-UV9D Plus2 3 TYT_TH-7800 File 54 Retevis_RT40B 192 Baofeng_UV-8D 39 United Star_MHR-148U 5 TID_TD-777S 17 TIDRADIO_TD-777S 730 TIDRADIO_TD-710 18 TID_TD-710 201 TIDRADIO_TD-710s 47 TID_TD-710S 30 TID_TD-V710 485 Retevis_RB23 202 TIDRADIO_TD-777S1 10 Retevis_RB28 3 Retevis_RB29 9 Retevis_RB629 1 TIDRADIO_TD-V710s 2 TIDRADIO_TD-V710 9 Retevis_RT15 13 Retevis_RT19 280 TYT_TH-UV98 8 BTECH_MURS-V2 29 BTECH_GMRS-50V2 4 TYT_MD-380 2 BTECH_UV-50X2_2G 3 Radioddity_UV-5X 4 Retevis_RB618XXX 1 Retevis_C50 3 Baofeng_C50 6 Retevis_RT619 306 Retevis_RT47 298 Retevis_RT47V 177 Retevis_RT647 212 Wouxun_KG-UV980P 456 Explorer_QRZ-1 2714 Wouxun_KG-UV8H-TEST-01 2 Wouxun_KG-935Ga 2 Wouxun_KG-UV9H 66 Wouxun_KG-935Gb 2 Radioddity_UV-5G-MOD 3 Yaesu_FT-7900 6 Retevis_RA685+ 15 Baofeng_BF-V8A 1982 TYT_TH-8600 21 Wouxun_KG-935G-AV 3 Kenwood_TK-8180E 134 Kenwood_TK-7180E 59 Kenwood_TH-D74 (live mode) 32 TYT_TH9000 1 Icom_IC-7610 56 Retevis_RB627B-H 9 Retevis_RB627B_Edd 4 Retevis_RB627BX 17 Wouxun_KG-1000G Plus 119 Icom_ID-5100 97 BTECH_UV-50X2_G2 40 CRT_CRT-279UV 1 Icom_ID-51 Plus2 46 Wouxun_KG-UV8T 61 Icom_IC-V80 35 Icom_ID-4100 12 Wouxun_KG-UV9Px 210 Radtel_RT-470 2 CHIRP_Fake Live Radio 3 TID_TD-H8 194 TID_TD-H8_GMRS 7 TID_TD-H8_HAM 2 Baofeng_BF-888_Custom 6 chirp-20240224/tests/icom_clone_simulator.py0000644000175000017500000001360614430171343017764 0ustar hibbyhibby# Copyright 2019 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys from builtins import bytes import struct from chirp.drivers import icf import logging LOG = logging.getLogger(__name__) log = logging.getLogger() log.level = logging.ERROR log.addHandler(logging.StreamHandler(sys.stdout)) class FakeIcomRadio(object): def __init__(self, radio, mapfile=None): self._buffer = bytes(b'') self._radio = radio if not mapfile: self._memory = bytes(b'\x00') * radio.get_memsize() else: self.load_from_file(mapfile) def load_from_file(self, filename): with open(filename, 'rb') as f: self._memory = bytes(f.read()) LOG.debug('Initialized %i bytes from %s' % (len(self._memory), filename)) def read(self, count): """read() from radio, so here we synthesize responses""" chunk = self._buffer[:count] self._buffer = self._buffer[count:] return chunk def queue(self, data): # LOG.debug('Queuing: %r' % data) self._buffer += data def make_response(self, cmd, payload): return bytes([ 0xFE, 0xFE, 0xEF, # Radio 0xEE, # PC cmd, ]) + payload + bytes([0xFD]) @property def address_fmt(self): if self._radio.get_memsize() > 0x10000: return 'I' else: return 'H' def do_clone_out(self): LOG.debug('Clone from radio started') size = 16 for addr in range(0, self._radio.get_memsize(), size): if len(self._memory[addr:]) < 4: # IC-W32E has an off-by-one hack for detection, # which will cause us to send a short one-byte # block of garbage, unlike the real radio. So, # if we get to the end and have a few bytes # left, don't be stupid. break header = bytes(struct.pack('>%sB' % self.address_fmt, addr, size)) chunk = [] cs = 0 for byte in header: chunk.extend(x for x in bytes(b'%02X' % byte)) cs += byte for byte in self._memory[addr:addr + size]: chunk.extend(x for x in bytes(b'%02X' % byte)) cs += byte vx = ((cs ^ 0xFFFF) + 1) & 0xFF chunk.extend(x for x in bytes(b'%02X' % vx)) self.queue(self.make_response(icf.CMD_CLONE_DAT, bytes(chunk))) self.queue(self.make_response(icf.CMD_CLONE_END, bytes([]))) def do_clone_in(self): LOG.debug('Clone to radio started') self._memory = bytes(b'') def do_clone_data(self, payload_hex): if self.address_fmt == 'I': header_len = 5 else: header_len = 3 def hex_to_byte(hexchars): return int('%s%s' % (chr(hexchars[0]), chr(hexchars[1])), 16) payload_bytes = bytes([hex_to_byte(payload_hex[i:i+2]) for i in range(0, len(payload_hex), 2)]) addr, size = struct.unpack( '>%sB' % self.address_fmt, payload_bytes[:header_len]) data = payload_bytes[header_len:-1] # csum = payload_bytes[-1] if len(data) != size: LOG.debug('Invalid frame size: expected %i, but got %i' % ( size, len(data))) expected_addr = len(self._memory) if addr < expected_addr: LOG.debug('Frame goes back to %04x from %04x' % (addr, expected_addr)) if len(self._memory) != addr: LOG.debug('Filling gap between %04x and %04x' % (expected_addr, addr)) self._memory += (bytes(b'\x00') * (addr - expected_addr)) # FIXME: Check checksum self._memory += data def do_clone_end(self): self.queue(self.make_response(icf.CMD_CLONE_OK, bytes([0]))) def write(self, data): """write() to radio, so here we process requests""" assert isinstance( data, bytes), 'Bytes required, %s received' % data.__class__ while data.startswith(b'\xfe\xfe\xfe'): data = data[1:] # src = data[2] # dst = data[3] cmd = data[4] payload = data[5:-1] # end = data[-1] LOG.debug('Received command: %x' % cmd) LOG.debug(' Full frame: %r' % data) model = self._radio.get_model() + bytes(b'\x00' * 20) if cmd == 0xE0: # Ident # FIXME self.queue(self.make_response(0x01, # Model model)) elif cmd == icf.CMD_CLONE_OUT: self.do_clone_out() elif cmd == icf.CMD_CLONE_IN: self.do_clone_in() elif cmd == icf.CMD_CLONE_DAT: self.do_clone_data(payload) elif cmd == icf.CMD_CLONE_END: self.do_clone_end() elif cmd == icf.CMD_CLONE_HISPEED: LOG.info('Got hispeed kicker') else: LOG.debug('Unknown command %i' % cmd) self.queue(self.make_response(0x00, bytes([0x01]))) return len(data) def flush(self): return chirp-20240224/tests/test_banks.py0000644000175000017500000001065114430171343015710 0ustar hibbyhibbyfrom chirp import chirp_common from tests import base class TestCaseBanks(base.DriverTest): @base.requires_feature('has_bank_names') def test_bank_names(self, testname='T'): bm = self.radio.get_bank_model() banks = bm.get_mappings() for bank in banks: self.assertIsInstance(bank.get_name(), str, 'Bank model returned non-string name') bank.set_name(testname) for bank in bm.get_mappings(): # We allow truncated storage of the name self.assertTrue( testname.lower().startswith(bank.get_name().lower()), 'Bank name %r did not stick after set_name(%r)' % ( bank.get_name(), testname)) # Bank names should not contain trailing whitespace self.assertEqual(bank.get_name(), bank.get_name().rstrip(), 'Bank stored with trailing whitespace') @base.requires_feature('has_bank_names') def test_bank_names_toolong(self): testname = "Not possibly this long" self.test_bank_names(testname) @base.requires_feature('has_bank_names') def test_bank_names_no_trailing_whitespace(self): self.test_bank_names('foo ') @base.requires_feature('has_bank') def test_bank_store(self): loc = self.rf.memory_bounds[0] mem = chirp_common.Memory() mem.number = loc mem.freq = self.rf.valid_bands[0][0] + 100000 # Make sure the memory is empty and we create it from scratch mem.empty = True self.radio.set_memory(mem) mem.empty = False self.radio.set_memory(mem) model = self.radio.get_bank_model() # If in your bank model every channel has to be tied to a bank, just # add a variable named channelAlwaysHasBank to it and make it True try: channelAlwaysHasBank = model.channelAlwaysHasBank except Exception: channelAlwaysHasBank = False mem_banks = model.get_memory_mappings(mem) if channelAlwaysHasBank: self.assertNotEqual(0, len(mem_banks), 'Freshly-created memory has no banks ' 'but it should') else: self.assertEqual(0, len(mem_banks), 'Freshly-created memory has banks ' 'and should not') banks = model.get_mappings() model.add_memory_to_mapping(mem, banks[0]) self.assertIn(banks[0], model.get_memory_mappings(mem), 'Memory does not claim bank after add') self.assertIn(loc, [x.number for x in model.get_mapping_memories(banks[0])], 'Bank does not claim memory after add') model.remove_memory_from_mapping(mem, banks[0]) if not channelAlwaysHasBank: self.assertNotIn(banks[0], model.get_memory_mappings(mem), 'Memory claims bank after remove') self.assertNotIn(loc, [x.number for x in model.get_mapping_memories( banks[0])], 'Bank claims memory after remove') if not channelAlwaysHasBank: # FIXME: We really need a standard exception for this, because # catching Exception here papers over the likely failures from # this going unchecked. self.assertRaises(Exception, model.remove_memory_from_mapping, mem, banks[0]) @base.requires_feature('has_bank_index') def test_bank_index(self): loc = self.rf.memory_bounds[0] mem = chirp_common.Memory() mem.number = loc mem.freq = self.rf.valid_bands[0][0] + 100000 self.radio.set_memory(mem) model = self.radio.get_bank_model() banks = model.get_mappings() index_bounds = model.get_index_bounds() model.add_memory_to_mapping(mem, banks[0]) for i in range(*index_bounds): model.set_memory_index(mem, banks[0], i) self.assertEqual(i, model.get_memory_index(mem, banks[0]), 'Bank index not persisted') suggested_index = model.get_next_mapping_index(banks[0]) self.assertIn(suggested_index, list(range(*index_bounds)), 'Suggested bank index not in valid range') chirp-20240224/tests/base.py0000644000175000017500000002056414522657251014502 0ustar hibbyhibbyimport functools import logging import os import unittest from chirp import chirp_common from chirp import bandplan_na LOG = logging.getLogger(__name__) class DriverTest(unittest.TestCase): RADIO_CLASS = None SUB_DEVICE = None TEST_IMAGE = None def setUp(self): super().setUp() self.patches = [] if ('CHIRP_TEST_BITWISE_STRICT_BYTES' in os.environ and not self.RADIO_CLASS.NEEDS_COMPAT_SERIAL): self.use_patch(unittest.mock.patch( 'chirp.bitwise.DataElement._compat_bytes', side_effect=self._strict_bytes)) self.use_patch(unittest.mock.patch( 'chirp.bitwise.string_straight_encode', side_effect=AssertionError( 'string_straight_encode not allowed in strict mode'))) self.parent = self.RADIO_CLASS(self.TEST_IMAGE) self.parent_rf = self.parent.get_features() # If SUB_DEVICE is set to an index, then the actual radio we are # to test is get_sub_devices()[SUB_DEVICE]. Otherwise, it's the # actual class we were handed. if self.SUB_DEVICE is not None: self.radio = self.parent.get_sub_devices()[self.SUB_DEVICE] self.rf = self.radio.get_features() else: self.radio = self.parent self.rf = self.parent_rf def use_patch(self, patch): self.patches.append(patch) patch.start() def tearDown(self): for patch in self.patches: patch.stop() def _strict_bytes(self, bs, asbytes): """Enforce strict get_raw() behavior returning bytes()""" assert asbytes, 'asbytes must be True in strict mode' assert isinstance(bs, bytes), 'Type should be bytes here' return bs def get_mem(self): """Attempt to build a suitable memory for testing""" # Check to see if memory #1 has immutable fields, and if so, # use that as our template instead of constructing a memory ourselves try: m = self.radio.get_memory(1) # Pre-filter the name so it will match what we expect back if 'name' not in m.immutable: m.name = self.radio.filter_name(m.name) # Disable duplex in case it's set because this will cause some # weirdness if we much with other values, like offset. if 'duplex' not in m.immutable: m.duplex = '' if m.immutable: return m except Exception: pass m = chirp_common.Memory() # Some of the exposed bands may not be transmit-enabled, so # iterate them all attempt = 0 for band_lo, band_hi in self.rf.valid_bands: m.freq = band_lo if self.rf.valid_tuning_steps: # If we have valid tuning steps, go one step above the # bottom of the band. Select a different tuning_step each # time, as some radios have various requirements for which # steps work in each band, mode, etc. steps = [x for x in self.rf.valid_tuning_steps if x > 1] step_index = attempt % len(steps) m.tuning_step = steps[step_index] m.freq += int(m.tuning_step * 1000) elif m.freq + 1000000 < band_hi: # Otherwise just pick 1MHz above the bottom, which has been # our test basis for a long time, unless that extends past # the end of the band. m.freq += 1000000 if m.freq < 30000000 and "AM" in self.rf.valid_modes: m.mode = "AM" else: try: m.mode = self.rf.valid_modes[0] except IndexError: pass for i in range(*self.rf.memory_bounds)[:10]: m.number = i msgs = self.radio.validate_memory(m) warnings, errors = chirp_common.split_validation_msgs(msgs) if warnings and not errors: # If we got some warnings and no errors, then we know the # memory is almost good enough. Set it and pull it back # to let the radio squash whatever was "almost correct" # and then use that. self.radio.set_memory(m) m = self.radio.get_memory(m.number) try: del m.extra except AttributeError: pass return m # If we got no warnings, or we have only one band, then # no errors means we found our candidate. elif not errors: return m attempt += 1 self.fail("No mutable memory locations found - unable to run this " "test because I don't have a memory to test with") def assertEqualMem(self, a, b, ignore=None): if a.tmode == "Cross": tx_mode, rx_mode = a.cross_mode.split("->") a_vals = {} b_vals = {} for k, v in list(a.__dict__.items()): if ignore and k in ignore: continue if k == "power": continue # FIXME elif k == "extra": continue elif k == "immutable": continue elif k == "name": if not self.rf.has_name: continue # Don't complain about name, if not supported else: # Name mismatch fair if filter_name() is right v = self.radio.filter_name(v).rstrip() elif k == "tuning_step" and not self.rf.has_tuning_step: continue elif k == "rtone" and not ( a.tmode == "Tone" or (a.tmode == "TSQL" and not self.rf.has_ctone) or (a.tmode == "Cross" and tx_mode == "Tone") or (a.tmode == "Cross" and rx_mode == "Tone" and not self.rf.has_ctone) ): continue elif k == "ctone" and (not self.rf.has_ctone or not (a.tmode == "TSQL" or (a.tmode == "Cross" and rx_mode == "Tone"))): continue elif k == "dtcs" and not ( (a.tmode == "DTCS" and not self.rf.has_rx_dtcs) or (a.tmode == "Cross" and tx_mode == "DTCS") or (a.tmode == "Cross" and rx_mode == "DTCS" and not self.rf.has_rx_dtcs)): continue elif k == "rx_dtcs" and (not self.rf.has_rx_dtcs or not (a.tmode == "Cross" and rx_mode == "DTCS")): continue elif k == "offset" and not a.duplex: continue elif k == "cross_mode" and a.tmode != "Cross": continue if (a.freq in bandplan_na.ALL_GMRS_FREQS and k in a.immutable or k in b.immutable): # If the radio returned a field in immutable, it probably # means that it's a mandatory setting (i.e. power or duplex # in GMRS) continue a_vals[k] = v b_vals[k] = b.__dict__[k] self.assertEqual(a_vals, b_vals, 'Memories have unexpected differences') # Consider mem.extra as matching if the structure remains the same. # Since we don't know anything about model-specific things here we # can't really assert any more than that, but we can ensure that the # structure doesn't change due to the contents of the rest of the # memory. if a.extra and b.extra: self.assertEqual([x.get_name() for x in a.extra], [x.get_name() for x in b.extra], 'Memories have different mem.extra keys') def requires_feature(flag): def inner(fn): @functools.wraps(fn) def wraps(self, *a, **k): if getattr(self.rf, flag): fn(self, *a, **k) else: self.skipTest('Feature %s not supported' % flag) return wraps return inner chirp-20240224/tests/test_features.py0000644000175000017500000000074514430171343016433 0ustar hibbyhibbyfrom unittest import mock from tests import base class TestCaseFeatures(base.DriverTest): def test_prompts(self): self.use_patch(mock.patch('builtins._', create=True, side_effect=lambda s: s)) prompts = self.radio.get_prompts() for p in ('info', 'experimental', 'pre_download', 'pre_upload'): prompt = getattr(prompts, p) if prompt is not None: self.assertIsInstance(prompt, str) chirp-20240224/tests/py3_driver_testers.txt0000644000175000017500000003532514566340166017621 0ustar hibbyhibby# Format is: # Driver_ID,Tester,Test Date # Tester is preferred as a github id, but obfuscated email or name is # acceptable. If a driver is literally identical to another, use # +DRIVER_KEY to mark it as implied-tested. # If the driver is tested with an in-tree image (or is a live driver) and the # clone routines are shared in common with other things that are tested, use # *MODULE_NAME to mark it as "probably works because of common code in # $module". If a user reported it as working in a chirp website issue, use # the form #BUGNUMBER. Abbree_AR-518,@KC9HI,16-Dec-2022 Abbree_AR-63,@KC9HI,30-Nov-2022 Abbree_AR-730,@KC9HI,17-Aug-2023 Abbree_AR-869,+Radtel_RT-490,11-Nov-2023 Abbree_AR-F5,@KC9HI,09-Aug-2023 Alinco_DJ175,+Alinco_DR235T,12-Dec-2022 Alinco_DJ596,+Alinco_DR235T,12-Dec-2022 Alinco_DJ-G7EG,@HB9UF,09-Dec-2022 Alinco_DJ-G7T,#10567,09-May-2023 Alinco_DR03T,+Alinco_DR235T,12-Dec-2022 Alinco_DR06T,+Alinco_DR235T,12-Dec-2022 Alinco_DR135T,+Alinco_DR235T,12-Dec-2022 Alinco_DR235T,@kk7ds,12-Dec-2022 Alinco_DR435T,+Alinco_DR235T,12-Dec-2022 Anysecu_UV-A37,@KC9HI,5-Jun-2023 Anysecu_WP-9900,@KC9HI,11-Nov-2022 Anysecu_AC-580,+Radioddity_GS-5B,17-Mar-2023 AnyTone_778UV,+Retevis_RT95,13-Nov-2022 AnyTone_778UV_VOX,+Retevis_RT95,13-Nov-2022 AnyTone_5888UV,@kk7ds,9-Dec-2022 AnyTone_5888UVIII,@bschuler42,9-Jan-2023 AnyTone_OBLTR-8R,@KC9HI,17-Dec-2022 AnyTone_TERMN-8R,@KC9HI,17-Dec-2022 BTECH_FRS-A1,@KC9HI,30-Nov-2022 BTECH_FRS-B1,@KC9HI,28-Nov-2022 BTECH_GMRS-20V2,@KC9HI,13-Nov-2022 BTECH_GMRS-50V2,@KC9HI,15-Feb-2023 BTECH_GMRS-50X1,@KC9HI,13-Nov-2022 BTECH_GMRS-V1,@KC9HI,10-Dec-2022 BTECH_GMRS-V2,@KC9HI,10-Dec-2022 BTECH_MURS-V1,@KC9HI,10-Dec-2022 BTECH_MURS-V2,@KC9HI,2-Mar-2023 BTECH_UV-2501,@KC9HI,11-Nov-2022 BTECH_UV-2501+220,@KC9HI,11-Nov-2022 BTECH_UV-25X2,@KC9HI,11-Nov-2022 BTECH_UV-25X2_G2,@KC9HI,23-Apr-2023 BTECH_UV-25X4,@KC9HI,10-Nov-2022 BTECH_UV-25X4_G2,@KC9HI,23-Apr-2023 BTECH_UV-5001,@KC9HI,11-Nov-2022 BTECH_UV-50X2,@KC9HI,11-Nov-2022 BTECH_UV-50X2_G2,@KC9HI,30-Nov-2022 BTECH_UV-50X3,@KC9HI,10-Dec-2022 BTECH_UV-5X3,@KC9HI,9-Dec-2022 Baofeng_5RM,@vdwel,7-Dec-2023 Baofeng_5RX,@KC9HI,16-Jan-2024 Baofeng_BF-1901,@cetinajero,3-Jul-2023 Baofeng_BF-1904,@cetinajero,3-Jul-2023 Baofeng_BF-888,@kk7ds,13-Feb-2019 Baofeng_BF-A58,@KC9HI,3-Dec-2022 Baofeng_BF-A58S,@KC9HI,3-Dec-2022 Baofeng_BF-F8HP,@KC9HI,18-Nov-2022 Baofeng_BF-M4,@cetinajero,8-May-2023 Baofeng_BF-T1,@KC9HI,10-Dec-2022 Baofeng_BF-T20,@KC9HI,15-Dec-2023 Baofeng_BF-T20FRS,@KC9HI,17-Dec-2023 Baofeng_BF-T8,@KC9HI,30-Nov-2022 Baofeng_BF-V8A,@KC9HI,28-Nov-2022 Baofeng_F-11,+Baofeng_UV-5R,18-Nov-2022 Baofeng_GT-3WP,@KC9HI,3-Dec-2022 Baofeng_GT-5R,@KC9HI,18-Nov-2022 Baofeng_UV-3R,@yarda,26-Sep-2022 Baofeng_UV-5R,@lekv,23-Oct-2022 Baofeng_UV-6,+Baofeng_UV-5R,18-Nov-2022 Baofeng_UV-6R,@KC9HI,10-Dec-2022 Baofeng_UV-82,@KC9HI,18-Nov-2022 Baofeng_UV-82HP,@KC9HI,18-Nov-2022 Baofeng_UV-82WP,@KC9HI,3-Dec-2022 Baofeng_UV-9G,@KC9HI,3-Dec-2022 Baofeng_UV-9R,@KC9HI,3-Dec-2022 Baofeng_UV-13Pro,@vdwel,21-Feb-2024 Baofeng_UV-17,@vdwel,27-Nov-2023 Baofeng_UV-17Pro,@vdwel,27-Nov-2023 Baofeng_UV-17ProGPS,@vdwel,27-Nov-2023 Baofeng_UV-B5,@KC9HI,18-Nov-2022 Baofeng_UV-S9X3,@KC9HI,22-Aug-2023 Baofeng_W31E,@KC9HI,14-Aug-2023 Baojie_BJ-218,+LUITON_LT-725UV,16-Feb-2023 Baojie_BJ-318,@KC9HI,2-Jan-2023 Boristone_8RS,+Radtel_RT-490,11-Nov-2023 Cignus_XTR-5,+Radioddity_GS-5B,17-Mar-2023 CRT_Micron_UV,+Retevis_RT95,13-Nov-2022 CRT_Micron_UV_V2,+Retevis_RT95,13-Nov-2022 Explorer_QRZ-1,+TYT_TH-UV88,5-Dec-2022 Generic_CSV,@kk7ds,4-Dec-2022 HamGeek_HG-590,+Radtel_RT-490,11-Nov-2023 Hiroyasu_HI-8811,@KC9HI,4-Jun-2023 HobbyPCB_RS-UV3,@kk7ds,9-Dec-2022 Icom_IC-208H,*icf,12-Dec-2022 Icom_IC-2100H,*icf,12-Dec-2022 Icom_IC-2200H,@kk7ds,24-Oct-2022 Icom_IC-2300H,#10264,13-Jan-2022 Icom_IC-2720H,*icf,12-Dec-2022 Icom_IC-2730A,#10261,17-Dec-2022 Icom_IC-2820H,@kk7ds,22-Oct-2022 Icom_IC-7000,#10510,10-Apr-2023 Icom_IC-7100,Mike W,16-Feb-2023 Icom_IC-7200,@kk7ds,22-Oct-2022 Icom_IC-7300,@kk7ds,22-Oct-2022 Icom_IC-746,#10346,3-Feb-2023 Icom_IC-7610,@kk7ds,24-Oct-2022 Icom_IC-91_92AD,@kk7ds,23-Nov-2022 Icom_IC-910,@mfncooper,1-Oct-2021 Icom_ID-31A,@kk7ds,1-Dec-2022 Icom_ID-51,+Icom_ID-31A,1-Dec-2022 Icom_ID-51_Plus,+Icom_ID-31A,1-Dec-2022 Icom_ID-51_Plus2,+Icom_ID-31A,17-Dec-2022 Icom_ID-4100,@n8sqt,18-Dec-2022 Icom_ID-5100,@kk7ds,17-Dec-2022 Icom_ID-800H_v2,@kk7ds,22-Oct-2022 Icom_ID-80H,*icf,22-Oct-2022 Icom_ID-880H,@kk7ds,22-Oct-2022 Icom_IC-E90,*icf,12-Dec-2022 Icom_IC-P7,*icf,12-Dec-2022 Icom_IC-T70,*icf,12-Dec-2022 Icom_IC-T7H,#10752,30-Jul-2023 Icom_IC-T8A,*icf,12-Dec-2022 Icom_IC-Q7A,@KC9HI,20-Nov-2022 Icom_IC-U82,+Icom_IC-V82,25-Jan-2023 Icom_IC-V80,@kk7ds,16-Feb-2023 Icom_IC-V82,@kk7ds,25-Jan-2023 Icom_IC-V86,*icf,12-Dec-2022 Icom_IC-W32A,#10238,12-Dec-2022 Icom_IC-W32E,*icf,12-Dec-2022 Intek_KT-980HP,+Baofeng_BF-F8HP,18-Nov-2022 Intek_HR-2040,+AnyTone_5888UV,9-Dec-2022 Jetstream_JT220M,+Alinco_DR235T,12-Dec-2022 Jetstream_JT270M,+Jetstream_JT270M,13-Dec-2022 Jetstream_JT270MH,@kk7ds,13-Dec-2022 Jianpai_8800_Plus,+Radtel_RT-490,11-Nov-2023 JJCC_JC-8629,+Radtel_RT-490,11-Nov-2023 Kenwood_HMK,+Generic_CSV,4-Dec-2022 Kenwood_TH-D7,*kenwood_live,12-Dec-2022 Kenwood_TH-D7G,*kenwood_live,12-Dec-2022 Kenwood_TH-D72_clone_mode,@kk7ds,28-Nov-2022 Kenwood_TH-D72_live_mode,@kk7ds,21-Oct-2022 Kenwood_TH-D74_clone_mode,@kk7ds,30-Nov-2022 Kenwood_TH-D74_live_mode,@kk7ds,20-Oct-2022 Kenwood_TH-D75,#11122,114-Feb-2024 Kenwood_TH-F6,@KC9HI,30-Nov-2022 Kenwood_TH-F7,@sv1,19-Oct-2022 Kenwood_TH-G71,*kenwood_live,12-Dec-2022 Kenwood_TH-K2,*kenwood_live,12-Dec-2022 Kenwood_TM-271,+Kenwood_TM-281,23-Oct-2022 Kenwood_TM-281,@kk7ds,23-Oct-2022 Kenwood_TM-471,*kenwood_live,12-Dec-2022 Kenwood_TM-D700,@kk7ds,20-Oct-2022 Kenwood_TM-D710,*kenwood_live,22-Oct-2022 Kenwood_TM-D710G,@kk7ds,22-Oct-2022 Kenwood_TM-D710G_CloneMode,@kk7ds,22-Oct-2022 Kenwood_TM-G707,*kenwood_live,12-Dec-2022 Kenwood_TM-V7,*kenwood_live,12-Dec-2022 Kenwood_TM-V71,@kk7ds,21-Oct-2022 Kenwood_TK-2140K,+Kenwood_TK-3140K,2-Feb-2023 Kenwood_TK-2180,@kk7ds,4-Dec-2022 Kenwood_TK-3140K,@kk7ds,2-Feb-2023 Kenwood_TK-3140K2,+Kenwood_TK-3140K,2-Feb-2023 Kenwood_TK-3140K3,+Kenwood_TK-3140K,2-Feb-2023 Kenwood_TK-3180K,@kk7ds,4-Dec-2022 Kenwood_TK-3180K2,+Kenwood_TK-3180K,4-Dec-2022 Kenwood_TK-7102,@kk7ds,15-Feb-2019 Kenwood_TK-7108,@kk7ds,15-Feb-2019 Kenwood_TK-7180,@kk7ds,18-Oct-2022 Kenwood_TK-7180E,+Kenwood_TK-7180,18-Oct-2022 Kenwood_TK-8102,@kk7ds,15-Feb-2019 Kenwood_TK-8108,@kk7ds,15-Feb-2019 Kenwood_TK-7160K,@kk7ds,27-Jan-2023 Kenwood_TK-7160M,+Kenwood_TK-7160K,27-Jan-2023 Kenwood_TK-8160K,+Kenwood_TK-7160K,27-Jan-2023 Kenwood_TK-8160M,+Kenwood_TK-7160K,27-Jan-2023 Kenwood_TK-8180,@kk7ds,18-Oct-2022 Kenwood_TK-8180E,+Kenwood_TK-8180,18-Dec-2022 Kenwood_TK-762G,@kk7ds,5-Dec-2022 Kenwood_TK-868G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-862G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-860G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-768G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-760G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-388G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-378G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-372G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-370G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-360G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-278G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-272G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-270G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-260G,+Kenwood_TK-762G,5-Dec-2022 Kenwood_TK-760,@kk7ds,5-Dec-2022 Kenwood_TK-762,+Kenwood_TK-760,5-Dec-2022 Kenwood_TK-768,+Kenwood_TK-760,5-Dec-2022 Kenwood_TK-860,+Kenwood_TK-760,5-Dec-2022 Kenwood_TK-862,+Kenwood_TK-760,5-Dec-2022 Kenwood_TK-868,+Kenwood_TK-760,5-Dec-2022 Kenwood_TS-2000,ZS6CRW,10-Jan-2022 Leixen_VV-898,+Jetstream_JT270MH,13-Dec-2022 Leixen_VV-898S,@READ10,19-Dec-2022 Leixen_VV-898S_Dual_Bank,#4069,10-Feb-2024 Leixen_VV-898E_Dual_Bank,+Leixen_VV-898S_Dual_Bank,10-Feb-2024 LUITON_LT-316,+Retevis_RT22,9-Dec-2022 LUITON_LT-580_UHF,@KC9HI,8-Dec-2022 LUITON_LT-580_VHF,@KC9HI,8-Dec-2022 LUITON_LT-588UV,@KC9HI,11-Nov-2022 LUITON_LT-725UV,@KC9HI,11-Dec-2022 Maverick_RA-100,@cetinajero,7-Jul-2023 Maverick_RA-425,@cetinajero,7-Jul-2023 MMLradio_JC-8629,@KC9HI,11-Nov-2023 MTC_UV-5R-3,+BTECH_UV-5X3,9-Dec-2022 Midland_DBR2500,+Retevis_RT95,13-Nov-2022 Polmar_DB-50M,+AnyTone_5888UV,9-Dec-2022 Powerwerx_DB-750X,+AnyTone_5888UV,9-Dec-2022 Puxing_PX-888K,#10544,09-May-2023 Q-MAC_HF-90_v300_or_earlier,@fthain,9-Mar-2023 Q-MAC_HF-90_v301_or_later,@fthain,9-Mar-2023 Quansheng_TG-UV2+,#10398,26-Feb-2023 Quansheng_UV-K5,@sq5bpf,29-May-2023 Quansheng_UV-K5_egzumer,@egzumer,23-Jan-2024 QYT_KT-8R,@KC9HI,11-Nov-2022 QYT_KT-UV980,+WACCOM_MINI-8900,11-Nov-2022 QYT_KT-WP12,+Anysecu_WP-9900,11-Nov-2022 QYT_KT5800,+BTECH_UV-25X2,11-Nov-2022 QYT_KT7900D,+BTECH_UV-25X4,11-Nov-2022 QYT_KT8900,+LUITON_LT-588UV,11-Nov-2022 QYT_KT8900D,+BTECH_UV-25X2,11-Nov-2022 QYT_KT8900R,+BTECH_UV-2501+220,11-Nov-2022 QYT_KT980PLUS,+BTECH_UV-25X2,11-Nov-2022 Radioddity_DB25-G,@KC9HI,11-Nov-2022 Radioddity_GA-2S,@KC9HI,4-Dec-2022 Radioddity_GA-510,@kk7ds,21-Oct-2022 Radioddity_GS-5B,@lunapiercook,5-Mar-2023 Radioddity_R2,@KC9HI,17-Dec-2022 Radioddity_UV-5G,@KC9HI,18-Nov-2022 Radioddity_UV-5RX3,@KC9HI,18-Nov-2022 Radioddity_UV-82X3,@KC9HI,18-Nov-2022 Radtel_RT-470,@KC9HI,2-Apr-2023 Radtel_RT-470L,@KC9HI,5-May-2023 Radtel_RT-470X,@KC9HI,10-Aug-2023 Radtel_RT-490,@KC9HI,11-Nov-2023 Radtel_T18,@KC9HI,28-Nov-2022 Retevis_H777S,@KC9HI,22-Dec-2022 Retevis_H777_Plus,@KC9HI,4-Dec-2022 Retevis_RA685,@KC9HI,19-Nov-2022 Retevis_RA79,@KC9HI,27-Oct-2023 Retevis_RA85,@KC9HI,19-Nov-2022 Retevis_RA89,@KC9HI,23-Nov-2023 Retevis_RB15,@KC9HI,18-Dec-2022 Retevis_RB17,@KC9HI,28-Nov-2022 Retevis_RB17A,@KC9HI,30-Nov-2022 Retevis_RB17P,@KC9HI,18-Dec-2022 Retevis_RB17V,@KC9HI,28-Nov-2022 Retevis_RB18,@KC9HI,28-Nov-2022 Retevis_RB19,@KC9HI,28-Nov-2022 Retevis_RB19P,@KC9HI,28-Nov-2022 Retevis_RB23,@KC9HI,30-Nov-2022 Retevis_RB26,@KC9HI,30-Nov-2022 Retevis_RB27,@KC9HI,30-Nov-2022 Retevis_RB27B,@KC9HI,30-Nov-2022 Retevis_RB28,@KC9HI,9-Feb-2023 Retevis_RB28B,@KC9HI,27-Jan-2023 Retevis_RB27V,@KC9HI,30-Nov-2022 Retevis_RB29,@KC9HI,24-Dec-2022 Retevis_RB615,@KC9HI,18-Dec-2022 Retevis_RB617,@KC9HI,28-Nov-2022 Retevis_RB618,@KC9HI,28-Nov-2022 Retevis_RB619,@KC9HI,28-Nov-2022 Retevis_RB627B,@KC9HI,30-Nov-2022 Retevis_RB628,@KC9HI,10-Feb-2023 Retevis_RB628B,@KC9HI,28-Jan-2023 Retevis_RB629,@KC9HI,24-Dec-2022 Retevis_RB75,@KC9HI,28-Nov-2022 Retevis_RB85,@KC9HI,28-Nov-2022 Retevis_RB87,@KC9HI,10-Mar-2023 Retevis_RT15,@KC9HI,18-Feb-2023 Retevis_RT16,@KC9HI,30-Nov-2022 Retevis_RT19,@KC9HI,30-Nov-2022 Retevis_RT20,@k9ps-paul,7-Sep-2023 Retevis_RT21,@KC9HI,30-Nov-2022 Retevis_RT21V,@KC9HI,24-Jul-2023 Retevis_RT22,@KC9HI,9-Dec-2022 Retevis_RT23,@KC9HI,17-Dec-2022 Retevis_RT22FRS,@KC9HI,9-Dec-2022 Retevis_RT22S,@KC9HI,28-Nov-2022 Retevis_RT24,@KC9HI,22-Dec-2022 Retevis_RT24V,@KC9HI,27-Aug-2023 Retevis_RT26,@KC9HI,17-Dec-2022 Retevis_RT29_UHF,@KC9HI,30-Nov-2022 Retevis_RT29_VHF,@KC9HI,30-Nov-2022 Retevis_RT40B,@KC9HI,30-Nov-2022 Retevis_RT47,@KC9HI,28-Nov-2022 Retevis_RT47V,@KC9HI,28-Nov-2022 Retevis_RT1,@KC9HI,11-Dec-2022 Retevis_RT6,@KC9HI,3-Dec-2022 Retevis_RT619,@KC9HI,30-Nov-2022 Retevis_RT622,@KC9HI,9-Dec-2022 Retevis_RT647,@KC9HI,28-Nov-2022 Retevis_RT668,@KC9HI,28-Nov-2022 Retevis_RT68,@KC9HI,28-Nov-2022 Retevis_RT76,@KC9HI,30-Nov-2022 Retevis_RT76P,@KC9HI,17-Dec-2022 Retevis_RT85,@KC9HI,5-Dec-2022 Retevis_RT86,@KC9HI,17-Feb-2023 Retevis_RT87,@KC9HI,17-Dec-2022 Retevis_RT95,@KC9HI,13-Nov-2022 Retevis_RT95_VOX,+Retevis_RT95,13-Nov-2022 Retevis_RT98,@KC9HI,14-Dec-2022 Retevis_RT9000D_136-174,@KC9HI,8-Dec-2022 Retevis_RT9000D_220-260,@KC9HI,8-Dec-2022 Retevis_RT9000D_400-490,@KC9HI,8-Dec-2022 Retevis_RT9000D_66-88,@KC9HI,8-Dec-2022 Ruyage_UV58Plus,@KC9HI,18-Mar-2023 SenhaiX_8800,+Radioddity_GS-5B,17-Mar-2023 Socotran_FB-8629,+Radtel_RT-490,11-Nov-2023 Socotran_JC-8629,+Radtel_RT-490,11-Nov-2023 Talkpod_A36plus,@KC9HI,12-Jun-2023 Talkpod_A36plus_8w,@KC9HI,16-Feb-2024 TDXone_TD-Q8A,@KC9HI,18-Dec-2022 TIDRADIO_TD-H6,@kk7ds,21-Oct-2022 TIDRADIO_TD-H8,@Sandmann34,7-Feb-2023 TIDRADIO_TD-H8-GMRS,@Sandmann34,7-Feb-2023 TIDRADIO_TD-H8-HAM,@Sandmann34,7-Feb-2023 TID_TD-M8,+Retevis_RT22,9-Dec-2022 TID_TD-UV68,@Sandmann34,7-Feb-2023 TIDRADIO_TD-H3,@songjunbiao,1-Dec-2023 TIDRADIO_TD-H3-GMRS,@songjunbiao,1-Dec-2023 TIDRADIO_TD-H3-HAM,@songjunbiao,1-Dec-2023 TYT_TH-UVF1,@kk7ds,13-Dec-2022 TYT_TH-UVF8D,@MELERIX,2-Feb-2023 TYT_TH-UV8000,@KC9HI,6-Jan-2023 TYT_TH-UV88,@KC9HI,5-Dec-2022 TYT_TH-7800,#10585,4-Jul-2023 TYT_TH9000_144,+Retevis_RT9000D_136-174,8-Dec-2022 TYT_TH9000_220,+Retevis_RT9000D_220-260,8-Dec-2022 TYT_TH9000_440,+Retevis_RT9000D_400-490,8-Dec-2022 TYT_TH-9800,#10755,30-Jul-2023 WACCOM_MINI-8900,@KC9HI,11-Nov-2022 WLN_KD-C1,+Retevis_RT22,9-Dec-2022 Wouxun_KG-1000G,@mrtjr1,23-jan-2023 Wouxun_KG-1000G_Plus,@mrtjr1,23-jan-2023 Wouxun_KG-816,+Wouxun_KG-UV6,11-Dec-2022 Wouxun_KG-818,+Wouxun_KG-UV6,11-Dec-2022 Wouxun_KG-UV6,@KC9HI,11-Dec-2022 Wouxun_KG-UVD1P,+Wouxun_KG-UV6,11-Dec-2022 Wouxun_KG-UV8D,Unit tested; needs confirm,24-Dec-2022 Wouxun_KG-UV8D_Plus,Unit tested; needs confirm,2-Jan-2022 Wouxun_KG-UV8H,@mrtjr1,27-Mar-2023 Wouxun_KG-UV8E,W5EGL,2-Jan-2022 Wouxun_KG-UV9D_Plus,@samwich,10-Jan-2023 Wouxun_KG-UV920P-A,@KC9HI,22-Dec-2022 Wouxun_KG-UV980P,@mrtjr1,23-jan-2023 Wouxun_KG-UV9PX,@mrtjr1,20-Jan-2022 Wouxun_KG-UV9GX,@mrtjr1,27-Mar-2023 Wouxun_KG-UV9G_Pro,@mrtjr1,25-Apr-2023 Wouxun_KG-UV9K,@mrtjr1,14-Apr-2023 Wouxun_KG-935G,@mrtjr1,4-Jan-2022 Wouxun_KG-935G_Plus,@mrtjr1,7-Feb-2023 Yaesu_FT-1500M,@f3sty,05-Dec-2022 Yaesu_FT-2800M,#10616,05-Jun-2023 Yaesu_FT-2900R_1900R,#10274,14-Jan-2023 Yaesu_FT-2900R_1900RTXMod_Opened_Xmit,+Yaesu_FT-2900R_1900R,14-Jan-2023 Yaesu_FT-1D_R,+Yaesu_FT3D_R,30-Dec-2022 Yaesu_FT2D_R,+Yaesu_FT3D_R,30-Dec-2022 Yaesu_FT2D_Rv2,+Yaesu_FT3D_R,30-Dec-2022 Yaesu_FT3D_R,@kk7ds,30-Dec-2022 Yaesu_FT-450,@WCurlew,03-Nov-2023 Yaesu_FT-450D,@Old-Phart,01-Jun-2023 Yaesu_FT-4XE,Unit tested; needs confirm,24-Dec-2022 Yaesu_FT-4XR,+Yaesu_FT-4XE,24-Dec-2022 Yaesu_FT-4VR,+Yaesu_FT-4XE,24-Dec-2022 Yaesu_FT-65R,#10266,13-Jan-2022 Yaesu_FT-65E,@kwirk,27-Jan-2023 Yaesu_FT-25R,+Yaesu_FT-4XE,24-Dec-2022 Yaesu_FT-50,#10824,5-Sep-2023 Yaesu_FT-60,N0EYE,9-Jan-2023 Yaesu_FT-70D,@n8sqt,05-Dec-2022 Yaesu_FT-7800_7900,@kk7ds,24-Oct-2022 Yaesu_FT-8100,#10904,19-Oct-2023 Yaesu_FT-8800,@kk7ds,24-Oct-2022 Yaesu_FT-8900,#10753,30-Jul-2023 Yaesu_FT-817,@kk7ds,14-Feb-2019 Yaesu_FT-817ND,+Yaesu_FT-817,14-Feb-2019 Yaesu_FT-817ND_US,+Yaesu_FT-817,14-Feb-2019 Yaesu_FT-818,@thomasrussellmurphy,4-Feb-2023 Yaesu_FT-818ND_US,+Yaesu_FT-817,14-Feb-2019 Yaesu_FT-857_897,+Yaesu_FT-817,14-Feb-2019 Yaesu_FT-857_897_US,+Yaesu_FT-817,14-Feb-2019 Yaesu_FT-90,#10386,22-Feb-2023 Yaesu_FTM-350,@kk7ds,4-Dec-2022 Yaesu_VX-2,@thomasrussellmurphy,20-Jan-2023 Yaesu_VX-3,@kk7ds,15-Feb-2019 Yaesu_VX-5,*yaesu_clone,12-Dec-2022 Yaesu_VX-6,@dominickpastore,10-Dec-2022 Yaesu_VX-7,@kk7ds,15-Feb-2019 Yaesu_VX-8R,+Yaesu_VX-8DR,15-Feb-2019 Yaesu_VX-8DR,@kk7ds,15-Feb-2019 Yaesu_VX-8GE,+Yaesu_VX-8DR,15-Feb-2019 Yedro_YC-M04VUS,+Retevis_RT95,13-Nov-2022 Zastone_ZT-X6,+Retevis_RT22,9-Dec-2022 chirp-20240224/tests/xfails.txt0000644000175000017500000000076714522657251015250 0ustar hibbyhibby# This is a list of tests that are expected to fail. DO NOT add new things to # this file without careful consideration and discussion. This is not a tool # to avoid fixing failures, it is purely a stop-gap to allow temporary # failures to avoid breaking the build while iterating towards a fix. # # One line per test nodeid with a comment above citing a bug number, example: # Bug #10931: FT-450 mem.extra fields cause UI corruption # tests/test_drivers.py::TestCaseBruteForce_Yaesu_FT-450D::test_mode chirp-20240224/tests/test_edges.py0000644000175000017500000001635514561124165015715 0ustar hibbyhibbyimport pytest from unittest import mock from chirp import bitwise from chirp import chirp_common from chirp import errors from tests import base class TestCaseEdges(base.DriverTest): def test_longname(self): m = self.get_mem() m.name = ("X" * 256) # Should be longer than any radio can handle m.name = self.radio.filter_name(m.name) self.radio.set_memory(m) n = self.radio.get_memory(m.number) self.assertEqualMem(m, n) def test_badname(self): m = self.get_mem() ascii = "".join([chr(x) for x in range(ord(" "), ord("~")+1)]) for i in range(0, len(ascii), 4): m.name = self.radio.filter_name(ascii[i:i+4]) self.radio.set_memory(m) n = self.radio.get_memory(m.number) self.assertEqualMem(m, n) def test_bandedges(self): m = self.get_mem() min_step = min(self.rf.has_tuning_step and self.rf.valid_tuning_steps or [10]) for low, high in self.rf.valid_bands: for freq in (low, high - int(min_step * 1000)): try: m.freq = freq except chirp_common.ImmutableValueError: self.skipTest('Test memory has immutable freq') if self.radio.validate_memory(m): # Radio doesn't like it, so skip continue self.radio.set_memory(m) n = self.radio.get_memory(m.number) self.assertEqualMem(m, n) def test_oddsteps(self): odd_steps = { 145000000: [145856250, 145862500], 445000000: [445856250, 445862500], 862000000: [862731250, 862737500], } m = self.get_mem() for low, high in self.rf.valid_bands: for band, totest in list(odd_steps.items()): if band < low or band > high: continue for testfreq in totest: step = chirp_common.required_step(testfreq) if step not in self.rf.valid_tuning_steps: continue try: m.freq = testfreq except chirp_common.ImmutableValueError: self.skipTest('Test channel has immutable freq') m.tuning_step = step self.radio.set_memory(m) n = self.radio.get_memory(m.number) self.assertEqualMem(m, n, ignore=['tuning_step']) def test_empty_to_not(self): firstband = self.rf.valid_bands[0] testfreq = firstband[0] for loc in range(*self.rf.memory_bounds): m = self.radio.get_memory(loc) if m.empty: m.empty = False m.freq = testfreq self.radio.set_memory(m) m = self.radio.get_memory(loc) self.assertEqual(testfreq, m.freq, 'Radio returned an unexpected frequency when' 'setting previously-empty location %i' % loc) break def test_delete_memory(self): for loc in range(*self.rf.memory_bounds): m = self.radio.get_memory(loc) if 'empty' in m.immutable: # This memory is not deletable continue if not m.empty: m.empty = True self.radio.set_memory(m) m = self.radio.get_memory(loc) self.assertTrue(m.empty, 'Radio returned non-empty memory when asked ' 'to delete location %i' % loc) break def test_get_set_specials(self): if not self.rf.valid_special_chans: self.skipTest('Radio has no specials') lo, hi = self.rf.memory_bounds for name in self.rf.valid_special_chans: m1 = self.radio.get_memory(name) # Flip to non-empty, but only touch it if it's false because some # radios have empty in the immutable set. if m1.empty: m1.empty = False try: del m1.extra except AttributeError: pass if m1.freq > 130000000 and m1.freq < 500000000: m1.freq += 5000 elif m1.freq == 0: # If the memory was empty before, we likely need to pick # a valid frequency. Use the bottom of the first supported # band. m1.freq = self.rf.valid_bands[0][0] try: self.radio.set_memory(m1) except errors.RadioError: # If the radio raises RadioError, assume we're editing a # special channel that is not editable continue m2 = self.radio.get_memory(name) self.assertEqualMem(m1, m2, ignore=['name']) self.assertFalse( lo < m1.number < hi, 'Special memory %s maps into memory bounds at %i' % ( name, m1.number)) def test_check_regular_not_special(self): lo, hi = self.rf.memory_bounds for i in range(lo, hi + 1): m = self.radio.get_memory(i) self.assertEqual('', m.extd_number, 'Non-special memory %i should not have ' 'extd_number set to %r' % (i, m.extd_number)) def test_get_memory_name_trailing_whitespace(self): if self.radio.MODEL == 'KG-UV8E': self.skipTest('The UV8E driver is so broken it does not even ' 'parse its own test image cleanly') for i in range(*self.rf.memory_bounds): m = self.radio.get_memory(i) self.assertEqual(m.name.rstrip(), m.name, 'Radio returned a memory with trailing ' 'whitespace in the name') def test_memory_name_stripped(self): if ' ' not in self.rf.valid_characters: self.skipTest('Radio does not support space characters') m1 = self.get_mem() m1.name = 'FOO ' self.radio.set_memory(m1) m2 = self.radio.get_memory(m1.number) self.assertEqual(m2.name.rstrip(), m2.name, 'Radio set and returned a memory with trailing ' 'whitespace in the name') class TestBitwiseStrict(base.DriverTest): def setUp(self): pass def _raise(self, message): raise SyntaxError(message) @pytest.mark.xfail(strict=False) @mock.patch.object(bitwise.Processor, 'assert_negative_seek', side_effect=_raise) def test_bitwise_negative_seek(self, mock_assert): super().setUp() @pytest.mark.xfail(strict=False) @mock.patch.object(bitwise.Processor, 'assert_unnecessary_seek', side_effect=_raise) def test_bitwise_unnecessary_seek(self, mock_assert): super().setUp() @pytest.mark.xfail(strict=False) @mock.patch.object(bitwise.LOG, 'error') def test_bitwise_errors(self, mock_log): super().setUp() self.assertFalse(mock_log.called, [x[0][0] for x in mock_log.call_args_list]) chirp-20240224/tests/test_clone.py0000644000175000017500000000545014430171343015713 0ustar hibbyhibbyimport logging import time from unittest import mock from chirp import chirp_common from chirp import errors from tests import base LOG = logging.getLogger(__name__) class SerialNone: def read(self, size): return b"" def write(self, data): if not isinstance(data, bytes): raise TypeError('Radio wrote non-bytes to serial') def setBaudrate(self, rate): pass def setTimeout(self, timeout): pass def setParity(self, parity): pass def __str__(self): return self.__class__.__name__.replace("Serial", "") class SerialError(SerialNone): def read(self, size): raise Exception("Foo") def write(self, data): raise Exception("Bar") class SerialGarbage(SerialNone): def read(self, size): buf = [] for i in range(0, size): buf.append(i % 256) return bytes(buf) class SerialShortGarbage(SerialNone): def read(self, size): return b'\x00' * (size - 1) class TestCaseClone(base.DriverTest): def setUp(self): super().setUp() self.live = isinstance(self.radio, chirp_common.LiveRadio) self.clone = isinstance(self.radio, chirp_common.CloneModeRadio) if not self.clone and not self.live: self.skipTest('Does not support clone') real_time = time.time def fake_time(): return real_time() * 1000 self.patches = [] self.use_patch(mock.patch('time.sleep')) self.use_patch(mock.patch('time.time', side_effect=fake_time)) def _test_with_serial(self, serial): # The base case sets us up with a file, so re-init with our serial. # The radio must not read (or fail) with unexpected/error serial # behavior on init. LOG.info('Initializing radio with fake serial; Radio should not fail') orig_mmap = self.parent._mmap self.radio = self.RADIO_CLASS(serial) self.radio._mmap = orig_mmap self.radio.status_fn = lambda s: True msg = ('Clone should have failed and raised an exception ' 'that inherits from RadioError') with self.assertRaises(errors.RadioError, msg=msg): self.radio.sync_in() msg = ('Clone should have failed and raised an exception ' 'that inherits from RadioError') with self.assertRaises(errors.RadioError, msg=msg): self.radio.sync_out() def test_clone_serial_error(self): self._test_with_serial(SerialError()) def test_clone_serial_none(self): self._test_with_serial(SerialNone()) def test_clone_serial_garbage(self): self._test_with_serial(SerialGarbage()) def test_clone_serial_short_garbage(self): self._test_with_serial(SerialShortGarbage()) chirp-20240224/tests/unit/0000755000175000017500000000000014566340177014172 5ustar hibbyhibbychirp-20240224/tests/unit/test_csv.py0000644000175000017500000001566714563632215016407 0ustar hibbyhibbyimport os import tempfile import unittest from chirp import chirp_common from chirp.drivers import generic_csv CHIRP_CSV_LEGACY = ( """Location,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,FRS 1,462.562500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 2,FRS 2,462.587500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, """) CHIRP_CSV_MINIMAL = ( """Location,Frequency 1,146.520 2,446.000 """) CHIRP_CSV_MODERN = ( """Location,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,RxDtcsCode,CrossMode,Mode,TStep,Skip,Power,Comment,URCALL,RPT1CALL,RPT2CALL,DVCODE 0,Nat Simplex,146.520000,,0.600000,TSQL,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,This is the national calling frequency on 2m,,,, 1,National Simp,446.000000,-,5.000000,DTCS,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,5.0W,This is NOT the UHF calling frequency,,,, """) # noqa class TestCSV(unittest.TestCase): def setUp(self): super().setUp() self.testfn = tempfile.mktemp('.csv', 'chirp-test') def tearDown(self): super().tearDown() try: os.remove(self.testfn) except FileNotFoundError: pass def test_parse_legacy(self): with open(self.testfn, 'w', encoding='utf-8') as f: f.write(CHIRP_CSV_LEGACY) csv = generic_csv.CSVRadio(self.testfn) mem = csv.get_memory(1) self.assertEqual(1, mem.number) self.assertEqual('FRS 1', mem.name) self.assertEqual(462562500, mem.freq) self.assertEqual('', mem.duplex) self.assertEqual(5000000, mem.offset) self.assertEqual('', mem.tmode) self.assertEqual(88.5, mem.rtone) self.assertEqual(88.5, mem.ctone) self.assertEqual(23, mem.dtcs) self.assertEqual('NN', mem.dtcs_polarity) self.assertEqual('NFM', mem.mode) self.assertEqual(12.5, mem.tuning_step) def test_parse_modern(self, output_encoding='utf-8'): with open(self.testfn, 'w', encoding=output_encoding) as f: f.write(CHIRP_CSV_MODERN) csv = generic_csv.CSVRadio(self.testfn) mem = csv.get_memory(1) self.assertEqual(1, mem.number) self.assertEqual('National Simp', mem.name) self.assertEqual(446000000, mem.freq) self.assertEqual('-', mem.duplex) self.assertEqual(5000000, mem.offset) self.assertEqual('DTCS', mem.tmode) self.assertEqual(88.5, mem.rtone) self.assertEqual(88.5, mem.ctone) self.assertEqual(23, mem.dtcs) self.assertEqual('NN', mem.dtcs_polarity) self.assertEqual('FM', mem.mode) self.assertEqual(5.0, mem.tuning_step) self.assertEqual('5.0W', str(mem.power)) self.assertIn('UHF calling', mem.comment) def test_csv_with_comments(self): lines = list(CHIRP_CSV_MODERN.strip().split('\n')) lines.insert(0, '# This is a comment') lines.insert(0, '# Test file with comments') lines.insert(4, '# Test comment in the middle') lines.append('# Comment at the end') with open(self.testfn, 'w', newline='') as f: f.write('\r\n'.join(lines)) csv = generic_csv.CSVRadio(self.testfn) mem = csv.get_memory(0) self.assertEqual(146520000, mem.freq) mem = csv.get_memory(1) self.assertEqual(446000000, mem.freq) csv.save(self.testfn) with open(self.testfn, 'r') as f: read_lines = [x.strip() for x in f.readlines()] self.assertEqual(lines, read_lines) def test_parse_modern_bom(self): self.test_parse_modern(output_encoding='utf-8-sig') def test_parse_minimal(self): with open(self.testfn, 'w', encoding='utf-8') as f: f.write(CHIRP_CSV_MINIMAL) csv = generic_csv.CSVRadio(self.testfn) mem = csv.get_memory(1) self.assertEqual(1, mem.number) self.assertEqual(146520000, mem.freq) def test_parse_unknown_field(self): with open(self.testfn, 'w', encoding='utf-8') as f: f.write('Location,Frequency,Color\n') f.write('1,146.520,Red\n') csv = generic_csv.CSVRadio(self.testfn) mem = csv.get_memory(1) self.assertEqual(1, mem.number) self.assertEqual(146520000, mem.freq) def test_parse_unknown_power(self): with open(self.testfn, 'w', encoding='utf-8') as f: f.write('Location,Frequency,Power\n') f.write('0,146.520,L1\n') f.write('1,146.520,5W\n') csv = generic_csv.CSVRadio(self.testfn) mem = csv.get_memory(1) self.assertEqual(1, mem.number) self.assertEqual(146520000, mem.freq) def test_foreign_power(self): csv = generic_csv.CSVRadio(None) m = chirp_common.Memory() m.number = 1 m.freq = 146520000 m.power = chirp_common.PowerLevel('Low', watts=17) csv.set_memory(m) m = csv.get_memory(1) self.assertEqual('17W', str(m.power)) self.assertEqual(int(chirp_common.watts_to_dBm(17)), int(m.power)) def test_default_power(self): m = chirp_common.Memory() m.number = 1 m.freq = 146520000 r = generic_csv.CSVRadio(None) r.set_memory(m) m2 = r.get_memory(1) self.assertEqual(generic_csv.DEFAULT_POWER_LEVEL, m2.power) def _write_and_read(self, mem): radio = generic_csv.CSVRadio(None) radio.set_memory(mem) radio.save(self.testfn) radio = generic_csv.CSVRadio(self.testfn) return radio.get_memory(mem.number) def test_escaped_string_chars(self): m = chirp_common.Memory() m.number = 1 m.name = 'This is "The one"' m.comment = 'Wow, a \nMulti-line comment!' m2 = self._write_and_read(m) self.assertEqual(m.name, m2.name) self.assertEqual(m.comment, m2.comment) def test_unicode_comment_chars(self): m = chirp_common.Memory() m.number = 1 m.name = 'This is "The one"' m.comment = b'This is b\xc9\x90d news'.decode() m2 = self._write_and_read(m) self.assertEqual(m.name, m2.name) self.assertEqual(m.comment, m2.comment) def test_cross_dtcs(self): m = chirp_common.Memory() m.number = 1 m.tmode = 'Cross' m.cross_mode = 'DTCS->DTCS' m.dtcs = 25 m.rx_dtcs = 73 m2 = self._write_and_read(m) self.assertEqual('Cross', m2.tmode) self.assertEqual('DTCS->DTCS', m2.cross_mode) self.assertEqual(25, m2.dtcs) self.assertEqual(73, m2.rx_dtcs) def test_csv_memories_are_private(self): m = chirp_common.Memory(name='foo') radio = generic_csv.CSVRadio(None) radio.set_memory(m) # If CSVRadio maintains a reference to m, then this will modify # its internal state and the following assertion will fail. m.name = 'bar' self.assertEqual('foo', radio.get_memory(0).name) chirp-20240224/tests/unit/test_repeaterbook.py0000644000175000017500000002307214435610651020261 0ustar hibbyhibbyimport datetime import json import os import shutil import tempfile import unittest from unittest import mock import pytest from chirp import chirp_common from chirp.sources import repeaterbook class TestRepeaterbook(unittest.TestCase): def fake_config(self, fn): return os.path.join(self.tempdir, fn) def setUp(self): self.tempdir = tempfile.mkdtemp() self.patches = [] self.patches.append(mock.patch('chirp.platform.Platform.config_file', self.fake_config)) for p in self.patches: p.start() self.testfile = os.path.join(os.path.dirname(__file__), 'rb-united_states-oregon.json') def tearDown(self): for p in self.patches: p.stop() shutil.rmtree(self.tempdir) @pytest.mark.network def test_get_oregon(self): rb = repeaterbook.RepeaterBook() self.assertRaises(IndexError, rb.get_memory, 0) rb.do_fetch(mock.MagicMock(), { 'country': 'United States', 'state': 'Oregon', 'lat': 45, 'lon': -122, 'dist': 100, }) m = rb.get_memory(0) self.assertIsInstance(m, chirp_common.Memory) f = rb.get_features() self.assertGreater(sum(f.memory_bounds), 20) for i in range(*f.memory_bounds): m = rb.get_memory(i) if m.mode == 'DV': self.assertIsInstance(m, chirp_common.DVMemory) self.assertEqual('CQCQCQ ', m.dv_urcall) self.assertEqual(8, len(m.dv_rpt1call)) self.assertEqual(8, len(m.dv_rpt2call)) self.assertEqual(m.dv_rpt1call, m.dv_rpt2call) self.assertNotEqual('', m.dv_rpt1call) break else: raise Exception('Did not find any DV results') @pytest.mark.network def test_get_wyoming(self): rb = repeaterbook.RepeaterBook() self.assertRaises(IndexError, rb.get_memory, 0) rb.do_fetch(mock.MagicMock(), { 'country': 'United States', 'state': 'Wyoming', 'lat': 45, 'lon': -122, 'dist': 0, }) m = rb.get_memory(0) self.assertIsInstance(m, chirp_common.Memory) f = rb.get_features() self.assertGreater(sum(f.memory_bounds), 20) @pytest.mark.network def test_get_oregon_gmrs(self): rb = repeaterbook.RepeaterBook() self.assertRaises(IndexError, rb.get_memory, 0) rb.do_fetch(mock.MagicMock(), { 'country': 'United States', 'state': 'Oregon', 'lat': 45, 'lon': -122, 'dist': 100, 'service': 'gmrs', }) m = rb.get_memory(0) self.assertIsInstance(m, chirp_common.Memory) f = rb.get_features() self.assertGreater(sum(f.memory_bounds), 1) @pytest.mark.network def test_get_australia(self): rb = repeaterbook.RepeaterBook() self.assertRaises(IndexError, rb.get_memory, 0) rb.do_fetch(mock.MagicMock(), { 'country': 'Australia', 'state': 'ALL', 'lat': -26, 'lon': 133, 'dist': 20000, }) m = rb.get_memory(0) self.assertIsInstance(m, chirp_common.Memory) f = rb.get_features() self.assertGreater(sum(f.memory_bounds), 20) def _test_with_mocked(self, params): rb = repeaterbook.RepeaterBook() with mock.patch.object(rb, 'get_data') as gd: gd.return_value = self.testfile rb.do_fetch(mock.MagicMock(), params) return rb def test_filter(self): params = {'country': 'United States', 'state': 'Oregon', 'lat': 45, 'lon': -122, 'dist': 0, 'filter': 'tower'} rb = self._test_with_mocked(params) self.assertGreater(sum(rb.get_features().memory_bounds), 5) def test_distance(self): params = {'country': 'United States', 'state': 'Oregon', 'lat': 45, 'lon': -122, 'dist': 0, 'filter': 'tower'} rb1 = self._test_with_mocked(dict(params)) self.assertGreater(sum(rb1.get_features().memory_bounds), 5) # Make sure we got fewer than everything in Oregon params['dist'] = 100 rb2 = self._test_with_mocked(dict(params)) self.assertLess(sum(rb2.get_features().memory_bounds), sum(rb1.get_features().memory_bounds)) # There is nothing 1km away from this spot in the ocean params['dist'] = 1 params['lat'] = 45 params['lon'] = -140 rb3 = self._test_with_mocked(dict(params)) self.assertEqual(sum(rb3.get_features().memory_bounds), -1) def test_get_data_500(self): rb = repeaterbook.RepeaterBook() with mock.patch('requests.get') as mock_get: mock_get.return_value.status_code = 500 status = mock.MagicMock() r = rb.get_data(status, 'US', 'OR', '') self.assertIsNone(r) status.send_fail.assert_called() # Make sure we wrote no files self.assertEqual([], os.listdir(os.path.join(self.tempdir, 'repeaterbook'))) def test_get_data_json_fail(self): rb = repeaterbook.RepeaterBook() with mock.patch('requests.get') as mock_get: mock_get.return_value.status_code = 200 mock_get.return_value.iter_content.return_value = [b'foo'] status = mock.MagicMock() r = rb.get_data(status, 'US', 'OR', '') self.assertIsNone(r) files = os.listdir(os.path.join(self.tempdir, 'repeaterbook')) # Make sure we only wrote one file and that it is a tempfile # not one we will find as a data file later self.assertEqual(1, len(files)) self.assertTrue(files[0].endswith('tmp')) status.send_fail.assert_called() def test_get_data_no_results(self): rb = repeaterbook.RepeaterBook() with mock.patch('requests.get') as mock_get: mock_get.return_value.status_code = 200 mock_get.return_value.iter_content.return_value = [json.dumps( {'count': 0}).encode()] status = mock.MagicMock() r = rb.get_data(status, 'US', 'OR', '') self.assertIsNone(r) files = os.listdir(os.path.join(self.tempdir, 'repeaterbook')) # Make sure we cleaned up and signaled failure self.assertEqual(0, len(files)) status.send_fail.assert_called() def test_get_data_got_results(self): files = os.listdir(self.tempdir) # Make sure we started with no data files self.assertEqual(0, len(files)) rb = repeaterbook.RepeaterBook() with mock.patch('requests.get') as mock_get: mock_get.return_value.status_code = 200 mock_get.return_value.iter_content.return_value = [json.dumps( {'count': 1}).encode()] status = mock.MagicMock() r = rb.get_data(status, 'US', 'OR', '') self.assertIsNotNone(r) files = os.listdir(os.path.join(self.tempdir, 'repeaterbook')) # Make sure we left only a data file and did not signal failure self.assertEqual(1, len(files)) self.assertFalse(files[0].endswith('tmp')) self.assertEqual(os.path.basename(r), files[0]) status.send_fail.assert_not_called() def test_get_data_honors_cache_rules(self): os.mkdir(os.path.join(self.tempdir, 'repeaterbook')) cache_file = os.path.join(self.tempdir, 'repeaterbook', os.path.basename(self.testfile)) with open(cache_file, 'w') as f: f.write('foo') rb = repeaterbook.RepeaterBook() with mock.patch('requests.get') as mock_get: r = rb.get_data(mock.MagicMock(), 'United States', 'Oregon', '') self.assertEqual(cache_file, r) # Make sure we returned the cached file mock_get.assert_not_called() real_timedelta = datetime.timedelta real_datetime = datetime.datetime future = datetime.datetime.now() + datetime.timedelta(days=4) with mock.patch.object(repeaterbook, 'datetime') as mock_dt: mock_dt.datetime.fromtimestamp = real_datetime.fromtimestamp mock_dt.timedelta = real_timedelta mock_dt.datetime.now.return_value = future r = rb.get_data(mock.MagicMock(), 'United States', 'Oregon', '') # Cache file is 4 days old, we should use it mock_get.assert_not_called() future = datetime.datetime.now() + datetime.timedelta(days=45) with mock.patch.object(repeaterbook, 'datetime') as mock_dt: mock_dt.datetime.fromtimestamp = real_datetime.fromtimestamp mock_dt.timedelta = real_timedelta mock_dt.datetime.now.return_value = future r = rb.get_data(mock.MagicMock(), 'United States', 'Oregon', '') # Cache file is 45 days old, we should re-fetch mock_get.assert_called() chirp-20240224/tests/unit/test_cli.py0000644000175000017500000000230314411666130016335 0ustar hibbyhibbyimport os import unittest from unittest import mock from chirp.cli import main class TestCLI(unittest.TestCase): def setUp(self): self.stdout_lines = [] self.patches = [] self.patches.append(mock.patch('sys.exit')) self.patches.append(mock.patch.object(main, 'print', new=self.fake_print)) for patch in self.patches: patch.start() # A path to an image file we can pass to the CLI for testing self.testfile = os.path.join( os.path.abspath( os.path.join( os.path.dirname(__file__), '..', 'images', 'Icom_IC-2820H.img'))) def tearDown(self): for patch in self.patches: patch.stop() def fake_print(self, *a): for i in a: self.stdout_lines.append(str(i)) @property def stdout(self): return '\n'.join(self.stdout_lines) def test_cli_simple(self): # Super simple, just print the first memory and make sure it # works args = ['--mmap', self.testfile, '--get-mem', 0] main.main(args=args) self.assertIn('147.56', self.stdout) chirp-20240224/tests/unit/base.py0000644000175000017500000000047114430171343015443 0ustar hibbyhibbyimport builtins import unittest import warnings warnings.simplefilter('ignore', Warning) builtins._ = lambda x: x class BaseTest(unittest.TestCase): def setUp(self): __builtins__['_'] = lambda s: s self.mocks = [] def tearDown(self): for m in self.mocks: m.stop() chirp-20240224/tests/unit/rb-united_states-oregon.json0000644000175000017500000150602214411666130021623 0ustar hibbyhibby{ "count": 462, "results": [ { "State ID": "41", "Rptr ID": "2", "Frequency": "145.17000", "Input Freq": "144.57000", "PL": "110.9", "TSQ": "110.9", "Nearest City": "Lime", "Landmark": "Lime Hill", "County": "Baker", "State": "Oregon", "Country": "United States", "Lat": "44.43144989", "Long": "-117.24941254", "Precise": "1", "Callsign": "W7NYW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "3", "Frequency": "145.27000", "Input Freq": "144.67000", "PL": "110.9", "TSQ": "110.9", "Nearest City": "Baker City", "Landmark": "Beaver Mountain", "County": "Baker", "State": "Oregon", "Country": "United States", "Lat": "44.58649826", "Long": "-117.78700256", "Precise": "1", "Callsign": "W7NYW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "414516", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "18776", "Frequency": "147.12000", "Input Freq": "147.72000", "PL": "100.0", "TSQ": "", "Nearest City": "Huntington", "Landmark": "", "County": "Baker", "State": "Oregon", "Country": "United States", "Lat": "44.35127260", "Long": "-117.26656860", "Precise": "0", "Callsign": "K7OJI", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-10-09" }, { "State ID": "41", "Rptr ID": "14", "Frequency": "146.78000", "Input Freq": "146.18000", "PL": "156.7", "TSQ": "107.2", "Nearest City": "Corvallis", "Landmark": "Marys Peak", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.50469971", "Long": "-123.55300140", "Precise": "1", "Callsign": "K7CVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-06" }, { "State ID": "41", "Rptr ID": "16", "Frequency": "147.16000", "Input Freq": "147.76000", "PL": "100.0", "TSQ": "", "Nearest City": "Corvallis", "Landmark": "Vineyard Mountain", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.64039993", "Long": "-123.27500153", "Precise": "1", "Callsign": "W7OSU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-07" }, { "State ID": "41", "Rptr ID": "17", "Frequency": "441.97500", "Input Freq": "446.97500", "PL": "100.0", "TSQ": "", "Nearest City": "Corvallis", "Landmark": "West Marys Peak", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.50469971", "Long": "-123.55300140", "Precise": "1", "Callsign": "W7CQZ", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "19", "Frequency": "442.30000", "Input Freq": "447.30000", "PL": "162.2", "TSQ": "", "Nearest City": "Corvallis", "Landmark": "Good Sam Hospital", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.60120010", "Long": "-123.25299835", "Precise": "1", "Callsign": "N8GFO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "3089", "Frequency": "440.42500", "Input Freq": "445.42500", "PL": "D125", "TSQ": "D125", "Nearest City": "Corvallis", "Landmark": "Mary's Peak", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.50469971", "Long": "-123.55300140", "Precise": "1", "Callsign": "K7LNK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "4,097 feet ASL.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "6277", "Frequency": "146.82000", "Input Freq": "146.22000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Corvallis", "Landmark": "Marys Peak", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.50759888", "Long": "-123.57599640", "Precise": "1", "Callsign": "WA7TUV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "7445", "Frequency": "443.05000", "Input Freq": "448.05000", "PL": "D032", "TSQ": "D032", "Nearest City": "Corvallis", "Landmark": "Dearborn Hall", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.56733720", "Long": "-123.27552370", "Precise": "1", "Callsign": "W7OSU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "On-campus repeater for club communications.", "Last Update": "2022-02-24" }, { "State ID": "41", "Rptr ID": "12350", "Frequency": "440.80000", "Input Freq": "445.80000", "PL": "D125", "TSQ": "", "Nearest City": "Corvallis", "Landmark": "", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.56460190", "Long": "-123.26200104", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "18785", "Frequency": "441.72500", "Input Freq": "446.72500", "PL": "136.5", "TSQ": "", "Nearest City": "Corvallis", "Landmark": "", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.56456590", "Long": "-123.26204350", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-07-04" }, { "State ID": "41", "Rptr ID": "19703", "Frequency": "444.27500", "Input Freq": "449.27500", "PL": "67.0", "TSQ": "", "Nearest City": "Corvallis", "Landmark": "Marys Peak", "County": "Benton", "State": "Oregon", "Country": "United States", "Lat": "44.50750000", "Long": "-123.57528000", "Precise": "1", "Callsign": "K7WVD", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "312072", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Please be sure to disconnect from reflectors & talkgroups when you are finished. Monitoring Talkgroups and reflectors occupy the repeater, preventing other modes from being used. Please be courteous! 67.0PL for analog operation.", "Last Update": "2022-12-03" }, { "State ID": "41", "Rptr ID": "26", "Frequency": "146.94000", "Input Freq": "146.34000", "PL": "CSQ", "TSQ": "", "Nearest City": "Clackamas", "Landmark": "Mt Scott", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45479965", "Long": "-122.55100250", "Precise": "1", "Callsign": "W7LT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": " ", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "27", "Frequency": "146.96000", "Input Freq": "146.36000", "PL": "127.3", "TSQ": "127.3", "Nearest City": "Colton", "Landmark": "Goat Mountain", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.13150024", "Long": "-122.29699707", "Precise": "1", "Callsign": "W7OTV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "917904", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "CARES second alternate repeater.", "Last Update": "2022-12-15" }, { "State ID": "41", "Rptr ID": "28", "Frequency": "147.12000", "Input Freq": "147.72000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Timberline", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.30300140", "Long": "-121.74299622", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "329379", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "CARES Primary repeater.", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "29", "Frequency": "147.28000", "Input Freq": "147.88000", "PL": "167.9", "TSQ": "167.9", "Nearest City": "Clackamas", "Landmark": "Mt Scott", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45479965", "Long": "-122.55100250", "Precise": "1", "Callsign": "WB7QIW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "MC-2 Multnomah County ARES", "Last Update": "2022-05-28" }, { "State ID": "41", "Rptr ID": "33", "Frequency": "440.25000", "Input Freq": "445.25000", "PL": "127.3", "TSQ": "", "Nearest City": "Colton", "Landmark": "Goat Mountain", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.13150024", "Long": "-122.29699707", "Precise": "1", "Callsign": "W7OTV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "CARES third alternate repeater.", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "34", "Frequency": "440.30000", "Input Freq": "445.30000", "PL": "167.9", "TSQ": "", "Nearest City": "Clackamas", "Landmark": "Mt Scott", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45489883", "Long": "-122.55100250", "Precise": "1", "Callsign": "KC7MZM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311758", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-13" }, { "State ID": "41", "Rptr ID": "38", "Frequency": "442.07500", "Input Freq": "447.07500", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Oregon City", "Landmark": "Boynton Standpipe Water Tower", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.35509872", "Long": "-122.60700226", "Precise": "0", "Callsign": "W7ZRS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "42", "Frequency": "443.47500", "Input Freq": "448.47500", "PL": "167.9", "TSQ": "167.9", "Nearest City": "Clackamas", "Landmark": "Mt Scott", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45479965", "Long": "-122.55100250", "Precise": "1", "Callsign": "WB7QIW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "45", "Frequency": "444.22500", "Input Freq": "449.22500", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Timberline", "Landmark": "Magic Mile Chairlift", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.30300140", "Long": "-121.74299622", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "59", "Frequency": "146.80000", "Input Freq": "146.20000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Clackamas", "Landmark": "Timberline", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.33323900", "Long": "-121.71432100", "Precise": "1", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "82962", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-08" }, { "State ID": "41", "Rptr ID": "78", "Frequency": "440.70000", "Input Freq": "445.70000", "PL": "77.0", "TSQ": "77.0", "Nearest City": "Molalla", "Landmark": "Molalla Fire District 73", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.14730072", "Long": "-122.57700348", "Precise": "0", "Callsign": "W7DTV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "92", "Frequency": "443.70000", "Input Freq": "448.70000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Colton", "Landmark": "Goat Mountain", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.13119888", "Long": "-122.29699707", "Precise": "1", "Callsign": "N7PIR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "132225", "IRLP Node": "3420", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "93", "Frequency": "443.87500", "Input Freq": "448.87500", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Government Camp", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.28749847", "Long": "-121.78199768", "Precise": "1", "Callsign": "N7PIR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "132225", "IRLP Node": "3420", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "5,070 feet ASL.", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "111", "Frequency": "1291.00000", "Input Freq": "1271.00000", "PL": "107.2", "TSQ": "", "Nearest City": "Clackamas", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.40760040", "Long": "-122.56999969", "Precise": "0", "Callsign": "KB7WUK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "63 watts EIRP", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "113", "Frequency": "53.35000", "Input Freq": "51.65000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Sandy", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.39730072", "Long": "-122.26100159", "Precise": "1", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "130", "Frequency": "442.87500", "Input Freq": "447.87500", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Sandy", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.39730072", "Long": "-122.26100159", "Precise": "0", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "133", "Frequency": "443.15000", "Input Freq": "448.15000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Clackamas", "Landmark": "Mt Scott", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45460129", "Long": "-122.55100250", "Precise": "0", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "254", "Frequency": "444.45000", "Input Freq": "449.45000", "PL": "131.8", "TSQ": "", "Nearest City": "Canby", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.26309967", "Long": "-122.69100189", "Precise": "0", "Callsign": "K7CFD", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "This repeater us not listed in the ORRC online database at: http://www.orrc.org/Coordinations/Published. Tried to add AC6SZ -- RICHARD V. MARTIN -- TRUSTEE as a Repeater Custodian, but AC6SZ must first obtain a Repeaterbook.com account before being added as a custodian. Please ask the AC6SZ to register for an account. There are currently no custodians for this repeater. ", "Last Update": "2021-03-16" }, { "State ID": "41", "Rptr ID": "281", "Frequency": "442.92500", "Input Freq": "447.92500", "PL": "107.2", "TSQ": "", "Nearest City": "Colton", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.17219925", "Long": "-122.43699646", "Precise": "0", "Callsign": "WB7DZG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "452", "Frequency": "442.42500", "Input Freq": "447.42500", "PL": "100.0", "TSQ": "", "Nearest City": "Sandy", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.40499878", "Long": "-122.27500153", "Precise": "0", "Callsign": "KE7AWR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-23" }, { "State ID": "41", "Rptr ID": "481", "Frequency": "145.43000", "Input Freq": "144.83000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Colton", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.17211920", "Long": "-122.43748030", "Precise": "1", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "82962", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-16" }, { "State ID": "41", "Rptr ID": "496", "Frequency": "223.94000", "Input Freq": "222.34000", "PL": "100.0", "TSQ": "", "Nearest City": "Colton", "Landmark": "Goat Mountain", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.13150024", "Long": "-122.29699707", "Precise": "1", "Callsign": "W7OTV", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-07-31" }, { "State ID": "41", "Rptr ID": "498", "Frequency": "224.46000", "Input Freq": "222.86000", "PL": "107.2", "TSQ": "", "Nearest City": "Estacada", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.28969955", "Long": "-122.33200073", "Precise": "0", "Callsign": "KD7DEG", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "555", "Frequency": "441.40000", "Input Freq": "446.40000", "PL": "88.5", "TSQ": "88.5", "Nearest City": "Colton", "Landmark": "Goat Mountain", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.13150024", "Long": "-122.29699707", "Precise": "1", "Callsign": "WB6EGS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "3091", "Frequency": "29.68000", "Input Freq": "29.58000", "PL": "162.2", "TSQ": "162.2", "Nearest City": "Clackamas", "Landmark": "Mount Scott", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45460129", "Long": "-122.55100250", "Precise": "1", "Callsign": "KR7IS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-12-14" }, { "State ID": "41", "Rptr ID": "6786", "Frequency": "443.85000", "Input Freq": "448.85000", "PL": "107.2", "TSQ": "", "Nearest City": "Estacada", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.28771980", "Long": "-122.33516380", "Precise": "0", "Callsign": "WB7DZG", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-07" }, { "State ID": "41", "Rptr ID": "6788", "Frequency": "444.17500", "Input Freq": "449.17500", "PL": "123.0", "TSQ": "", "Nearest City": "West Linn", "Landmark": "Stafford", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.36569977", "Long": "-122.61199951", "Precise": "0", "Callsign": "WA7BND", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "8309", "Frequency": "224.78000", "Input Freq": "223.18000", "PL": "136.5", "TSQ": "136.5", "Nearest City": "Government Camp", "Landmark": "Mount Hood", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.28829956", "Long": "-121.78299713", "Precise": "1", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "11141", "Frequency": "441.65000", "Input Freq": "446.65000", "PL": "107.2", "TSQ": "", "Nearest City": "West Linn", "Landmark": "West Linn Ridge", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.36569977", "Long": "-122.61199951", "Precise": "0", "Callsign": "WA7DRO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "13885", "Frequency": "147.18000", "Input Freq": "147.78000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Clackamas", "Landmark": "Mount Scott, Happy Valley", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45309830", "Long": "-122.54799652", "Precise": "0", "Callsign": "W7LT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Per PARC website 26 April 2021: This repeater is located on Mt. Scott, OR; running a Yaesu System Fusion (YSF) repeater in Automatic Mode Select (AMS) mode to provide functionality to both FM analog (with a tone of 103.5) and digital users. Previously, this was a dedicated digital mode 1200 baud packet repeater. On 22 July 2020, this repeater was tested to verify both YSF Fusion and FM Analog operation. No YSF Fusion response was received at that time. This repeater's YSF capability needs to be confirmed by the Trustee.", "Last Update": "2021-04-26" }, { "State ID": "41", "Rptr ID": "15196", "Frequency": "442.75000", "Input Freq": "447.75000", "PL": "Restricted", "TSQ": "Restricted", "Nearest City": "Colton", "Landmark": "Goat Mtn", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.13150024", "Long": "-122.29699707", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314107", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "15201", "Frequency": "442.98750", "Input Freq": "447.98750", "PL": "Restricted", "TSQ": "Restricted", "Nearest City": "Government Camp", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.36700058", "Long": "-121.99099731", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314104", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "15792", "Frequency": "52.97000", "Input Freq": "51.27000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Government Camp", "Landmark": "Timberline Lodge", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.33119965", "Long": "-121.71099854", "Precise": "0", "Callsign": "WB7DZG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-09-28" }, { "State ID": "41", "Rptr ID": "15806", "Frequency": "223.96000", "Input Freq": "222.36000", "PL": "107.2", "TSQ": "", "Nearest City": "Sandy", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.39730072", "Long": "-122.26100159", "Precise": "0", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "16800", "Frequency": "444.30000", "Input Freq": "449.30000", "PL": "82.5", "TSQ": "82.5", "Nearest City": "Lake Oswego", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.42070007", "Long": "-122.67099762", "Precise": "0", "Callsign": "WA7LO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "17251", "Frequency": "441.32500", "Input Freq": "446.32500", "PL": "", "TSQ": "", "Nearest City": "Clackamas", "Landmark": "Mt Scott", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.45472300", "Long": "-122.55139200", "Precise": "1", "Callsign": "KA7AGH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "7", "DMR ID": "314116", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Connected to PNW Digital System. Visit PNWDigital.net for further info on supported TG.", "Last Update": "2021-03-26" }, { "State ID": "41", "Rptr ID": "18793", "Frequency": "444.60000", "Input Freq": "449.60000", "PL": "100.0", "TSQ": "", "Nearest City": "Beavercreek", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.22968800", "Long": "-122.44240900", "Precise": "1", "Callsign": "WA7ABU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Wires-X to be installed. No courtesy tone due to Yaesu defaults.", "Last Update": "2020-10-10" }, { "State ID": "41", "Rptr ID": "20134", "Frequency": "440.63750", "Input Freq": "445.63750", "PL": "", "TSQ": "", "Nearest City": "Ripplebrook", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.08250000", "Long": "-122.04222000", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "3", "DMR ID": "312233", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "20180", "Frequency": "444.15000", "Input Freq": "449.15000", "PL": "", "TSQ": "", "Nearest City": "Government Camp", "Landmark": "Mount Hood", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.34501100", "Long": "-121.71177200", "Precise": "0", "Callsign": "K7PN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311190", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Connected to PNW Digital System. Visit PNWDigital.net for further info on supported TG.", "Last Update": "2021-09-06" }, { "State ID": "41", "Rptr ID": "20374", "Frequency": "224.30000", "Input Freq": "222.70000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Molalla", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.10333300", "Long": "-122.62666700", "Precise": "0", "Callsign": "K7JCN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-26" }, { "State ID": "41", "Rptr ID": "20726", "Frequency": "224.34000", "Input Freq": "224.74000", "PL": "100.0", "TSQ": "", "Nearest City": "Oregon City", "Landmark": "", "County": "Clackamas", "State": "Oregon", "Country": "United States", "Lat": "45.35560990", "Long": "-122.60585300", "Precise": "0", "Callsign": "K7JCN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-10-05" }, { "State ID": "41", "Rptr ID": "176", "Frequency": "146.66000", "Input Freq": "146.06000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Astoria", "Landmark": "Wickiup Mountain", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.10609818", "Long": "-123.58499908", "Precise": "1", "Callsign": "W7BU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "March 12, 2020 The repeater was recently sold to the W7BU club. Operations and usage of the repeater may be subject to change.", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "177", "Frequency": "146.74000", "Input Freq": "146.14000", "PL": "118.8", "TSQ": "", "Nearest City": "Cannon Beach", "Landmark": "Arch Cape", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "45.80220032", "Long": "-123.96700287", "Precise": "1", "Callsign": "W7BU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "178", "Frequency": "146.76000", "Input Freq": "146.16000", "PL": "118.8", "TSQ": "", "Nearest City": "Astoria", "Landmark": "Nicolai Mountain", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.08720016", "Long": "-123.45800018", "Precise": "0", "Callsign": "W7BU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "183", "Frequency": "444.50000", "Input Freq": "449.50000", "PL": "118.8", "TSQ": "", "Nearest City": "Astoria", "Landmark": "Nicolai Mountain", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.08720016", "Long": "-123.45800018", "Precise": "1", "Callsign": "N7XAC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "184", "Frequency": "444.77500", "Input Freq": "449.77500", "PL": "118.8", "TSQ": "", "Nearest City": "Astoria", "Landmark": "Wickiup Mountain", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.10589981", "Long": "-123.58599854", "Precise": "1", "Callsign": "W7BU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-21" }, { "State ID": "41", "Rptr ID": "3004", "Frequency": "145.49000", "Input Freq": "144.89000", "PL": "118.8", "TSQ": "", "Nearest City": "Seaside", "Landmark": "reservoir", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "45.95420074", "Long": "-123.91899872", "Precise": "1", "Callsign": "WA7VE", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-03" }, { "State ID": "41", "Rptr ID": "5827", "Frequency": "443.87500", "Input Freq": "448.87500", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Seaside", "Landmark": "", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "45.95399857", "Long": "-123.91899872", "Precise": "1", "Callsign": "N7PIR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "3430", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-14" }, { "State ID": "41", "Rptr ID": "5829", "Frequency": "147.00000", "Input Freq": "147.60000", "PL": "118.8", "TSQ": "", "Nearest City": "Seaside", "Landmark": "", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "45.86420059", "Long": "-123.55500031", "Precise": "1", "Callsign": "WA7PIX", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "6880", "Frequency": "147.52000", "Input Freq": "147.52000", "PL": "118.8", "TSQ": "", "Nearest City": "Hammond", "Landmark": "", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.19931230", "Long": "-123.95205880", "Precise": "1", "Callsign": "NA7Q", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "54166", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Open to all users.
Permanently linked to the Coastal Amateur Radio Network Hub 54189.", "Last Update": "2022-11-28" }, { "State ID": "41", "Rptr ID": "11325", "Frequency": "146.72000", "Input Freq": "146.12000", "PL": "114.8", "TSQ": "114.8", "Nearest City": "Astoria", "Landmark": "Wickiup Mountain", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.10589981", "Long": "-123.58599854", "Precise": "0", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Repeater is in testing mode.
Linked to 442.32500 (K7RPT) at Forest Grove, South Saddle Mountain, OR.

", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "14641", "Frequency": "442.50000", "Input Freq": "447.50000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Astoria", "Landmark": "Wickiup Mtn", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.10589981", "Long": "-123.58599854", "Precise": "0", "Callsign": "W7BU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Low activity repeater system. Receiver is currently experiencing signal loss. Users may have a difficult time accessing this repeater.", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "17427", "Frequency": "444.85000", "Input Freq": "449.85000", "PL": "118.8", "TSQ": "", "Nearest City": "Astoria", "Landmark": "", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.13859940", "Long": "-123.84799957", "Precise": "1", "Callsign": "W7BU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-11" }, { "State ID": "41", "Rptr ID": "17428", "Frequency": "146.80000", "Input Freq": "146.20000", "PL": "118.8", "TSQ": "", "Nearest City": "Gearhart", "Landmark": "", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.03150177", "Long": "-123.89299774", "Precise": "1", "Callsign": "W7BU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "17913", "Frequency": "224.28000", "Input Freq": "222.68000", "PL": "103.5", "TSQ": "", "Nearest City": "Astoria", "Landmark": "Nicolai Mountain", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.08710098", "Long": "-123.45899963", "Precise": "0", "Callsign": "", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Linked System", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "18108", "Frequency": "52.81000", "Input Freq": "51.11000", "PL": "100.0", "TSQ": "", "Nearest City": "Astoria", "Landmark": "Nicolai Mountain", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.08710098", "Long": "-123.45899963", "Precise": "0", "Callsign": "", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "19856", "Frequency": "147.16000", "Input Freq": "147.76000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Knappa", "Landmark": "", "County": "Clatsop", "State": "Oregon", "Country": "United States", "Lat": "46.17139090", "Long": "-123.57122100", "Precise": "0", "Callsign": "NA7Q", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "54094", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Open to all users. Permanently linked to the Coastal Amateur Radio Network Hub 54189.", "Last Update": "2022-09-21" }, { "State ID": "41", "Rptr ID": "142", "Frequency": "146.88000", "Input Freq": "146.28000", "PL": "114.8", "TSQ": "114.8", "Nearest City": "Deer Island", "Landmark": "Meissner Lookout", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "45.96030045", "Long": "-122.99600220", "Precise": "0", "Callsign": "N7EI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Separate RX and TX antennas.", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "505", "Frequency": "441.70000", "Input Freq": "446.70000", "PL": "", "TSQ": "", "Nearest City": "Rainier", "Landmark": "Ranier Hill", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "46.04959869", "Long": "-122.91999817", "Precise": "1", "Callsign": "N3EG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "315328", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "509", "Frequency": "444.62500", "Input Freq": "449.62500", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Warren", "Landmark": "McNulty Water Tower", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "45.83900070", "Long": "-122.87799835", "Precise": "1", "Callsign": "N7EI", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "20 watts.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "6366", "Frequency": "146.68000", "Input Freq": "146.08000", "PL": "114.8", "TSQ": "114.8", "Nearest City": "Warren", "Landmark": "McNulty Water Tower", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "45.83900070", "Long": "-122.87799835", "Precise": "1", "Callsign": "N7EI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "10611", "Frequency": "224.66000", "Input Freq": "223.06000", "PL": "114.8", "TSQ": "114.8", "Nearest City": "Rainier", "Landmark": "Rainier Hill", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "46.08900070", "Long": "-122.93599701", "Precise": "0", "Callsign": "N7DEM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-07-18" }, { "State ID": "41", "Rptr ID": "16128", "Frequency": "441.86250", "Input Freq": "446.86250", "PL": "", "TSQ": "", "Nearest City": "Scappoose", "Landmark": "", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "45.75429916", "Long": "-122.87799835", "Precise": "0", "Callsign": "AA7BG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314111", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-11-27" }, { "State ID": "41", "Rptr ID": "16277", "Frequency": "145.25000", "Input Freq": "144.65000", "PL": "114.8", "TSQ": "", "Nearest City": "Vernonia", "Landmark": "Corey Hill", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "45.86180115", "Long": "-123.20600128", "Precise": "0", "Callsign": "W7VER", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Vernonia Emergency Radio Association V.E.R.A", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "17151", "Frequency": "224.38000", "Input Freq": "222.78000", "PL": "114.8", "TSQ": "", "Nearest City": "Deer Island", "Landmark": "", "County": "Columbia", "State": "Oregon", "Country": "United States", "Lat": "45.93220139", "Long": "-122.84500122", "Precise": "0", "Callsign": "N7EI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "No squelch tail.", "Last Update": "2019-11-17" }, { "State ID": "41", "Rptr ID": "149", "Frequency": "145.19000", "Input Freq": "144.59000", "PL": "146.2", "TSQ": "", "Nearest City": "Myrtle Point", "Landmark": "Bennett Butte", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "42.95869827", "Long": "-124.27300262", "Precise": "1", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "151", "Frequency": "146.61000", "Input Freq": "146.01000", "PL": "110.9", "TSQ": "110.9", "Nearest City": "Coquille", "Landmark": "Beaver Hill", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.20500183", "Long": "-124.30200195", "Precise": "1", "Callsign": "K7CCH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-07-12" }, { "State ID": "41", "Rptr ID": "152", "Frequency": "146.92000", "Input Freq": "146.32000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Camas Valley", "Landmark": "Kenyon Mountain", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.00149918", "Long": "-123.77899933", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "521741", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,250 feet.", "Last Update": "2020-09-25" }, { "State ID": "41", "Rptr ID": "156", "Frequency": "147.28000", "Input Freq": "147.88000", "PL": "146.2", "TSQ": "146.2", "Nearest City": "Coos Bay", "Landmark": "Blossom Hill", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.35419846", "Long": "-124.24199677", "Precise": "1", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "159", "Frequency": "440.80000", "Input Freq": "445.80000", "PL": "103.5", "TSQ": "", "Nearest City": "Coos Bay", "Landmark": "Blossom Hill", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.35419846", "Long": "-124.24199677", "Precise": "1", "Callsign": "WA7JAW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "650 feet, 30 watts.", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "164", "Frequency": "444.17500", "Input Freq": "449.17500", "PL": "146.2", "TSQ": "", "Nearest City": "Myrtle Point", "Landmark": "Bennett Butte", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.06499863", "Long": "-124.13800049", "Precise": "0", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-08-25" }, { "State ID": "41", "Rptr ID": "165", "Frequency": "444.52500", "Input Freq": "449.52500", "PL": "123.0", "TSQ": "", "Nearest City": "Myrtle Point", "Landmark": "Bennett Butte", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "42.95869827", "Long": "-124.27300262", "Precise": "1", "Callsign": "KD7IOP", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "479", "Frequency": "147.10000", "Input Freq": "147.70000", "PL": "88.5", "TSQ": "88.5", "Nearest City": "Coos Bay", "Landmark": "", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.36809921", "Long": "-124.21600342", "Precise": "0", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-07-19" }, { "State ID": "41", "Rptr ID": "13019", "Frequency": "146.88000", "Input Freq": "146.28000", "PL": "D023", "TSQ": "", "Nearest City": "Coos Bay", "Landmark": "Noah Butte", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.36650085", "Long": "-124.21800232", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-09-21" }, { "State ID": "41", "Rptr ID": "15807", "Frequency": "441.72500", "Input Freq": "446.72500", "PL": "131.8", "TSQ": "", "Nearest City": "Coos Bay", "Landmark": "", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.36650085", "Long": "-124.21800232", "Precise": "0", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "18777", "Frequency": "147.32000", "Input Freq": "147.92000", "PL": "", "TSQ": "", "Nearest City": "Coos Bay", "Landmark": "", "County": "Coos", "State": "Oregon", "Country": "United States", "Lat": "43.36650070", "Long": "-124.21789030", "Precise": "0", "Callsign": "K7REA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "64162", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Use DG-ID TX01 for Wires-X access. This repeater is digital mode only, no FM analog voice. See web page on info linking to other repeaters (http://www.k7rea.com/).", "Last Update": "2021-04-21" }, { "State ID": "41", "Rptr ID": "240", "Frequency": "147.38000", "Input Freq": "147.98000", "PL": "162.2", "TSQ": "", "Nearest City": "Prineville", "Landmark": "Grizzly Mountain", "County": "Crook", "State": "Oregon", "Country": "United States", "Lat": "44.43780136", "Long": "-120.95500183", "Precise": "1", "Callsign": "N7CCO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "Yes", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "10191", "Frequency": "444.17500", "Input Freq": "449.17500", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Prineville", "Landmark": "Grizzly Mountain", "County": "Crook", "State": "Oregon", "Country": "United States", "Lat": "44.43780136", "Long": "-120.95500183", "Precise": "1", "Callsign": "N7PIR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "132225", "IRLP Node": "3420", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "15796", "Frequency": "145.21000", "Input Freq": "144.61000", "PL": "141.3", "TSQ": "", "Nearest City": "Prineville", "Landmark": "Round Mtn", "County": "Crook", "State": "Oregon", "Country": "United States", "Lat": "44.39220047", "Long": "-120.34700012", "Precise": "0", "Callsign": "N7CCO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-05-09" }, { "State ID": "41", "Rptr ID": "18784", "Frequency": "441.25000", "Input Freq": "446.25000", "PL": "", "TSQ": "", "Nearest City": "Prineville", "Landmark": "", "County": "Crook", "State": "Oregon", "Country": "United States", "Lat": "44.29984850", "Long": "-120.83446640", "Precise": "0", "Callsign": "N7CCO", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311455", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "187", "Frequency": "145.21000", "Input Freq": "144.61000", "PL": "88.5", "TSQ": "", "Nearest City": "Langlois", "Landmark": "Stone Butte", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.87189865", "Long": "-124.43599701", "Precise": "1", "Callsign": "KA7GNK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "A separate tone of 100.0 is listed.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "188", "Frequency": "146.74000", "Input Freq": "146.14000", "PL": "88.5", "TSQ": "", "Nearest City": "Gold Beach", "Landmark": "Grizzly Mountain", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.39749908", "Long": "-124.36599731", "Precise": "1", "Callsign": "K7SEG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "190", "Frequency": "146.96000", "Input Freq": "146.36000", "PL": "88.5", "TSQ": "", "Nearest City": "Brookings", "Landmark": "Harbor Hill", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.05260086", "Long": "-124.28399658", "Precise": "0", "Callsign": "W7BKG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1200', 50 watts. ", "Last Update": "2020-08-31" }, { "State ID": "41", "Rptr ID": "192", "Frequency": "147.25000", "Input Freq": "147.85000", "PL": "88.5", "TSQ": "", "Nearest City": "Brookings", "Landmark": "Bosley Butte", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.20920181", "Long": "-124.22599792", "Precise": "1", "Callsign": "N7UBQ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "500", "Frequency": "440.72500", "Input Freq": "445.72500", "PL": "114.8", "TSQ": "", "Nearest City": "Port Orford", "Landmark": "Cape Blanco", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.83729935", "Long": "-124.56300354", "Precise": "1", "Callsign": "KD7IOP", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "215 feet, 50 watts.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "2812", "Frequency": "146.84000", "Input Freq": "146.24000", "PL": "88.5", "TSQ": "", "Nearest City": "Brookings", "Landmark": "Fire Station", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.12609863", "Long": "-124.32099915", "Precise": "1", "Callsign": "W7BKG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "6759", "Frequency": "147.04000", "Input Freq": "147.64000", "PL": "88.5", "TSQ": "", "Nearest City": "Agness", "Landmark": "", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.55649948", "Long": "-124.06900024", "Precise": "0", "Callsign": "WA7JAW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-07-18" }, { "State ID": "41", "Rptr ID": "20214", "Frequency": "443.80000", "Input Freq": "448.80000", "PL": "", "TSQ": "", "Nearest City": "Brookings", "Landmark": "", "County": "Curry", "State": "Oregon", "Country": "United States", "Lat": "42.06830000", "Long": "-124.27120000", "Precise": "0", "Callsign": "K6JR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "312550", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-02" }, { "State ID": "41", "Rptr ID": "175", "Frequency": "443.05000", "Input Freq": "448.05000", "PL": "162.2", "TSQ": "", "Nearest City": "Bend", "Landmark": "Jack Pine Ridge", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.05830002", "Long": "-121.31400299", "Precise": "0", "Callsign": "KB7LNR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "195", "Frequency": "145.45000", "Input Freq": "144.85000", "PL": "103.5", "TSQ": "CSQ", "Nearest City": "Bend", "Landmark": "Mount Bachelor", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "43.98139954", "Long": "-121.68900299", "Precise": "1", "Callsign": "W7DCO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Per AI7NC, this repeater does not transmit a tone for tone squelch. ", "Last Update": "2022-07-13" }, { "State ID": "41", "Rptr ID": "197", "Frequency": "145.49000", "Input Freq": "144.89000", "PL": "162.2", "TSQ": "162.2", "Nearest City": "Bend", "Landmark": "Sand Shed", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "43.98240000", "Long": "-121.57890000", "Precise": "1", "Callsign": "W7HWY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Elevation = 6,032 feet ASL.", "Last Update": "2022-01-01" }, { "State ID": "41", "Rptr ID": "198", "Frequency": "146.70000", "Input Freq": "146.10000", "PL": "162.2", "TSQ": "", "Nearest City": "Millican", "Landmark": "Pine Mountain", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "43.80289841", "Long": "-120.91400146", "Precise": "1", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "199", "Frequency": "444.75000", "Input Freq": "449.75000", "PL": "156.7", "TSQ": "", "Nearest City": "Millican", "Landmark": "Pine Mtn", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "43.80289841", "Long": "-120.91400146", "Precise": "1", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "201", "Frequency": "146.90000", "Input Freq": "146.30000", "PL": "123.0", "TSQ": "", "Nearest City": "Sisters", "Landmark": "Fivemile Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.35219955", "Long": "-121.69100189", "Precise": "1", "Callsign": "W7DUX", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "There is no Repeater Record Custodian (RRC) assigned to this repeater. Please ask W7DUX -- DANNY J. TUCKER -- TRUSTEE to register with RepeaterBook.com so that he (or others of his choosing) can be assigned as such. ", "Last Update": "2021-07-12" }, { "State ID": "41", "Rptr ID": "202", "Frequency": "146.94000", "Input Freq": "146.34000", "PL": "162.2", "TSQ": "", "Nearest City": "Bend", "Landmark": "Long Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.17369843", "Long": "-121.27600098", "Precise": "1", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "204", "Frequency": "147.04000", "Input Freq": "147.64000", "PL": "114.8", "TSQ": "", "Nearest City": "Redmond", "Landmark": "Cinder Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.31740189", "Long": "-121.17400360", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,604 feet ASL, 300 watts ERP.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "209", "Frequency": "442.12500", "Input Freq": "447.12500", "PL": "D125", "TSQ": "", "Nearest City": "Bend", "Landmark": "Cline Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.25279999", "Long": "-121.30400085", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Tone might also be 123.0. This repeater is not in the ORCC online database. Moved from UNKNOWN to OFF-AIR.", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "477", "Frequency": "146.64000", "Input Freq": "146.04000", "PL": "123.0", "TSQ": "", "Nearest City": "Sunriver", "Landmark": "Spring River Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "43.85029984", "Long": "-121.45800018", "Precise": "0", "Callsign": "KA7QAV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-05-22" }, { "State ID": "41", "Rptr ID": "526", "Frequency": "443.65000", "Input Freq": "448.65000", "PL": "162.2", "TSQ": "", "Nearest City": "Bend", "Landmark": "", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.05830002", "Long": "-121.31400299", "Precise": "0", "Callsign": "KB7LNR", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "211222", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "10074", "Frequency": "145.13000", "Input Freq": "144.53000", "PL": "D026", "TSQ": "D026", "Nearest City": "Redmond", "Landmark": "Cline Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.27259827", "Long": "-121.17400360", "Precise": "0", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-01" }, { "State ID": "41", "Rptr ID": "10561", "Frequency": "444.45000", "Input Freq": "449.45000", "PL": "162.2", "TSQ": "100.0", "Nearest City": "Redmond", "Landmark": "Long Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.17499924", "Long": "-121.25399780", "Precise": "1", "Callsign": "KC7DMF", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "27038", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "3141290", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "All talk groups are open/available.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "11149", "Frequency": "444.92500", "Input Freq": "449.92500", "PL": "100.0", "TSQ": "", "Nearest City": "La Pine", "Landmark": "Finley Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "43.65017000", "Long": "-121.42954500", "Precise": "1", "Callsign": "AA1JW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-16" }, { "State ID": "41", "Rptr ID": "15200", "Frequency": "442.95000", "Input Freq": "447.95000", "PL": "Restricted", "TSQ": "Restricted", "Nearest City": "Redmond", "Landmark": "Gray Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.27259827", "Long": "-121.17400360", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314105", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "17050", "Frequency": "442.55000", "Input Freq": "447.55000", "PL": "162.2", "TSQ": "", "Nearest City": "Bend", "Landmark": "", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "44.05820084", "Long": "-121.31500244", "Precise": "0", "Callsign": "W7DCO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "This repeater is not listed in the ORCC online database. ", "Last Update": "2021-05-22" }, { "State ID": "41", "Rptr ID": "19642", "Frequency": "443.75000", "Input Freq": "448.75000", "PL": "156.7", "TSQ": "", "Nearest City": "Bend", "Landmark": "Long Butte", "County": "Deschutes", "State": "Oregon", "Country": "United States", "Lat": "43.80413340", "Long": "-120.55420120", "Precise": "0", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-24" }, { "State ID": "41", "Rptr ID": "157", "Frequency": "147.38000", "Input Freq": "147.98000", "PL": "146.2", "TSQ": "146.2", "Nearest City": "Mapleton", "Landmark": "Roman Nose", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.91199875", "Long": "-123.73899841", "Precise": "1", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-10-18" }, { "State ID": "41", "Rptr ID": "213", "Frequency": "145.21000", "Input Freq": "144.61000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Glide", "Landmark": "Chilcoot Mountain", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.43230057", "Long": "-122.73000336", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "This repeater is solar and link times out after 15 mins. Simply key up and the link will auto-connect. 15 mins after the last local key (signal) is herd, the link will auto shut down to save batteries.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "215", "Frequency": "145.43000", "Input Freq": "144.83000", "PL": "88.5", "TSQ": "", "Nearest City": "Glide", "Landmark": "Scott Mountain", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.37210083", "Long": "-123.06400299", "Precise": "1", "Callsign": "WA7BWT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-08-05" }, { "State ID": "41", "Rptr ID": "217", "Frequency": "146.90000", "Input Freq": "146.30000", "PL": "100.0", "TSQ": "", "Nearest City": "Roseburg", "Landmark": "Lane Mountain", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.19530106", "Long": "-123.11900330", "Precise": "1", "Callsign": "KC7TLY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "219", "Frequency": "147.12000", "Input Freq": "147.72000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Winston", "Landmark": "", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.12233830", "Long": "-123.41257230", "Precise": "1", "Callsign": "KC7UAV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "83672", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-03" }, { "State ID": "41", "Rptr ID": "221", "Frequency": "147.24000", "Input Freq": "147.84000", "PL": "136.5", "TSQ": "136.5", "Nearest City": "Roseburg", "Landmark": "Lane Mountain", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.19530106", "Long": "-123.11900330", "Precise": "1", "Callsign": "WB7RKR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Permanently linked to the SWORA repeater system", "Last Update": "2022-04-11" }, { "State ID": "41", "Rptr ID": "223", "Frequency": "224.10000", "Input Freq": "222.50000", "PL": "114.8", "TSQ": "", "Nearest City": "Glide", "Landmark": "Scott Mountain", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.37210083", "Long": "-123.06400299", "Precise": "1", "Callsign": "WB7RKR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "There is no Repeater Record Custodian (RRC) assigned to this repeater. Please ask WB7RKR -- KEITH A. PETERSON -- TRUSTEE to registyer with RepeaterBool.com so that he (or others of his choosing) can be assigned as such. ", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "224", "Frequency": "441.85000", "Input Freq": "446.85000", "PL": "D125", "TSQ": "D125", "Nearest City": "Roseburg", "Landmark": "Mt Scott", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.37200165", "Long": "-123.06500244", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "480", "Frequency": "147.18000", "Input Freq": "147.78000", "PL": "146.2", "TSQ": "", "Nearest City": "Reedsport", "Landmark": "Winchester Hill", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.65719986", "Long": "-124.18599701", "Precise": "1", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "680", "Frequency": "441.87500", "Input Freq": "446.87500", "PL": "88.5", "TSQ": "", "Nearest City": "Roseburg", "Landmark": "", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.21670151", "Long": "-123.34100342", "Precise": "0", "Callsign": "WB6MFV", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "This is a solar site repeater and power can be limited on no sun days. Please keep transmissions as short as possible.", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "2814", "Frequency": "444.62500", "Input Freq": "449.62500", "PL": "91.5", "TSQ": "", "Nearest City": "Glide", "Landmark": "Scott Mountain", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.37210083", "Long": "-123.06400299", "Precise": "1", "Callsign": "WB7RKR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "There is no Repeater Record Custodian (RRC) assigned to this repeater. Please ask WB7RKR -- KEITH A. PETERSON -- TRUSTEE to register with RepeaterBool.com so that he (or others of his choosing) can be assigned as such. ", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "3092", "Frequency": "440.62500", "Input Freq": "445.62500", "PL": "114.8", "TSQ": "", "Nearest City": "Roseburg", "Landmark": "Mount Nebo", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.20619965", "Long": "-123.36399841", "Precise": "1", "Callsign": "WA7JAW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,168 feet ASL.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "10031", "Frequency": "146.70000", "Input Freq": "146.10000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Roseburg", "Landmark": "Scott Mountain", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.30149841", "Long": "-123.10099792", "Precise": "0", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "11148", "Frequency": "444.87500", "Input Freq": "449.87500", "PL": "127.3", "TSQ": "", "Nearest City": "Glide", "Landmark": "", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.30149841", "Long": "-123.10099792", "Precise": "0", "Callsign": "WB7RKR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "There is no Repeater Record Custodian (RRC) assigned to this repeater. Please ask WB7RKR -- KEITH A. PETERSON -- TRUSTEE to register with RepeaterBool.com so that he (or others of his choosing) can be assigned as such. ", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "11533", "Frequency": "147.14000", "Input Freq": "147.74000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Lakeside", "Landmark": "Roman Nose Mtn", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.91199875", "Long": "-123.73899841", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "11660", "Frequency": "147.22000", "Input Freq": "147.82000", "PL": "67.0", "TSQ": "67.0", "Nearest City": "Diamond Lake", "Landmark": "Cinnamon Butte", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.24062200", "Long": "-122.11011300", "Precise": "1", "Callsign": "K7RBG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-06-28" }, { "State ID": "41", "Rptr ID": "14280", "Frequency": "444.40000", "Input Freq": "449.40000", "PL": "", "TSQ": "123.0", "Nearest City": "Reedsport", "Landmark": "Winchester Hill", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.70230103", "Long": "-124.09700012", "Precise": "0", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-08-10" }, { "State ID": "41", "Rptr ID": "15429", "Frequency": "444.90000", "Input Freq": "449.90000", "PL": "D125", "TSQ": "", "Nearest City": "Yoncalla", "Landmark": "Harness Mtn", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.52550125", "Long": "-123.09200287", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,150 feet ASL.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "18774", "Frequency": "145.47000", "Input Freq": "144.87000", "PL": "", "TSQ": "", "Nearest City": "Tiller", "Landmark": "", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "42.92845410", "Long": "-122.95116510", "Precise": "0", "Callsign": "K7BRG", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "19705", "Frequency": "449.25000", "Input Freq": "444.25000", "PL": "", "TSQ": "", "Nearest City": "Roseburg", "Landmark": "", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.21650500", "Long": "-123.34173810", "Precise": "0", "Callsign": "KG7YHY", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "2", "DMR ID": "314906", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-31" }, { "State ID": "41", "Rptr ID": "20029", "Frequency": "441.87500", "Input Freq": "446.87500", "PL": "162.2", "TSQ": "", "Nearest City": "Roseburg", "Landmark": "Whitetail Ridge Winery", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.12220000", "Long": "-123.41280000", "Precise": "1", "Callsign": "N7TZ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "72122", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Whitetail Ridge UHF Repeater Wires-X #82122", "Last Update": "2022-12-18" }, { "State ID": "41", "Rptr ID": "21306", "Frequency": "440.92500", "Input Freq": "445.92500", "PL": "77.0", "TSQ": "77.0", "Nearest City": "Winston", "Landmark": "112 Weigh Station", "County": "Douglas", "State": "Oregon", "Country": "United States", "Lat": "43.00336740", "Long": "-123.35875000", "Precise": "0", "Callsign": "KK7HEP", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-18" }, { "State ID": "41", "Rptr ID": "210", "Frequency": "145.24000", "Input Freq": "144.64000", "PL": "162.2", "TSQ": "", "Nearest City": "John Day", "Landmark": "Airport", "County": "Grant", "State": "Oregon", "Country": "United States", "Lat": "44.40319824", "Long": "-118.96199799", "Precise": "1", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,576 feet ASL.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "211", "Frequency": "146.64000", "Input Freq": "146.04000", "PL": "", "TSQ": "", "Nearest City": "Canyon City", "Landmark": "Eagle Peak", "County": "Grant", "State": "Oregon", "Country": "United States", "Lat": "44.37340164", "Long": "-118.96499634", "Precise": "1", "Callsign": "N7LZM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "4,833 feet. Covers about 40% of Grant County - this is well monitored.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "212", "Frequency": "147.22000", "Input Freq": "147.82000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "John Day", "Landmark": "Fall Mountain", "County": "Grant", "State": "Oregon", "Country": "United States", "Lat": "44.29370117", "Long": "-119.04299927", "Precise": "1", "Callsign": "N7LZM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "Yes", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "19070", "Frequency": "145.43000", "Input Freq": "144.83000", "PL": "136.5", "TSQ": "", "Nearest City": "Prairie City", "Landmark": "Sheep Mountain", "County": "Grant", "State": "Oregon", "Country": "United States", "Lat": "44.25052100", "Long": "-118.48316500", "Precise": "0", "Callsign": "", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2023-01-01" }, { "State ID": "41", "Rptr ID": "228", "Frequency": "146.76000", "Input Freq": "146.16000", "PL": "103.5", "TSQ": "", "Nearest City": "Burns", "Landmark": "Radar Hill", "County": "Harney", "State": "Oregon", "Country": "United States", "Lat": "43.56480026", "Long": "-119.15299988", "Precise": "1", "Callsign": "KF7HPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2018-07-14" }, { "State ID": "41", "Rptr ID": "229", "Frequency": "147.30000", "Input Freq": "147.90000", "PL": "162.2", "TSQ": "", "Nearest City": "Burns", "Landmark": "Sharps Ridge", "County": "Harney", "State": "Oregon", "Country": "United States", "Lat": "43.68109894", "Long": "-118.92299652", "Precise": "1", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "4,704 feet ASL.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "18262", "Frequency": "145.11000", "Input Freq": "144.51000", "PL": "136.5", "TSQ": "67.0", "Nearest City": "Burns", "Landmark": "Steens Mountain", "County": "Harney", "State": "Oregon", "Country": "United States", "Lat": "43.58629990", "Long": "-119.05400085", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "485630", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "10,000 feet asl. Solar site", "Last Update": "2020-11-02" }, { "State ID": "41", "Rptr ID": "232", "Frequency": "145.15000", "Input Freq": "144.55000", "PL": "94.8", "TSQ": "", "Nearest City": "Hood River", "Landmark": "Mount Defiance", "County": "Hood River", "State": "Oregon", "Country": "United States", "Lat": "45.64250183", "Long": "-121.72200012", "Precise": "1", "Callsign": "WA7ROB", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "NW Emergency Radio System
4,959'.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "233", "Frequency": "147.10000", "Input Freq": "147.70000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Hood River", "Landmark": "Mount Defiance", "County": "Hood River", "State": "Oregon", "Country": "United States", "Lat": "45.64849854", "Long": "-121.72200012", "Precise": "1", "Callsign": "KF7LN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "5,000'.", "Last Update": "2021-01-22" }, { "State ID": "41", "Rptr ID": "538", "Frequency": "440.95000", "Input Freq": "445.95000", "PL": "100.0", "TSQ": "", "Nearest City": "Cascade Locks", "Landmark": "", "County": "Hood River", "State": "Oregon", "Country": "United States", "Lat": "45.66983920", "Long": "-121.89063540", "Precise": "0", "Callsign": "KF7LN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "0", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "2782", "Frequency": "927.16250", "Input Freq": "902.16250", "PL": "151.4", "TSQ": "151.4", "Nearest City": "Cascade Locks", "Landmark": "Mt Defiance", "County": "Hood River", "State": "Oregon", "Country": "United States", "Lat": "45.64849854", "Long": "-121.72200012", "Precise": "1", "Callsign": "KF7LN", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "97040", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "5,000' AMSLE.", "Last Update": "2022-03-10" }, { "State ID": "41", "Rptr ID": "12345", "Frequency": "444.90000", "Input Freq": "449.90000", "PL": "100.0", "TSQ": "", "Nearest City": "Hood River", "Landmark": "Middle Mountain", "County": "Hood River", "State": "Oregon", "Country": "United States", "Lat": "45.70539856", "Long": "-121.52100372", "Precise": "0", "Callsign": "KA7HRC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-07-18" }, { "State ID": "41", "Rptr ID": "17229", "Frequency": "440.60000", "Input Freq": "445.60000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Hood River", "Landmark": "Columbia River Gorge", "County": "Hood River", "State": "Oregon", "Country": "United States", "Lat": "45.64270020", "Long": "-121.57599640", "Precise": "0", "Callsign": "AF7YV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "43296", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "18736", "Frequency": "443.32500", "Input Freq": "448.32500", "PL": "", "TSQ": "", "Nearest City": "Cascade Locks", "Landmark": "Cascade Locks Hill", "County": "Hood River", "State": "Oregon", "Country": "United States", "Lat": "45.66983920", "Long": "-121.89063550", "Precise": "0", "Callsign": "N7LF", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311388", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Open use. Connected to PNW Digital System. Visit PNWDigital.net for further info on supported TG's and other important info.", "Last Update": "2021-03-26" }, { "State ID": "41", "Rptr ID": "21", "Frequency": "442.30000", "Input Freq": "447.30000", "PL": "D125", "TSQ": "D125", "Nearest City": "Ashland", "Landmark": "Mount Ashland", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.08069992", "Long": "-122.71700287", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "168", "Frequency": "147.06000", "Input Freq": "147.66000", "PL": "CSQ", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.32669830", "Long": "-122.87400055", "Precise": "0", "Callsign": "W9PCI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "308", "Frequency": "146.62000", "Input Freq": "146.02000", "PL": "123.0", "TSQ": "", "Nearest City": "Ashland", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.19459915", "Long": "-122.70899963", "Precise": "0", "Callsign": "W9PCI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "3383", "IRLP Node": "3383", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,305'", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "311", "Frequency": "440.70000", "Input Freq": "445.70000", "PL": "162.2", "TSQ": "", "Nearest City": "Ashland", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.19469833", "Long": "-122.70800018", "Precise": "0", "Callsign": "WX7MFR", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "312", "Frequency": "440.82500", "Input Freq": "445.82500", "PL": "136.5", "TSQ": "", "Nearest City": "Central Point", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.37609863", "Long": "-122.91500092", "Precise": "0", "Callsign": "WA6RHK", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Uplink tone may be DCS 125.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "369", "Frequency": "444.82500", "Input Freq": "449.82500", "PL": "100.0", "TSQ": "", "Nearest City": "Rogue River", "Landmark": "Elk Mountain", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.54010010", "Long": "-123.14499664", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "436", "Frequency": "147.16000", "Input Freq": "147.76000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Ashland", "Landmark": "Soda Mtn", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.06460190", "Long": "-122.47899628", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "521741", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "6,280 feet ASL.", "Last Update": "2020-09-25" }, { "State ID": "41", "Rptr ID": "472", "Frequency": "145.33000", "Input Freq": "144.73000", "PL": "123.0", "TSQ": "", "Nearest City": "Central Point", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.37595860", "Long": "-122.91643070", "Precise": "0", "Callsign": "W9PCI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "2,665 feet.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "491", "Frequency": "147.10000", "Input Freq": "147.70000", "PL": "136.5", "TSQ": "", "Nearest City": "Central Point", "Landmark": "Johns Peak", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.35689926", "Long": "-122.97799683", "Precise": "1", "Callsign": "AK7SB", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "This repeater is not listed in the ORCC online database. As of 11 July 2021 this repeater (formerly KB7SKB) is owned by (and identifies as) AK7SB.", "Last Update": "2021-07-11" }, { "State ID": "41", "Rptr ID": "493", "Frequency": "147.00000", "Input Freq": "147.60000", "PL": "123.0", "TSQ": "", "Nearest City": "Medford", "Landmark": "Rogue Valley Manor", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.32669830", "Long": "-122.87400055", "Precise": "0", "Callsign": "K7RVM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "494", "Frequency": "147.02000", "Input Freq": "147.62000", "PL": "100.0", "TSQ": "", "Nearest City": "Medford", "Landmark": "Downtown", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.32649994", "Long": "-122.87599945", "Precise": "0", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-09" }, { "State ID": "41", "Rptr ID": "525", "Frequency": "147.26000", "Input Freq": "147.86000", "PL": "123.0", "TSQ": "", "Nearest City": "Ashland", "Landmark": "Mount Ashland", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.08069992", "Long": "-122.71700287", "Precise": "1", "Callsign": "WX7MFR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-08-05" }, { "State ID": "41", "Rptr ID": "550", "Frequency": "443.15000", "Input Freq": "448.15000", "PL": "136.5", "TSQ": "", "Nearest City": "Central Point", "Landmark": "QTH", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.21500015", "Long": "-121.70800018", "Precise": "0", "Callsign": "KL7VK", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,405 feet.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "551", "Frequency": "443.77500", "Input Freq": "448.77500", "PL": "", "TSQ": "", "Nearest City": "Medford", "Landmark": "Baldy", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.29859924", "Long": "-122.75000000", "Precise": "1", "Callsign": "KE7MVI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-13" }, { "State ID": "41", "Rptr ID": "661", "Frequency": "145.41000", "Input Freq": "144.81000", "PL": "100.0", "TSQ": "", "Nearest City": "Central Point", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.35421800", "Long": "-122.96097300", "Precise": "1", "Callsign": "KB7QMV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "The repeater reaches from north of Eagle Point south past Ashland and east up 140 toward Klamath Falls", "Last Update": "2021-01-10" }, { "State ID": "41", "Rptr ID": "673", "Frequency": "444.10000", "Input Freq": "449.10000", "PL": "123.0", "TSQ": "", "Nearest City": "Central Point", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.37609863", "Long": "-122.91500092", "Precise": "1", "Callsign": "W9PCI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,355 feet.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "674", "Frequency": "444.20000", "Input Freq": "449.20000", "PL": "100.0", "TSQ": "", "Nearest City": "Jacksonville", "Landmark": "Roxy Ann QTH", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.31359863", "Long": "-122.96600342", "Precise": "0", "Callsign": "W9PCI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "385956", "IRLP Node": "3414", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,075 feet.", "Last Update": "2022-09-17" }, { "State ID": "41", "Rptr ID": "675", "Frequency": "444.30000", "Input Freq": "449.30000", "PL": "123.0", "TSQ": "", "Nearest City": "Jacksonville", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.31359863", "Long": "-122.96600342", "Precise": "0", "Callsign": "W9PCI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "0", "Notes": "2,685 feet.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "2807", "Frequency": "147.38000", "Input Freq": "147.98000", "PL": "131.8", "TSQ": "", "Nearest City": "Central Point", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.37609863", "Long": "-122.91500092", "Precise": "0", "Callsign": "KL7VK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,405 feet ASL.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "3577", "Frequency": "146.84000", "Input Freq": "146.24000", "PL": "123.0", "TSQ": "", "Nearest City": "Medford", "Landmark": "Baldy", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.29850006", "Long": "-122.75099945", "Precise": "1", "Callsign": "K7JAX", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,797 feet ASL.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "6736", "Frequency": "146.72000", "Input Freq": "146.12000", "PL": "131.8", "TSQ": "", "Nearest City": "Ruch", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.24489975", "Long": "-123.03500366", "Precise": "0", "Callsign": "KL7VK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "11145", "Frequency": "444.45000", "Input Freq": "449.45000", "PL": "100.0", "TSQ": "", "Nearest City": "Medford", "Landmark": "Rogue Valley Manor", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.32649994", "Long": "-122.87599945", "Precise": "0", "Callsign": "K7RVM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "11230", "Frequency": "145.24000", "Input Freq": "144.64000", "PL": "", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.30770111", "Long": "-122.83899689", "Precise": "1", "Callsign": "KG7FOJ", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "As of 06/25/2021 03:04:48 UTC -- Unique Stations Heard In The Last 14 Days on KG7FOJ: ***NO STATIONS HEARD ! *** There are no Repeater Record Custodians assigned to this repeater. Please ask WD6ESU -- ROBERT N. TANGEL -- TRUSTEE to register with RepeaterBook.com so that he (or others of his choosing) can be assigned as such. Confirmed that this repeater is listed in the ORCC online database. Accordingly, moved from UNKNOWN to ON-AIR. If you hear this repeater ON-AIR or know of a different status, please email KV4VT@RepeaterBook.com ASAP.", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "11231", "Frequency": "444.65000", "Input Freq": "449.65000", "PL": "", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.30770111", "Long": "-122.83899689", "Precise": "1", "Callsign": "KG7FOJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-13" }, { "State ID": "41", "Rptr ID": "11232", "Frequency": "1293.12500", "Input Freq": "1313.12500", "PL": "", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.30770111", "Long": "-122.83899689", "Precise": "1", "Callsign": "KG7FOJ", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "As of 06/25/2021 03:00:04 UTC -- Unique Stations Heard In The Last 14 Days on KG7FOJ: ***NO STATIONS HEARD !*** If you hear this repeater ON-AIR or know of a different status, please email KV4VT@RepeaterBook.com ASAP.", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "12806", "Frequency": "145.27000", "Input Freq": "144.67000", "PL": "136.5", "TSQ": "136.5", "Nearest City": "Rogue River", "Landmark": "Elk Mtn", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.43600082", "Long": "-123.17199707", "Precise": "0", "Callsign": "WA6HWW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "17153", "Frequency": "1248.50000", "Input Freq": "1228.50000", "PL": "", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.32649994", "Long": "-122.87599945", "Precise": "0", "Callsign": "KG7FOJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "There are no Repeater Record Custodians assigned to this repeater. Please ask WD6ESU -- ROBERT N. TANGEL -- TRUSTEE to register with RepeaterBook.com so that he (or others of his choosing) can be assigned as such. Confirmed that this repeater is listed in the ORCC online database. Accordingly, moved from UNKNOWN to ON-AIR. If you hear this repeater ON-AIR or know of a different status, please email KV4VT@RepeaterBook.com ASAP.", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "18062", "Frequency": "52.81000", "Input Freq": "51.11000", "PL": "103.5", "TSQ": "", "Nearest City": "Grants Pass", "Landmark": "Elk Mountain", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.03089905", "Long": "-124.12300110", "Precise": "0", "Callsign": "WD7RW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "7366", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Split site, receiver on Fielder and transmitter on Elk.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "18573", "Frequency": "444.25000", "Input Freq": "449.25000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Rogue River", "Landmark": "Fielder Mtn", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.44567490", "Long": "-123.21672058", "Precise": "0", "Callsign": "WD7FGX", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "7366", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-03-10" }, { "State ID": "41", "Rptr ID": "18782", "Frequency": "440.22500", "Input Freq": "445.22500", "PL": "131.8", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.32651520", "Long": "-122.87559490", "Precise": "0", "Callsign": "K7RVM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "There are no Repeater Record Custodians assigned to this repeater. Please ask N6WN -- DANIEL B. CURTIS -- TRUSTEE to register with RepeaterBook.com so that he (or others of his choosing) can be assigned as such. Confirmed that this repeater is listed in the ORCC online database. If you hear this repeater ON-AIR or know of a different status, please email KV4VT@RepeaterBook.com ASAP. ", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "19080", "Frequency": "440.72500", "Input Freq": "445.72500", "PL": "D023", "TSQ": "D023", "Nearest City": "Medford", "Landmark": "Roxy Ann Peak", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.35293200", "Long": "-122.78685200", "Precise": "0", "Callsign": "", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,511 feet.", "Last Update": "2020-08-25" }, { "State ID": "41", "Rptr ID": "19641", "Frequency": "147.24000", "Input Freq": "147.84000", "PL": "123.0", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "43.80413340", "Long": "-120.55420120", "Precise": "0", "Callsign": "W9PCI", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "3414", "IRLP Node": "3414", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Currently bench testing.", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "19702", "Frequency": "442.80000", "Input Freq": "447.80000", "PL": "", "TSQ": "", "Nearest City": "Medford", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.32651520", "Long": "-122.87559490", "Precise": "0", "Callsign": "KD7MPA", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311499", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-31" }, { "State ID": "41", "Rptr ID": "21166", "Frequency": "145.00000", "Input Freq": "145.00000", "PL": "D503", "TSQ": "", "Nearest City": "Rogue River", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.43000000", "Long": "-123.16000000", "Precise": "1", "Callsign": "KL7XL", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "54016", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "10 ft tower with 60 watts-o-power.", "Last Update": "2022-12-31" }, { "State ID": "41", "Rptr ID": "21206", "Frequency": "439.00000", "Input Freq": "439.00000", "PL": "D503", "TSQ": "", "Nearest City": "Rogue River", "Landmark": "", "County": "Jackson", "State": "Oregon", "Country": "United States", "Lat": "42.43595400", "Long": "-123.17199760", "Precise": "1", "Callsign": "KL7XL", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "54016", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "10 foot tower with 50 watts. ", "Last Update": "2022-10-06" }, { "State ID": "41", "Rptr ID": "423", "Frequency": "147.18000", "Input Freq": "147.78000", "PL": "162.2", "TSQ": "", "Nearest City": "Mitchell", "Landmark": "Stephenson Mountain", "County": "Jefferson", "State": "Oregon", "Country": "United States", "Lat": "44.58240128", "Long": "-120.45200348", "Precise": "1", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "6,312 feet ASL.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "15786", "Frequency": "442.22500", "Input Freq": "447.22500", "PL": "114.8", "TSQ": "", "Nearest City": "Madras", "Landmark": "Eagle Butte", "County": "Jefferson", "State": "Oregon", "Country": "United States", "Lat": "44.83960000", "Long": "-121.23530000", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,800 feet ASL, 50 watts.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "17783", "Frequency": "444.42500", "Input Freq": "449.42500", "PL": "", "TSQ": "", "Nearest City": "Culver", "Landmark": "", "County": "Jefferson", "State": "Oregon", "Country": "United States", "Lat": "44.52569962", "Long": "-121.21299744", "Precise": "0", "Callsign": "KC7DMF", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "0", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-02-24" }, { "State ID": "41", "Rptr ID": "242", "Frequency": "145.49000", "Input Freq": "144.89000", "PL": "136.5", "TSQ": "", "Nearest City": "Cave Junction", "Landmark": "Eight Dollar Mtn", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.25780106", "Long": "-123.66200256", "Precise": "1", "Callsign": "WB6YQP", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "244", "Frequency": "146.94000", "Input Freq": "146.34000", "PL": "D023", "TSQ": "D023", "Nearest City": "Wolf Creek", "Landmark": "King Mountain", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.69169998", "Long": "-123.23100281", "Precise": "1", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "5,283', 75 watts.", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "246", "Frequency": "147.22000", "Input Freq": "147.82000", "PL": "CSQ", "TSQ": "", "Nearest City": "Grants Pass", "Landmark": "", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.40319824", "Long": "-123.35800171", "Precise": "1", "Callsign": "WA6OTP", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "247", "Frequency": "147.30000", "Input Freq": "147.90000", "PL": "136.5", "TSQ": "", "Nearest City": "Grants Pass", "Landmark": "Gilbert Peak", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.47159958", "Long": "-123.30599976", "Precise": "1", "Callsign": "K7LIX", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-17" }, { "State ID": "41", "Rptr ID": "248", "Frequency": "147.34000", "Input Freq": "147.94000", "PL": "136.5", "TSQ": "", "Nearest City": "Wolf Creek", "Landmark": "King Mountain", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.69169998", "Long": "-123.23100281", "Precise": "1", "Callsign": "WB6YQP", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "258", "Frequency": "444.50000", "Input Freq": "449.50000", "PL": "D125", "TSQ": "D125", "Nearest City": "Wolf Creek", "Landmark": "King Mountain", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.69169998", "Long": "-123.23100281", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "370", "Frequency": "440.55000", "Input Freq": "445.55000", "PL": "173.8", "TSQ": "", "Nearest City": "Grants Pass", "Landmark": "Onion Mountain", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.45439911", "Long": "-123.61900330", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Though this is a solar site, enough power is available to keep this repeater linked full time. This repeater is not listed in ORCC online database. Moved from UNKNOWN to OFF-AIR. ", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "8090", "Frequency": "440.46250", "Input Freq": "445.46250", "PL": "", "TSQ": "", "Nearest City": "Grants Pass", "Landmark": "Mt Fielder", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.42422450", "Long": "-123.19380240", "Precise": "0", "Callsign": "KE7LKX", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "8244", "Frequency": "443.52500", "Input Freq": "448.52500", "PL": "173.8", "TSQ": "", "Nearest City": "Wolf Creek", "Landmark": "King Mountain", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.69169998", "Long": "-123.23100281", "Precise": "1", "Callsign": "W6PRN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-07-28" }, { "State ID": "41", "Rptr ID": "17726", "Frequency": "52.81000", "Input Freq": "52.31000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Grants Pass", "Landmark": "", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.41460037", "Long": "-123.33899689", "Precise": "1", "Callsign": "WD7FGX", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "7366", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-03-10" }, { "State ID": "41", "Rptr ID": "17971", "Frequency": "444.67500", "Input Freq": "449.67500", "PL": "100.0", "TSQ": "", "Nearest City": "Grants Pass", "Landmark": "Gilbert Peak", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.48880005", "Long": "-123.30699921", "Precise": "0", "Callsign": "W6PRN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-07-28" }, { "State ID": "41", "Rptr ID": "20194", "Frequency": "449.97500", "Input Freq": "449.97500", "PL": "100.0", "TSQ": "", "Nearest City": "Grants Pass", "Landmark": "", "County": "Josephine", "State": "Oregon", "Country": "United States", "Lat": "42.41458700", "Long": "-123.33907500", "Precise": "0", "Callsign": "W2HR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "47871", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Full time connected to the GRANTS PASS HUB FM only.", "Last Update": "2022-10-16" }, { "State ID": "41", "Rptr ID": "169", "Frequency": "440.67500", "Input Freq": "445.67500", "PL": "136.5", "TSQ": "", "Nearest City": "Keno", "Landmark": "Chase Mountain", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.09450150", "Long": "-121.99400330", "Precise": "1", "Callsign": "WA6RHK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Links to the west via Soda Mtn.", "Last Update": "2021-05-29" }, { "State ID": "41", "Rptr ID": "196", "Frequency": "145.47000", "Input Freq": "144.87000", "PL": "123.0", "TSQ": "", "Nearest City": "Chemult", "Landmark": "Walker Mountain", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "43.26119995", "Long": "-121.74600220", "Precise": "0", "Callsign": "AA1JW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Antenna elevation is 7,100 feet ASL. This repeater is now listed in the ORCC online database as AA1JW -- JAMES A. WILLIAMS -- TRUSTEE. Trustee has no email address posted in QRZ with which to help validate this listing. ", "Last Update": "2022-10-24" }, { "State ID": "41", "Rptr ID": "267", "Frequency": "146.61000", "Input Freq": "146.01000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Klamath Falls", "Landmark": "Hogback Mtn", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.24269867", "Long": "-121.70600128", "Precise": "1", "Callsign": "W7VW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "270", "Frequency": "146.85000", "Input Freq": "146.25000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Klamath Falls", "Landmark": "Hamaker Mountain", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.06840134", "Long": "-121.97299957", "Precise": "1", "Callsign": "W7VW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "272", "Frequency": "443.90000", "Input Freq": "448.90000", "PL": "118.8", "TSQ": "", "Nearest City": "Klamath Falls", "Landmark": "Hogsback Mtn", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.24269867", "Long": "-121.70600128", "Precise": "1", "Callsign": "W7VW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "273", "Frequency": "443.20000", "Input Freq": "448.20000", "PL": "100.0", "TSQ": "", "Nearest City": "Keno", "Landmark": "Hamaker Mountain", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.06850052", "Long": "-121.97299957", "Precise": "1", "Callsign": "K6PRN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-06-23" }, { "State ID": "41", "Rptr ID": "275", "Frequency": "147.20000", "Input Freq": "147.80000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Klamath Falls", "Landmark": "Chase Mountain", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.09469986", "Long": "-121.99400330", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "482", "Frequency": "147.18000", "Input Freq": "147.78000", "PL": "100.0", "TSQ": "", "Nearest City": "Keno", "Landmark": "Hamaker Mountain", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.06850052", "Long": "-121.97299957", "Precise": "1", "Callsign": "", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "5,918 feet.", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "11142", "Frequency": "442.52500", "Input Freq": "447.52500", "PL": "118.8", "TSQ": "", "Nearest City": "Keno", "Landmark": "", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.12649918", "Long": "-121.93000031", "Precise": "0", "Callsign": "KD7TNG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "17133", "Frequency": "444.95000", "Input Freq": "449.95000", "PL": "136.5", "TSQ": "82.5", "Nearest City": "Chiloquin", "Landmark": "Train Mtn", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "42.55680084", "Long": "-121.88600159", "Precise": "0", "Callsign": "K7LNK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-11-25" }, { "State ID": "41", "Rptr ID": "19135", "Frequency": "147.14000", "Input Freq": "147.74000", "PL": "141.3", "TSQ": "91.5", "Nearest City": "Chemult", "Landmark": "Walker Mtn", "County": "Klamath", "State": "Oregon", "Country": "United States", "Lat": "43.67039950", "Long": "-121.50363600", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "206", "Frequency": "147.20000", "Input Freq": "147.80000", "PL": "162.2", "TSQ": "", "Nearest City": "Hampton", "Landmark": "Glass Butte", "County": "Lake", "State": "Oregon", "Country": "United States", "Lat": "43.80410004", "Long": "-120.55400085", "Precise": "0", "Callsign": "W7JVO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "6,312 feet ASL.", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "295", "Frequency": "145.31000", "Input Freq": "144.71000", "PL": "173.8", "TSQ": "", "Nearest City": "Lakeview", "Landmark": "Drake Peak", "County": "Lake", "State": "Oregon", "Country": "United States", "Lat": "42.30039978", "Long": "-120.12300110", "Precise": "1", "Callsign": "KE7QP", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "8,222 feet. We have ran out of propane fuel that helps when the solar system has no sun. This site is unlinked until we get some sunshine in the coming months. ", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "296", "Frequency": "146.80000", "Input Freq": "146.20000", "PL": "173.8", "TSQ": "", "Nearest City": "Summer Lake", "Landmark": "Dead Indian Mountain", "County": "Lake", "State": "Oregon", "Country": "United States", "Lat": "42.98339844", "Long": "-120.82800293", "Precise": "1", "Callsign": "KE7QP", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "7,022 feet ASL", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "297", "Frequency": "147.34000", "Input Freq": "147.94000", "PL": "173.8", "TSQ": "", "Nearest City": "Lakeview", "Landmark": "Grizzly Peak", "County": "Lake", "State": "Oregon", "Country": "United States", "Lat": "42.25270081", "Long": "-120.63899994", "Precise": "1", "Callsign": "KE7QP", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "3796", "Frequency": "145.15000", "Input Freq": "144.55000", "PL": "173.8", "TSQ": "", "Nearest City": "Fort Rock", "Landmark": "Washtina Butte", "County": "Lake", "State": "Oregon", "Country": "United States", "Lat": "43.33915000", "Long": "-121.27118000", "Precise": "1", "Callsign": "AA1JW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-10-11" }, { "State ID": "41", "Rptr ID": "11", "Frequency": "53.03000", "Input Freq": "51.33000", "PL": "100.0", "TSQ": "", "Nearest City": "Monroe", "Landmark": "Prairie Peak", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.27700043", "Long": "-123.60800171", "Precise": "1", "Callsign": "W7ARD", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "12", "Frequency": "146.68000", "Input Freq": "146.08000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Horton", "Landmark": "Prairie Mtn", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.27957000", "Long": "-123.59071200", "Precise": "1", "Callsign": "W7EUG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "13", "Frequency": "146.72000", "Input Freq": "146.12000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Junction City", "Landmark": "Prairie Peak", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.28002800", "Long": "-123.58297100", "Precise": "1", "Callsign": "W7PXL", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "538022", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Access to the Echolink system is granted only to members of the Valley Radio Club, Eugene OR.", "Last Update": "2023-01-11" }, { "State ID": "41", "Rptr ID": "55", "Frequency": "441.62500", "Input Freq": "446.62500", "PL": "100.0", "TSQ": "", "Nearest City": "Sisters", "Landmark": "Hoodoo Butte", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.40190125", "Long": "-121.88300323", "Precise": "1", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "300", "Frequency": "53.07000", "Input Freq": "51.37000", "PL": "100.0", "TSQ": "", "Nearest City": "Oakridge", "Landmark": "Wolf Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.61619949", "Long": "-122.23000336", "Precise": "1", "Callsign": "W7ARD", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "305", "Frequency": "145.37000", "Input Freq": "144.77000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Blue River", "Landmark": "Indian Ridge", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00529861", "Long": "-122.25599670", "Precise": "1", "Callsign": "W7EUG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-22" }, { "State ID": "41", "Rptr ID": "309", "Frequency": "146.66000", "Input Freq": "146.06000", "PL": "100.0", "TSQ": "", "Nearest City": "Cottage Grove", "Landmark": "Harness Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.52550125", "Long": "-123.09200287", "Precise": "1", "Callsign": "W7ZQE", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "310", "Frequency": "443.02500", "Input Freq": "448.02500", "PL": "156.7", "TSQ": "", "Nearest City": "Cottage Grove", "Landmark": "", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.79779816", "Long": "-123.05799866", "Precise": "0", "Callsign": "K7SLA", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "314", "Frequency": "146.74000", "Input Freq": "146.14000", "PL": "100.0", "TSQ": "", "Nearest City": "Springfield", "Landmark": "Willamette Heights Park", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.03979874", "Long": "-123.01799774", "Precise": "1", "Callsign": "WA7FQD", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "315", "Frequency": "146.76000", "Input Freq": "146.16000", "PL": "123.0", "TSQ": "", "Nearest City": "Cottage Grove", "Landmark": "Bear Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.84260178", "Long": "-122.89199829", "Precise": "1", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,680", "Last Update": "2022-05-06" }, { "State ID": "41", "Rptr ID": "316", "Frequency": "146.80000", "Input Freq": "146.20000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Florence", "Landmark": "Herman Peak", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.12419891", "Long": "-124.01300049", "Precise": "1", "Callsign": "W7FLO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "612184", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-08-13" }, { "State ID": "41", "Rptr ID": "317", "Frequency": "146.88000", "Input Freq": "146.28000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Eugene", "Landmark": "Blanton Heights", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00260162", "Long": "-123.11299896", "Precise": "1", "Callsign": "K7TBL", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,270 feet ASL.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "318", "Frequency": "146.98000", "Input Freq": "146.38000", "PL": "88.5", "TSQ": "", "Nearest City": "Oakridge", "Landmark": "Wolf Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.61669922", "Long": "-122.23000336", "Precise": "1", "Callsign": "N7NPA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Used as an ARES/RACES tactical channel.", "Last Update": "2022-12-14" }, { "State ID": "41", "Rptr ID": "319", "Frequency": "147.08000", "Input Freq": "147.68000", "PL": "100.0", "TSQ": "91.5", "Nearest City": "Eugene", "Landmark": "Coburg Ridge", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.13660049", "Long": "-123.01499939", "Precise": "0", "Callsign": "W7CQZ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "521741", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "321", "Frequency": "147.26000", "Input Freq": "147.86000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Eugene", "Landmark": "Blanton Heights", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00260162", "Long": "-123.11299896", "Precise": "1", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,270'", "Last Update": "2021-02-24" }, { "State ID": "41", "Rptr ID": "322", "Frequency": "147.36000", "Input Freq": "147.96000", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Eugene", "Landmark": "Blanton Heights", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00260162", "Long": "-123.11299896", "Precise": "1", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,270 feet ASL.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "327", "Frequency": "441.12500", "Input Freq": "446.12500", "PL": "141.3", "TSQ": "141.3", "Nearest City": "Coburg", "Landmark": "Coburg Ridge", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.11510086", "Long": "-123.00099945", "Precise": "1", "Callsign": "K7QT", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "119178", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-08" }, { "State ID": "41", "Rptr ID": "329", "Frequency": "441.67500", "Input Freq": "446.67500", "PL": "D023", "TSQ": "D023", "Nearest City": "Oakridge", "Landmark": "Wolf Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.61619949", "Long": "-122.23000336", "Precise": "1", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-11-09" }, { "State ID": "41", "Rptr ID": "331", "Frequency": "442.12500", "Input Freq": "447.12500", "PL": "D125", "TSQ": "D125", "Nearest City": "Eugene", "Landmark": "Coburg Ridge", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.13660049", "Long": "-123.01499939", "Precise": "1", "Callsign": "K7THO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "333", "Frequency": "442.57500", "Input Freq": "447.57500", "PL": "D125", "TSQ": "D125", "Nearest City": "Florence", "Landmark": "Herman Peak", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.12419891", "Long": "-124.01300049", "Precise": "1", "Callsign": "W7FLO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "Not connected to Wires-X.", "Last Update": "2020-04-23" }, { "State ID": "41", "Rptr ID": "335", "Frequency": "443.50000", "Input Freq": "448.50000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Horton", "Landmark": "Prairie Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.27999878", "Long": "-123.58300018", "Precise": "1", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,360 feet ASL.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "336", "Frequency": "443.80000", "Input Freq": "448.82500", "PL": "100.0", "TSQ": "", "Nearest City": "Eugene", "Landmark": "Blanton Heights", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00149918", "Long": "-123.11399841", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-08" }, { "State ID": "41", "Rptr ID": "352", "Frequency": "145.13000", "Input Freq": "144.53000", "PL": "D023", "TSQ": "D023", "Nearest City": "Junction City", "Landmark": "Prairie Peak", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.29100037", "Long": "-123.54100037", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "521741", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,510 feet ASL.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "438", "Frequency": "145.17000", "Input Freq": "144.57000", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Eugene", "Landmark": "Buck Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.19789886", "Long": "-122.98600006", "Precise": "1", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,130 feet elevation", "Last Update": "2021-04-13" }, { "State ID": "41", "Rptr ID": "471", "Frequency": "441.32500", "Input Freq": "446.32500", "PL": "D023", "TSQ": "D023", "Nearest City": "Eugene", "Landmark": "Coburg Ridge", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.11569977", "Long": "-123.00000000", "Precise": "1", "Callsign": "K7UND", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-22" }, { "State ID": "41", "Rptr ID": "485", "Frequency": "145.23000", "Input Freq": "144.63000", "PL": "110.9", "TSQ": "110.9", "Nearest City": "Cottage Grove", "Landmark": "Fairview Peak", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.58570099", "Long": "-122.65299988", "Precise": "1", "Callsign": "W7SLA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-06" }, { "State ID": "41", "Rptr ID": "486", "Frequency": "145.31000", "Input Freq": "144.71000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Walton", "Landmark": "Walker Point", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.06610107", "Long": "-123.62799835", "Precise": "1", "Callsign": "W7SLA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "2,325 feet.", "Last Update": "2021-10-16" }, { "State ID": "41", "Rptr ID": "528", "Frequency": "442.80000", "Input Freq": "447.80000", "PL": "77.0", "TSQ": "77.0", "Nearest City": "Eugene", "Landmark": "Blanton Heights", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00260162", "Long": "-123.11299896", "Precise": "1", "Callsign": "W7DTV", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,270 feet elevation", "Last Update": "2022-04-08" }, { "State ID": "41", "Rptr ID": "669", "Frequency": "442.90000", "Input Freq": "447.90000", "PL": "110.9", "TSQ": "110.9", "Nearest City": "Eugene", "Landmark": "Blanton Heights", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00260162", "Long": "-123.11299896", "Precise": "1", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Standalone repeater. 1,270'.", "Last Update": "2022-04-08" }, { "State ID": "41", "Rptr ID": "681", "Frequency": "145.45000", "Input Freq": "144.85000", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Eugene", "Landmark": "Blanton Heights", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00260162", "Long": "-123.11299896", "Precise": "1", "Callsign": "W7ARD", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "3088", "Frequency": "147.34000", "Input Freq": "147.94000", "PL": "D023", "TSQ": "D023", "Nearest City": "Blue River", "Landmark": "Mount Hagan", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.13890076", "Long": "-122.41100311", "Precise": "1", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-08" }, { "State ID": "41", "Rptr ID": "3713", "Frequency": "443.05000", "Input Freq": "448.05000", "PL": "100.0", "TSQ": "", "Nearest City": "Walton", "Landmark": "Walker Point", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.06650162", "Long": "-123.62899780", "Precise": "1", "Callsign": "W7ZQD", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "PL could be 162.2.", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "6369", "Frequency": "224.70000", "Input Freq": "223.10000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Coburg", "Landmark": "Buck Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.19765000", "Long": "-122.98650000", "Precise": "1", "Callsign": "W7EXH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,150 feet.", "Last Update": "2020-12-19" }, { "State ID": "41", "Rptr ID": "6780", "Frequency": "443.10000", "Input Freq": "448.10000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Blue River", "Landmark": "Mount Hagan", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.13890076", "Long": "-122.41100311", "Precise": "1", "Callsign": "K7SLA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "8243", "Frequency": "444.35000", "Input Freq": "449.35000", "PL": "173.8", "TSQ": "", "Nearest City": "Alsea", "Landmark": "Prairie Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.27999878", "Long": "-123.58100128", "Precise": "1", "Callsign": "W6PRN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-07-28" }, { "State ID": "41", "Rptr ID": "11144", "Frequency": "443.27500", "Input Freq": "448.27500", "PL": "100.0", "TSQ": "", "Nearest City": "Eugene", "Landmark": "", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.05210114", "Long": "-123.08699799", "Precise": "0", "Callsign": "W7EXH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-29" }, { "State ID": "41", "Rptr ID": "15421", "Frequency": "145.39000", "Input Freq": "144.79000", "PL": "D025", "TSQ": "D025", "Nearest City": "Cottage Grove", "Landmark": "Bear Mtn", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.84299850", "Long": "-122.89199829", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "3,699'.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "15427", "Frequency": "444.80000", "Input Freq": "449.80000", "PL": "D125", "TSQ": "", "Nearest City": "Blue River", "Landmark": "Mt Hagan", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.16159821", "Long": "-122.33599854", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "15428", "Frequency": "444.92500", "Input Freq": "449.92500", "PL": "D125", "TSQ": "", "Nearest City": "Walton", "Landmark": "Walker Point", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.10290146", "Long": "-123.59600067", "Precise": "0", "Callsign": "K7LNK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "15803", "Frequency": "147.14000", "Input Freq": "147.74000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Mapleton", "Landmark": "Roman Nose Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.91189957", "Long": "-123.73899841", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "15811", "Frequency": "443.57500", "Input Freq": "448.57500", "PL": "D125", "TSQ": "D125", "Nearest City": "Junction City", "Landmark": "Prairie Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.27999878", "Long": "-123.58300018", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "16997", "Frequency": "441.10000", "Input Freq": "446.10000", "PL": "D125", "TSQ": "D125", "Nearest City": "Florence", "Landmark": "Glenada Hill", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.95579910", "Long": "-124.07499695", "Precise": "0", "Callsign": "W7FLO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "30225", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "70", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2020-04-23" }, { "State ID": "41", "Rptr ID": "17131", "Frequency": "440.10000", "Input Freq": "445.10000", "PL": "110.9", "TSQ": "", "Nearest City": "Creswell", "Landmark": "", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.91790009", "Long": "-123.02500153", "Precise": "0", "Callsign": "N7NPA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-03-23" }, { "State ID": "41", "Rptr ID": "17134", "Frequency": "444.55000", "Input Freq": "449.55000", "PL": "100.0", "TSQ": "91.5", "Nearest City": "Cottage Grove", "Landmark": "Bear Mtn", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.98139954", "Long": "-123.00800323", "Precise": "0", "Callsign": "K7LNK", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "17136", "Frequency": "440.80000", "Input Freq": "445.80000", "PL": "103.5", "TSQ": "100.0", "Nearest City": "Blue River", "Landmark": "Mt Hagan", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.14229965", "Long": "-122.41200256", "Precise": "0", "Callsign": "", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "18574", "Frequency": "442.42500", "Input Freq": "447.42500", "PL": "67.0", "TSQ": "", "Nearest City": "Eugene", "Landmark": "", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.00260162", "Long": "-123.11329651", "Precise": "0", "Callsign": "W7OEC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311427", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Please be sure to disconnect from reflectors and talkgroups when you are done using them. Monitoring reflectors and talkgroups occupy the repeater, and lock it into one mode, preventing other modes from being activated by other users. Please be courteous.", "Last Update": "2022-07-05" }, { "State ID": "41", "Rptr ID": "19302", "Frequency": "442.70000", "Input Freq": "447.70000", "PL": "123.0", "TSQ": "", "Nearest City": "Eugene", "Landmark": "", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.98772300", "Long": "-123.06566400", "Precise": "0", "Callsign": "K7REA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "80142", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Use DG-ID TX01 for Wires-X access. This repeater is digital only, no FM analog voice. See web page on info linking to other repeaters (http://www.k7rea.com/).", "Last Update": "2021-04-21" }, { "State ID": "41", "Rptr ID": "19451", "Frequency": "444.45000", "Input Freq": "449.45000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Eugene", "Landmark": "", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.10770000", "Long": "-123.14920000", "Precise": "0", "Callsign": "KC7RJK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "3543", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "*Pause, pause first to see if others are using the machine or links. Then ID and make your call or link. *Use DTMF command *70 to see if the repeater is already linked to a node or reflector.
*DO identify before sending DTMF command tones.
", "Last Update": "2021-09-06" }, { "State ID": "41", "Rptr ID": "19472", "Frequency": "444.42500", "Input Freq": "449.42500", "PL": "", "TSQ": "", "Nearest City": "Eugene", "Landmark": "Santa Clara", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.10770000", "Long": "-123.14920000", "Precise": "0", "Callsign": "KC7RJK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314117", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-06" }, { "State ID": "41", "Rptr ID": "19650", "Frequency": "145.55000", "Input Freq": "145.55000", "PL": "", "TSQ": "", "Nearest City": "Eugene", "Landmark": "", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.03173840", "Long": "-123.10594360", "Precise": "1", "Callsign": "K7EZR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "55490", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-16" }, { "State ID": "41", "Rptr ID": "20395", "Frequency": "145.15000", "Input Freq": "144.55000", "PL": "146.2", "TSQ": "146.2", "Nearest City": "Cottage Grove", "Landmark": "Bear Mountain", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "43.84279500", "Long": "-122.89175900", "Precise": "0", "Callsign": "W7OC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-10-19" }, { "State ID": "41", "Rptr ID": "21259", "Frequency": "441.22500", "Input Freq": "446.22500", "PL": "127.3", "TSQ": "127.3", "Nearest City": "Blue River", "Landmark": "North Deathball Mt.", "County": "Lane", "State": "Oregon", "Country": "United States", "Lat": "44.13487500", "Long": "-122.27627600", "Precise": "0", "Callsign": "AI7NC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-17" }, { "State ID": "41", "Rptr ID": "342", "Frequency": "145.37000", "Input Freq": "144.77000", "PL": "167.9", "TSQ": "", "Nearest City": "Newport", "Landmark": "Cape Foulweather", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.77230072", "Long": "-124.07599640", "Precise": "1", "Callsign": "W7VTW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Telemetry Status: ", "Last Update": "2021-08-03" }, { "State ID": "41", "Rptr ID": "344", "Frequency": "147.00000", "Input Freq": "147.60000", "PL": "136.5", "TSQ": "", "Nearest City": "Waldport", "Landmark": "Table Mountain", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.46920013", "Long": "-123.84200287", "Precise": "1", "Callsign": "W7VTW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "2,800'.", "Last Update": "2020-08-05" }, { "State ID": "41", "Rptr ID": "345", "Frequency": "147.04000", "Input Freq": "147.64000", "PL": "100.0", "TSQ": "", "Nearest City": "Lincoln City", "Landmark": "", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.95830154", "Long": "-124.01699829", "Precise": "0", "Callsign": "W7VTW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "85 feet. ", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "347", "Frequency": "147.30000", "Input Freq": "147.90000", "PL": "156.7", "TSQ": "156.7", "Nearest City": "Newport", "Landmark": "Otter Crest", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.76119995", "Long": "-124.06500244", "Precise": "0", "Callsign": "W7VTW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "350", "Frequency": "444.47500", "Input Freq": "449.47500", "PL": "103.5", "TSQ": "", "Nearest City": "Waldport", "Landmark": "Table Mountain", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.46920013", "Long": "-123.84200287", "Precise": "1", "Callsign": "W7VTW", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-25" }, { "State ID": "41", "Rptr ID": "351", "Frequency": "444.75000", "Input Freq": "449.75000", "PL": "118.8", "TSQ": "", "Nearest City": "Newport", "Landmark": "Otter Crest", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.76119995", "Long": "-124.06500244", "Precise": "1", "Callsign": "W7GC", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Telemetry Status: ", "Last Update": "2020-09-25" }, { "State ID": "41", "Rptr ID": "13018", "Frequency": "145.39000", "Input Freq": "144.79000", "PL": "D023", "TSQ": "D023", "Nearest City": "Newport", "Landmark": "Otter Crest", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.63679886", "Long": "-124.05300140", "Precise": "0", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-09-24" }, { "State ID": "41", "Rptr ID": "21340", "Frequency": "147.06000", "Input Freq": "147.66000", "PL": "156.7", "TSQ": "CSQ", "Nearest City": "Yachats", "Landmark": "Cape Perpetua", "County": "Lincoln", "State": "Oregon", "Country": "United States", "Lat": "44.29359700", "Long": "-124.08066700", "Precise": "0", "Callsign": "N7HQR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-18" }, { "State ID": "41", "Rptr ID": "353", "Frequency": "146.61000", "Input Freq": "146.01000", "PL": "167.9", "TSQ": "", "Nearest City": "Scio", "Landmark": "Rodgers Mountain", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.68330002", "Long": "-122.77899933", "Precise": "1", "Callsign": "KA7ENW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "355", "Frequency": "147.20000", "Input Freq": "147.80000", "PL": "167.9", "TSQ": "167.9", "Nearest City": "Sweet Home", "Landmark": "Marks Ridge", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.44139862", "Long": "-122.73799896", "Precise": "1", "Callsign": "K7ENW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-01-08" }, { "State ID": "41", "Rptr ID": "357", "Frequency": "444.97500", "Input Freq": "449.97500", "PL": "100.0", "TSQ": "", "Nearest City": "Albany", "Landmark": "", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.61529922", "Long": "-123.15799713", "Precise": "1", "Callsign": "KD6VLR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "75954", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "220 feet ASL.", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "541", "Frequency": "442.85000", "Input Freq": "447.85000", "PL": "167.9", "TSQ": "", "Nearest City": "Scio", "Landmark": "Rodgers Mountain", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.68330002", "Long": "-122.77899933", "Precise": "1", "Callsign": "KA7ENW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,124 feet ASL.", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "5910", "Frequency": "147.06000", "Input Freq": "147.66000", "PL": "100.0", "TSQ": "", "Nearest City": "Lyons", "Landmark": "McCully Mountain", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.75730133", "Long": "-122.62400055", "Precise": "0", "Callsign": "W1ARK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Repeater elevation is 1,130 feet ASL.", "Last Update": "2021-09-12" }, { "State ID": "41", "Rptr ID": "6368", "Frequency": "440.60000", "Input Freq": "445.60000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Lyons", "Landmark": "McCulley Mountain", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.75730133", "Long": "-122.62400055", "Precise": "1", "Callsign": "KG7MKW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-12" }, { "State ID": "41", "Rptr ID": "10032", "Frequency": "444.82500", "Input Freq": "449.82500", "PL": "D023", "TSQ": "D023", "Nearest City": "Harrisburg", "Landmark": "Buck Mountain", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.27399826", "Long": "-123.17099762", "Precise": "0", "Callsign": "W7PRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "521741", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-09" }, { "State ID": "41", "Rptr ID": "13261", "Frequency": "147.26000", "Input Freq": "147.86000", "PL": "D026", "TSQ": "D026", "Nearest City": "Brownsville", "Landmark": "Scott Mountain", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.39870071", "Long": "-122.86399841", "Precise": "0", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "2,130'.", "Last Update": "2021-02-24" }, { "State ID": "41", "Rptr ID": "15216", "Frequency": "52.91000", "Input Freq": "51.21000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Sweet Home", "Landmark": "Marks Ridge", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.39759827", "Long": "-122.73600006", "Precise": "0", "Callsign": "KG7BZ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-15" }, { "State ID": "41", "Rptr ID": "15217", "Frequency": "443.12500", "Input Freq": "448.12500", "PL": "77.0", "TSQ": "77.0", "Nearest City": "Sweet Home", "Landmark": "Marks Ridge", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.39759827", "Long": "-122.73600006", "Precise": "0", "Callsign": "KG7BZ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-15" }, { "State ID": "41", "Rptr ID": "15218", "Frequency": "442.60000", "Input Freq": "447.60000", "PL": "D023", "TSQ": "D023", "Nearest City": "Brownsville", "Landmark": "Washburn Heights", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.39350128", "Long": "-122.98500061", "Precise": "0", "Callsign": "KB7KUB", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "23", "YSF DG IS Downlink": "23", "YSF DSC": "023", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "15451", "Frequency": "224.00000", "Input Freq": "222.40000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Brownsville", "Landmark": "Washburn Heights", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.43840027", "Long": "-122.98400116", "Precise": "1", "Callsign": "K7VFO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "1,280 feet.", "Last Update": "2021-06-09" }, { "State ID": "41", "Rptr ID": "17150", "Frequency": "147.30000", "Input Freq": "147.90000", "PL": "77.0", "TSQ": "", "Nearest City": "Brownsville", "Landmark": "", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.39350128", "Long": "-122.98500061", "Precise": "0", "Callsign": "W7WZA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "As Seen on Tiktok!!! https://www.tiktok.com/@trailertravis", "Last Update": "2021-01-27" }, { "State ID": "41", "Rptr ID": "18789", "Frequency": "443.25000", "Input Freq": "448.25000", "PL": "", "TSQ": "", "Nearest City": "Sweet Home", "Landmark": "", "County": "Linn", "State": "Oregon", "Country": "United States", "Lat": "44.39762470", "Long": "-122.73619580", "Precise": "0", "Callsign": "W7NK", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-13" }, { "State ID": "41", "Rptr ID": "10", "Frequency": "444.15000", "Input Freq": "449.15000", "PL": "100.0", "TSQ": "", "Nearest City": "Vale", "Landmark": "Malheur Butte", "County": "Malhuer", "State": "Oregon", "Country": "United States", "Lat": "44.00579834", "Long": "-117.05000305", "Precise": "1", "Callsign": "K7OJI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "360", "Frequency": "147.10000", "Input Freq": "147.70000", "PL": "100.0", "TSQ": "", "Nearest City": "Ontario", "Landmark": "Malheur Butte", "County": "Malhuer", "State": "Oregon", "Country": "United States", "Lat": "44.01110077", "Long": "-117.08399963", "Precise": "1", "Callsign": "K7OJI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "2,201 feet. ", "Last Update": "2021-09-19" }, { "State ID": "41", "Rptr ID": "549", "Frequency": "443.15000", "Input Freq": "448.15000", "PL": "100.0", "TSQ": "", "Nearest City": "Ontario", "Landmark": "", "County": "Malhuer", "State": "Oregon", "Country": "United States", "Lat": "44.02389908", "Long": "-116.96700287", "Precise": "1", "Callsign": "K7RHB", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "224189", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Incoming EchoLink connections restricted.", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "139", "Frequency": "441.37500", "Input Freq": "446.37500", "PL": "123.0", "TSQ": "", "Nearest City": "Salem", "Landmark": "", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94309998", "Long": "-123.03399658", "Precise": "0", "Callsign": "AB7F", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "365", "Frequency": "145.29000", "Input Freq": "144.69000", "PL": "", "TSQ": "", "Nearest City": "Salem", "Landmark": "", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94879913", "Long": "-122.93299866", "Precise": "1", "Callsign": "WA7ABU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "592473", "IRLP Node": "7638", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-10-10" }, { "State ID": "41", "Rptr ID": "367", "Frequency": "145.35000", "Input Freq": "144.75000", "PL": "CSQ", "TSQ": "CSQ", "Nearest City": "Salem", "Landmark": "Popcorn Hill", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94309998", "Long": "-123.03399658", "Precise": "0", "Callsign": "K7LWV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "312893", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-02-07" }, { "State ID": "41", "Rptr ID": "372", "Frequency": "441.27500", "Input Freq": "446.27500", "PL": "", "TSQ": "", "Nearest City": "Salem", "Landmark": "Prospect Hill", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.85459900", "Long": "-123.12200165", "Precise": "1", "Callsign": "W7SRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311450", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "375", "Frequency": "443.72500", "Input Freq": "448.72500", "PL": "186.2", "TSQ": "186.2", "Nearest City": "Salem", "Landmark": "Prospect Hill", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.85449982", "Long": "-123.12200165", "Precise": "1", "Callsign": "W7SRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "376", "Frequency": "444.25000", "Input Freq": "449.25000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Silverton", "Landmark": "Silver Falls", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.95080185", "Long": "-122.68699646", "Precise": "1", "Callsign": "W7SAA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "3292", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "377", "Frequency": "444.95000", "Input Freq": "449.95000", "PL": "100.0", "TSQ": "", "Nearest City": "Salem", "Landmark": "Silver Creek Falls", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "45.00529861", "Long": "-122.78199768", "Precise": "0", "Callsign": "WA7ABU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "592473", "IRLP Node": "7638", "Wires Node": "11977", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "MCARES emergency repeater.", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "382", "Frequency": "146.86000", "Input Freq": "146.26000", "PL": "186.2", "TSQ": "", "Nearest City": "Salem", "Landmark": "Prospect Hill", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.85459900", "Long": "-123.12200165", "Precise": "1", "Callsign": "W7SRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-21" }, { "State ID": "41", "Rptr ID": "427", "Frequency": "145.49000", "Input Freq": "144.89000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Salem", "Landmark": "Prospect Hill", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.84730148", "Long": "-123.11100006", "Precise": "1", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "521741", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-07-09" }, { "State ID": "41", "Rptr ID": "447", "Frequency": "441.70000", "Input Freq": "446.70000", "PL": "186.2", "TSQ": "", "Nearest City": "Salem", "Landmark": "Popcorn Hill", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94290161", "Long": "-123.03500366", "Precise": "0", "Callsign": "K7UN", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "503", "Frequency": "224.16000", "Input Freq": "222.56000", "PL": "100.0", "TSQ": "", "Nearest City": "Silverton", "Landmark": "Silver Falls", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.85120010", "Long": "-122.64600372", "Precise": "0", "Callsign": "W7BJH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-06-13" }, { "State ID": "41", "Rptr ID": "670", "Frequency": "443.17500", "Input Freq": "448.17500", "PL": "88.5", "TSQ": "88.5", "Nearest City": "Salem", "Landmark": "CCC", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94309998", "Long": "-123.03399658", "Precise": "0", "Callsign": "AD7ET", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-21" }, { "State ID": "41", "Rptr ID": "6019", "Frequency": "145.19000", "Input Freq": "144.59000", "PL": "100.0", "TSQ": "", "Nearest City": "Gates", "Landmark": "", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "45.00299835", "Long": "-122.78199768", "Precise": "1", "Callsign": "WA7ABU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "8240", "Frequency": "441.17500", "Input Freq": "446.17500", "PL": "77.0", "TSQ": "77.0", "Nearest City": "Salem", "Landmark": "Prospect Hill", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.84700012", "Long": "-123.11100006", "Precise": "1", "Callsign": "W7DTV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "11139", "Frequency": "440.27500", "Input Freq": "445.27500", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Salem", "Landmark": "", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94290161", "Long": "-123.03500366", "Precise": "0", "Callsign": "AC7RF", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "11753", "Frequency": "147.34000", "Input Freq": "147.94000", "PL": "77.0", "TSQ": "", "Nearest City": "Silverton", "Landmark": "Silver Falls", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.89989853", "Long": "-122.64399719", "Precise": "0", "Callsign": "W7SAA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-08-01" }, { "State ID": "41", "Rptr ID": "13350", "Frequency": "440.72500", "Input Freq": "445.72500", "PL": "", "TSQ": "", "Nearest City": "Salem", "Landmark": "", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.93460083", "Long": "-122.97299957", "Precise": "1", "Callsign": "KB7PPM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "40143", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-05" }, { "State ID": "41", "Rptr ID": "18780", "Frequency": "440.05000", "Input Freq": "445.05000", "PL": "100.0", "TSQ": "", "Nearest City": "Salem", "Landmark": "", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94289750", "Long": "-123.03509630", "Precise": "0", "Callsign": "K7RTL", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-21" }, { "State ID": "41", "Rptr ID": "18783", "Frequency": "440.86250", "Input Freq": "445.86250", "PL": "", "TSQ": "", "Nearest City": "Salem", "Landmark": "", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.94289750", "Long": "-123.03509630", "Precise": "0", "Callsign": "KB7PPM", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Per Trustee: XLX 289 - This repeater will be ON-AIR for approximately one(1) month (from 06 September 2021 to 06 October 2021). It will be bridged to YSF 32398.", "Last Update": "2021-09-06" }, { "State ID": "41", "Rptr ID": "19700", "Frequency": "442.97500", "Input Freq": "447.97500", "PL": "", "TSQ": "", "Nearest City": "Mill City", "Landmark": "House Mountain", "County": "Marion", "State": "Oregon", "Country": "United States", "Lat": "44.75583330", "Long": "-122.46944440", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "310151", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-31" }, { "State ID": "41", "Rptr ID": "378", "Frequency": "146.62000", "Input Freq": "146.02000", "PL": "88.5", "TSQ": "", "Nearest City": "Heppner", "Landmark": "Black Mtn", "County": "Morrow", "State": "Oregon", "Country": "United States", "Lat": "45.21319962", "Long": "-119.29499817", "Precise": "1", "Callsign": "W7URG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Limit talk time in winter months due to solar power.", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "379", "Frequency": "146.78000", "Input Freq": "146.18000", "PL": "67.0", "TSQ": "", "Nearest City": "Heppner", "Landmark": "Black Mountain", "County": "Morrow", "State": "Oregon", "Country": "United States", "Lat": "45.21319962", "Long": "-119.29499817", "Precise": "1", "Callsign": "KC7SOY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "Yes", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "12904", "Frequency": "147.16000", "Input Freq": "147.76000", "PL": "", "TSQ": "", "Nearest City": "Boardman", "Landmark": "Coalfire plant", "County": "Morrow", "State": "Oregon", "Country": "United States", "Lat": "45.83990097", "Long": "-119.70099640", "Precise": "0", "Callsign": "AI7HO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-04-22" }, { "State ID": "41", "Rptr ID": "14694", "Frequency": "145.23000", "Input Freq": "144.63000", "PL": "67.0", "TSQ": "CSQ", "Nearest City": "Heppner", "Landmark": "Black Mountain", "County": "Morrow", "State": "Oregon", "Country": "United States", "Lat": "45.21319962", "Long": "-119.29499810", "Precise": "1", "Callsign": "KC7SOY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Primarily used for packet traffic.", "Last Update": "2022-03-20" }, { "State ID": "41", "Rptr ID": "18138", "Frequency": "444.85000", "Input Freq": "449.85000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Heppner", "Landmark": "", "County": "Morrow", "State": "Oregon", "Country": "United States", "Lat": "45.35319901", "Long": "-119.55799866", "Precise": "1", "Callsign": "WB7ILL", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "40289", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "20362", "Frequency": "145.37000", "Input Freq": "144.77000", "PL": "D073", "TSQ": "D073", "Nearest City": "Heppner", "Landmark": "", "County": "Morrow", "State": "Oregon", "Country": "United States", "Lat": "45.21304588", "Long": "-119.29673700", "Precise": "1", "Callsign": "W7NEO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "40289", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-10-18" }, { "State ID": "41", "Rptr ID": "43", "Frequency": "443.55000", "Input Freq": "448.55000", "PL": "100.0", "TSQ": "", "Nearest City": "Portland", "Landmark": "Garden Home", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.45989990", "Long": "-122.73400116", "Precise": "1", "Callsign": "K7GDS", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "52", "Frequency": "145.23000", "Input Freq": "144.63000", "PL": "CSQ", "TSQ": "123.0", "Nearest City": "Portland", "Landmark": "Council Crest", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.49829865", "Long": "-122.70800018", "Precise": "1", "Callsign": "K7LJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-27" }, { "State ID": "41", "Rptr ID": "57", "Frequency": "145.39000", "Input Freq": "144.79000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "Mt Tabor", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51219940", "Long": "-122.59400177", "Precise": "1", "Callsign": "K7LJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-24" }, { "State ID": "41", "Rptr ID": "58", "Frequency": "146.70000", "Input Freq": "146.10000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "Stonehenge Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.48920059", "Long": "-122.69599915", "Precise": "1", "Callsign": "KE7AWR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "574925", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "1,485', 80 watts.", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "62", "Frequency": "146.98000", "Input Freq": "146.38000", "PL": "D023", "TSQ": "D023", "Nearest City": "Portland", "Landmark": "KGW Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52230072", "Long": "-122.74700165", "Precise": "1", "Callsign": "N7EXH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "47178", "EchoLink Node": "256957", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Allstar requires admin approval.", "Last Update": "2022-11-27" }, { "State ID": "41", "Rptr ID": "63", "Frequency": "147.04000", "Input Freq": "147.64000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "Sylvan TV Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51589966", "Long": "-122.73400116", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "7959", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "850', 500 watts ERP.", "Last Update": "2021-01-16" }, { "State ID": "41", "Rptr ID": "72", "Frequency": "440.35000", "Input Freq": "445.35000", "PL": "127.3", "TSQ": "127.3", "Nearest City": "Portland", "Landmark": "Stonehenge Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.48920059", "Long": "-122.69599915", "Precise": "1", "Callsign": "KB7OYI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-23" }, { "State ID": "41", "Rptr ID": "73", "Frequency": "440.40000", "Input Freq": "445.40000", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Portland", "Landmark": "KOIN Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51557939", "Long": "-122.73307750", "Precise": "1", "Callsign": "W7RAT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "3039", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "75", "Frequency": "440.45000", "Input Freq": "445.45000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52220154", "Long": "-122.74700165", "Precise": "1", "Callsign": "N7PIR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "132225", "IRLP Node": "3420", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-23" }, { "State ID": "41", "Rptr ID": "81", "Frequency": "441.35000", "Input Freq": "446.35000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52239990", "Long": "-122.74700165", "Precise": "1", "Callsign": "W7EXH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "82", "Frequency": "442.02500", "Input Freq": "447.02500", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "West Hills", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52379990", "Long": "-122.75299835", "Precise": "0", "Callsign": "N7NLL", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "83", "Frequency": "442.22500", "Input Freq": "447.22500", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Portland", "Landmark": "Sylvan KOIN Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51589966", "Long": "-122.73400116", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "758452", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "88", "Frequency": "443.22500", "Input Freq": "448.22500", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Portland", "Landmark": "", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52360153", "Long": "-122.67500305", "Precise": "0", "Callsign": "W7PMC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "91", "Frequency": "443.62500", "Input Freq": "448.62500", "PL": "77.0", "TSQ": "77.0", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52239990", "Long": "-122.74700165", "Precise": "1", "Callsign": "W7DTV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "96", "Frequency": "440.47500", "Input Freq": "445.47500", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Portland", "Landmark": "OHSU", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.50079953", "Long": "-122.68613440", "Precise": "1", "Callsign": "K0HSU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "42", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Linked full time to K0HSU repeater at OHSU West Campus in Beaverton/Hillsboro. Both analog FM and YSF Digital.", "Last Update": "2022-12-23" }, { "State ID": "41", "Rptr ID": "426", "Frequency": "145.41000", "Input Freq": "144.81000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Corbett", "Landmark": "Lookout Point", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.48379898", "Long": "-122.12799835", "Precise": "1", "Callsign": "N7LF", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-27" }, { "State ID": "41", "Rptr ID": "455", "Frequency": "442.70000", "Input Freq": "447.70000", "PL": "100.0", "TSQ": "", "Nearest City": "Portland", "Landmark": "OHSU", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.49919891", "Long": "-122.68499756", "Precise": "1", "Callsign": "K7LTA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-23" }, { "State ID": "41", "Rptr ID": "459", "Frequency": "442.65000", "Input Freq": "447.65000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "Council Crest", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.48889923", "Long": "-122.70099640", "Precise": "1", "Callsign": "K7LJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-23" }, { "State ID": "41", "Rptr ID": "507", "Frequency": "440.82500", "Input Freq": "445.82500", "PL": "110.9", "TSQ": "110.9", "Nearest City": "Portland", "Landmark": "Emanuel Hospital", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52999878", "Long": "-122.69799805", "Precise": "1", "Callsign": "K7LHS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "40 watts.", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "524", "Frequency": "927.12500", "Input Freq": "902.12500", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Portland", "Landmark": "KGW Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52230072", "Long": "-122.74700165", "Precise": "1", "Callsign": "K7QDX", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "42215", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Repeater is linked full-time to the 927-Tech reflector", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "655", "Frequency": "443.30000", "Input Freq": "448.30000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "Council Crest", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51589966", "Long": "-122.73400116", "Precise": "1", "Callsign": "K7LJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "599934", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2023-01-13" }, { "State ID": "41", "Rptr ID": "660", "Frequency": "145.31000", "Input Freq": "144.71000", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52239990", "Long": "-122.74700165", "Precise": "1", "Callsign": "N7EXH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-27" }, { "State ID": "41", "Rptr ID": "671", "Frequency": "440.20000", "Input Freq": "445.20000", "PL": "100.0", "TSQ": "", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52239990", "Long": "-122.74700165", "Precise": "1", "Callsign": "N7BAR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "5464", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "686", "Frequency": "147.14000", "Input Freq": "147.74000", "PL": "107.2", "TSQ": "", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52230072", "Long": "-122.74700165", "Precise": "1", "Callsign": "W7AC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "CARES 1st Alternate Repeater.", "Last Update": "2021-01-16" }, { "State ID": "41", "Rptr ID": "3505", "Frequency": "444.80000", "Input Freq": "449.80000", "PL": "107.2", "TSQ": "", "Nearest City": "Portland", "Landmark": "", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52349854", "Long": "-122.67600250", "Precise": "0", "Callsign": "N7PRM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "6628", "Frequency": "443.05000", "Input Freq": "448.05000", "PL": "", "TSQ": "", "Nearest City": "Portland", "Landmark": "Stonehenge Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.48920059", "Long": "-122.69599915", "Precise": "1", "Callsign": "WA7BND", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "11998", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "Yaesu WIRES-X is linked to this repeater. Tune in and learn about C4FM digital. Enjoy", "Last Update": "2022-11-27" }, { "State ID": "41", "Rptr ID": "8239", "Frequency": "443.20000", "Input Freq": "448.20000", "PL": "173.8", "TSQ": "", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.60570145", "Long": "-122.83300018", "Precise": "1", "Callsign": "K6PRN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Receive antenna issues", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "14723", "Frequency": "442.25000", "Input Freq": "447.25000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Portland", "Landmark": "Skyline Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52289963", "Long": "-122.75299835", "Precise": "1", "Callsign": "WB1ARB", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "", "Last Update": "2022-11-13" }, { "State ID": "41", "Rptr ID": "14941", "Frequency": "444.67500", "Input Freq": "449.67500", "PL": "100.0", "TSQ": "", "Nearest City": "Portland", "Landmark": "Council Crest", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.49900055", "Long": "-122.70800018", "Precise": "0", "Callsign": "W7PGE", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "15199", "Frequency": "440.62500", "Input Freq": "445.62500", "PL": "Restricted", "TSQ": "Restricted", "Nearest City": "Portland", "Landmark": "West Hills", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.50519943", "Long": "-122.70600128", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314102", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-18" }, { "State ID": "41", "Rptr ID": "15431", "Frequency": "440.50000", "Input Freq": "445.50000", "PL": "D125", "TSQ": "D125", "Nearest City": "Portland", "Landmark": "KGW Tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52230072", "Long": "-122.74700165", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "15504", "Frequency": "443.10000", "Input Freq": "448.10000", "PL": "", "TSQ": "", "Nearest City": "Corbett", "Landmark": "Lookout Point", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.53179932", "Long": "-122.29100037", "Precise": "1", "Callsign": "N7LF", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "312435", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Connected to PNW Digital System. Visit PNWDigital.net for further info on supported TG.", "Last Update": "2021-04-13" }, { "State ID": "41", "Rptr ID": "17145", "Frequency": "443.27500", "Input Freq": "448.27500", "PL": "167.9", "TSQ": "167.9", "Nearest City": "Portland", "Landmark": "Healy Heights", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.48929977", "Long": "-122.69699860", "Precise": "1", "Callsign": "KA7AGH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-12" }, { "State ID": "41", "Rptr ID": "17154", "Frequency": "1249.75000", "Input Freq": "1229.75000", "PL": "", "TSQ": "", "Nearest City": "Portland", "Landmark": "", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51219940", "Long": "-122.65899658", "Precise": "0", "Callsign": "KG7KOU", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "18063", "Frequency": "444.83750", "Input Freq": "449.83750", "PL": "", "TSQ": "", "Nearest City": "Portland", "Landmark": "Providence Portland Medical Center", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52861111", "Long": "-122.61333330", "Precise": "1", "Callsign": "WA7HAA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "7", "DMR ID": "310395", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Open use. Connected to PNW Digital System. Visit PNWDigital.net for further info on supported TG's and other important info.", "Last Update": "2021-03-26" }, { "State ID": "41", "Rptr ID": "18665", "Frequency": "443.07500", "Input Freq": "448.07500", "PL": "", "TSQ": "", "Nearest City": "Gresham", "Landmark": "Hospital", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51682050", "Long": "-122.40688330", "Precise": "1", "Callsign": "N7LF", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314103", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Connected to PNW Digital System. Visit PNWDigital.net for further info on supported TG.", "Last Update": "2021-03-26" }, { "State ID": "41", "Rptr ID": "18737", "Frequency": "440.51250", "Input Freq": "445.51250", "PL": "", "TSQ": "", "Nearest City": "Portland", "Landmark": "Sylvan KOIN tower", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.50510640", "Long": "-122.67502610", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311391", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Open use. Connected to PNW Digital System. Visit PNWDigital.net for further info on supported TG.", "Last Update": "2021-03-04" }, { "State ID": "41", "Rptr ID": "19825", "Frequency": "443.25000", "Input Freq": "448.25000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Gresham", "Landmark": "Legacy Mount Hood Medical Cntr", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51663900", "Long": "-122.40736100", "Precise": "1", "Callsign": "N7KOJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Everyone is welcome to use this open repeater. This repeater is not yet listed in the ORRC online database.", "Last Update": "2021-02-28" }, { "State ID": "41", "Rptr ID": "20396", "Frequency": "440.15000", "Input Freq": "445.15000", "PL": "", "TSQ": "", "Nearest City": "Portland", "Landmark": "Skyline", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.52220154", "Long": "-122.74700165", "Precise": "1", "Callsign": "K7KSN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "5", "DMR ID": "315338", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-10-18" }, { "State ID": "41", "Rptr ID": "20709", "Frequency": "927.15000", "Input Freq": "902.15000", "PL": "", "TSQ": "", "Nearest City": "Portland", "Landmark": "downtown", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.49687050", "Long": "-122.68376800", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "310392", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-10" }, { "State ID": "41", "Rptr ID": "20710", "Frequency": "440.01250", "Input Freq": "445.01250", "PL": "", "TSQ": "", "Nearest City": "Portland", "Landmark": "OHSU", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.49836790", "Long": "-122.68534590", "Precise": "1", "Callsign": "K7CLL", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-10" }, { "State ID": "41", "Rptr ID": "20711", "Frequency": "440.77500", "Input Freq": "445.77500", "PL": "Restricted", "TSQ": "Restricted", "Nearest City": "Portland", "Landmark": "", "County": "Multnomah", "State": "Oregon", "Country": "United States", "Lat": "45.51523200", "Long": "-122.67838530", "Precise": "0", "Callsign": "KB7APU", "Use": "CLOSED", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "ARES and SAR repeater traffic only.", "Last Update": "2022-03-10" }, { "State ID": "41", "Rptr ID": "366", "Frequency": "145.33000", "Input Freq": "144.73000", "PL": "186.2", "TSQ": "186.2", "Nearest City": "Salem", "Landmark": "Eagle Crest", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.98640060", "Long": "-123.13300323", "Precise": "1", "Callsign": "W7SRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Swaptoberfest Talk-in Frequency", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "383", "Frequency": "147.02000", "Input Freq": "147.62000", "PL": "186.2", "TSQ": "186.2", "Nearest City": "Falls City", "Landmark": "Laurel Mountain", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.92340088", "Long": "-123.57299805", "Precise": "1", "Callsign": "W7SRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "520", "Frequency": "442.50000", "Input Freq": "447.50000", "PL": "100.0", "TSQ": "", "Nearest City": "Salem", "Landmark": "", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.94290161", "Long": "-123.03500366", "Precise": "0", "Callsign": "W7BJH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "100 watts.", "Last Update": "2022-06-13" }, { "State ID": "41", "Rptr ID": "2783", "Frequency": "927.70000", "Input Freq": "902.70000", "PL": "162.2", "TSQ": "", "Nearest City": "Monmouth", "Landmark": "", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.84859848", "Long": "-123.23300171", "Precise": "0", "Callsign": "KE7AAJ", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "0000-00-00" }, { "State ID": "41", "Rptr ID": "6773", "Frequency": "224.60000", "Input Freq": "223.00000", "PL": "100.0", "TSQ": "", "Nearest City": "Salem", "Landmark": "", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.94290161", "Long": "-123.03500366", "Precise": "0", "Callsign": "W7BJH", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-06-13" }, { "State ID": "41", "Rptr ID": "8071", "Frequency": "440.07500", "Input Freq": "445.07500", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Salem", "Landmark": "Bald Hill (Eagle Crest)", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.98389816", "Long": "-123.14399719", "Precise": "1", "Callsign": "N7PIR", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "132225", "IRLP Node": "3420", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "11905", "Frequency": "224.92000", "Input Freq": "223.32000", "PL": "136.5", "TSQ": "", "Nearest City": "Salem", "Landmark": "Salem Hills", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.94290161", "Long": "-123.03500366", "Precise": "0", "Callsign": "W6WHD", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "40676", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Usually connected via Allstar to node 45830.", "Last Update": "2022-12-07" }, { "State ID": "41", "Rptr ID": "14576", "Frequency": "442.45000", "Input Freq": "447.45000", "PL": "D125", "TSQ": "D125", "Nearest City": "Salem", "Landmark": "Eagle Crest", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "44.98450089", "Long": "-123.14299774", "Precise": "0", "Callsign": "AB7BS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "17725", "Frequency": "146.66000", "Input Freq": "146.06000", "PL": "136.5", "TSQ": "91.5", "Nearest City": "Grande Ronde", "Landmark": "", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "45.07870102", "Long": "-123.48600006", "Precise": "0", "Callsign": "W7GRT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-25" }, { "State ID": "41", "Rptr ID": "17795", "Frequency": "442.82500", "Input Freq": "447.82500", "PL": "123.0", "TSQ": "", "Nearest City": "Grande Ronde", "Landmark": "Spirit Mtn Casino", "County": "Polk", "State": "Oregon", "Country": "United States", "Lat": "45.05824470", "Long": "-123.58170040", "Precise": "1", "Callsign": "W7GRT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "114", "Frequency": "145.27000", "Input Freq": "144.67000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Timber", "Landmark": "", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.72000122", "Long": "-123.29299927", "Precise": "0", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-08-14" }, { "State ID": "41", "Rptr ID": "230", "Frequency": "440.17500", "Input Freq": "445.17500", "PL": "100.0", "TSQ": "", "Nearest City": "Manzanita", "Landmark": "Angora Peak", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.78779984", "Long": "-123.91899872", "Precise": "1", "Callsign": "W7EM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-21" }, { "State ID": "41", "Rptr ID": "386", "Frequency": "147.22000", "Input Freq": "147.82000", "PL": "100.0", "TSQ": "", "Nearest City": "Hebo", "Landmark": "Mt Hebo", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.21480179", "Long": "-123.75499725", "Precise": "0", "Callsign": "W7LI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "389", "Frequency": "440.90000", "Input Freq": "445.90000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Hebo", "Landmark": "Mt Hebo", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.21480179", "Long": "-123.75499725", "Precise": "1", "Callsign": "W7GC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": " Telemetry Status: ", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "390", "Frequency": "441.25000", "Input Freq": "446.25000", "PL": "118.8", "TSQ": "", "Nearest City": "Hebo", "Landmark": "Mt Hebo", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.21799850", "Long": "-123.75499725", "Precise": "0", "Callsign": "W7LI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "391", "Frequency": "441.30000", "Input Freq": "446.30000", "PL": "100.0", "TSQ": "", "Nearest City": "Hebo", "Landmark": "Mt Hebo", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.21480179", "Long": "-123.75499725", "Precise": "1", "Callsign": "W7EM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "266640", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "393", "Frequency": "442.75000", "Input Freq": "447.75000", "PL": "118.8", "TSQ": "", "Nearest City": "Rockaway Beach", "Landmark": "", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.61360168", "Long": "-123.94200134", "Precise": "1", "Callsign": "W7GC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Telemetry Status: ", "Last Update": "2020-09-25" }, { "State ID": "41", "Rptr ID": "518", "Frequency": "443.07500", "Input Freq": "448.07500", "PL": "167.9", "TSQ": "", "Nearest City": "Hebo", "Landmark": "Mt Hebo", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.21480179", "Long": "-123.75499725", "Precise": "1", "Callsign": "WB7QIW", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "665", "Frequency": "440.52500", "Input Freq": "445.52500", "PL": "77.0", "TSQ": "", "Nearest City": "Tillamook", "Landmark": "Triangulation Point", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.63150024", "Long": "-123.64399719", "Precise": "1", "Callsign": "W7EM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-21" }, { "State ID": "41", "Rptr ID": "5174", "Frequency": "147.39000", "Input Freq": "147.99000", "PL": "", "TSQ": "", "Nearest City": "Hebo", "Landmark": "Mt Hebo", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.21480179", "Long": "-123.75499725", "Precise": "1", "Callsign": "W7GC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "15198", "Frequency": "442.81250", "Input Freq": "447.81250", "PL": "Restricted", "TSQ": "Restricted", "Nearest City": "Hebo", "Landmark": "Mt Hebo", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.22669983", "Long": "-123.84799957", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314106", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-18" }, { "State ID": "41", "Rptr ID": "18791", "Frequency": "444.42500", "Input Freq": "449.42500", "PL": "107.2", "TSQ": "", "Nearest City": "Manzanita", "Landmark": "", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.72398400", "Long": "-123.93282700", "Precise": "1", "Callsign": "W7MOC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-09-25" }, { "State ID": "41", "Rptr ID": "21214", "Frequency": "442.12500", "Input Freq": "447.12500", "PL": "123.0", "TSQ": "", "Nearest City": "Manzanita", "Landmark": "Neahkahnie Mtn", "County": "Tillamook", "State": "Oregon", "Country": "United States", "Lat": "45.74399570", "Long": "-123.94096950", "Precise": "1", "Callsign": "W7MOC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-12" }, { "State ID": "41", "Rptr ID": "397", "Frequency": "146.80000", "Input Freq": "146.20000", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Elgin", "Landmark": "Spout Springs Ski Resort", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.74670029", "Long": "-118.03700256", "Precise": "1", "Callsign": "WF7S", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "Open", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "398", "Frequency": "145.33000", "Input Freq": "144.73000", "PL": "103.5", "TSQ": "", "Nearest City": "Pendleton", "Landmark": "Deadman Pass", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.60100174", "Long": "-118.50399780", "Precise": "0", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "108 watts ERP, 3,606'.", "Last Update": "2021-02-21" }, { "State ID": "41", "Rptr ID": "399", "Frequency": "146.88000", "Input Freq": "146.28000", "PL": "D073", "TSQ": "D073", "Nearest City": "Pendleton", "Landmark": "Cabbage Hill", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.55459976", "Long": "-118.61100006", "Precise": "1", "Callsign": "W7NEO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "405", "Frequency": "147.28000", "Input Freq": "147.88000", "PL": "", "TSQ": "", "Nearest City": "Milton-Freewater", "Landmark": "Pikes Peak", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.98429871", "Long": "-118.16899872", "Precise": "1", "Callsign": "KD7DDQ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "RF Linked to the AK2O 223.9 mhz hub repeater on Stensgar Mt. using yagi antenna.", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "406", "Frequency": "224.56000", "Input Freq": "222.96000", "PL": "CSQ", "TSQ": "", "Nearest City": "Pendleton", "Landmark": "Cabbage Hill", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.55459976", "Long": "-118.61100006", "Precise": "1", "Callsign": "N7NKT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "408", "Frequency": "444.65000", "Input Freq": "449.65000", "PL": "CSQ", "TSQ": "", "Nearest City": "Weston", "Landmark": "Waldo Mountain", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.80640030", "Long": "-118.33499908", "Precise": "1", "Callsign": "N7DWC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-13" }, { "State ID": "41", "Rptr ID": "410", "Frequency": "444.95000", "Input Freq": "449.95000", "PL": "136.5", "TSQ": "", "Nearest City": "Ukiah", "Landmark": "Carney Butte", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.28099823", "Long": "-118.94899750", "Precise": "1", "Callsign": "W7URG", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "900 Watts ERP. Blue Mountains Outback areas for Deer and Elk hunters.", "Last Update": "2021-09-27" }, { "State ID": "41", "Rptr ID": "411", "Frequency": "444.97500", "Input Freq": "449.97500", "PL": "", "TSQ": "", "Nearest City": "Pendleton", "Landmark": "Cabbage Hill", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.58549881", "Long": "-118.58200073", "Precise": "1", "Callsign": "W7NEO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "40289", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "0", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "413", "Frequency": "927.50000", "Input Freq": "902.50000", "PL": "", "TSQ": "", "Nearest City": "Pendleton", "Landmark": "Cabbage Hill", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.58549881", "Long": "-118.58200073", "Precise": "1", "Callsign": "N7ERT", "Use": "CLOSED", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Closed repeater. PL withheld by request.", "Last Update": "0000-00-00" }, { "State ID": "41", "Rptr ID": "5176", "Frequency": "441.95000", "Input Freq": "446.95000", "PL": "", "TSQ": "", "Nearest City": "Hermiston", "Landmark": "", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.84040070", "Long": "-119.28900146", "Precise": "0", "Callsign": "W7URG", "Use": "OPEN", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-01" }, { "State ID": "41", "Rptr ID": "15461", "Frequency": "147.04000", "Input Freq": "147.64000", "PL": "", "TSQ": "", "Nearest City": "Athena", "Landmark": "Weston Mountain", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.80049896", "Long": "-118.37799835", "Precise": "0", "Callsign": "W7NEO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "40289", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "none", "Notes": "", "Last Update": "2022-08-17" }, { "State ID": "41", "Rptr ID": "16922", "Frequency": "441.70000", "Input Freq": "446.70000", "PL": "131.8", "TSQ": "131.8", "Nearest City": "Athena", "Landmark": "Weston Mtn", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.80049896", "Long": "-118.37799835", "Precise": "1", "Callsign": "W7NEO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-02-22" }, { "State ID": "41", "Rptr ID": "17814", "Frequency": "443.80000", "Input Freq": "448.80000", "PL": "118.8", "TSQ": "118.8", "Nearest City": "Hermiston", "Landmark": "", "County": "Umatilla", "State": "Oregon", "Country": "United States", "Lat": "45.85459900", "Long": "-119.27999878", "Precise": "1", "Callsign": "WB7ILL", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "40289", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-06" }, { "State ID": "41", "Rptr ID": "414", "Frequency": "145.15000", "Input Freq": "144.55000", "PL": "110.9", "TSQ": "110.9", "Nearest City": "La Grande", "Landmark": "Mount Emily", "County": "Union", "State": "Oregon", "Country": "United States", "Lat": "45.43739025", "Long": "-118.09203014", "Precise": "1", "Callsign": "K7UNI", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "Yes", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2023-01-03" }, { "State ID": "41", "Rptr ID": "417", "Frequency": "147.26000", "Input Freq": "147.86000", "PL": "103.5", "TSQ": "", "Nearest City": "La Grande", "Landmark": "Mount Fanny", "County": "Union", "State": "Oregon", "Country": "United States", "Lat": "45.30789948", "Long": "-117.73000336", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "420", "Frequency": "444.92500", "Input Freq": "449.92500", "PL": "146.2", "TSQ": "146.2", "Nearest City": "La Grande", "Landmark": "Mount Harris", "County": "Union", "State": "Oregon", "Country": "United States", "Lat": "45.44039917", "Long": "-117.89299774", "Precise": "1", "Callsign": "KF7GOR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "727358", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "This system has a remote base on 147.500 MHz Simplex Tone 146.2. Remote base works on Echolink and is always on. ", "Last Update": "2021-11-22" }, { "State ID": "41", "Rptr ID": "13817", "Frequency": "146.98000", "Input Freq": "146.38000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "La Grande", "Landmark": "Grande Ronde Hospital", "County": "Union", "State": "Oregon", "Country": "United States", "Lat": "45.31969833", "Long": "-118.10600281", "Precise": "0", "Callsign": "W7GRA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "30274", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "**NEWS***12/20/19: Wires-X is back online.", "Last Update": "2019-12-30" }, { "State ID": "41", "Rptr ID": "19450", "Frequency": "145.29000", "Input Freq": "144.69000", "PL": "", "TSQ": "", "Nearest City": "Ukiah", "Landmark": "Tower Mt", "County": "Union", "State": "Oregon", "Country": "United States", "Lat": "45.03048100", "Long": "-118.34054000", "Precise": "0", "Callsign": "W7NEO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "40289", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-24" }, { "State ID": "41", "Rptr ID": "2990", "Frequency": "147.00000", "Input Freq": "147.60000", "PL": "103.5", "TSQ": "103.5", "Nearest City": "Joseph", "Landmark": "", "County": "Wallowa", "State": "Oregon", "Country": "United States", "Lat": "45.38859940", "Long": "-117.23300171", "Precise": "1", "Callsign": "KB7DZR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "323569", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Open for any use and everyone is welcome on this system.", "Last Update": "2022-11-13" }, { "State ID": "41", "Rptr ID": "11147", "Frequency": "444.78750", "Input Freq": "449.78750", "PL": "", "TSQ": "", "Nearest City": "Joseph", "Landmark": "", "County": "Wallowa", "State": "Oregon", "Country": "United States", "Lat": "45.38859940", "Long": "-117.23300171", "Precise": "1", "Callsign": "KB7DZR", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "312685", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "This system is open and can be linked to any talk group or private call. Please use talk group 312685 WC on time slot 1 for local communications. Remote users can link to this talk group also.", "Last Update": "2022-08-15" }, { "State ID": "41", "Rptr ID": "421", "Frequency": "146.74000", "Input Freq": "146.14000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "The Dalles", "Landmark": "", "County": "Wasco", "State": "Oregon", "Country": "United States", "Lat": "45.59469986", "Long": "-121.17700195", "Precise": "0", "Callsign": "KC7LDD", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-08-14" }, { "State ID": "41", "Rptr ID": "3090", "Frequency": "147.26000", "Input Freq": "147.86000", "PL": "82.5", "TSQ": "", "Nearest City": "Dufur", "Landmark": "Tygh Ridge", "County": "Wasco", "State": "Oregon", "Country": "United States", "Lat": "45.30559921", "Long": "-121.06600189", "Precise": "0", "Callsign": "WC7EC", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "5538", "Frequency": "444.70000", "Input Freq": "449.70000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "The Dalles", "Landmark": "Stacker Butte", "County": "Wasco", "State": "Oregon", "Country": "United States", "Lat": "45.59460068", "Long": "-121.17900085", "Precise": "0", "Callsign": "KF7LN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-08-14" }, { "State ID": "41", "Rptr ID": "101", "Frequency": "444.85000", "Input Freq": "449.85000", "PL": "123.0", "TSQ": "", "Nearest City": "Beaverton", "Landmark": "St Vincent Hosp", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.51050186", "Long": "-122.77200317", "Precise": "1", "Callsign": "W7PSV", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "500 feet, 50 watts.", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "115", "Frequency": "147.36000", "Input Freq": "147.96000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Aloha", "Landmark": "Cooper Mountain", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.45529938", "Long": "-122.87100220", "Precise": "1", "Callsign": "N7QQU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "118", "Frequency": "147.32000", "Input Freq": "147.92000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Forest Grove", "Landmark": "South Saddle Mountain", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.54980087", "Long": "-123.37400055", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "121", "Frequency": "147.38000", "Input Freq": "147.98000", "PL": "100.0", "TSQ": "", "Nearest City": "Cedar Mill", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.52479935", "Long": "-122.81099701", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "218 watts ERP, 250'.", "Last Update": "2021-01-16" }, { "State ID": "41", "Rptr ID": "125", "Frequency": "442.05000", "Input Freq": "447.05000", "PL": "", "TSQ": "", "Nearest City": "Aloha", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.51499939", "Long": "-122.84899902", "Precise": "1", "Callsign": "K7WWG", "Use": "CLOSED", "Operational Status": "Off-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-21" }, { "State ID": "41", "Rptr ID": "127", "Frequency": "442.32500", "Input Freq": "447.32500", "PL": "100.0", "TSQ": "", "Nearest City": "Forest Grove", "Landmark": "South Saddle Mountain", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.54980087", "Long": "-123.37400055", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "125 watts and 3,600 feet.", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "128", "Frequency": "442.52500", "Input Freq": "447.52500", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Aloha", "Landmark": "Cooper Mountain", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.45539856", "Long": "-122.87100220", "Precise": "0", "Callsign": "KA7OSM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "134", "Frequency": "443.35000", "Input Freq": "448.35000", "PL": "156.7", "TSQ": "", "Nearest City": "Aloha", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.49449921", "Long": "-122.86599731", "Precise": "0", "Callsign": "NM7B", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "467", "Frequency": "444.97500", "Input Freq": "449.97500", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Hillsboro", "Landmark": "Intel's Jones Farm Campus", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.54240036", "Long": "-122.95999908", "Precise": "1", "Callsign": "K7CPU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "469", "Frequency": "145.45000", "Input Freq": "144.85000", "PL": "136.5", "TSQ": "", "Nearest City": "North Plains", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.59719849", "Long": "-122.99199677", "Precise": "0", "Callsign": "KE7DC", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-16" }, { "State ID": "41", "Rptr ID": "523", "Frequency": "1292.00000", "Input Freq": "1272.00000", "PL": "", "TSQ": "", "Nearest City": "Sherwood", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.35649872", "Long": "-122.83999634", "Precise": "1", "Callsign": "WB7DZG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "659", "Frequency": "441.82500", "Input Freq": "446.82500", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Timber", "Landmark": "Hoffman Hill", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.75830078", "Long": "-123.16999817", "Precise": "1", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "82962", "IRLP Node": "3881", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "2808", "Frequency": "440.10000", "Input Freq": "445.10000", "PL": "162.2", "TSQ": "", "Nearest City": "Tigard", "Landmark": "QTH", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.43140030", "Long": "-122.76999664", "Precise": "0", "Callsign": "K7ICY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "159 feet asl, 40 watts ERP.", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "3503", "Frequency": "440.55000", "Input Freq": "445.55000", "PL": "", "TSQ": "", "Nearest City": "Hillsboro", "Landmark": "Synopsys", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.53340149", "Long": "-122.90299988", "Precise": "1", "Callsign": "N7QQU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Repeater is located on the top of the Synopsys building at the intersection of Cornelius Pass Road and Cornell Road in Hillsboro and provides general coverage in Washington County.", "Last Update": "2020-12-04" }, { "State ID": "41", "Rptr ID": "5172", "Frequency": "444.31250", "Input Freq": "449.31250", "PL": "", "TSQ": "", "Nearest City": "Sherwood", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.35649872", "Long": "-122.83999634", "Precise": "1", "Callsign": "WB7DZG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-04" }, { "State ID": "41", "Rptr ID": "5173", "Frequency": "146.62000", "Input Freq": "146.02000", "PL": "", "TSQ": "", "Nearest City": "Sherwood", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.35649872", "Long": "-122.83999634", "Precise": "1", "Callsign": "WB7DZG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "Yes", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "7441", "Frequency": "927.11250", "Input Freq": "902.11250", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Gales Creek", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.58649826", "Long": "-123.21499634", "Precise": "0", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-03-10" }, { "State ID": "41", "Rptr ID": "8620", "Frequency": "443.75000", "Input Freq": "448.75000", "PL": "100.0", "TSQ": "", "Nearest City": "Newberg", "Landmark": "Chehalem Ridge", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.34999847", "Long": "-122.97000122", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "8896", "Frequency": "52.85000", "Input Freq": "51.15000", "PL": "107.2", "TSQ": "", "Nearest City": "Timber", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.71979904", "Long": "-123.29599762", "Precise": "0", "Callsign": "KR7IS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "9660", "Frequency": "444.80000", "Input Freq": "449.80000", "PL": "107.2", "TSQ": "", "Nearest City": "Cedar Mill", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.52709961", "Long": "-122.79299927", "Precise": "0", "Callsign": "N7PRM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "11138", "Frequency": "440.17500", "Input Freq": "445.17500", "PL": "110.9", "TSQ": "110.9", "Nearest City": "Tigard", "Landmark": "Bull Mountain", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.41559982", "Long": "-122.81300354", "Precise": "1", "Callsign": "KF7TTS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Normally open to all hams - Preparedness topics encouraged - Closed during emergency: Tigard CERT only", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "11146", "Frequency": "444.75000", "Input Freq": "449.75000", "PL": "123.0", "TSQ": "", "Nearest City": "Beaverton", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.48709869", "Long": "-122.80400085", "Precise": "0", "Callsign": "WB7CRT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "15227", "Frequency": "444.02500", "Input Freq": "449.02500", "PL": "Restricted", "TSQ": "Restricted", "Nearest City": "Buxton", "Landmark": "Green Mountain/Buxton Lookout", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.68870163", "Long": "-123.19100189", "Precise": "0", "Callsign": "KB7APU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "9", "DMR ID": "314108", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "15808", "Frequency": "442.27500", "Input Freq": "447.27500", "PL": "107.2", "TSQ": "", "Nearest City": "Sherwood", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.35649872", "Long": "-122.83999634", "Precise": "0", "Callsign": "KJ7IY", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "15810", "Frequency": "442.57500", "Input Freq": "447.57500", "PL": "123.0", "TSQ": "", "Nearest City": "Sherwood", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.35632610", "Long": "-122.84027490", "Precise": "0", "Callsign": "K7REA", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "80041", "FM Analog": "No", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "OPEN", "Notes": "Use DG-ID TX01 for Wires-X access. This repeater is digital only, no FM analog voice. See web page on info linking to other repeaters (http://www.k7rea.com/).", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "18792", "Frequency": "444.52500", "Input Freq": "449.52500", "PL": "136.5", "TSQ": "", "Nearest City": "Tualatin", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.37799880", "Long": "-122.78218170", "Precise": "0", "Callsign": "KJ7ECQ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "19704", "Frequency": "441.47500", "Input Freq": "446.47500", "PL": "", "TSQ": "", "Nearest City": "Beaverton", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.48887610", "Long": "-122.80137710", "Precise": "0", "Callsign": "KG7RFM", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "2", "DMR ID": "314118", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "20133", "Frequency": "440.81250", "Input Freq": "445.81250", "PL": "", "TSQ": "", "Nearest City": "Hillsboro", "Landmark": "South Saddle Mountain", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.54508300", "Long": "-123.38236100", "Precise": "1", "Callsign": "K7RPT", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "311191", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-07-04" }, { "State ID": "41", "Rptr ID": "20684", "Frequency": "440.07500", "Input Freq": "445.07500", "PL": "123.0", "TSQ": "123.0", "Nearest City": "Hillsboro", "Landmark": "", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.52346412", "Long": "-122.87331893", "Precise": "0", "Callsign": "K0HSU", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "13", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2022-05-17" }, { "State ID": "41", "Rptr ID": "21346", "Frequency": "440.75000", "Input Freq": "445.75000", "PL": "97.4", "TSQ": "", "Nearest City": "Tualatin", "Landmark": "Pony Ridge", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.38654000", "Long": "-122.81416400", "Precise": "1", "Callsign": "NA7A", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-19" }, { "State ID": "41", "Rptr ID": "21347", "Frequency": "145.25000", "Input Freq": "144.65000", "PL": "97.4", "TSQ": "", "Nearest City": "Tualatin", "Landmark": "Pony Ridge", "County": "Washington", "State": "Oregon", "Country": "United States", "Lat": "45.38654000", "Long": "-122.81416400", "Precise": "1", "Callsign": "NA7A", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "Yes", "YSF DG ID Uplink": "00", "YSF DG IS Downlink": "00", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-19" }, { "State ID": "41", "Rptr ID": "16116", "Frequency": "146.68000", "Input Freq": "146.08000", "PL": "162.2", "TSQ": "", "Nearest City": "Fossil", "Landmark": "Snowboard Ridge", "County": "Wheeler", "State": "Oregon", "Country": "United States", "Lat": "44.99819946", "Long": "-120.21600342", "Precise": "0", "Callsign": "KG7CXO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-01-17" }, { "State ID": "41", "Rptr ID": "23", "Frequency": "145.47000", "Input Freq": "144.87000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Sherwood", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.35649872", "Long": "-122.83999634", "Precise": "0", "Callsign": "KR7IS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "25", "Frequency": "146.92000", "Input Freq": "146.32000", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Sherwood", "Landmark": "Parrett Mountain", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.30914900", "Long": "-122.88458600", "Precise": "1", "Callsign": "AH6LE", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "303161", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Node is accessible via the entire AH6LE Repeater System.", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "37", "Frequency": "442.67500", "Input Freq": "447.67500", "PL": "100.0", "TSQ": "100.0", "Nearest City": "Newberg", "Landmark": "Chehelam Ridge", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.33926100", "Long": "-122.91595300", "Precise": "1", "Callsign": "AH6LE", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "303161", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "Node is accessible via the entire AH6LE Repeater System.", "Last Update": "2022-07-09" }, { "State ID": "41", "Rptr ID": "40", "Frequency": "443.42500", "Input Freq": "448.42500", "PL": "107.2", "TSQ": "", "Nearest City": "Sherwood", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.35649872", "Long": "-122.83999634", "Precise": "0", "Callsign": "KR7IS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "839'.", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "84", "Frequency": "442.55000", "Input Freq": "447.55000", "PL": "114.8", "TSQ": "", "Nearest City": "Newberg", "Landmark": "Bald Peak", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.29999924", "Long": "-122.98000336", "Precise": "0", "Callsign": "WA7RGO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "112", "Frequency": "1291.50000", "Input Freq": "1271.50000", "PL": "", "TSQ": "", "Nearest City": "Laurelwood", "Landmark": "Bald Peak", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.39599991", "Long": "-123.05599976", "Precise": "1", "Callsign": "K7AUO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "There is not Repeater Record Custodian (RRC) assigned to this repeater. Please ask WA3RMX -- THOMAS C. HILL, III -- TRUSTEE to Register with RepeaterBook.com so that he (and others of his choice) can be assigned as such. ", "Last Update": "2021-06-24" }, { "State ID": "41", "Rptr ID": "117", "Frequency": "146.90000", "Input Freq": "146.30000", "PL": "127.3", "TSQ": "127.3", "Nearest City": "Newberg", "Landmark": "Chehalem Mountain", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.37620163", "Long": "-123.03700256", "Precise": "1", "Callsign": "K7WWG", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "Yes", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-23" }, { "State ID": "41", "Rptr ID": "122", "Frequency": "224.06000", "Input Freq": "222.46000", "PL": "107.2", "TSQ": "", "Nearest City": "Newberg", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.35670090", "Long": "-122.83899689", "Precise": "0", "Callsign": "KR7IS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-02-19" }, { "State ID": "41", "Rptr ID": "135", "Frequency": "443.65000", "Input Freq": "448.65000", "PL": "100.0", "TSQ": "", "Nearest City": "Laurelwood", "Landmark": "Bald Peak", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.39599991", "Long": "-123.05599976", "Precise": "1", "Callsign": "K7AUO", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "There is no Repeater Record Custodian (RRC) assigned to this repeater. Please ask WA3RMX -- THOMAS C. HILL, III -- TRUSTEE to register with RepeaterBoook.com so that he (and others he so chooses) can be assigned as such. ", "Last Update": "2022-01-12" }, { "State ID": "41", "Rptr ID": "425", "Frequency": "145.11000", "Input Freq": "144.51000", "PL": "103.5", "TSQ": "", "Nearest City": "Newberg", "Landmark": "Chehalem Mountain", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.37620163", "Long": "-123.03700256", "Precise": "1", "Callsign": "KB7PSM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "PL not required.", "Last Update": "2022-11-18" }, { "State ID": "41", "Rptr ID": "428", "Frequency": "146.64000", "Input Freq": "146.04000", "PL": "100.0", "TSQ": "", "Nearest City": "McMinnville", "Landmark": "Eola Hills", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.07540131", "Long": "-123.12400055", "Precise": "1", "Callsign": "W7RXJ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "Yes", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "576557", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-12-06" }, { "State ID": "41", "Rptr ID": "431", "Frequency": "441.80000", "Input Freq": "446.80000", "PL": "114.8", "TSQ": "", "Nearest City": "McMinnville", "Landmark": "Eola Hill", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.09960175", "Long": "-123.14700317", "Precise": "1", "Callsign": "W7YAM", "Use": "OPEN", "Operational Status": "On-air", "ARES": "Yes", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-04-05" }, { "State ID": "41", "Rptr ID": "474", "Frequency": "52.83000", "Input Freq": "51.13000", "PL": "107.2", "TSQ": "107.2", "Nearest City": "Newberg", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.30009842", "Long": "-122.97299957", "Precise": "0", "Callsign": "KR7IS", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-06-22" }, { "State ID": "41", "Rptr ID": "664", "Frequency": "224.56000", "Input Freq": "222.96000", "PL": "100.0", "TSQ": "", "Nearest City": "Sheridan", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.09700012", "Long": "-123.39499664", "Precise": "0", "Callsign": "AC7ZQ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2019-05-05" }, { "State ID": "41", "Rptr ID": "15506", "Frequency": "444.48750", "Input Freq": "449.48750", "PL": "", "TSQ": "", "Nearest City": "Newberg", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.30009842", "Long": "-122.97299957", "Precise": "0", "Callsign": "N7MAQ", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "", "IRLP Node": "", "Wires Node": "", "FM Analog": "No", "DMR": "Yes", "DMR Color Code": "1", "DMR ID": "314110", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "On air, but not on network at this time.", "Last Update": "2020-04-11" }, { "State ID": "41", "Rptr ID": "18772", "Frequency": "52.89000", "Input Freq": "51.19000", "PL": "156.7", "TSQ": "", "Nearest City": "Newberg", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.30642580", "Long": "-122.94694630", "Precise": "0", "Callsign": "N7MAQ", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-12" }, { "State ID": "41", "Rptr ID": "18794", "Frequency": "926.26250", "Input Freq": "916.26250", "PL": "", "TSQ": "", "Nearest City": "Newberg", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.30642580", "Long": "-122.94694630", "Precise": "0", "Callsign": "WA7SUP", "Use": "OPEN", "Operational Status": "Unknown", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2020-05-13" }, { "State ID": "41", "Rptr ID": "18994", "Frequency": "145.21000", "Input Freq": "144.61000", "PL": "110.9", "TSQ": "", "Nearest City": "Amity", "Landmark": "Eola Hill", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.09766580", "Long": "-123.14510480", "Precise": "0", "Callsign": "W1ARK", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2021-09-12" }, { "State ID": "41", "Rptr ID": "20969", "Frequency": "224.20000", "Input Freq": "222.60000", "PL": "100.0", "TSQ": "", "Nearest City": "Carlton", "Landmark": "", "County": "Yamhill", "State": "Oregon", "Country": "United States", "Lat": "45.29419730", "Long": "-123.17701830", "Precise": "0", "Callsign": "K7JCN", "Use": "OPEN", "Operational Status": "On-air", "ARES": "No", "RACES": "No", "SKYWARN": "No", "CANWARN": "No", "AllStar Node": "0", "EchoLink Node": "0", "IRLP Node": "0", "Wires Node": "", "FM Analog": "Yes", "DMR": "No", "DMR Color Code": "", "DMR ID": "", "D-Star": "No", "NXDN": "No", "APCO P-25": "No", "P-25 NAC": "", "M17": "No", "M17 CAN": "", "Tetra": "No", "Tetra MCC": "", "Tetra MNC": "", "System Fusion": "No", "YSF DG ID Uplink": "", "YSF DG IS Downlink": "", "YSF DSC": "", "Notes": "", "Last Update": "2022-07-18" }, { }]} chirp-20240224/tests/unit/test_wxui_radiothread.py0000644000175000017500000001374514541530233021142 0ustar hibbyhibbyimport sys import time from unittest import mock sys.modules['wx'] = wx = mock.MagicMock() sys.modules['wx.lib'] = mock.MagicMock() sys.modules['wx.lib.scrolledpanel'] = mock.MagicMock() sys.modules['wx.lib.sized_controls'] = mock.MagicMock() sys.modules['wx.richtext'] = mock.MagicMock() wx.lib.newevent.NewCommandEvent.return_value = None, None sys.modules['chirp.wxui.developer'] = mock.MagicMock() # These need to be imported after the above mock so that we don't require # wx to be present for these tests from tests.unit import base # noqa from chirp.wxui import clone # noqa from chirp.wxui import radiothread # noqa class TestRadioThread(base.BaseTest): def setUp(self): super().setUp() def test_radiojob(self): radio = mock.MagicMock() editor = mock.MagicMock() job = radiothread.RadioJob(editor, 'get_memory', [12], {}) self.assertIsNone(job.dispatch(radio)) radio.get_memory.assert_called_once_with(12) self.assertEqual(job.result, radio.get_memory.return_value) def test_radiojob_exception(self): radio = mock.MagicMock() radio.get_memory.side_effect = ValueError('some error') editor = mock.MagicMock() job = radiothread.RadioJob(editor, 'get_memory', [12], {}) self.assertIsNone(job.dispatch(radio)) radio.get_memory.assert_called_once_with(12) self.assertIsInstance(job.result, ValueError) def test_thread(self): radio = mock.MagicMock() radio.get_features.side_effect = ValueError('some error') editor = mock.MagicMock() # Simulate an edit conflict with the first event by returning # False for "delivered" to force us to queue an event. editor.radio_thread_event.side_effect = [False, True, True, True] thread = radiothread.RadioThread(radio) mem = mock.MagicMock() job1id = thread.submit(editor, 'get_memory', 12) job2id = thread.submit(editor, 'set_memory', mem) job3id = thread.submit(editor, 'get_features') # We have to start the thread after we submit the main jobs so # the order is stable for comparison. thread.start() # Wait for the main jobs to be processed before we signal exit while not all([radio.get_memory.called, radio.set_memory.called, radio.get_features.called]): time.sleep(0.1) thread.end() thread.join(5) self.assertFalse(thread.is_alive()) radio.get_memory.assert_called_once_with(12) radio.set_memory.assert_called_once_with(mem) radio.get_features.assert_called_once_with() self.assertEqual(4, editor.radio_thread_event.call_count) # We expect the jobs to be delivered in order of # priority. Since we return False for the first call to # radio_thread_event(), job2 should be queued and then # delivered first on the next cycle. expected_order = [job2id, job2id, job3id, job1id] for i, (jobid, call) in enumerate( zip(expected_order, editor.radio_thread_event.call_args_list)): job = call[0][0] self.assertEqual(jobid, job.id) # We should call non-blocking for every call except the last # one, when the queue is empty editor.radio_thread_event.assert_has_calls([ mock.call(mock.ANY, block=False), mock.call(mock.ANY, block=False), mock.call(mock.ANY, block=False), mock.call(mock.ANY, block=True), ]) def test_thread_abort_priority(self): radio = mock.MagicMock() radio.get_features.side_effect = ValueError('some error') editor = mock.MagicMock() thread = radiothread.RadioThread(radio) mem = mock.MagicMock() thread.submit(editor, 'get_memory', 12) thread.submit(editor, 'set_memory', mem) thread.submit(editor, 'get_features') thread.end() # We have to start the thread after we submit the main jobs so # the order is stable for comparison. thread.start() thread.join(5) self.assertFalse(thread.is_alive()) # Our end sentinel should have gone to the head of the queue # so that exiting the application does not leave a thread # running in the background fetching hundreds of memories. radio.get_memory.assert_not_called() radio.set_memory.assert_not_called() radio.get_features.assert_not_called() wx.PostEvent.assert_not_called() class TestClone(base.BaseTest): @mock.patch('platform.system', return_value='Linux') def test_sort_ports_unix(self, system): ports = [ mock.MagicMock(device='/dev/cu.zed', description='My Zed'), mock.MagicMock(device='/dev/cu.abc', description='Some device'), mock.MagicMock(device='/dev/cu.serial', description='') ] self.assertEqual( ['Some device (cu.abc)', 'cu.serial', 'My Zed (cu.zed)'], [clone.port_label(p) for p in sorted(ports, key=clone.port_sort_key)]) @mock.patch('platform.system', return_value='Windows') def test_sort_ports_windows(self, system): ports = [ mock.MagicMock(device='COM7', description='Some serial device'), mock.MagicMock(device='COM17', description='Some other device'), mock.MagicMock(device='CNC0', description='Some weird device'), mock.MagicMock(device='COM4', description=''), ] self.assertEqual( ['CNC0: Some weird device', 'COM4', 'COM7: Some serial device', 'COM17: Some other device'], [clone.port_label(p) for p in sorted(ports, key=clone.port_sort_key)]) chirp-20240224/tests/unit/test_network_sources.py0000644000175000017500000000200614430171343021020 0ustar hibbyhibbyimport unittest from unittest import mock from chirp.sources import dmrmarc # Hopefully this will provide a sentinel and forcing function for # network sources when APIs stop working. Unfortunately, live queries # are more likely to add spurious failures into the tests, but time # will tell if it's worth it. class TestDMRMARC(unittest.TestCase): def test_marc_works(self): r = dmrmarc.DMRMARCRadio() r.do_fetch(mock.MagicMock(), {'city': 'portland', 'state': 'oregon', 'country': ''}) f = r.get_features() # Assert that we found some repeaters. If they all go away in # Portland, this will break and we will need another target self.assertGreater(f.memory_bounds[1], 2) for i in range(*f.memory_bounds): m = r.get_memory(i) self.assertEqual('DMR', m.mode) # Assume all DMR repeaters are above 100MHz self.assertGreater(m.freq, 100000000) chirp-20240224/tests/unit/test_yaesu_clone.py0000644000175000017500000001136314430171343020100 0ustar hibbyhibbyfrom builtins import bytes import os import tempfile import unittest from chirp import directory from chirp.drivers import ft60 from chirp.drivers import ft4 from chirp.drivers import yaesu_clone from chirp import memmap class TestYaesuChecksum(unittest.TestCase): def _test_checksum(self, mmap): cs = yaesu_clone.YaesuChecksum(0, 2, 3) self.assertEqual(42, cs.get_existing(mmap)) self.assertEqual(0x8A, cs.get_calculated(mmap)) try: mmap = mmap.get_byte_compatible() mmap[0] = 3 except AttributeError: # str or bytes try: # str mmap = memmap.MemoryMap('\x03' + mmap[1:]) except TypeError: # bytes mmap = memmap.MemoryMapBytes(b'\x03' + mmap[1:]) cs.update(mmap) self.assertEqual(95, cs.get_calculated(mmap)) def test_with_MemoryMap(self): mmap = memmap.MemoryMap('...\x2A') self._test_checksum(mmap) def test_with_MemoryMapBytes(self): mmap = memmap.MemoryMapBytes(bytes(b'...\x2A')) self._test_checksum(mmap) def test_with_bytes(self): self._test_checksum(b'...\x2A') def test_with_str(self): self._test_checksum('...\x2A') class FakeFT60: def __init__(self): self.readbuf = b'' self.writebuf = b'' def start_download(self): self.readbuf += b'\x00' * 8 for i in range(448): self.readbuf += b'\x00' * 64 def write(self, data): assert isinstance(data, bytes) # Prepend echo so it is read first next self.readbuf = data + self.readbuf self.writebuf += data if len(data) == 1: # If we're doing an upload, we need to ack this # last short block if self.writebuf.startswith(b'AH017'): self.readbuf += b'\x06' elif len(data) in (8, 64): self.readbuf += b'\x06' else: raise Exception('Unhandled') def read(self, n): buf = self.readbuf[:n] self.readbuf = self.readbuf[n:] return buf class TestFT60(unittest.TestCase): def test_download(self): f = FakeFT60() f.start_download() r = ft60.FT60Radio(f) r.sync_in() # Make sure the ACKs are there self.assertEqual(449, len(f.writebuf)) self.assertEqual(f.writebuf, b'\x06' * 449) def test_upload(self): f = FakeFT60() img = os.path.join(os.path.dirname(__file__), '..', 'images', 'Yaesu_FT-60.img') r = ft60.FT60Radio(img) r.set_pipe(f) r.sync_out() class FakeFTX4: ID = ft4.YaesuFT4XERadio.id_str def __init__(self): self.readbuf = b'' self.writebuf = b'' def write(self, buf): assert isinstance(buf, bytes) # Echo self.readbuf = buf + self.readbuf if buf.startswith(b'PROGRAM'): self.readbuf += b'QX' elif buf == b'\x02': # Ident self.readbuf += self.ID elif buf.startswith(b'R'): resp = b'W' + buf[1:] + b'\x00' * 16 self.readbuf += resp + bytes([ft4.checkSum8(resp[1:])]) elif buf.startswith(b'W'): pass elif buf == b'END': pass else: raise Exception('Unhandled %r' % buf) self.readbuf += b'\x06' def read(self, n): buf = self.readbuf[:n] self.readbuf = self.readbuf[n:] return buf class FakeFT25R(FakeFTX4): ID = ft4.YaesuFT25RRadio.id_str class FakeFT25R_Asian(FakeFTX4): ID = ft4.YaesuFT25RRadio.id_str[:-1] + b'\x03' class TestFTX4(unittest.TestCase): RCLASS = ft4.YaesuFT4XERadio FAKE = FakeFTX4 def test_download(self): f = self.FAKE() r = self.RCLASS(f) r.sync_in() self.assertEqual(f.ID[-1], r.subtype) def test_upload(self): f = self.FAKE() fn = directory.radio_class_id(self.RCLASS) img = os.path.join(os.path.dirname(__file__), '..', 'images', '%s.img' % fn) r = self.RCLASS(img) r.set_pipe(f) r.sync_out() def test_download_open(self): f = self.FAKE() r = self.RCLASS(f) r.sync_in() # Make sure we got subtype set as expected after download self.assertEqual(f.ID[-1], r.subtype) # Save it out to a file fn = tempfile.mktemp('.img', 'ft4') r.save(fn) # Make sure if we re-load our image, we keep the same subtype r = self.RCLASS(fn) self.assertEqual(f.ID[-1], r.subtype) class TestFT25(TestFTX4): RCLASS = ft4.YaesuFT25RRadio FAKE = FakeFT25R class TestFT25_Asian(TestFT25): FAKE = FakeFT25R_Asian chirp-20240224/tests/unit/test_logger.py0000644000175000017500000000215514556146076017066 0ustar hibbyhibbyimport logging from chirp import logger from tests.unit import base class TestLogger(base.BaseTest): def test_log_history(self): drv_log = logging.getLogger('chirp.drivers.foo') ui_log = logging.getLogger('chirp.wxui.foo') root_log = logging.getLogger() root_log.setLevel(logging.DEBUG) def log_all(): for log in (drv_log, ui_log, root_log): log.debug('debug') log.warning('warning') log.error('error') # Log to everything log_all() with logger.log_history(logging.WARNING, 'chirp.drivers') as h: log_all() history = h.get_history() # We should only have the error,warning messages from drivers # since we started the capture, not before self.assertEqual(2, len(history)) with logger.log_history(logging.WARNING, 'chirp.drivers') as h: log_all() history = h.get_history() # Make sure we only have the captured logs, not any leftover from # the previous run self.assertEqual(2, len(history)) chirp-20240224/tests/unit/test_icf.py0000644000175000017500000001413014437323351016333 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import shutil import tempfile import unittest from chirp import directory from chirp.drivers import ic2820, icf, id31 class TestFileICF(unittest.TestCase): def setUp(self): self.tempdir = tempfile.mkdtemp() def cleanUp(self): shutil.rmtree(self.tempdir) def test_read_icf_data_modern(self): fn = os.path.join(self.tempdir, 'test.icf') with open(fn, 'w', newline='\r\n') as f: f.write('12345678\n#Foo=somefoovalue\n#Bar=123\n') f.write('0000000020015C70000020800000E4002020202020' '20202020202020202020200040810204\n') f.write('000000202008102040810204081020408102040810' '20015B9903E821700000E4284C614772\n') f.write('#CD=fakehash\n') f.flush() icfdata, mmap = icf.read_file(fn) self.assertEqual({'model': b'\x12\x34\x56\x78', 'Foo': 'somefoovalue', 'Bar': 123, 'recordsize': 32, 'CD': 'fakehash'}, icfdata) try: directory.get_radio_by_image(fn) except Exception as e: self.assertIn('Unknown file format', str(e)) else: self.fail('Directory failed to reject unknown model') def test_read_icf_data_old(self): fn = os.path.join(self.tempdir, 'test.icf') with open(fn, 'w', newline='\r\n') as f: f.write('29700001\n#\n') f.write('00001008BBB7C0000927C04351435143512020\n') f.write('00101020202020202020202020202020202020\n') f.flush() icfdata, mmap = icf.read_file(fn) self.assertEqual({'model': b'\x29\x70\x00\x01', 'recordsize': 16}, icfdata) def test_read_write_icf(self): fn1 = os.path.join(self.tempdir, 'test1.icf') with open(fn1, 'w', newline='\r\n') as f: # These are different values than the default, so make # sure we persist them to the output ICF file. f.write('33220001\n#MapRev=2\n#EtcData=000006\n') f.write('0000000020015C70000020800000E4002020202020' '20202020202020202020200040810204\n') f.write('000000202008102040810204081020408102040810' '20015B9903E821700000E4284C614772\n') f.write('#CD=fakehash\n') f.flush() r = id31.ID31Radio(fn1) fn2 = os.path.join(self.tempdir, 'test2.icf') with open(fn2, 'w', newline='\r\n') as f: r.save(fn2) icfdata, mmap = icf.read_file(fn2) self.assertEqual({'MapRev': 2, 'EtcData': 6, 'Comment': '', 'model': r.get_model(), 'CD': '9674E1C86BA17D36DB9D3D8A144F1081', 'recordsize': 32}, icfdata) def test_read_img_write_icf_modern(self): img_file = os.path.join(os.path.dirname(__file__), '..', 'images', 'Icom_ID-31A.img') r = id31.ID31Radio(img_file) fn = os.path.join(self.tempdir, 'test.icf') with open(fn, 'w', newline='\r\n'): r.save(fn) icfdata, mmap = icf.read_file(fn) # If we sourced from an image, we use our defaults in # generating the ICF metadata self.assertEqual({'MapRev': 1, 'EtcData': 5, 'Comment': '', 'model': r.get_model(), 'CD': '9F240F598EF20683726ED252278C61D0', 'recordsize': 32}, icfdata) self.assertIsInstance(directory.get_radio_by_image(fn), id31.ID31Radio) def test_read_img_write_icf_old(self): img_file = os.path.join(os.path.dirname(__file__), '..', 'images', 'Icom_IC-2820H.img') r = ic2820.IC2820Radio(img_file) fn = os.path.join(self.tempdir, 'test.icf') with open(fn, 'w', newline='\r\n'): r.save(fn) icfdata, mmap = icf.read_file(fn) self.assertEqual({'MapRev': 1, 'EtcData': 0, 'Comment': '', 'model': r.get_model(), 'recordsize': 16}, icfdata) self.assertIsInstance(directory.get_radio_by_image(fn), ic2820.IC2820Radio) class TestCloneICF(unittest.TestCase): def test_frame_parse(self): f = icf.IcfFrame.parse(b'\xfe\xfe\xee\xef\xe0\x00\01\xfd') self.assertEqual(0xEE, f.src) self.assertEqual(0xEF, f.dst) self.assertEqual(0xE0, f.cmd) self.assertEqual(b'\x00\x01', f.payload) def test_frame_parse_no_end(self): f = icf.IcfFrame.parse(b'\xfe\xfe\xee\xef\xe0\x00\01') self.assertIsNone(f) def test_frame_parse_trailing_garbage(self): f = icf.IcfFrame.parse(b'\xfe\xfe\xee\xef\xe0\x00\01\xfd\x01') self.assertEqual(0xEE, f.src) self.assertEqual(0xEF, f.dst) self.assertEqual(0xE0, f.cmd) self.assertEqual(b'\x00\x01', f.payload) def test_pack(self): f = icf.IcfFrame(icf.ADDR_PC, icf.ADDR_RADIO, icf.CMD_CLONE_ID) f.payload = b'\x01\x02' self.assertEqual(b'\xfe\xfe\xee\xef\xe0\x01\x02\xfd', f.pack()) chirp-20240224/tests/unit/test_kguv8d.py0000644000175000017500000000420514430171343016777 0ustar hibbyhibbyimport os import struct import unittest from chirp.drivers import kguv8e from chirp.drivers import kguv8d from chirp.drivers import kguv8dplus from chirp.drivers import kg935g from chirp import directory class FakeUV8D: def __init__(self, rclass): self.writebuf = b'' self.readbuf = b'' self.rclass = rclass self._model = rclass._model def write(self, data): assert isinstance(data, bytes) cmd = data[1] response = b'' if cmd == kguv8d.CMD_ID: response = self._model + b'\x00' * 10 elif cmd == kguv8d.CMD_RD: response = b'\x00' * 64 elif cmd == kguv8d.CMD_WR: response = data[4:6] if hasattr(self.rclass, 'decrypt'): response = self.rclass(None).decrypt(response) elif cmd == kguv8d.CMD_END: return else: raise Exception('Unhandled command') packet = struct.pack('xxxB', len(response)) + response cs = sum(x for x in packet) % 256 packet += struct.pack('B', cs) if hasattr(self.rclass, 'encrypt'): payload = self.rclass(None).encrypt(packet[4:]) packet = packet[:4] + payload self.readbuf += packet def read(self, n): buf = self.readbuf[:n] self.readbuf = self.readbuf[n:] return buf class TestKGUV8D(unittest.TestCase): RCLASS = kguv8d.KGUV8DRadio def test_identify(self): f = FakeUV8D(self.RCLASS) r = self.RCLASS(f) r._identify() def test_download(self): f = FakeUV8D(self.RCLASS) r = self.RCLASS(f) r.sync_in() def test_upload(self): f = FakeUV8D(self.RCLASS) img = os.path.join(os.path.dirname(__file__), '..', 'images', '%s.img' % directory.radio_class_id(self.RCLASS)) r = self.RCLASS(img) r.set_pipe(f) r.sync_out() class TestKGUV8DPlus(TestKGUV8D): RCLASS = kguv8dplus.KGUV8DPlusRadio class TestKGUV8ER(TestKGUV8D): RCLASS = kguv8e.KGUV8ERadio class TestKG935(TestKGUV8D): RCLASS = kg935g.KG935GRadio chirp-20240224/tests/unit/test_baofeng_fmradio.py0000644000175000017500000001150514430171343020672 0ustar hibbyhibbyimport os import struct import pytest from tests.unit import base from chirp.drivers import bf_t1 from chirp.drivers import uv5r from chirp import settings class FMRadioTest(base.BaseTest): IMAGE = None RADIO_CLASS = None MEMOBJ = 'element' SETTINGS_INDEX = (0, 'element') def setUp(self): if self.IMAGE is None: self.skipTest('Base test') img = os.path.join(os.path.dirname(__file__), '..', 'images', self.IMAGE) self.radio = self.RADIO_CLASS(img) return super().setUp() def set_fmvfo_raw(self, value): """Set FM VFO as integer directly in memory""" val_bytes = struct.pack('>H', value) obj = self.radio._memobj for element in self.MEMOBJ.split('.'): obj = getattr(obj, element) obj.set_raw(val_bytes) def get_fmvfo_raw(self): """Get FM VFO as integer directly from memory""" obj = self.radio._memobj for element in self.MEMOBJ.split('.'): obj = getattr(obj, element) return int(obj) def check_fmvfo(self, expected): """Check FM VFO from settings expected should be something like 106.1 """ settings = self.radio.get_settings() index, name = self.SETTINGS_INDEX vfo = settings[index][name] self.assertEqual(expected, float(vfo.value)) def set_fmvfo(self, value): """Set FM VFO via settings value is a float like 106.1 """ index, name = self.SETTINGS_INDEX settings = self.radio.get_settings() vfo = settings[index][name] vfo.value = value self.radio.set_settings(settings) def test_get_original(self): # 100.0 in original form would be: # 100.0 - 65 = 35.0 * 10 = 350 = 0x015E # Set it directly in our memory in old format self.set_fmvfo_raw(0x015E) # Make sure we get the expected value from settings self.check_fmvfo(100.0) def test_set_original(self): # Set it via settings self.set_fmvfo(106.1) # Make sure it's the expected value in memory, old format, since our # test image was in old format self.assertEqual(0x019B, self.get_fmvfo_raw()) # Make sure we still get it back from settings as expected self.check_fmvfo(106.1) def test_get_2022(self): # 100.0 in original form would be: # 100.0 - 65 = 35.0 * 10 = 350 = 0x015E # New form is byte-swapped: 0x5E01 # Set it directly in our memory in new format self.set_fmvfo_raw(0x5E01) # Make sure we get the expected value from settings self.check_fmvfo(100.0) def test_set_2022(self): # First set it in new format directly to 100.0 self.set_fmvfo_raw(0x5E01) # Make sure we see it via settings as expected self.check_fmvfo(100.0) # Now set it via settings to a new value self.set_fmvfo(106.1) # Make sure it is in new form in the memory self.assertEqual(0x9B01, self.get_fmvfo_raw()) # Make sure it is returned properly in settings self.check_fmvfo(106.1) def _test_edges(self, new=True): """Test the edges around the supported range. Make sure that we don't confuse old and new values on either side of the supported range as the wrong format. """ if new: default = 0x5E01 else: default = 0x015E for dial in range(50, 500, 10): if 65 <= dial <= 108: self.set_fmvfo(dial) self.check_fmvfo(dial) else: # Set this to a good default value so that we can set via # settings below. self.set_fmvfo_raw(default) # We should not be able to set this out-of-range value self.assertRaises(settings.InvalidValueError, self.set_fmvfo, dial) # Can't physically set this in memory if dial <= 65: continue # Set it anyway in memory directly self.set_fmvfo_raw(int((dial - 65) * 10)) # Make sure we do not interpret it incorrectly self.assertRaises(KeyError, self.check_fmvfo, dial) def test_edges_original(self): self._test_edges(False) def test_edges_2022(self): self._test_edges(True) class TestBFT1(FMRadioTest): IMAGE = 'Baofeng_BF-T1.img' RADIO_CLASS = bf_t1.BFT1 SETTINGS_INDEX = (1, 'fm_vfo') MEMOBJ = 'settings.fm_vfo' @pytest.mark.skip('This radio needs fixing') class TestUV5R(FMRadioTest): IMAGE = 'Baofeng_UV-5R.img' RADIO_CLASS = uv5r.BaofengUV5R SETTINGS_INDEX = (3, 'fm_presets') MEMOBJ = 'fm_presets' chirp-20240224/tests/unit/test_icom_clone.py0000644000175000017500000001051014430171343017672 0ustar hibbyhibby# Copyright 2019 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys from tests import icom_clone_simulator from chirp import memmap from chirp.drivers import icw32 from builtins import bytes import glob import os import unittest from chirp import directory directory.import_drivers() class BaseIcomCloneTest(): def setUp(self): self.radio = directory.get_radio(self.RADIO_IDENT)(None) self.simulator = icom_clone_simulator.FakeIcomRadio(self.radio) self.radio.set_pipe(self.simulator) def image_filename(self, filename): tests_base = os.path.dirname(os.path.abspath(__file__)) return os.path.join(tests_base, 'images', filename) def load_from_test_image(self, filename): self.simulator.load_from_file(self.image_filename(filename)) def image_version(self, filename): end = self.radio.get_memsize() with open(self.image_filename(filename), 'rb') as f: data = f.read() if data[-8:-6] == b'%02x' % self.radio.get_model()[0]: return 2 elif data[end-16:end] == b'IcomCloneFormat3': return 3 def test_sync_in(self): test_file = self.IMAGE_FILE self.load_from_test_image(test_file) self.radio.sync_in() img_ver = self.image_version(test_file) if img_ver == 2: endstring = b''.join(b'%02x' % ord(c) for c in self.radio._model[:2]) self.assertEqual(endstring + b'0001', self.radio._mmap[-8:]) elif img_ver == 3: self.assertEqual(b'IcomCloneFormat3', self.radio._mmap[-16:]) elif img_ver is None: if isinstance(self.radio, icw32.ICW32ERadio): # The IC-W32E does some unclean things with the image size to # pass pre-metadata detection. It will fail here, so just # skip it. return self.assertEqual(self.radio.get_memsize(), len(self.radio._mmap)) def test_sync_out(self): self.radio._mmap = memmap.MemoryMapBytes( bytes(b'\x00') * self.radio.get_memsize()) self.radio._mmap[50] = bytes(b'abcdefgh') self.radio.sync_out() self.assertEqual(b'abcdefgh', self.simulator._memory[50:58]) class TestRawRadioData(unittest.TestCase): def test_get_payload(self): radio = directory.get_radio('Icom_IC-2730A')(None) payload = radio.get_payload(bytes(b'\x00\x10\xFE\x00'), True, True) self.assertEqual(b'\x00\x10\xFF\x0E\x00\xF2', payload) payload = radio.get_payload(bytes(b'\x00\x10\xFE\x00'), True, False) self.assertEqual(b'\x00\x10\xFF\x0E\x00', payload) def test_process_frame_payload(self): radio = directory.get_radio('Icom_IC-2730A')(None) data = radio.process_frame_payload(bytes(b'\x00\x10\xFF\x0E\x00')) self.assertEqual(b'\x00\x10\xFE\x00', data) class TestAdapterMeta(type): def __new__(cls, name, parents, dct): return super(TestAdapterMeta, cls).__new__(cls, name, parents, dct) test_file_glob = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'images', 'Icom_*.img') for image_file in glob.glob(test_file_glob): base, _ext = os.path.splitext(os.path.basename(image_file)) try: radio = directory.get_radio(base) except Exception: continue if radio._raw_frames: # The simulator does not behave like a raw radio continue class_name = 'Test_%s' % base sys.modules[__name__].__dict__[class_name] = \ TestAdapterMeta(class_name, (BaseIcomCloneTest, unittest.TestCase), dict(RADIO_IDENT=base, IMAGE_FILE=image_file)) chirp-20240224/tests/unit/test_util.py0000644000175000017500000000117514411666130016551 0ustar hibbyhibbyfrom chirp import util from tests.unit import base class TestUtils(base.BaseTest): def test_hexprint_with_string(self): util.hexprint('00000000000000') def test_hexprint_with_bytes(self): util.hexprint(b'00000000000000') def test_hexprint_short(self): expected = ('000: 00 00 00 00 00 00 00 00 ........\n' '008: 00 ........\n') self.assertEqual(expected, util.hexprint(b'\x00' * 9)) def test_hexprint_even(self): expected = '000: 00 00 00 00 00 00 00 00 ........\n' self.assertEqual(expected, util.hexprint(b'\x00' * 8)) chirp-20240224/tests/unit/test_mappingmodel.py0000644000175000017500000002501514411666130020247 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from unittest import mock from tests.unit import base from chirp import chirp_common from chirp.drivers import icf class TestBaseMapping(base.BaseTest): CLS = chirp_common.MemoryMapping def test_mapping(self): model = chirp_common.MappingModel(None, 'Foo') mapping = self.CLS(model, 1, 'Foo') self.assertEqual(str(mapping), 'Foo') self.assertEqual(mapping.get_name(), 'Foo') self.assertEqual(mapping.get_index(), 1) self.assertEqual(repr(mapping), '%s-1' % self.CLS.__name__) self.assertEqual(mapping._model, model) def test_mapping_eq(self): mapping1 = self.CLS(None, 1, 'Foo') mapping2 = self.CLS(None, 1, 'Bar') mapping3 = self.CLS(None, 2, 'Foo') self.assertEqual(mapping1, mapping2) self.assertNotEqual(mapping1, mapping3) class TestBaseBank(TestBaseMapping): CLS = chirp_common.Bank class _TestBaseClass(base.BaseTest): ARGS = tuple() def setUp(self): super(_TestBaseClass, self).setUp() self.model = self.CLS(*self.ARGS) def _test_base(self, method, *args): self.assertRaises(NotImplementedError, getattr(self.model, method), *args) class TestBaseMappingModel(_TestBaseClass): CLS = chirp_common.MappingModel ARGS = tuple([None, 'Foo']) def test_base_class(self): methods = [('get_num_mappings', ()), ('get_mappings', ()), ('add_memory_to_mapping', (None, None)), ('remove_memory_from_mapping', (None, None)), ('get_mapping_memories', (None,)), ('get_memory_mappings', (None,)), ] for method, args in methods: self._test_base(method, *args) def test_get_name(self): self.assertEqual(self.model.get_name(), 'Foo') class TestBaseBankModel(TestBaseMappingModel): ARGS = tuple([None]) CLS = chirp_common.BankModel def test_get_name(self): self.assertEqual(self.model.get_name(), 'Banks') class TestBaseMappingModelIndexInterface(_TestBaseClass): CLS = chirp_common.MappingModelIndexInterface def test_base_class(self): methods = [('get_index_bounds', ()), ('get_memory_index', (None, None)), ('set_memory_index', (None, None, None)), ('get_next_mapping_index', (None,)), ] for method, args in methods: self._test_base(method, *args) class TestIcomBanks(TestBaseMapping): def test_icom_bank(self): bank = icf.IcomBank(None, 1, 'Foo') # IcomBank has an index attribute used by IcomBankModel self.assertTrue(hasattr(bank, 'index')) class TestIcomBankModel(base.BaseTest): CLS = icf.IcomBankModel def _get_rf(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 10) return rf def setUp(self): super(TestIcomBankModel, self).setUp() class FakeRadio(icf.IcomCloneModeRadio): _num_banks = 10 _bank_index_bounds = (0, 10) def get_features(the_radio): return self._get_rf() def _set_bank(self, number, index): pass def _get_bank(self, number): pass def _get_bank_index(self, number): pass def _set_bank_index(self, number, index): pass def get_memory(self, number): pass self._radio = FakeRadio(None) self._model = self.CLS(self._radio) for a in ('_set_bank', '_get_bank', '_set_bank_index', '_get_bank_index', 'get_memory'): m = mock.patch.object(self._radio, a) m.start() self.mocks.append(m) def test_get_num_mappings(self): self.assertEqual(self._model.get_num_mappings(), 10) def test_get_mappings(self): banks = self._model.get_mappings() self.assertEqual(len(banks), 10) i = 0 for bank in banks: index = chr(ord("A") + i) self.assertEqual(bank.get_index(), index) self.assertEqual(bank.get_name(), 'BANK-%s' % index) self.assertEqual(bank.index, i) i += 1 def test_add_memory_to_mapping(self): mem = chirp_common.Memory() mem.number = 5 banks = self._model.get_mappings() bank = banks[2] self._model.add_memory_to_mapping(mem, bank) self._radio._set_bank.assert_called_once_with(5, 2) def _setup_test_remove_memory_from_mapping(self, curbank): mem = chirp_common.Memory() mem.number = 5 banks = self._model.get_mappings() bank = banks[2] self._radio._get_bank.return_value = curbank return mem, bank def test_remove_memory_from_mapping(self): mem, bank = self._setup_test_remove_memory_from_mapping(2) self._model.remove_memory_from_mapping(mem, bank) self._radio._get_bank.assert_called_once_with(5) self._radio._set_bank.assert_called_once_with(5, None) def test_remove_memory_from_mapping_wrong_bank(self): mem, bank = self._setup_test_remove_memory_from_mapping(3) self.assertRaises(Exception, self._model.remove_memory_from_mapping, mem, bank) def test_remove_memory_from_mapping_no_bank(self): mem, bank = self._setup_test_remove_memory_from_mapping(None) self.assertRaises(Exception, self._model.remove_memory_from_mapping, mem, bank) def test_get_mapping_memories(self): banks = self._model.get_mappings() expected = [] _get_bank = [] for i in range(1, 10): should_include = bool(i % 2) _get_bank.append( should_include and banks[1].index or None) if should_include: expected.append(i) self._radio._get_bank.side_effect = _get_bank self._radio.get_memory.side_effect = expected members = self._model.get_mapping_memories(banks[1]) self.assertEqual(members, expected) self._radio.get_memory.assert_has_calls([ mock.call(i) for i in range(1, 10) if i % 2]) self._radio._get_bank.assert_has_calls([ mock.call(i) for i in range(1, 10)]) def test_get_memory_mappings(self): banks = self._model.get_mappings() mem1 = chirp_common.Memory() mem1.number = 5 mem2 = chirp_common.Memory() mem2.number = 6 self._radio._get_bank.side_effect = [2, None] self.assertEqual(self._model.get_memory_mappings(mem1)[0], banks[2]) self.assertEqual(self._model.get_memory_mappings(mem2), []) self._radio._get_bank.assert_has_calls([ mock.call(mem1.number), mock.call(mem2.number)]) class TestIcomIndexedBankModel(TestIcomBankModel): CLS = icf.IcomIndexedBankModel def _get_rf(self): rf = super(TestIcomIndexedBankModel, self)._get_rf() rf.has_bank_index = True return rf def test_get_index_bounds(self): self.assertEqual(self._model.get_index_bounds(), (0, 10)) def test_get_memory_index(self): mem = chirp_common.Memory() mem.number = 5 self._radio._get_bank_index.return_value = 1 self.assertEqual(self._model.get_memory_index(mem, None), 1) self._radio._get_bank_index.assert_called_once_with(mem.number) def test_set_memory_index(self): mem = chirp_common.Memory() mem.number = 5 banks = self._model.get_mappings() with mock.patch.object(self._model, 'get_memory_mappings') as m: m.return_value = [banks[3]] self._model.set_memory_index(mem, banks[3], 1) m.assert_called_once_with(mem) self._radio._set_bank_index.assert_called_once_with(mem.number, 1) def test_set_memory_index_bad_bank(self): mem = chirp_common.Memory() mem.number = 5 banks = self._model.get_mappings() with mock.patch.object(self._model, 'get_memory_mappings') as m: m.return_value = [banks[4]] self.assertRaises(Exception, self._model.set_memory_index, mem, banks[3], 1) m.assert_called_once_with(mem) def test_set_memory_index_bad_index(self): mem = chirp_common.Memory() mem.number = 5 banks = self._model.get_mappings() with mock.patch.object(self._model, 'get_memory_mappings') as m: m.return_value = [banks[3]] self.assertRaises(Exception, self._model.set_memory_index, mem, banks[3], 99) m.assert_called_once_with(mem) def test_get_next_mapping_index(self): banks = self._model.get_mappings() bank_exp_calls = [] index_exp_calls = [] bank_returns = [] index_returns = [] for i in range(*self._radio.get_features().memory_bounds): bank_returns.append((i % 2) and banks[1].index) bank_exp_calls.append(mock.call(i)) if bool(i % 2): index_returns.append(i) index_exp_calls.append(mock.call(i)) idx = 0 for i in range(*self._radio.get_features().memory_bounds): bank_exp_calls.append(mock.call(i)) bank_returns.append((i % 2) and banks[2].index) if i % 2: index_exp_calls.append(mock.call(i)) index_returns.append(idx) idx += 1 self._radio._get_bank.side_effect = bank_returns self._radio._get_bank_index.side_effect = index_returns self.assertEqual(self._model.get_next_mapping_index(banks[1]), 0) self.assertEqual(self._model.get_next_mapping_index(banks[2]), 5) self._radio._get_bank.assert_has_calls(bank_exp_calls) self._radio._get_bank_index.assert_has_calls(index_exp_calls) chirp-20240224/tests/unit/test_bitwise.py0000644000175000017500000003532114566340166017253 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import unittest from unittest import mock import six from chirp import bitwise from chirp import memmap class BaseTest(unittest.TestCase): def _compare_structure(self, obj, primitive): for key, value in primitive.items(): if isinstance(value, dict): self._compare_structure(getattr(obj, key), value) else: self.assertEqual(type(value)(getattr(obj, key)), value) class TestMemoryMapCoherence(BaseTest): def test_byte_char_coherence(self): charmmap = memmap.MemoryMap('00') # This will to a get_byte_compatible() from chars obj = bitwise.parse('char foo[2];', charmmap) self.assertEqual('00', str(obj.foo)) obj.foo = '11' # The above assignment happens on the byte-compatible mmap, # make sure it is still visible in the charmmap we know about. # This confirms that get_byte_compatible() links the backing # store of the original mmap to the new one. self.assertEqual('11', charmmap.get_packed()) class TestBitwiseBaseIntTypes(BaseTest): def _test_type(self, datatype, _data, value): data = memmap.MemoryMapBytes(bytes(_data)) obj = bitwise.parse("%s foo;" % datatype, data) self.assertEqual(int(obj.foo), value) self.assertEqual(obj.foo.size(), len(data) * 8) obj.foo = 0 self.assertEqual(int(obj.foo), 0) self.assertEqual(data.get_packed(), (b"\x00" * (obj.size() // 8))) obj.foo = value self.assertEqual(int(obj.foo), value) self.assertEqual(data.get_packed(), _data) obj.foo = 7 # Compare against the equivalent real division so we get consistent # results on py2 and py3 self.assertEqual(7 // 2, obj.foo // 2) self.assertEqual(7 / 2, obj.foo / 2) self.assertEqual(7 / 2.0, obj.foo / 2.0) def test_type_u8(self): self._test_type("u8", b"\x80", 128) def test_type_u16(self): self._test_type("u16", b"\x01\x00", 256) def test_type_u24(self): self._test_type("u24", b"\x80\x00\x00", 2**23) def test_type_u32(self): self._test_type("u32", b"\x80\x00\x00\x00", 2**31) def test_type_ul16(self): self._test_type("ul16", b"\x00\x01", 256) def test_type_ul24(self): self._test_type("ul24", b"\x00\x00\x80", 2**23) def test_type_ul32(self): self._test_type("ul32", b"\x00\x00\x00\x80", 2**31) def test_int_array(self): data = memmap.MemoryMapBytes(bytes(b'\x00\x01\x02\x03')) obj = bitwise.parse('u8 foo[4];', data) for i in range(4): self.assertEqual(i, obj.foo[i]) obj.foo[i] = i * 2 self.assertEqual(b'\x00\x02\x04\x06', data.get_packed()) def test_int_array_set_raw(self): data = memmap.MemoryMapBytes(bytes(b'\x00\x01\x02\x03')) obj = bitwise.parse('u8 foo[4];', data) obj.foo.set_raw(b'\x09\x08\x07\x06') self.assertEqual(9, obj.foo[0]) self.assertEqual(8, obj.foo[1]) self.assertEqual(7, obj.foo[2]) self.assertEqual(6, obj.foo[3]) obj = bitwise.parse('u16 foo[2];', data) obj.foo.set_raw(b'\x00\x01\x00\x02') self.assertEqual(1, obj.foo[0]) self.assertEqual(2, obj.foo[1]) with self.assertRaises(AssertionError): obj.foo.set_raw(b'123') with self.assertRaises(AssertionError): obj.foo.set_raw(b'12345') class TestBitfieldTypes(BaseTest): def test_bitfield_u8(self): defn = "u8 foo:4, bar:4;" data = memmap.MemoryMapBytes(bytes(b"\x12")) obj = bitwise.parse(defn, data) self.assertEqual(obj.foo, 1) self.assertEqual(obj.bar, 2) self.assertEqual(obj.foo.size(), 4) self.assertEqual(obj.bar.size(), 4) obj.foo = 0x8 obj.bar = 0x1 self.assertEqual(data.get_packed(), b"\x81") def _test_bitfield_16(self, variant, data): defn = "u%s16 foo:4, bar:8, baz:4;" % variant data = memmap.MemoryMapBytes(bytes(data)) obj = bitwise.parse(defn, data) self.assertEqual(int(obj.foo), 1) self.assertEqual(int(obj.bar), 0x23) self.assertEqual(int(obj.baz), 4) self.assertEqual(obj.foo.size(), 4) self.assertEqual(obj.bar.size(), 8) self.assertEqual(obj.baz.size(), 4) obj.foo = 0x2 obj.bar = 0x11 obj.baz = 0x3 if variant == "l": self.assertEqual(data.get_packed(), b"\x13\x21") else: self.assertEqual(data.get_packed(), b"\x21\x13") def test_bitfield_u16(self): self._test_bitfield_16("", b"\x12\x34") def test_bitfield_ul16(self): self._test_bitfield_16('l', b"\x34\x12") def _test_bitfield_24(self, variant, data): defn = "u%s24 foo:12, bar:6, baz:6;" % variant data = memmap.MemoryMapBytes(bytes(data)) obj = bitwise.parse(defn, data) self.assertEqual(int(obj.foo), 4) self.assertEqual(int(obj.bar), 3) self.assertEqual(int(obj.baz), 2) self.assertEqual(obj.foo.size(), 12) self.assertEqual(obj.bar.size(), 6) self.assertEqual(obj.baz.size(), 6) obj.foo = 1 obj.bar = 2 obj.baz = 3 if variant == 'l': self.assertEqual(data.get_packed(), b"\x83\x10\x00") else: self.assertEqual(data.get_packed(), b"\x00\x10\x83") def test_bitfield_u24(self): self._test_bitfield_24("", b"\x00\x40\xC2") def test_bitfield_ul24(self): self._test_bitfield_24("l", b"\xC2\x40\x00") class TestBitType(BaseTest): def test_bit_array(self): defn = "bit foo[24];" data = memmap.MemoryMapBytes(bytes(b"\x00\x80\x01")) obj = bitwise.parse(defn, data) for i, v in [(0, False), (8, True), (23, True)]: self.assertEqual(bool(obj.foo[i]), v) for i in range(0, 24): obj.foo[i] = i % 2 self.assertEqual(data.get_packed(), b"\x55\x55\x55") def test_bit_array_fail(self): self.assertRaises(ValueError, bitwise.parse, "bit foo[23];", b"000") class TestBitwiseBCDTypes(BaseTest): def _test_def(self, definition, name, _data, value): data = memmap.MemoryMapBytes(bytes(_data)) obj = bitwise.parse(definition, data) self.assertEqual(int(getattr(obj, name)), value) self.assertEqual(getattr(obj, name).size(), len(_data) * 8) setattr(obj, name, 0) self.assertEqual(data.get_packed(), (b"\x00" * len(_data))) setattr(obj, name, 42) if definition.startswith("b"): expected = (len(_data) == 2 and b"\x00" or b"") + b"\x42" else: expected = b"\x42" + (len(_data) == 2 and b"\x00" or b"") raw = data.get_packed() self.assertEqual(raw, expected) def test_bbcd(self): self._test_def("bbcd foo;", "foo", b"\x12", 12) def test_lbcd(self): self._test_def("lbcd foo;", "foo", b"\x12", 12) def test_bbcd_array(self): self._test_def("bbcd foo[2];", "foo", b"\x12\x34", 1234) def test_lbcd_array(self): self._test_def("lbcd foo[2];", "foo", b"\x12\x34", 3412) class TestBitwiseCharTypes(BaseTest): def test_char(self): data = memmap.MemoryMapBytes(bytes(b"c")) obj = bitwise.parse("char foo;", data) self.assertEqual(str(obj.foo), "c") self.assertEqual(obj.foo.size(), 8) obj.foo = "d" self.assertEqual(data.get_packed(), b"d") def test_string(self): data = memmap.MemoryMapBytes(bytes(b"foobar")) obj = bitwise.parse("char foo[6];", data) self.assertEqual(str(obj.foo), "foobar") self.assertEqual(obj.foo.size(), 8 * 6) obj.foo = "bazfoo" self.assertEqual(data.get_packed(), b"bazfoo") def test_string_invalid_chars(self): data = memmap.MemoryMapBytes(bytes(b"\xFFoobar1")) obj = bitwise.parse("struct {char foo[7];} bar;", data) if six.PY3: expected = '\xffoobar1' else: expected = '\\xffoobar1' self.assertIn(expected, repr(obj.bar)) def test_string_wrong_length(self): data = memmap.MemoryMapBytes(bytes(b"foobar")) obj = bitwise.parse("char foo[6];", data) self.assertRaises(ValueError, setattr, obj, "foo", "bazfo") self.assertRaises(ValueError, setattr, obj, "foo", "bazfooo") def test_string_with_various_input_types(self): data = memmap.MemoryMapBytes(bytes(b"foobar")) obj = bitwise.parse("char foo[6];", data) self.assertEqual('foobar', str(obj.foo)) self.assertEqual(6, len(b'barfoo')) obj.foo = b'barfoo' self.assertEqual('barfoo', str(obj.foo)) obj.foo = [ord(c) for c in 'fffbbb'] self.assertEqual('fffbbb', str(obj.foo)) def test_string_get_raw(self): data = memmap.MemoryMapBytes(bytes(b"foobar")) obj = bitwise.parse("char foo[6];", data) self.assertEqual(b'foobar', obj.foo.get_raw()) self.assertEqual('foobar', obj.foo.get_raw(asbytes=False)) class TestBitwiseStructTypes(BaseTest): def _test_def(self, definition, data, primitive): obj = bitwise.parse(definition, data) self._compare_structure(obj, primitive) self.assertEqual(obj.size(), len(data) * 8) def test_struct_one_element(self): defn = "struct { u8 bar; } foo;" value = {"foo": {"bar": 128}} self._test_def(defn, b"\x80", value) def test_struct_two_elements(self): defn = "struct { u8 bar; u16 baz; } foo;" value = {"foo": {"bar": 128, "baz": 256}} self._test_def(defn, b"\x80\x01\x00", value) def test_struct_writes(self): data = memmap.MemoryMapBytes(bytes(b"..")) defn = "struct { u8 bar; u8 baz; } foo;" obj = bitwise.parse(defn, data) obj.foo.bar = 0x12 obj.foo.baz = 0x34 self.assertEqual(data.get_packed(), b"\x12\x34") def test_struct_get_raw(self): data = memmap.MemoryMapBytes(bytes(b"..")) defn = "struct { u8 bar; u8 baz; } foo;" obj = bitwise.parse(defn, data) self.assertEqual(b'..', obj.get_raw()) self.assertEqual('..', obj.get_raw(asbytes=False)) def test_struct_get_raw_small(self): data = memmap.MemoryMapBytes(bytes(b".")) defn = "struct { u8 bar; } foo;" obj = bitwise.parse(defn, data) self.assertEqual(b'.', obj.get_raw()) self.assertEqual('.', obj.get_raw(asbytes=False)) def test_struct_set_raw(self): data = memmap.MemoryMapBytes(bytes(b".")) defn = "struct { u8 bar; } foo;" obj = bitwise.parse(defn, data) obj.set_raw(b'1') self.assertEqual(b'1', data.get_packed()) obj.set_raw('2') self.assertEqual(b'2', data.get_packed()) @mock.patch.object(bitwise.LOG, 'error') def test_struct_duplicate(self, mock_log): bitwise.parse('struct\n{ u8 foo; u8 foo1:2, foo:4, foo3:2;} bar;', memmap.MemoryMapBytes(b'\x00' * 128)) bitwise.parse('struct\n{ u8 foo; u8 foo;} bar;', memmap.MemoryMapBytes(b'\x00' * 128)) bitwise.parse('struct\n{ u8 foo; u8 foo[2];} bar;', memmap.MemoryMapBytes(b'\x00' * 128)) self.assertEqual(3, mock_log.call_count) def test_struct_fill_raw(self): data = memmap.MemoryMapBytes(bytes(b"...")) defn = "struct { u8 bar; u16 baz; } foo;" obj = bitwise.parse(defn, data) obj.fill_raw(b'\xAA') self.assertEqual(0xAA, obj.foo.bar) self.assertEqual(0xAAAA, obj.foo.baz) obj.foo.fill_raw(b'\xBB') self.assertEqual(0xBB, obj.foo.bar) self.assertEqual(0xBBBB, obj.foo.baz) obj.foo.bar.fill_raw(b'\xCC') self.assertEqual(0xCC, obj.foo.bar) self.assertEqual(0xBBBB, obj.foo.baz) self.assertRaises(AssertionError, obj.fill_raw, '1') self.assertRaises(AssertionError, obj.fill_raw, b'AB') self.assertRaises(AssertionError, obj.fill_raw, False) class TestBitwisePrintoffset(BaseTest): @mock.patch.object(bitwise.LOG, 'debug') def test_printoffset(self, mock_log): defn = 'u8 foo; u16 bar; #printoffset "bar";' bitwise.parse(defn, b"abcdZ") mock_log.assert_called_once_with('bar: 3 (0x00000003)') class TestBitwiseSeek(BaseTest): def test_seekto(self): defn = "#seekto 4; char foo;" obj = bitwise.parse(defn, b"abcdZ") self.assertEqual(str(obj.foo), "Z") def test_seek(self): defn = "char foo; #seek 3; char bar;" obj = bitwise.parse(defn, b"AbcdZ") self.assertEqual(str(obj.foo), "A") self.assertEqual(str(obj.bar), "Z") class TestBitwiseErrors(BaseTest): def test_missing_semicolon(self): self.assertRaises(SyntaxError, bitwise.parse, "u8 foo", "") class TestBitwiseComments(BaseTest): def test_comment_inline_cppstyle(self): obj = bitwise.parse('u8 foo; // test', b'\x10') self.assertEqual(16, obj.foo) def test_comment_cppstyle(self): obj = bitwise.parse('// Test this\nu8 foo;', b'\x10') self.assertEqual(16, obj.foo) class TestBitwiseStringEncoders(BaseTest): def test_encode_bytes(self): self.assertEqual(b'foobar\x00', bitwise.string_straight_encode('foobar\x00')) def test_decode_bytes(self): self.assertEqual('foobar\x00', bitwise.string_straight_decode(b'foobar\x00')) class TestPath(BaseTest): def test_get_path(self): fmt = ("u8 foo;" "u8 bar[2];" "struct {" " u8 foo;" " u8 bar[2];" " u8 baz1:4," " baz2:4;" " struct {" " u16 childitem;" " } child;" "} structure[2];") obj = bitwise.parse(fmt, memmap.MemoryMapBytes(b'\x00' * 128)) obj.structure[0].bar[1] = 123 obj.structure[1].child.childitem = 456 self.assertEqual(123, obj.get_path('.structure[0].bar[1]')) self.assertEqual(456, obj.get_path('structure[1].child.childitem')) chirp-20240224/tests/unit/test_chirp_common.py0000644000175000017500000010675414565075506020275 0ustar hibbyhibbyimport base64 import copy import json import os import pickle import tempfile from unittest import mock from tests.unit import base from chirp import CHIRP_VERSION from chirp import chirp_common from chirp import directory from chirp import errors from chirp import settings class TestUtilityFunctions(base.BaseTest): def test_parse_freq_whole(self): self.assertEqual(chirp_common.parse_freq("146.520000"), 146520000) self.assertEqual(chirp_common.parse_freq("146.5200"), 146520000) self.assertEqual(chirp_common.parse_freq("146.52"), 146520000) self.assertEqual(chirp_common.parse_freq("146"), 146000000) self.assertEqual(chirp_common.parse_freq("1250"), 1250000000) self.assertEqual(chirp_common.parse_freq("123456789"), 123456789000000) def test_parse_freq_decimal(self): self.assertEqual(chirp_common.parse_freq("1.0"), 1000000) self.assertEqual(chirp_common.parse_freq("1.000000"), 1000000) self.assertEqual(chirp_common.parse_freq("1.1"), 1100000) self.assertEqual(chirp_common.parse_freq("1.100"), 1100000) self.assertEqual(chirp_common.parse_freq("0.6"), 600000) self.assertEqual(chirp_common.parse_freq("0.600"), 600000) self.assertEqual(chirp_common.parse_freq("0.060"), 60000) self.assertEqual(chirp_common.parse_freq(".6"), 600000) def test_parse_freq_whitespace(self): self.assertEqual(chirp_common.parse_freq("1 "), 1000000) self.assertEqual(chirp_common.parse_freq(" 1"), 1000000) self.assertEqual(chirp_common.parse_freq(" 1 "), 1000000) self.assertEqual(chirp_common.parse_freq("1.0 "), 1000000) self.assertEqual(chirp_common.parse_freq(" 1.0"), 1000000) self.assertEqual(chirp_common.parse_freq(" 1.0 "), 1000000) self.assertEqual(chirp_common.parse_freq(""), 0) self.assertEqual(chirp_common.parse_freq(" "), 0) def test_parse_freq_bad(self): self.assertRaises(ValueError, chirp_common.parse_freq, "a") self.assertRaises(ValueError, chirp_common.parse_freq, "1.a") self.assertRaises(ValueError, chirp_common.parse_freq, "a.b") self.assertRaises(ValueError, chirp_common.parse_freq, "1.0000001") def test_format_freq(self): self.assertEqual(chirp_common.format_freq(146520000), "146.520000") self.assertEqual(chirp_common.format_freq(54000000), "54.000000") self.assertEqual(chirp_common.format_freq(1800000), "1.800000") self.assertEqual(chirp_common.format_freq(1), "0.000001") self.assertEqual(chirp_common.format_freq(1250000000), "1250.000000") @mock.patch('chirp.CHIRP_VERSION', new='daily-20151021') def test_compare_version_to_current(self): self.assertTrue(chirp_common.is_version_newer('daily-20180101')) self.assertFalse(chirp_common.is_version_newer('daily-20140101')) self.assertFalse(chirp_common.is_version_newer('0.3.0')) self.assertFalse(chirp_common.is_version_newer('0.3.0dev')) @mock.patch('chirp.CHIRP_VERSION', new='0.3.0dev') def test_compare_version_to_current_dev(self): self.assertTrue(chirp_common.is_version_newer('daily-20180101')) def test_from_Hz(self): # FIXME: These are wrong! Adding them here purely to test the # python3 conversion, but they should be fixed. self.assertEqual(140, chirp_common.from_GHz(14000000001)) self.assertEqual(140, chirp_common.from_MHz(14000001)) self.assertEqual(140, chirp_common.from_kHz(14001)) def test_mem_from_text_rb1(self): text = '145.2500 -0.6 MHz 97.4 OPEN' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(145250000, mem.freq) self.assertEqual(600000, mem.offset) self.assertEqual('-', mem.duplex) self.assertEqual('Tone', mem.tmode) self.assertEqual(97.4, mem.rtone) def test_mem_from_text_rb2(self): text = '147.3000 +0.6 MHz 156.7 / 156.7 OPEN' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(147300000, mem.freq) self.assertEqual(600000, mem.offset) self.assertEqual('+', mem.duplex) self.assertEqual('TSQL', mem.tmode) self.assertEqual(156.7, mem.ctone) def test_mem_from_text_rb3(self): text = '441.1000 +5 MHz D125 / D125 OPEN' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(441100000, mem.freq) self.assertEqual(5000000, mem.offset) self.assertEqual('+', mem.duplex) self.assertEqual('DTCS', mem.tmode) self.assertEqual(125, mem.dtcs) def test_mem_from_text_rb4(self): text = '441.1000 +5 MHz 88.5 / D125 OPEN' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(441100000, mem.freq) self.assertEqual(5000000, mem.offset) self.assertEqual('+', mem.duplex) self.assertEqual('Cross', mem.tmode) self.assertEqual(88.5, mem.rtone) self.assertEqual(125, mem.rx_dtcs) self.assertEqual('Tone->DTCS', mem.cross_mode) def test_mem_from_text_random1(self): text = 'Glass Butte 147.200 + 162.2' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(147200000, mem.freq) # This is a default self.assertEqual(600000, mem.offset) # Just a random + or - on the line isn't enough to trigger offset # pattern self.assertEqual('+', mem.duplex) self.assertEqual('Tone', mem.tmode) self.assertEqual(162.2, mem.rtone) def test_mem_from_text_random2(self): text = 'Glass - Butte 147.200 + 162.2' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(147200000, mem.freq) # This is a default self.assertEqual(600000, mem.offset) # Just a random + or - on the line isn't enough to trigger offset # pattern self.assertEqual('+', mem.duplex) self.assertEqual('Tone', mem.tmode) self.assertEqual(162.2, mem.rtone) def test_mem_from_text_random3(self): text = 'Glass - Butte 147.200 + 88.5' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(147200000, mem.freq) # This is a default self.assertEqual(600000, mem.offset) # Just a random + or - on the line isn't enough to trigger offset # pattern self.assertEqual('+', mem.duplex) self.assertEqual('Tone', mem.tmode) self.assertEqual(88.5, mem.rtone) def test_mem_from_text_random4(self): text = '146.640 | 146.040 | 136.5' mem = chirp_common.mem_from_text(text) self.assertIsNotNone(mem) self.assertEqual(146640000, mem.freq) self.assertEqual(600000, mem.offset) self.assertEqual('-', mem.duplex) self.assertEqual('Tone', mem.tmode) self.assertEqual(136.5, mem.rtone) def test_mem_from_text_chirp1(self): text = '[400.625000/136.000000]' chirp_common.mem_from_text(text) def test_mem_from_text_chirp2(self): text = '[462.675000/+5.000/136.5/136.5]' mem = chirp_common.mem_from_text(text) self.assertEqual(462675000, mem.freq) self.assertEqual('+', mem.duplex) self.assertEqual(5000000, mem.offset) def test_mem_from_text_chirp3(self): text = '[1.675000/1.685/136.5/136.5]' mem = chirp_common.mem_from_text(text) self.assertEqual(1675000, mem.freq) self.assertEqual('+', mem.duplex) self.assertEqual(10000, mem.offset) def test_mem_from_text_chirp4(self): text = '[450.000000/150.000000]' mem = chirp_common.mem_from_text(text) self.assertEqual(450000000, mem.freq) self.assertEqual(150000000, mem.offset) self.assertEqual('split', mem.duplex) def test_mem_from_text_chirp5(self): text = '[500.000000/-9.900]' mem = chirp_common.mem_from_text(text) self.assertEqual(500000000, mem.freq) self.assertEqual(9900000, mem.offset) self.assertEqual('-', mem.duplex) self.assertEqual(text, chirp_common.mem_to_text(mem)) def test_mem_from_text_chirp6(self): text = '[450.000000/150.000]' mem = chirp_common.mem_from_text(text) self.assertEqual(450000000, mem.freq) self.assertEqual(150000000, mem.offset) self.assertEqual('split', mem.duplex) def test_mem_from_text_chirp7(self): # Offsets >= 10MHz are not allowed, so this will get # parsed as a tx frequency of 15MHz text = '[450.000000/+15.000]' mem = chirp_common.mem_from_text(text) self.assertEqual(450000000, mem.freq) self.assertEqual(15000000, mem.offset) self.assertEqual('split', mem.duplex) def test_mem_from_text_chirp8(self): # Offsets >= 10MHz are not allowed, so this will get # parsed as a tx frequency of 15MHz text = '[450.000000/+150.000]' mem = chirp_common.mem_from_text(text) self.assertEqual(450000000, mem.freq) self.assertEqual(150000000, mem.offset) self.assertEqual('split', mem.duplex) def test_mem_to_text1(self): mem = chirp_common.Memory() mem.freq = 146900000 mem.duplex = '-' mem.offset = 600000 mem.tmode = 'TSQL' mem.ctone = 100.0 txt = chirp_common.mem_to_text(mem) self.assertEqual('[146.900000/-0.600/100.0/100.0]', txt) chirp_common.mem_from_text(txt) self.assertEqual(600000, mem.offset) self.assertEqual('-', mem.duplex) def test_mem_to_text2(self): mem = chirp_common.Memory() mem.freq = 146900000 mem.duplex = 'split' mem.offset = 446000000 mem.tmode = 'Cross' mem.cross_mode = 'Tone->DTCS' mem.rtone = 100.0 mem.rx_dtcs = 25 txt = chirp_common.mem_to_text(mem) self.assertEqual('[146.900000/446.000000/100.0/D025]', txt) chirp_common.mem_from_text(txt) def test_mem_to_text3(self): mem = chirp_common.Memory() mem.freq = 146520000 mem.duplex = '' mem.offset = 600000 mem.tmode = 'DTCS' mem.dtcs = 25 txt = chirp_common.mem_to_text(mem) self.assertEqual('[146.520000/D025/D025]', txt) chirp_common.mem_from_text(txt) def test_parse_power(self): valid = [ ('0.1', 0.1), ('0.1W', 0.1), ('0.25', 0.2), ('0.25W', 0.2), ('11.0', 11), ('11', 11), ('11.0W', 11), ('11w', 11), ('1500', 1500), ('2500', 2500), ('2500W', 2500), ('2500.0W', 2500)] for s, v in valid: power = chirp_common.parse_power(s) self.assertEqual(v, chirp_common.dBm_to_watts(float(power))) def test_parse_power_invalid(self): invalid = ['2500d', '2d1', 'aaa', 'a', ''] for s in invalid: self.assertRaises(ValueError, chirp_common.parse_power, s) class TestSplitTone(base.BaseTest): def _test_split_tone_decode(self, tx, rx, **vals): mem = chirp_common.Memory() chirp_common.split_tone_decode(mem, tx, rx) for key, value in list(vals.items()): self.assertEqual(getattr(mem, key), value) def test_split_tone_decode_none(self): self._test_split_tone_decode((None, None, None), (None, None, None), tmode='') def test_split_tone_decode_tone(self): self._test_split_tone_decode(('Tone', 100.0, None), ('', 0, None), tmode='Tone', rtone=100.0) def test_split_tone_decode_tsql(self): self._test_split_tone_decode(('Tone', 100.0, None), ('Tone', 100.0, None), tmode='TSQL', ctone=100.0) def test_split_tone_decode_dtcs(self): self._test_split_tone_decode(('DTCS', 23, None), ('DTCS', 23, None), tmode='DTCS', dtcs=23) def test_split_tone_decode_cross_tone_tone(self): self._test_split_tone_decode(('Tone', 100.0, None), ('Tone', 123.0, None), tmode='Cross', cross_mode='Tone->Tone', rtone=100.0, ctone=123.0) def test_split_tone_decode_cross_tone_dtcs(self): self._test_split_tone_decode(('Tone', 100.0, None), ('DTCS', 32, 'R'), tmode='Cross', cross_mode='Tone->DTCS', rtone=100.0, rx_dtcs=32, dtcs_polarity='NR') def test_split_tone_decode_cross_dtcs_tone(self): self._test_split_tone_decode(('DTCS', 32, 'R'), ('Tone', 100.0, None), tmode='Cross', cross_mode='DTCS->Tone', ctone=100.0, dtcs=32, dtcs_polarity='RN') def test_split_tone_decode_cross_dtcs_dtcs(self): self._test_split_tone_decode(('DTCS', 32, 'R'), ('DTCS', 25, 'R'), tmode='Cross', cross_mode='DTCS->DTCS', dtcs=32, rx_dtcs=25, dtcs_polarity='RR') def test_split_tone_decode_cross_none_dtcs(self): self._test_split_tone_decode((None, None, None), ('DTCS', 25, 'R'), tmode='Cross', cross_mode='->DTCS', rx_dtcs=25, dtcs_polarity='NR') def test_split_tone_decode_cross_none_tone(self): self._test_split_tone_decode((None, None, None), ('Tone', 100.0, None), tmode='Cross', cross_mode='->Tone', ctone=100.0) def _set_mem(self, **vals): mem = chirp_common.Memory() for key, value in list(vals.items()): setattr(mem, key, value) return chirp_common.split_tone_encode(mem) def split_tone_encode_test_none(self): self.assertEqual(self._set_mem(tmode=''), (('', None, None), ('', None, None))) def split_tone_encode_test_tone(self): self.assertEqual(self._set_mem(tmode='Tone', rtone=100.0), (('Tone', 100.0, None), ('', None, None))) def split_tone_encode_test_tsql(self): self.assertEqual(self._set_mem(tmode='TSQL', ctone=100.0), (('Tone', 100.0, None), ('Tone', 100.0, None))) def split_tone_encode_test_dtcs(self): self.assertEqual(self._set_mem(tmode='DTCS', dtcs=23, dtcs_polarity='RN'), (('DTCS', 23, 'R'), ('DTCS', 23, 'N'))) def split_tone_encode_test_cross_tone_tone(self): self.assertEqual(self._set_mem(tmode='Cross', cross_mode='Tone->Tone', rtone=100.0, ctone=123.0), (('Tone', 100.0, None), ('Tone', 123.0, None))) def split_tone_encode_test_cross_tone_dtcs(self): self.assertEqual(self._set_mem(tmode='Cross', cross_mode='Tone->DTCS', rtone=100.0, rx_dtcs=25), (('Tone', 100.0, None), ('DTCS', 25, 'N'))) def split_tone_encode_test_cross_dtcs_tone(self): self.assertEqual(self._set_mem(tmode='Cross', cross_mode='DTCS->Tone', ctone=100.0, dtcs=25), (('DTCS', 25, 'N'), ('Tone', 100.0, None))) def split_tone_encode_test_cross_none_dtcs(self): self.assertEqual(self._set_mem(tmode='Cross', cross_mode='->DTCS', rx_dtcs=25), (('', None, None), ('DTCS', 25, 'N'))) def split_tone_encode_test_cross_none_tone(self): self.assertEqual(self._set_mem(tmode='Cross', cross_mode='->Tone', ctone=100.0), (('', None, None), ('Tone', 100.0, None))) class TestStepFunctions(base.BaseTest): _625 = [145856250, 445856250, 862731250, 146118750, ] _125 = [145862500, 445862500, 862737500, ] _005 = [145005000, 445005000, 850005000, ] _025 = [145002500, 445002500, 850002500, ] def test_is_fractional_step(self): for freq in self._125 + self._625: print(freq) self.assertTrue(chirp_common.is_fractional_step(freq)) def test_is_6_25(self): for freq in self._625: self.assertTrue(chirp_common.is_6_25(freq)) def test_is_12_5(self): for freq in self._125: self.assertTrue(chirp_common.is_12_5(freq)) def test_is_5_0(self): for freq in self._005: self.assertTrue(chirp_common.is_5_0(freq)) def test_is_2_5(self): for freq in self._025: self.assertTrue(chirp_common.is_2_5(freq)) def test_required_step(self): steps = {2.5: self._025, 5.0: self._005, 6.25: self._625, 12.5: self._125, } for step, freqs in list(steps.items()): for freq in freqs: self.assertEqual(step, chirp_common.required_step(freq)) def test_required_step_with_list(self): steps = {5.0: self._005, 6.25: self._625, 12.5: self._125, } allowed = [6.25, 12.5] for step, freqs in list(steps.items()): for freq in freqs: # We don't support 5.0, so any of the frequencies in that # list should raise an error if step == 5.0: self.assertRaises(errors.InvalidDataError, chirp_common.required_step, freq, allowed) else: self.assertEqual(step, chirp_common.required_step( freq, allowed)) def test_required_step_finds_suitable(self): # If we support 5.0, we should get it as the step for those self.assertEqual(5.0, chirp_common.required_step(self._005[0], allowed=[2.5, 5.0])) # If we support 2.5 and not 5.0, then we should find 2.5 as a suitable # alternative self.assertEqual(2.5, chirp_common.required_step(self._005[0], allowed=[2.5])) def test_required_step_fail(self): self.assertRaises(errors.InvalidDataError, chirp_common.required_step, 146520500) def test_fix_rounded_step_250(self): self.assertEqual(146106250, chirp_common.fix_rounded_step(146106000)) def test_fix_rounded_step_500(self): self.assertEqual(146112500, chirp_common.fix_rounded_step(146112000)) def test_fix_rounded_step_750(self): self.assertEqual(146118750, chirp_common.fix_rounded_step(146118000)) class TestImageMetadata(base.BaseTest): def test_make_metadata(self): class TestRadio(chirp_common.CloneModeRadio): VENDOR = 'Dan' MODEL = 'Foomaster 9000' VARIANT = 'R' r = TestRadio(None) r._metadata['someextra'] = 'foo' # We should always take the base properties from the class, so this # should not show up in the result. r._metadata['vendor'] = 'oops' raw_metadata = r._make_metadata() metadata = json.loads(base64.b64decode(raw_metadata).decode()) expected = { 'vendor': 'Dan', 'model': 'Foomaster 9000', 'variant': 'R', 'rclass': 'TestRadio', 'chirp_version': CHIRP_VERSION, 'someextra': 'foo', } self.assertEqual(expected, metadata) def test_strip_metadata(self): class TestRadio(chirp_common.CloneModeRadio): VENDOR = 'Dan' MODEL = 'Foomaster 9000' VARIANT = 'R' r = TestRadio(None) r._metadata['someextra'] = 'foo' raw_metadata = r._make_metadata() raw_data = (b'foooooooooooooooooooooo' + TestRadio.MAGIC + raw_metadata) data, metadata = chirp_common.CloneModeRadio._strip_metadata(raw_data) self.assertEqual(b'foooooooooooooooooooooo', data) expected = { 'vendor': 'Dan', 'model': 'Foomaster 9000', 'variant': 'R', 'rclass': 'TestRadio', 'someextra': 'foo', 'chirp_version': CHIRP_VERSION, } self.assertEqual(expected, metadata) def test_load_mmap_no_metadata(self): fn = os.path.join(tempfile.gettempdir(), 'testfile') with open(fn, 'wb') as f: f.write(b'thisisrawdata') f.flush() with mock.patch('chirp.memmap.MemoryMap') as mock_mmap: chirp_common.CloneModeRadio(None).load_mmap(fn) mock_mmap.assert_called_once_with(b'thisisrawdata') os.remove(fn) def test_load_mmap_bad_metadata(self): fn = os.path.join(tempfile.gettempdir(), 'testfile') with open(fn, 'wb') as f: f.write(b'thisisrawdata') f.write(chirp_common.CloneModeRadio.MAGIC + b'bad') f.flush() with mock.patch('chirp.memmap.MemoryMap') as mock_mmap: chirp_common.CloneModeRadio(None).load_mmap(fn) mock_mmap.assert_called_once_with(b'thisisrawdata') os.remove(fn) def test_save_mmap_includes_metadata(self): # Make sure that a file saved with a .img extension includes # the metadata blob class TestRadio(chirp_common.CloneModeRadio): VENDOR = 'Dan' MODEL = 'Foomaster 9000' VARIANT = 'R' fn = os.path.join(tempfile.gettempdir(), 'test.img') r = TestRadio(None) r._mmap = mock.Mock() r._mmap.get_byte_compatible.return_value.get_packed.return_value = ( b'thisisrawdata') r.save_mmap(fn) with open(fn, 'rb') as f: filedata = f.read() os.remove(fn) data, metadata = chirp_common.CloneModeRadio._strip_metadata(filedata) self.assertEqual(b'thisisrawdata', data) expected = { 'vendor': 'Dan', 'model': 'Foomaster 9000', 'variant': 'R', 'rclass': 'TestRadio', 'chirp_version': CHIRP_VERSION, } self.assertEqual(expected, metadata) def test_save_mmap_no_metadata_not_img_file(self): # Make sure that if we save without a .img extension we do # not include the metadata blob class TestRadio(chirp_common.CloneModeRadio): VENDOR = 'Dan' MODEL = 'Foomaster 9000' VARIANT = 'R' with tempfile.NamedTemporaryFile(suffix='.txt') as f: fn = f.name r = TestRadio(None) r._mmap = mock.Mock() r._mmap.get_byte_compatible.return_value.get_packed.return_value = ( b'thisisrawdata') r.save_mmap(fn) with open(fn, 'rb') as f: filedata = f.read() os.remove(fn) data, metadata = chirp_common.CloneModeRadio._strip_metadata(filedata) self.assertEqual(b'thisisrawdata', data) self.assertEqual({}, metadata) def test_load_mmap_saves_metadata_on_radio(self): class TestRadio(chirp_common.CloneModeRadio): VENDOR = 'Dan' MODEL = 'Foomaster 9000' VARIANT = 'R' with tempfile.NamedTemporaryFile(suffix='.img') as f: fn = f.name r = TestRadio(None) r._mmap = mock.Mock() r._mmap.get_byte_compatible.return_value.get_packed.return_value = ( b'thisisrawdata') r.save_mmap(fn) newr = TestRadio(None) newr.load_mmap(fn) expected = { 'vendor': 'Dan', 'model': 'Foomaster 9000', 'variant': 'R', 'rclass': 'TestRadio', 'chirp_version': CHIRP_VERSION, } self.assertEqual(expected, newr.metadata) def test_sub_devices_linked_metadata(self): class FakeRadio(chirp_common.CloneModeRadio): def get_sub_devices(self): return [FakeRadioSub('a'), FakeRadioSub('b')] class FakeRadioSub(FakeRadio): def __init__(self, name): self.VARIANT = name r = FakeRadio(None) subs = r.get_sub_devices() r.link_device_metadata(subs) subs[1]._metadata['foo'] = 'bar' self.assertEqual({'a': {}, 'b': {'foo': 'bar'}}, r._metadata) class FakeRadio(chirp_common.CloneModeRadio): def __init__(self, *a, **k): super().__init__(*a, **k) self._mems = {} def get_memory(self, number): return self._mems[number] def set_memory(self, mem): # Simulate not storing the comment in our memory mem = copy.deepcopy(mem) mem.comment = '' self._mems[mem.number] = mem class TestCloneModeExtras(base.BaseTest): def test_extra_comment(self): r = FakeRadio(None) m = chirp_common.Memory() m.number = 0 m.freq = 146520000 m.comment = 'a comment' r.set_memory(m) # Make sure our fake driver didn't modify our copy self.assertEqual('a comment', m.comment) m = r.get_memory(0) self.assertEqual(146520000, m.freq) # Before we call extra, we have no comment self.assertEqual('', m.comment) m = r.get_memory_extra(m) # We haven't called set_extra, so still nothing self.assertEqual('', m.comment) # Do a normal set, set_extra m.comment = 'a comment' r.set_memory(m) r.set_memory_extra(m) # Do a get, get_extra m = r.get_memory(0) m = r.get_memory_extra(m) self.assertEqual(146520000, m.freq) # Now we should have the comment self.assertEqual('a comment', m.comment) # Make sure it is in the metadata self.assertIn('0000_comment', r.metadata['mem_extra']) # Erase the memory (only extra) and make sure we get no comment r.erase_memory_extra(0) # Make sure it's gone from metadata self.assertNotIn('0000_comment', r.metadata['mem_extra']) # Do a get, get_extra m = r.get_memory(0) m = r.get_memory_extra(m) self.assertEqual(146520000, m.freq) # Now we should have no comment because we erased self.assertEqual('', m.comment) r.set_memory_extra(m) # Make sure we don't keep empty comments self.assertNotIn('0000_comment', r.metadata['mem_extra']) class TestOverrideRules(base.BaseTest): # You should not need to add your radio to this list. If you think you do, # please ask permission first. IMMUTABLE_WHITELIST = [ # Uncomment me when the time comes 'Baofeng_GT-5R', 'BTECH_GMRS-20V2', 'BTECH_GMRS-50V2', 'BTECH_GMRS-50X1', 'BTECH_GMRS-V2', 'BTECH_MURS-V2', 'Radioddity_DB25-G', 'Retevis_RB17P', 'Baofeng_UV-17ProGPS', 'Baofeng_5RM', ] def _test_radio_override_immutable_policy(self, rclass): self.assertEqual( chirp_common.Radio.check_set_memory_immutable_policy, rclass.check_set_memory_immutable_policy, 'Radio %s should not override ' 'check_set_memory_immutable_policy' % ( directory.radio_class_id(rclass))) def _test_radio_override_calls_super(self, rclass): r = rclass(None) method = r.check_set_memory_immutable_policy # Make sure the radio actually overrides it self.assertNotEqual( chirp_common.Radio.check_set_memory_immutable_policy, method, ('Radio %s in whitelist does not override ' 'check_set_memory_immutable_policy') % ( directory.radio_class_id(rclass))) # Make sure super() is called in the child class self.assertIn('__class__', method.__code__.co_freevars, '%s.%s must call super() but does not' % ( rclass.__name__, method.__name__)) def test_radio_overrides(self): for rclass in directory.DRV_TO_RADIO.values(): if directory.radio_class_id(rclass) in self.IMMUTABLE_WHITELIST: self._test_radio_override_calls_super(rclass) else: self._test_radio_override_immutable_policy(rclass) class TestMemory(base.BaseTest): def test_pickle_with_extra(self): m = chirp_common.Memory() m.extra = settings.RadioSettingGroup('extra', 'extra') m.extra.append(settings.RadioSetting( 'test', 'test', settings.RadioSettingValueString(1, 32, current='foo'))) n = pickle.loads(pickle.dumps(m)) self.assertEqual(str(n.extra['test'].value), str(m.extra['test'].value)) def test_frozen_from_frozen(self): m = chirp_common.FrozenMemory(chirp_common.Memory(123)) n = chirp_common.FrozenMemory(m) self.assertEqual(123, n.number) def test_frozen_dupe_unfrozen(self): FrozenMemory = chirp_common.FrozenMemory( chirp_common.Memory()).__class__ m = chirp_common.FrozenMemory(chirp_common.Memory(123)).dupe() self.assertNotIsInstance(m, FrozenMemory) self.assertFalse(hasattr(m, '_frozen')) def test_frozen_modifications(self): orig = chirp_common.Memory(123) orig.extra = [settings.RadioSetting( 'foo', 'Foo', settings.RadioSettingValueBoolean(False))] frozen = chirp_common.FrozenMemory(orig) with self.assertRaises(ValueError): frozen.extra[0].value = True def test_tone_validator(self): m = chirp_common.Memory() # 100.0 is a valid tone m.rtone = 100.0 m.ctone = 100.0 # 100 is not (must be a float) with self.assertRaises(ValueError): m.rtone = 100 with self.assertRaises(ValueError): m.ctone = 100 # 30.0 and 300.0 are out of range with self.assertRaises(ValueError): m.rtone = 30.0 with self.assertRaises(ValueError): m.rtone = 300.0 with self.assertRaises(ValueError): m.ctone = 30.0 with self.assertRaises(ValueError): m.ctone = 300.0 def test_repr_dump(self): m = chirp_common.Memory() self.assertEqual( "Tone',dtcs_polarity='NN'," "skip='',power=None,duplex='',offset=600000,mode='FM'," "tuning_step=5.0,comment='',empty=False,immutable=[]>", repr(m)) m.freq = 146520000 m.rtone = 107.2 m.tmode = 'Tone' self.assertEqual( "Tone'," "dtcs_polarity='NN',skip='',power=None,duplex='',offset=600000," "mode='FM',tuning_step=5.0,comment='',empty=False,immutable=[]>", repr(m)) m.number = 101 m.extd_number = 'Call' self.assertEqual( "", repr(m)) m.extra = settings.RadioSettingGroup('extra', 'Extra') m.extra.append( settings.RadioSetting('test1', 'Test Setting 1', settings.RadioSettingValueBoolean(False))) m.extra.append( settings.RadioSetting('test2', 'Test Setting 2', settings.RadioSettingValueList( ['foo', 'bar'], 'foo'))) self.assertEqual( "", repr(m)) def test_debug_diff(self): m1 = chirp_common.Memory(1) m2 = chirp_common.Memory(1) m1.freq = 146520000 m2.freq = 446000000 self.assertEqual('freq=146520000>446000000', m1.debug_diff(m2, '>')) m2.tmode = 'TSQL' self.assertEqual("freq=146520000/446000000,tmode=''/'TSQL'", m1.debug_diff(m2)) # Make sure ident diffs come first and are noticed m2.number = 2 m2.freq = 146520000 self.assertEqual("ident=1/2,tmode=''/'TSQL'", m1.debug_diff(m2)) # Make sure we can diff extras, and amongst heterogeneous formats m2.number = 1 m1.extra = settings.RadioSettingGroup('extra', 'Extra') m2.extra = settings.RadioSettingGroup('extra', 'Extra') m1.extra.append( settings.RadioSetting('test1', 'Test Setting 1', settings.RadioSettingValueBoolean(False))) m2.extra.append( settings.RadioSetting('test2', 'Test Setting 2', settings.RadioSettingValueList( ['foo', 'bar'], 'foo'))) self.assertEqual( "extra.test1='False'/'',extra.test2=''/'foo'," "tmode=''/'TSQL'", m1.debug_diff(m2)) class TestRadioFeatures(base.BaseTest): def test_valid_tones(self): rf = chirp_common.RadioFeatures() # These are valid tones rf.valid_tones = [100.0, 107.2] # These contain invalid tones with self.assertRaises(ValueError): rf.valid_tones = [100.0, 30.0] with self.assertRaises(ValueError): rf.valid_tones = [100.0, 300.0] with self.assertRaises(ValueError): rf.valid_tones = [100, 107.2] chirp-20240224/tests/unit/test_bandplan.py0000644000175000017500000000155414430171343017352 0ustar hibbyhibbyimport unittest from chirp import bandplan class FakeConfig: def __init__(self, bandplan): self.bandplan = bandplan def is_defined(self, opt, sec): return True def get(self, opt, sec): return None def get_bool(self, opt, sec): return opt == self.bandplan class BandPlanTest(unittest.TestCase): def test_get_repeater_bands(self): plans = bandplan.BandPlans(FakeConfig('north_america')) expected = ['10 Meter Band', '6 Meter Band', '2 Meter Band', '1.25 Meter Band', '70 Centimeter Band', '33 Centimeter Band', '23 Centimeter Band', '13 Centimeter Band'] self.assertEqual(expected, [b.name for b in plans.get_repeater_bands()]) chirp-20240224/tests/unit/test_kguv920.py0000644000175000017500000000371714411666130017007 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import unittest from chirp.drivers import kguv920pa from chirp import memmap class FakeSerial: def __init__(self): self.ibuf = b'' self.obuf = b'' def write(self, b): assert isinstance(b, bytes) self.obuf += b def read(self, n): print('read %i (rem %i)' % (n, len(self.ibuf))) r = self.ibuf[:n] self.ibuf = self.ibuf[n:] return r class TestClone(unittest.TestCase): def test_identify(self): s = FakeSerial() s.ibuf = struct.pack( 'BBBB10sB', 0, 0, 0, len(kguv920pa.KGUV920PARadio._model), kguv920pa._str_encode(kguv920pa.KGUV920PARadio._model), 3) print(s.ibuf) d = kguv920pa.KGUV920PARadio(s) d._identify() def test_download(self): s = FakeSerial() oneresp = struct.pack('xxxB16sB', 0x10, b'\x01' * 16, 0) s.ibuf = oneresp * 2 d = kguv920pa.KGUV920PARadio(s) d._do_download(0, 0x20, 0x10) def test_upload(self): s = FakeSerial() s.ibuf = (struct.pack('>xxxBHB', 0x02, 0, 2) + struct.pack('>xxxBHB', 0x02, 0x10, 2)) d = kguv920pa.KGUV920PARadio(s) d._mmap = memmap.MemoryMapBytes(b'\x00' * 0x20) d._do_upload(0, 0x20, 0x10) chirp-20240224/tests/unit/test_alinco_clone.py0000644000175000017500000001265414430171343020223 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import binascii import os import unittest from unittest import mock from chirp import directory from chirp.drivers import alinco from chirp import memmap class FakeAlincoSerial: """Behaves like a Serial with an Alinco radio connected""" def __init__(self, image): self.image = memmap.MemoryMapBytes(open(image, 'rb').read()) self.readbuf = [] self.ident = b'' def zero(self): """Zero the mmap before an upload""" self.image = memmap.MemoryMapBytes(b'\x00' * len(self.image)) def _handle_rw(self, data): if b'R' in data: cmdindex = data.index(b'R') elif b'W' in data: cmdindex = data.index(b'W') else: raise Exception('Unable to handle RW command %r' % data) if cmdindex - 4 == 4: block_size = 16 else: block_size = 64 addr = int(data[4:cmdindex], 16) cmd = data[cmdindex:cmdindex + 1] if cmd == b'R': chunk = binascii.hexlify(self.image[addr:addr + block_size]) if b'DJ175' in self.ident: # The DJ175 uses 16-byte blocks, but without the colon # separator self.readbuf.append(b'%s\r\n' % chunk) elif block_size == 64: self.readbuf.append(b'\r\n%s\r\n' % chunk) else: self.readbuf.append(b'\r\n%04X:%s\r\n' % (addr, chunk)) elif cmd == b'W': chunk = binascii.unhexlify(data[cmdindex + 1:].rstrip()) if len(chunk) != block_size: raise Exception('Expected %i, got %i' % (block_size, len(chunk))) self.image[addr] = chunk if block_size == 64: self.readbuf.append(b'OK\r\n\r\n') else: raise Exception('Unable to handle command %s: %r' % (cmd, data)) def write(self, data): """Write to the radio (i.e. buffer some response for read)""" # Serial port echo self.readbuf.append(data) ident_ack = b'OK\r\n\r\n' if data.startswith(b'DR'): self.ident = data.strip() self.readbuf.append(ident_ack) elif data.startswith(b'AL~DJ-G7'): self.ident = data.strip() self.readbuf.append(ident_ack) elif data.startswith(b'DJ'): self.ident = data.strip() self.readbuf.append(ident_ack) elif data.startswith(b'AL~F'): self._handle_rw(data) elif data.startswith(b'AL~E'): self.readbuf.append(b'OK' * 10) else: raise Exception('Unable to handle %r' % data) def read(self, length): """Read from the radio (i.e. generate a radio's response)""" if len(self.readbuf[0]) == length: return self.readbuf.pop(0) else: raise Exception('Read of %i not match %i %r' % ( length, len(self.readbuf[0]), self.readbuf[0])) class AlincoCloneTest(unittest.TestCase): def _test_alinco_download(self, rclass, image): pipe = FakeAlincoSerial(image) radio = rclass(pipe) radio.sync_in() if not radio.NEEDS_COMPAT_SERIAL: self.assertIsInstance(radio._mmap, memmap.MemoryMapBytes) def _test_alinco_upload(self, rclass, image): pipe = FakeAlincoSerial(image) pipe.zero() radio = rclass(image) radio.pipe = pipe radio.sync_out() ref_image = open(image, 'rb').read() self.assertEqual(ref_image[0x200:rclass._memsize], pipe.image.get_packed()[0x200:rclass._memsize]) def _test_alinco(self, rclass): ident = directory.radio_class_id(rclass) image = os.path.join(os.path.dirname(__file__), '..', 'images', '%s.img' % ident) with mock.patch('time.sleep'): self._test_alinco_upload(rclass, image) self._test_alinco_download(rclass, image) def test_djg7(self): self._test_alinco(alinco.AlincoDJG7EG) def test_dr235(self): self._test_alinco(alinco.DR235Radio) def test_dj175(self): # The 175 has a slightly different download string, so test it # specifically self._test_alinco(alinco.DJ175Radio) def test_all_alinco_identify(self): # Make sure all the alinco models have bytes for their _model # and can identify properly alincos = [x for x in directory.DRV_TO_RADIO.values() if x.VENDOR == 'Alinco'] for rclass in alincos: pipe = FakeAlincoSerial(__file__) radio = rclass(None) radio.pipe = pipe radio._identify() self.assertEqual(pipe.ident, radio._model) chirp-20240224/tests/unit/test_directory.py0000644000175000017500000001254714430171343017603 0ustar hibbyhibbyimport base64 import glob import json import os import shutil import tempfile import yaml from tests.unit import base from chirp import chirp_common from chirp import directory class TestDirectory(base.BaseTest): def cleanUp(self): shutil.rmtree(self.tempdir) def setUp(self): super(TestDirectory, self).setUp() self.tempdir = tempfile.mkdtemp() directory.enable_reregistrations() class FakeAlias(chirp_common.Alias): VENDOR = 'Taylor' MODEL = 'Barmaster 2000' VARIANT = 'A' @directory.register class FakeRadio(chirp_common.CloneModeRadio): VENDOR = 'Dan' MODEL = 'Foomaster 9000' VARIANT = 'R' ALIASES = [FakeAlias] @classmethod def match_model(cls, file_data, image_file): return file_data == b'thisisrawdata' self.test_class = FakeRadio def _test_detect_finds_our_class(self, tempfn): radio = directory.get_radio_by_image(tempfn) self.assertTrue(isinstance(radio, self.test_class)) return radio def test_detect_with_no_metadata(self): fn = os.path.join(self.tempdir, 'testfile') with open(fn, 'wb') as f: f.write(b'thisisrawdata') f.flush() self._test_detect_finds_our_class(fn) def test_detect_with_metadata_base_class(self): fn = os.path.join(self.tempdir, 'testfile') with open(fn, 'wb') as f: f.write(b'thisisrawdata') f.write(self.test_class.MAGIC + b'-') f.write(self.test_class(None)._make_metadata()) f.flush() self._test_detect_finds_our_class(fn) def test_detect_with_metadata_alias_class(self): fn = os.path.join(self.tempdir, 'testfile') with open(fn, 'wb') as f: f.write(b'thisisrawdata') f.write(self.test_class.MAGIC + b'-') FakeAlias = self.test_class.ALIASES[0] fake_metadata = base64.b64encode(json.dumps( {'vendor': FakeAlias.VENDOR, 'model': FakeAlias.MODEL, 'variant': FakeAlias.VARIANT, }).encode()) f.write(fake_metadata) f.flush() radio = self._test_detect_finds_our_class(fn) self.assertEqual('Taylor', radio.VENDOR) self.assertEqual('Barmaster 2000', radio.MODEL) self.assertEqual('A', radio.VARIANT) class TestDetectBruteForce(base.BaseTest): def test_detect_all(self): # Attempt a brute-force detection of all test images. # # This confirms that no test image is detected by more than one # radio class. If it is, fail and report those classes. path = os.path.dirname(__file__) path = os.path.join(path, '..', 'images', '*.img') test_images = glob.glob(path) self.assertNotEqual(0, len(test_images)) for image in test_images: detections = [] filedata = open(image, 'rb').read() for cls in directory.RADIO_TO_DRV: if not hasattr(cls, 'match_model'): continue if cls.match_model(filedata, image): detections.append(cls) if len(detections) > 1: raise Exception('Detection of %s failed: %s' % (image, detections)) class TestAliasMap(base.BaseTest): def test_uniqueness(self): directory_models = {} for rclass in directory.DRV_TO_RADIO.values(): for cls in [rclass] + rclass.ALIASES: # Make sure there are no duplicates directory_models.setdefault(cls.VENDOR, set()) fullmodel = '%s%s' % (cls.MODEL, cls.VARIANT) self.assertNotIn(fullmodel, directory_models[cls.VENDOR]) directory_models[cls.VENDOR].add(fullmodel) aliases = yaml.load(open(os.path.join(os.path.dirname(__file__), '..', '..', 'chirp', 'share', 'model_alias_map.yaml')).read(), Loader=yaml.FullLoader) for vendor, models in sorted(aliases.items()): directory_models.setdefault(vendor, set()) my_aliases = set([x['model'] for x in models]) vendor = vendor.split('/')[0] for model in models: # Make sure the thing we tell users to use is in the # directory try: alt_vendor, alt_model = model['alt'].split(' ', 1) except ValueError: alt_vendor = vendor alt_model = model['alt'] # Aliases may reference other aliases? self.assertIn(alt_model, directory_models[alt_vendor] | my_aliases, '%s %s not found for %s %s' % ( alt_vendor, alt_model, vendor, model['model'])) # Make sure the alias model is NOT in the directory # before we add it to ensure there are no duplicates self.assertNotIn(model['model'], directory_models[vendor]) directory_models[vendor].add(model['model']) chirp-20240224/tests/unit/test_th9800.py0000644000175000017500000000274614430171343016533 0ustar hibbyhibbyimport os import unittest from chirp.drivers import th9800 class Fake9800: ident = (b'\x54\x48\x39\x38\x30\x30\xff\xff' b'\x56\x31\x34\x78\xff\xff\xff\xff') def __init__(self): self.writebuf = b'' # Pre-load the identify dance self.readbuf = b'A' + self.ident def write(self, data): assert isinstance(data, bytes) self.writebuf += data if data.startswith(b'R'): self.readbuf += b'W\x00\x00\x00' + (b'\x00' * 0x80) elif data.startswith(b'W'): self.writebuf += data self.readbuf += b'A' elif data == b'A': assert len(self.readbuf) == 0 self.readbuf += b'A' elif data == b'ENDW': self.readbuf += b'123' def read(self, n): buf = self.readbuf[:n] self.readbuf = self.readbuf[n:] return buf class TestTH9800(unittest.TestCase): def test_identify(self): f = Fake9800() r = th9800.TYTTH9800Radio(f) ident = th9800._identify(r) self.assertEqual(f.ident, ident) self.assertEqual(b'\x02PROGRAM\x02A', f.writebuf) def test_download(self): f = Fake9800() r = th9800.TYTTH9800Radio(f) r.sync_in() def test_upload(self): f = Fake9800() img = os.path.join(os.path.dirname(__file__), '..', 'images', 'TYT_TH-9800.img') r = th9800.TYTTH9800Radio(img) r.set_pipe(f) r.sync_out() chirp-20240224/tests/unit/__pycache__/0000755000175000017500000000000014566340177016402 5ustar hibbyhibbychirp-20240224/tests/unit/__pycache__/test_chirp_common.cpython-310-pytest-7.1.3.pyc0000644000175000017500000007517614565076105026625 0ustar hibbyhibbyo F{дeьу@sDddlZddlmmZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddlmZddlmZddlmZddlmZddlmZddlmZGd d „d ejƒZGd d „d ejƒZGd d„dejƒZGdd„dejƒZGdd„dejƒZGdd„dejƒZGdd„dejƒZGdd„dejƒZGdd„dejƒZ dS)щN)кmock)кbase)к CHIRP_VERSION)к chirp_common)к directory)кerrors)кsettingsc@seZdZdd„Zdd„Zdd„Zdd„Zd d „Zej d d d dd„ƒZ ej d dd dd„ƒZ dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+d,„Zd-d.„Zd/d0„Zd1d2„Zd3d4„Zd5d6„Zd7d8„Zd9d:„Zd;d<„Z d=d>„Z!d?S)@кTestUtilityFunctionscCsp| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t d Ёd ЁdS) Nњ 146.520000щРЗЛz146.5200z146.52к146i€ШГк1250щ€|Jк 123456789l@/ "AЉк assertEqualrк parse_freqЉкselfЉrњT/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_chirp_common.pyкtest_parse_freq_wholes џz*TestUtilityFunctions.test_parse_freq_wholecCs”| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t d ЁdЁ| t d Ёd Ё| t d ЁdЁdS) Nz1.0щ@Bz1.000000z1.1iрШz1.100z0.6щР' z0.600z0.060i`ъz.6rrrrrкtest_parse_freq_decimalsz,TestUtilityFunctions.test_parse_freq_decimalcCs”| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁd Ё| t d Ёd ЁdS) Nz1 rz 1z 1 z1.0 z 1.0z 1.0 кrњ rrrrrкtest_parse_freq_whitespace&sz/TestUtilityFunctions.test_parse_freq_whitespacecCsD| ttjdЁ| ttjdЁ| ttjdЁ| ttjdЁdS)Nкaz1.aza.bz 1.0000001)к assertRaisesк ValueErrorrrrrrrкtest_parse_freq_bad1s  џz(TestUtilityFunctions.test_parse_freq_badcCs^| t dЁdЁ| t dЁdЁ| t dЁdЁ| t dЁdЁ| t d Ёd ЁdS) Nr r i€љ7z 54.000000i@wz1.800000щz0.000001rz 1250.000000)rrк format_freqrrrrкtest_format_freq8s z%TestUtilityFunctions.test_format_freqzchirp.CHIRP_VERSIONzdaily-20151021)кnewcCsD| t dЁЁ| t dЁЁ| t dЁЁ| t dЁЁdS)Nњdaily-20180101zdaily-20140101z0.3.0њ0.3.0dev)к assertTruerкis_version_newerк assertFalserrrrкtest_compare_version_to_current?sz4TestUtilityFunctions.test_compare_version_to_currentr'cCs| t dЁЁdS)Nr&)r(rr)rrrrк#test_compare_version_to_current_devFsz8TestUtilityFunctions.test_compare_version_to_current_devcCs:| dt dЁЁ| dt dЁЁ| dt dЁЁdS)NщŒl ю iŸеiБ6)rrкfrom_GHzкfrom_MHzкfrom_kHzrrrrк test_from_HzJsz!TestUtilityFunctions.test_from_HzcCѓbd}t |Ё}| |Ё| d|jЁ| d|jЁ| d|jЁ| d|jЁ| d|jЁdS)Nz145.2500 -0.6 MHz 97.4 OPENiаVЈrњ-кTonegš™™™™YX@Љ rк mem_from_textкassertIsNotNonerкfreqкoffsetкduplexкtmodeкrtoneЉrкtextкmemrrrкtest_mem_from_text_rb1Qѓ  z+TestUtilityFunctions.test_mem_from_text_rb1cCr2)Nz'147.3000 +0.6 MHz 156.7 / 156.7 OPENi žЧrњ+кTSQLgfffff–c@) rr6r7rr8r9r:r;кctoner=rrrкtest_mem_from_text_rb2[rAz+TestUtilityFunctions.test_mem_from_text_rb2cCr2)Nz#441.1000 +5 MHz D125 / D125 OPENщрІJщ@KLrBкDTCSщ}) rr6r7rr8r9r:r;кdtcsr=rrrкtest_mem_from_text_rb3erAz+TestUtilityFunctions.test_mem_from_text_rb3cCs~d}t |Ё}| |Ё| d|jЁ| d|jЁ| d|jЁ| d|jЁ| d|jЁ| d|j Ё| d|j ЁdS) Nz#441.1000 +5 MHz 88.5 / D125 OPENrFrGrBкCrossч V@rIњ Tone->DTCS) rr6r7rr8r9r:r;r<кrx_dtcsк cross_moder=rrrкtest_mem_from_text_rb4os  z+TestUtilityFunctions.test_mem_from_text_rb4cCr2)NzGlass Butte 147.200 + 162.2щЦrrBr4чfffffFd@r5r=rrrкtest_mem_from_text_random1{ѓ  z/TestUtilityFunctions.test_mem_from_text_random1cCr2)NzGlass - Butte 147.200 + 162.2rRrrBr4rSr5r=rrrкtest_mem_from_text_random2ˆrUz/TestUtilityFunctions.test_mem_from_text_random2cCr2)NzGlass - Butte 147.200 + 88.5rRrrBr4rMr5r=rrrкtest_mem_from_text_random3•rUz/TestUtilityFunctions.test_mem_from_text_random3cCr2)Nz146.640 | 146.040 | 136.5i€ŒНrr3r4ga@r5r=rrrкtest_mem_from_text_random4ЂrAz/TestUtilityFunctions.test_mem_from_text_random4cCsd}t |ЁdS)Nz[400.625000/136.000000])rr6)rr>rrrкtest_mem_from_text_chirp1Ќsz.TestUtilityFunctions.test_mem_from_text_chirp1cCѓ<d}t |Ё}| d|jЁ| d|jЁ| d|jЁdS)Nz[462.675000/+5.000/136.5/136.5]i8м“rBrGЉrr6rr8r:r9r=rrrкtest_mem_from_text_chirp2Аѓ  z.TestUtilityFunctions.test_mem_from_text_chirp2cCrZ)Nz[1.675000/1.685/136.5/136.5]iјŽrBi'r[r=rrrкtest_mem_from_text_chirp3Зr]z.TestUtilityFunctions.test_mem_from_text_chirp3cCrZ)Nz[450.000000/150.000000]щ€tвщ€б№кsplitЉrr6rr8r9r:r=rrrкtest_mem_from_text_chirp4Оr]z.TestUtilityFunctions.test_mem_from_text_chirp4cCsNd}t |Ё}| d|jЁ| d|jЁ| d|jЁ| |t |ЁЁdS)Nz[500.000000/-9.900]ieЭiр—r3)rr6rr8r9r:к mem_to_textr=rrrкtest_mem_from_text_chirp5Хs  z.TestUtilityFunctions.test_mem_from_text_chirp5cCrZ)Nz[450.000000/150.000]r_r`rarbr=rrrкtest_mem_from_text_chirp6Эr]z.TestUtilityFunctions.test_mem_from_text_chirp6cCrZ)Nz[450.000000/+15.000]r_iРсфrarbr=rrrкtest_mem_from_text_chirp7дѓ  z.TestUtilityFunctions.test_mem_from_text_chirp7cCrZ)Nz[450.000000/+150.000]r_r`rarbr=rrrкtest_mem_from_text_chirp8нrhz.TestUtilityFunctions.test_mem_from_text_chirp8cCsft Ё}d|_d|_d|_d|_d|_t |Ё}| d|Ёt  |Ё| d|jЁ| d|jЁdS)Nщ „Сr3rrCчY@z[146.900000/-0.600/100.0/100.0]) rкMemoryr8r:r9r;rDrdrr6Љrr?кtxtrrrкtest_mem_to_text1цs   z&TestUtilityFunctions.test_mem_to_text1cCsVt Ё}d|_d|_d|_d|_d|_d|_d|_t  |Ё}|  d|Ёt  |ЁdS) Nrjraщ€k•rLrNrkщz"[146.900000/446.000000/100.0/D025]) rrlr8r:r9r;rPr<rOrdrr6rmrrrкtest_mem_to_text2ѓs  z&TestUtilityFunctions.test_mem_to_text2cCsJt Ё}d|_d|_d|_d|_d|_t |Ё}| d|Ёt  |ЁdS)Nr rrrHrqz[146.520000/D025/D025]) rrlr8r:r9r;rJrdrr6rmrrrкtest_mem_to_text3s  z&TestUtilityFunctions.test_mem_to_text3cCs:gdЂ}|D]\}}t |Ё}| |t t|ƒЁЁqdS)N) )z0.1чš™™™™™Й?)z0.1Wrt)z0.25чš™™™™™Щ?)z0.25Wru)z11.0щ )к11rv)z11.0Wrv)к11wrv)к1500iм)к2500щФ )к2500Wr{)z2500.0Wr{)rк parse_powerrк dBm_to_wattsкfloat)rкvalidкsкvкpowerrrrкtest_parse_power s  ўz%TestUtilityFunctions.test_parse_powercCs&gdЂ}|D] }| ttj|ЁqdS)N)к2500dк2d1кaaarr)rr rr})rкinvalidrrrrкtest_parse_power_invalidsџz-TestUtilityFunctions.test_parse_power_invalidN)"к__name__к __module__к __qualname__rrrr!r$rкpatchr+r,r1r@rErKrQrTrVrWrXrYr\r^rcrerfrgrirorrrsr„r‰rrrrr s@                    r c@sДeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Zd'd(„Zd)d*„Zd+S),к TestSplitTonecKsBt Ё}t |||Ёt| ЁƒD] \}}| t||ƒ|ЁqdSЉN)rrlкsplit_tone_decodeкlistкitemsrкgetattr)rкtxкrxкvalsr?кkeyкvaluerrrк_test_split_tone_decode$s џz%TestSplitTone._test_split_tone_decodecCs|jdddddS)NЉNNNrЉr;Љr™rrrrкtest_split_tone_decode_none*s ўz)TestSplitTone.test_split_tone_decode_nonecCs|jddddddS)NЉr4rkN)rrNr4rkЉr;r<rœrrrrкtest_split_tone_decode_tone/ѓ  §z)TestSplitTone.test_split_tone_decode_tonecCѓ|jddddddS)NržrCrkЉr;rDrœrrrrкtest_split_tone_decode_tsql5rЁz)TestSplitTone.test_split_tone_decode_tsqlcCrЂ)N)rHщNrHrЅ)r;rJrœrrrrкtest_split_tone_decode_dtcs;rЁz)TestSplitTone.test_split_tone_decode_dtcscCѓ|jddddddddS)NržЉr4чР^@NrLњ Tone->TonerkrЉЉr;rPr<rDrœrrrrк&test_split_tone_decode_cross_tone_toneAѓ ћz4TestSplitTone.test_split_tone_decode_cross_tone_tonec Cѓ|jdddddddddS) NržЉrHщ кRrLrNrkrАкNR)r;rPr<rOк dtcs_polarityrœrrrrк&test_split_tone_decode_cross_tone_dtcsIѓ њz4TestSplitTone.test_split_tone_decode_cross_tone_dtcsc CrЎ) NrЏržrLњ DTCS->TonerkrАкRN)r;rPrDrJrГrœrrrrк&test_split_tone_decode_cross_dtcs_toneRrЕz4TestSplitTone.test_split_tone_decode_cross_dtcs_tonec CrЎ) NrЏЉrHrqrБrLz DTCS->DTCSrАrqкRR)r;rPrJrOrГrœrrrrк&test_split_tone_decode_cross_dtcs_dtcs[rЕz4TestSplitTone.test_split_tone_decode_cross_dtcs_dtcscCrЇ)NršrЙrLњ->DTCSrqrВ)r;rPrOrГrœrrrrк&test_split_tone_decode_cross_none_dtcsdr­z4TestSplitTone.test_split_tone_decode_cross_none_dtcscCs|jdddddddS)NršržrLњ->TonerkЉr;rPrDrœrrrrк&test_split_tone_decode_cross_none_tonels  ќz4TestSplitTone.test_split_tone_decode_cross_none_tonecKs4t Ё}t| ЁƒD] \}}t|||ƒq t |ЁSr)rrlr‘r’кsetattrкsplit_tone_encode)rr–r?r—r˜rrrк_set_memss zTestSplitTone._set_memcCs| |jdddЁdS)Nrr›)ЉrNNrФЉrrУrrrrкsplit_tone_encode_test_noneysџz)TestSplitTone.split_tone_encode_test_nonecCѓ| |jddddЁdS)Nr4rkrŸ)ržrФrХrrrrкsplit_tone_encode_test_tone~ѓџz)TestSplitTone.split_tone_encode_test_tonecCrЧ)NrCrkrЃ)ržržrХrrrrкsplit_tone_encode_test_tsqlƒrЩz)TestSplitTone.split_tone_encode_test_tsqlcCѓ| |jdddddЁdS)NrHrЅrЗ)r;rJrГ))rHrЅrБ)rHrЅкNrХrrrrкsplit_tone_encode_test_dtcsˆѓ џўz)TestSplitTone.split_tone_encode_test_dtcscCѓ| |jddddddЁdS)NrLrЊrkrЉrЋ)ržrЈrХrrrrк&split_tone_encode_test_cross_tone_toneŽѓ џўz4TestSplitTone.split_tone_encode_test_cross_tone_tonecCrЯ)NrLrNrkrq)r;rPr<rO)ržЉrHrqrЬrХrrrrк&split_tone_encode_test_cross_tone_dtcs”rбz4TestSplitTone.split_tone_encode_test_cross_tone_dtcscCrЯ)NrLrЖrkrq)r;rPrDrJ)rвržrХrrrrк&split_tone_encode_test_cross_dtcs_tonešrбz4TestSplitTone.split_tone_encode_test_cross_dtcs_tonecCrЫ)NrLrМrq)r;rPrO)rФrвrХrrrrк&split_tone_encode_test_cross_none_dtcs rЮz4TestSplitTone.split_tone_encode_test_cross_none_dtcscCrЫ)NrLrОrkrП)rФržrХrrrrк&split_tone_encode_test_cross_none_toneІrЮz4TestSplitTone.split_tone_encode_test_cross_none_toneN)rŠr‹rŒr™rr rЄrІrЌrДrИrЛrНrРrУrЦrШrЪrЭrаrгrдrеrжrrrrrŽ#s,    rŽc@sŒeZdZgdЂZgdЂZgdЂZgdЂZdd„Zdd„Zd d „Z d d „Z d d„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd„ZdS)кTestStepFunctions)iњ–Бiњ9“iђ;l3щ^˜Е)idЏБidR“i\Tl3)iШ™ЄiШ<†i Њ2)iЄi3†iDЊ2cCs.|j|jD]}t|ƒ| t |ЁЁqdSr)к_125к_625кprintr(rкis_fractional_stepЉrr8rrrкtest_is_fractional_stepРsўz)TestStepFunctions.test_is_fractional_stepcCѓ |jD] }| t |ЁЁqdSr)rкr(rкis_6_25rнrrrк test_is_6_25Хѓ џzTestStepFunctions.test_is_6_25cCrпr)rйr(rкis_12_5rнrrrк test_is_12_5ЩrтzTestStepFunctions.test_is_12_5cCrпr)к_005r(rкis_5_0rнrrrк test_is_5_0ЭrтzTestStepFunctions.test_is_5_0cCrпr)к_025r(rкis_2_5rнrrrк test_is_2_5бrтzTestStepFunctions.test_is_2_5cCsL|j|j|j|jdœ}t| ЁƒD]\}}|D] }| |t |ЁЁqqdS)N)ч@ч@ч@ч)@) rшrхrкrйr‘r’rrк required_step)rкstepsкstepкfreqsr8rrrкtest_required_stepеs§џџz$TestStepFunctions.test_required_stepc Csp|j|j|jdœ}ddg}t| ЁƒD]"\}}|D]}|dkr*| tjtj ||Ёq|  |t  ||ЁЁqqdS)N)rьrэrюrэrюrь) rхrкrйr‘r’rrкInvalidDataErrorrrяr)rr№кallowedrёrђr8rrrкtest_required_step_with_listпs"ўў џјџz.TestStepFunctions.test_required_step_with_listcCsB| dtj|jdddgdЁ| dtj|jddgdЁdS)Nrьrrы)rѕ)rrrяrхrrrrк!test_required_step_finds_suitableёs џ џz3TestStepFunctions.test_required_step_finds_suitablecCs| tjtjdЁdS)NiДЙЛ)rrrєrrяrrrrкtest_required_step_failњsўz)TestStepFunctions.test_required_step_failcCѓ| dt dЁЁdS)NiŠgЕifЕЉrrкfix_rounded_steprrrrкtest_fix_rounded_step_250џѓџz+TestStepFunctions.test_fix_rounded_step_250cCrљ)NiєЕi~Еrњrrrrкtest_fix_rounded_step_500r§z+TestStepFunctions.test_fix_rounded_step_500cCrљ)Nrиip•Еrњrrrrкtest_fix_rounded_step_750r§z+TestStepFunctions.test_fix_rounded_step_750N)rŠr‹rŒrкrйrхrшrоrсrфrчrъrѓrіrїrјrќrўrџrrrrrз­s"   rзc@sLeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dS)кTestImageMetadatacCslGdd„dtjƒ}|dƒ}d|jd<d|jd<| Ё}t t |Ё ЁЁ}ddd dt dd œ}|  ||ЁdS) Nc@ѓeZdZdZdZdZdS)z7TestImageMetadata.test_make_metadata..TestRadioкDanњFoomaster 9000rБNЉrŠr‹rŒкVENDORкMODELкVARIANTrrrrк TestRadioѓrкfooк someextraкoopsкvendorrrrБ)r кmodelкvariantкrclassк chirp_versionr ) rкCloneModeRadioк _metadataк_make_metadataкjsonкloadsкbase64к b64decodeкdecoderr)rrкrк raw_metadataкmetadataкexpectedrrrкtest_make_metadata s  њz$TestImageMetadata.test_make_metadatacCsxGdd„dtjƒ}|dƒ}d|jd<| Ё}d|j|}tj |Ё\}}| d|Ёdddddtd œ}| ||ЁdS) Nc@r)z8TestImageMetadata.test_strip_metadata..TestRadiorrrБNrrrrrr%r rr r sfoooooooooooooooooooooorrrБ)r rrrr r)rrrrкMAGICк_strip_metadatarr)rrrrкraw_dataкdatarrrrrкtest_strip_metadata$s" џ њz%TestImageMetadata.test_strip_metadatacCs tj t ЁdЁ}t|dƒ}| dЁ| ЁWdƒn1s"wYt  dЁ}t   dЁ  |Ё|  dЁWdƒn1sDwYt |ЁdS)Nкtestfileкwbѓ thisisrawdataњchirp.memmap.MemoryMap)кosкpathкjoinкtempfileк gettempdirкopenкwriteкflushrrrrк load_mmapкassert_called_once_withкremoveЉrкfnкfк mock_mmaprrrкtest_load_mmap_no_metadata;s   ў  ўz,TestImageMetadata.test_load_mmap_no_metadatacCsВtj t ЁdЁ}t|dƒ}| dЁ| tjj dЁ|  ЁWdƒn1s+wYt   dЁ}t dЁ  |Ё| dЁWdƒn1sMwYt |ЁdS)Nr$r%r&sbadr')r(r)r*r+r,r-r.rrrr/rrr0r1r2r3rrrкtest_load_mmap_bad_metadataFs   §  ўz-TestImageMetadata.test_load_mmap_bad_metadatac CsЦGdd„dtjƒ}tj t ЁdЁ}|dƒ}t Ё|_ d|j j j j _ |  |Ёt|dƒ }| Ё}Wdƒn1s;wYt |Ёtj |Ё\}}| d|Ёddddtd œ}| ||ЁdS) Nc@r)zETestImageMetadata.test_save_mmap_includes_metadata..TestRadiorrrБNrrrrrrUr rztest.imgr&кrbrrrБЉr rrrr)rrr(r)r*r+r,rкMockк_mmapкget_byte_compatibleк return_valueк get_packedк save_mmapr-кreadr2r rr) rrr4rr5кfiledatar"rrrrrк test_save_mmap_includes_metadataRs(  џ   џ  ћz2TestImageMetadata.test_save_mmap_includes_metadatacCsжGdd„dtjƒ}tjdd }|j}Wdƒn1swY|dƒ}t Ё|_d|jjj j _ |  |Ёt |dƒ }|  Ё}Wdƒn1sKwYt |Ёtj |Ё\}}| d|Ё| i|ЁdS)Nc@r)zLTestImageMetadata.test_save_mmap_no_metadata_not_img_file..TestRadiorrrБNrrrrrrqr rz.txtЉкsuffixr&r9)rrr+кNamedTemporaryFileкnamerr;r<r=r>r?r@r-rAr(r2r r)rrr5r4rrBr"rrrrк'test_save_mmap_no_metadata_not_img_filens џ  џ   џ  z9TestImageMetadata.test_save_mmap_no_metadata_not_img_filecCsЂGdd„dtjƒ}tjdd }|j}Wdƒn1swY|dƒ}t Ё|_d|jjj j _ |  |Ё|dƒ}|  |Ёddddt d œ}| ||jЁdS) Nc@r)zKTestImageMetadata.test_load_mmap_saves_metadata_on_radio..TestRadiorrrБNrrrrrr…r rz.imgrDr&rrrБr:)rrr+rFrGrr;r<r=r>r?r@r0rrr)rrr5r4rкnewrrrrrк&test_load_mmap_saves_metadata_on_radio„s$џ  џ  ћz8TestImageMetadata.test_load_mmap_saves_metadata_on_radiocsjG‡fdd„dtjƒ}Gdd„d|ƒ‰|dƒ}| Ё}| |Ёd|djd<| iddidœ|jЁdS) NcseZdZ‡fdd„ZdS)zETestImageMetadata.test_sub_devices_linked_metadata..FakeRadiocsˆdƒˆdƒgS)NrкbrrЉк FakeRadioSubrrкget_sub_devicesŸszUTestImageMetadata.test_sub_devices_linked_metadata..FakeRadio.get_sub_devicesN)rŠr‹rŒrNrrLrrк FakeRadiožsrOc@ѓeZdZdd„ZdS)zHTestImageMetadata.test_sub_devices_linked_metadata..FakeRadioSubcSs ||_dSr)r)rrGrrrк__init__Ѓѓ zQTestImageMetadata.test_sub_devices_linked_metadata..FakeRadioSub.__init__N)rŠr‹rŒrQrrrrrMЂѓ rMкbarr"r )rrK)rrrNкlink_device_metadatarr)rrOrкsubsrrLrк test_sub_devices_linked_metadatas z2TestImageMetadata.test_sub_devices_linked_metadataN) rŠr‹rŒrr#r7r8rCrHrJrWrrrrr s   rcs,eZdZ‡fdd„Zdd„Zdd„Z‡ZS)rOcstƒj|i|ЄŽi|_dSr)кsuperrQк_mems)rrкkЉк __class__rrrQЎs zFakeRadio.__init__cCs |j|Sr)rY)rкnumberrrrк get_memoryВrRzFakeRadio.get_memorycCs t |Ё}d|_||j|j<dS)Nr)кcopyкdeepcopyкcommentrYr])rr?rrrк set_memoryЕs zFakeRadio.set_memory)rŠr‹rŒrQr^rbк __classcell__rrr[rrO­s rOc@rP)кTestCloneModeExtrascCs@tdƒ}t Ё}d|_d|_d|_| |Ё| d|jЁ| dЁ}| d|jЁ| d|jЁ|  |Ё}| d|jЁd|_| |Ё|  |Ё| dЁ}|  |Ё}| d|jЁ| d|jЁ|  d|j dЁ|  dЁ| d|j dЁ| dЁ}|  |Ё}| d|jЁ| d|jЁ|  |Ё| d|j dЁdS)Nrr z a commentrк 0000_commentк mem_extra)rOrrlr]r8rarbrr^кget_memory_extraкset_memory_extraкassertInrкerase_memory_extraк assertNotIn)rrкmrrrкtest_extra_commentНs8           z&TestCloneModeExtras.test_extra_commentN)rŠr‹rŒrmrrrrrdМrSrdc@s,eZdZgdЂZdd„Zdd„Zdd„ZdS) кTestOverrideRules) z Baofeng_GT-5RzBTECH_GMRS-20V2zBTECH_GMRS-50V2zBTECH_GMRS-50X1z BTECH_GMRS-V2z BTECH_MURS-V2zRadioddity_DB25-Gк Retevis_RB17PzBaofeng_UV-17ProGPSк Baofeng_5RMcCs"| tjj|jdt |ЁЁdS)Nz>Radio %s should not override check_set_memory_immutable_policy)rrкRadioк!check_set_memory_immutable_policyrкradio_class_idЉrrrrrк%_test_radio_override_immutable_policysў§z7TestOverrideRules._test_radio_override_immutable_policycCsL|dƒ}|j}| tjj|dt |ЁЁ| d|jjd|j |j fЁdS)NzIRadio %s in whitelist does not override check_set_memory_immutable_policyr\z$%s.%s must call super() but does not) rrкassertNotEqualrrqrrsriк__code__к co_freevarsrŠ)rrrкmethodrrrк _test_radio_override_calls_super sў§ џџz2TestOverrideRules._test_radio_override_calls_supercCs:tj ЁD]}t |Ё|jvr| |Ёq| |ЁqdSr)rк DRV_TO_RADIOкvaluesrsкIMMUTABLE_WHITELISTrzrurtrrrкtest_radio_overridess   ќz&TestOverrideRules.test_radio_overridesN)rŠr‹rŒr}rurzr~rrrrrnёs  rnc@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)к TestMemoryc Cspt Ё}t ddЁ|_|j t ddtjddddЁЁt  t  |ЁЁ}|  t |jdj ƒt |jdj ƒЁdS)Nкextraкtestr"rАr )кcurrent)rrlrкRadioSettingGroupr€кappendк RadioSettingкRadioSettingValueStringкpicklerкdumpsrкstrr˜Љrrlкnrrrкtest_pickle_with_extra$s ўџz!TestMemory.test_pickle_with_extracCs,t t dЁЁ}t |Ё}| d|jЁdS)Nщ{)rк FrozenMemoryrlrr]rŠrrrкtest_frozen_from_frozen.s z"TestMemory.test_frozen_from_frozencCsDt t ЁЁj}t t dЁЁ Ё}| ||Ё| t|dƒЁdS)Nrк_frozen)rrŽrlr\кdupeкassertNotIsInstancer*кhasattr)rrŽrlrrrкtest_frozen_dupe_unfrozen3sџџ z$TestMemory.test_frozen_dupe_unfrozencCsht dЁ}t ddt dЁЁg|_t |Ё}| tЁd|jd_ WdƒdS1s-wYdS)Nrr кFooFTr) rrlrr…кRadioSettingValueBooleanr€rŽrr r˜)rкorigкfrozenrrrкtest_frozen_modifications:s ў  "џz$TestMemory.test_frozen_modificationscCs:t Ё}d|_d|_| tЁ d|_Wdƒn1swY| tЁ d|_Wdƒn1s5wY| tЁ d|_Wdƒn1sMwY| tЁ d|_Wdƒn1sewY| tЁ d|_Wdƒn1s}wY| tЁ d|_WdƒdS1s–wYdS)Nrkщdч>@чРr@)rrlr<rDrr Љrrlrrrкtest_tone_validatorCs* џ џ џ џ џ "џzTestMemory.test_tone_validatorc CsЖt Ё}| dt|ƒЁd|_d|_d|_| dt|ƒЁd|_d|_| dt|ƒЁt   d d Ё|_ |j   t   d d t  d ЁЁЁ|j   t   ddt  ddgdЁЁЁ| dt|ƒЁdS)NzцTone',dtcs_polarity='NN',skip='',power=None,duplex='',offset=600000,mode='FM',tuning_step=5.0,comment='',empty=False,immutable=[]>r чЭЬЬЬЬЬZ@r4zѓTone',dtcs_polarity='NN',skip='',power=None,duplex='',offset=600000,mode='FM',tuning_step=5.0,comment='',empty=False,immutable=[]>щeкCallzћTone',dtcs_polarity='NN',skip='',power=None,duplex='',offset=600000,mode='FM',tuning_step=5.0,comment='',empty=False,immutable=[]>r€кExtraкtest1њTest Setting 1Fкtest2њTest Setting 2r rTa!Tone',dtcs_polarity='NN',skip='',power=None,duplex='',offset=600000,mode='FM',tuning_step=5.0,comment='',empty=False,immutable=[],extra.test1='False',extra.test2='foo'>)rrlrкreprr8r<r;r]к extd_numberrrƒr€r„r…r–кRadioSettingValueListrrrrкtest_repr_dumpYsFќћћџџџџџњzTestMemory.test_repr_dumpc Csрt dЁ}t dЁ}d|_d|_| d| |dЁЁd|_| d| |ЁЁd|_d|_| d | |ЁЁd|_t d d Ё|_ t d d Ё|_ |j   t  d d t  dЁЁЁ|j   t  ddt  ddgdЁЁЁ| d| |ЁЁdS)Nr"r rpzfreq=146520000>446000000њ>rCz(freq=146520000/446000000,tmode=''/'TSQL'щzident=1/2,tmode=''/'TSQL'r€rЂrЃrЄFrЅrІr rTzMextra.test1='False'/'',extra.test2=''/'foo',tmode=''/'TSQL')rrlr8rк debug_diffr;r]rrƒr€r„r…r–rЉ)rкm1кm2rrrкtest_debug_diff„s>  џџџџџџўzTestMemory.test_debug_diffN) rŠr‹rŒrŒrr”r™ržrЊrАrrrrr#s   +rc@rP)кTestRadioFeaturescCsДt Ё}ddg|_| tЁ ddg|_Wdƒn1swY| tЁ ddg|_Wdƒn1s8wY| tЁddg|_WdƒdS1sSwYdS)NrkrŸr›rœrš)rк RadioFeaturesк valid_tonesrr )rкrfrrrкtest_valid_tonesІs   џ  џ  "џz"TestRadioFeatures.test_valid_tonesN)rŠr‹rŒrЕrrrrrБЅrSrБ)!кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arrr_rr(r‡r+кunittestrк tests.unitrкchirprrrrrкBaseTestr rŽrзrrrOrdrnrrБrrrrкs6"        _"52chirp-20240224/tests/unit/__pycache__/test_mappingmodel.cpython-310-pytest-7.1.3.pyc0000644000175000017500000002712114411666553026611 0ustar hibbyhibbyo Xl'd *у@sфddlZddlmmZddlmZddlm Z ddl m Z ddl m Z Gdd„de jƒZGdd „d eƒZGd d „d e jƒZGd d „d eƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„de jƒZGdd„deƒZdS)щN)кmock)кbase)к chirp_common)кicfc@s"eZdZejZdd„Zdd„ZdS)кTestBaseMappingcCstt ddЁ}| |ddЁ}| t|ƒdЁ| | ЁdЁ| | ЁdЁ| t|ƒd|jjЁ| |j |ЁdS)NкFooщz%s-1) rк MappingModelкCLSк assertEqualкstrкget_nameк get_indexкreprк__name__к_model)кselfкmodelкmappingЉrњT/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_mappingmodel.pyк test_mappings zTestBaseMapping.test_mappingcCsF| dddЁ}| dddЁ}| dddЁ}| ||Ё| ||ЁdS)NrrкBarщ)r r кassertNotEqual)rкmapping1кmapping2кmapping3rrrкtest_mapping_eq#s  zTestBaseMapping.test_mapping_eqN)rк __module__к __qualname__rк MemoryMappingr rrrrrrrs rc@seZdZejZdS)к TestBaseBankN)rrr rкBankr rrrrr",s r"cs*eZdZeƒZ‡fdd„Zdd„Z‡ZS)к_TestBaseClasscs tt|ƒ Ё|j|jŽ|_dSЉN)кsuperr$кsetUpr кARGSrЉrЉк __class__rrr'3sz_TestBaseClass.setUpcGs |jtt|j|ƒg|ЂRŽdSr%)к assertRaisesкNotImplementedErrorкgetattrr)rкmethodкargsrrrк _test_base7s  џ џz_TestBaseClass._test_base)rrr кtupler(r'r1к __classcell__rrr*rr$0s r$c@s.eZdZejZeddgƒZdd„Zdd„Z dS)кTestBaseMappingModelNrcCѓ,gdЂ}|D] \}}|j|g|ЂRŽqdS)N))кget_num_mappingsr)к get_mappingsr)кadd_memory_to_mappingЉNN)кremove_memory_from_mappingr9)кget_mapping_memoriesr%)кget_memory_mappingsr%Љr1Љrкmethodsr/r0rrrкtest_base_class@s џz$TestBaseMappingModel.test_base_classcCѓ| |j ЁdЁdS)NrЉr rr r)rrrк test_get_nameKѓz"TestBaseMappingModel.test_get_name) rrr rr r r2r(r@rCrrrrr4<s   r4c@s$eZdZedgƒZejZdd„ZdS)кTestBaseBankModelNcCrA)NкBanksrBr)rrrrCSrDzTestBaseBankModel.test_get_name) rrr r2r(rк BankModelr rCrrrrrEOs  rEc@seZdZejZdd„ZdS)к"TestBaseMappingModelIndexInterfacecCr5)N))кget_index_boundsr)кget_memory_indexr9)кset_memory_index)NNN)кget_next_mapping_indexr%r=r>rrrr@Zs џz2TestBaseMappingModelIndexInterface.test_base_classN)rrr rкMappingModelIndexInterfacer r@rrrrrHWs rHc@seZdZdd„ZdS)к TestIcomBankscCs"t dddЁ}| t|dƒЁdS)Nrrкindex)rкIcomBankк assertTrueкhasattr)rкbankrrrкtest_icom_bankeszTestIcomBanks.test_icom_bankN)rrr rTrrrrrNds rNcsreZdZejZdd„Z‡fdd„Zdd„Zdd„Z d d „Z d d „Z d d„Z dd„Z dd„Zdd„Zdd„Z‡ZS)кTestIcomBankModelcCst Ё}d|_|S)N)rщ )rк RadioFeaturesк memory_boundsЉrкrfrrrк_get_rfnszTestIcomBankModel._get_rfcsnttˆƒ ЁG‡fdd„dtjƒ}|dƒˆ_ˆ ˆjЁˆ_dD]}tj   ˆj|Ё}|  Ёˆj   |Ёq dS)NcsHeZdZdZdZ‡fdd„Zdd„Zdd„Zd d „Zd d „Z d d„Z dS)z*TestIcomBankModel.setUp..FakeRadiorVЉrrVcsˆ ЁSr%)r[)к the_radior)rrк get_featureszsz7TestIcomBankModel.setUp..FakeRadio.get_featurescSѓdSr%rЉrкnumberrOrrrк _set_bank}ѓz4TestIcomBankModel.setUp..FakeRadio._set_bankcSr_r%rЉrrarrrк _get_bank€rcz4TestIcomBankModel.setUp..FakeRadio._get_bankcSr_r%rrdrrrк_get_bank_indexƒrcz:TestIcomBankModel.setUp..FakeRadio._get_bank_indexcSr_r%rr`rrrк_set_bank_index†rcz:TestIcomBankModel.setUp..FakeRadio._set_bank_indexcSr_r%rrdrrrк get_memory‰rcz5TestIcomBankModel.setUp..FakeRadio.get_memoryN) rrr к _num_banksк_bank_index_boundsr^rbrerfrgrhrr)rrк FakeRadiovs  rk)rbrergrfrh)r&rUr'rкIcomCloneModeRadioк_radior rrкpatchкobjectкstartкmocksкappend)rrkкaкmr*r)rr'ss ќzTestIcomBankModel.setUpcCrA)NrV)r rr6r)rrrкtest_get_num_mappings”rDz'TestIcomBankModel.test_get_num_mappingscCsv|j Ё}| t|ƒdЁd}|D]'}ttdƒ|ƒ}| | Ё|Ё| | Ёd|Ё| |j|Ё|d7}qdS)NrVrкAzBANK-%sr) rr7r кlenкchrкordrr rO)rкbanksкirSrOrrrкtest_get_mappings—s  ћz#TestIcomBankModel.test_get_mappingscCsBt Ё}d|_|j Ё}|d}|j ||Ё|jj ddЁdSЉNщr) rкMemoryrarr7r8rmrbкassert_called_once_with)rкmemrzrSrrrкtest_add_memory_to_mappingЂs  z,TestIcomBankModel.test_add_memory_to_mappingcCs2t Ё}d|_|j Ё}|d}||jj_||fSr})rrrarr7rmreк return_value)rкcurbankrrzrSrrrк&_setup_test_remove_memory_from_mappingЊs   z8TestIcomBankModel._setup_test_remove_memory_from_mappingcCs>| dЁ\}}|j ||Ё|jj dЁ|jj ddЁdS)Nrr~)r…rr:rmrer€rbЉrrrSrrrкtest_remove_memory_from_mappingВsz1TestIcomBankModel.test_remove_memory_from_mappingcCs&| dЁ\}}| t|jj||ЁdS)NщЉr…r,к Exceptionrr:r†rrrк*test_remove_memory_from_mapping_wrong_bankИѓ џzаs џџz?TestIcomBankModel.test_get_mapping_memories..cSsg|]}t |Ё‘qSrrŽrrrrr’вs џ) rr7кrangeкboolrrrOrmreк side_effectrhr;r кassert_has_calls)rrzкexpectedrer{кshould_includeкmembersrrrкtest_get_mapping_memoriesТs*  џ €   џ џz+TestIcomBankModel.test_get_mapping_memoriescCsŠ|j Ё}t Ё}d|_t Ё}d|_ddg|jj_| |j  |Ёd|dЁ| |j  |ЁgЁ|jj  t   |jЁt   |jЁgЁdS)Nr~щrr) rr7rrrarmrer•r r<r–rr)rrzкmem1кmem2rrrкtest_get_memory_mappingsеs  џz*TestIcomBankModel.test_get_memory_mappings)rrr rк IcomBankModelr r[r'rur|r‚r…r‡r‹rršržr3rrr*rrUks ! rUcsReZdZejZ‡fdd„Zdd„Zdd„Zdd„Z d d „Z d d „Z d d„Z ‡Z S)кTestIcomIndexedBankModelcstt|ƒ Ё}d|_|S)NT)r&r r[кhas_bank_indexrYr*rrr[хsz TestIcomIndexedBankModel._get_rfcCrA)Nr\)r rrIr)rrrкtest_get_index_boundsъrDz.TestIcomIndexedBankModel.test_get_index_boundscCsBt Ё}d|_d|jj_| |j |dЁdЁ|jj  |jЁdS)Nr~r) rrrarmrfrƒr rrJr€)rrrrrкtest_get_memory_indexэs  z.TestIcomIndexedBankModel.test_get_memory_indexcCsˆt Ё}d|_|j Ё}tj |jdЁ}|dg|_|j  ||ddЁ|  |ЁWdƒn1s4wY|j j   |jdЁdS)Nr~r<rˆr) rrrarr7rrnrorƒrKr€rmrgЉrrrzrtrrrкtest_set_memory_indexєs   §z.TestIcomIndexedBankModel.test_set_memory_indexcCs~t Ё}d|_|j Ё}tj |jdЁ!}|dg|_|  t |jj ||ddЁ|  |ЁWdƒdS1s8wYdS)Nr~r<щrˆrЉ rrrarr7rrnrorƒr,rŠrKr€rЄrrrкtest_set_memory_index_bad_bankўѓ  џ "ќz7TestIcomIndexedBankModel.test_set_memory_index_bad_bankcCs~t Ё}d|_|j Ё}tj |jdЁ!}|dg|_|  t |jj ||ddЁ|  |ЁWdƒdS1s8wYdS)Nr~r<rˆщcrЇrЄrrrкtest_set_memory_index_bad_indexrЉz8TestIcomIndexedBankModel.test_set_memory_index_bad_indexcCsN|j Ё}g}g}g}g}t|j ЁjŽD])}| |do!|djЁ| t  |ЁЁt |dƒr>| |Ё| t  |ЁЁqd}t|j ЁjŽD]+}| t  |ЁЁ| |do]|djЁ|drt| t  |ЁЁ| |Ё|d7}qI||jj _ ||jj _ | |j |dЁdЁ| |j |dЁdЁ|jj  |Ё|jj  |ЁdS)Nrrrr~)rr7r“rmr^rXrrrOrrr”rer•rfr rLr–)rrzкbank_exp_callsкindex_exp_callsк bank_returnsк index_returnsr{кidxrrrкtest_get_next_mapping_indexs6   € €  z4TestIcomIndexedBankModel.test_get_next_mapping_index)rrr rкIcomIndexedBankModelr r[rЂrЃrЅrЈrЋrБr3rrr*rr тs    r )кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкunittestrк tests.unitrкchirprк chirp.driversrкBaseTestrr"r$r4rErHrNrUr rrrrкs&     wchirp-20240224/tests/unit/__pycache__/test_logger.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000246214556146510025411 0ustar hibbyhibbyo >ЬИemу@sPddlZddlmmZddlZddlmZddl m Z Gdd„de j ƒZ dS)щN)кlogger)кbasec@seZdZdd„ZdS)к TestLoggercsкt dЁ‰t dЁ‰t Ё‰ˆ tjЁ‡‡‡fdd„}|ƒt tjdЁ}|ƒ| Ё}Wdƒn1s8wY| dt |ƒЁt tjdЁ}|ƒ| Ё}Wdƒn1s^wY| dt |ƒЁdS)Nzchirp.drivers.foozchirp.wxui.foocs2ˆˆˆfD]}| dЁ| dЁ| dЁqdS)Nкdebugкwarningкerror)rrr)кlogЉкdrv_logкroot_logкui_logЉњN/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_logger.pyкlog_alls    §z,TestLogger.test_log_history..log_allz chirp.driversщ) кloggingк getLoggerкsetLevelкDEBUGrк log_historyкWARNINGк get_historyк assertEqualкlen)кselfrкhкhistoryr r rкtest_log_historys    ў ўzTestLogger.test_log_historyN)к__name__к __module__к __qualname__rr r r rrs r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arrкchirprк tests.unitrкBaseTestrr r r rкs"  chirp-20240224/tests/unit/__pycache__/__init__.cpython-310.pyc0000644000175000017500000000025014411666552022634 0ustar hibbyhibbyo Xl'dу@sdS)NЉrrrњK/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/__init__.pyкschirp-20240224/tests/unit/__pycache__/test_settings.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001712714560403524025772 0ustar hibbyhibbyo 8Тe”у@sZddlZddlmmZddlmZddlm Z Gdd„dej ƒZ Gdd„dej ƒZ dS)щN)кbase)кsettingsc@s\eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dS)кTestSettingValuescGs(|D]}| |Ё| | Ё|ЁqdSЉN)к set_valueк assertEqualк get_valueЉкselfкrsvкvaluesкvalueЉrњP/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_settings.pyк _set_and_tests ўzTestSettingValues._set_and_testcGs |D] }| tj|j|ЁqdSr)к assertRaisesrкInvalidValueErrorrr rrrк_set_and_catchs џџz TestSettingValues._set_and_catchcCsHt dddЁ}| Ё| | ЁdЁ| |dddЁ| |ddЁdS)Nrщ щщщџџџџщ )rкRadioSettingValueIntegerк initializerrrrЉr r rrrк test_radio_setting_value_integers z2TestSettingValues.test_radio_setting_value_integercCsJt dddЁ}| Ё| | ЁdЁ| |dddЁ| |dddЁdS)Ng№?g%@g@g@gЭЬЬЬЬЬь?g333333%@gјП)rкRadioSettingValueFloatrrrrrrrrrкtest_radio_setting_value_float&s z0TestSettingValues.test_radio_setting_value_floatcCs2t dЁ}| Ё| | ЁЁ| |ddЁdS)NTF)rкRadioSettingValueBooleanrк assertTruerrrrrrк test_radio_setting_value_boolean-s z2TestSettingValues.test_radio_setting_value_booleancCsngdЂ}t |dЁ}| Ё| | ЁdЁ| t|ƒdЁ| |dddЁ| |ddЁ| | Ё|ЁdS)NЉкAbcкDefкGhir#rr$r%кJklкXyz) rкRadioSettingValueListrrrкintrrк get_optionsЉr кoptsr rrrкtest_radio_setting_value_list3s z/TestSettingValues.test_radio_setting_value_listcCsкgdЂ}tj|dd}| Ё| | ЁdЁ| t|ƒdЁ| |dddЁ| |ddЁ| | Ё|Ёtj|d d}| Ё| | ЁdЁ|  d Ё| | ЁdЁ|  d Ё| | ЁdЁ|  t |j d ЁdS) Nr"r)к current_indexr$r%r#r&r'к1rк0щ) rr(rrrr)rrr*к set_indexrк IndexErrorr+rrrк&test_radio_setting_value_list_by_index=s   z8TestSettingValues.test_radio_setting_value_list_by_indexcCs\tjddddd}| Ё| | ЁdЁ| t|ƒdЁ| |dddЁ| |d d ЁdS) NrrкfooFЉкautopadкaкabcкabdefккabcdefg)rкRadioSettingValueStringrrrкstrrrrrrrкtest_radio_setting_value_stringUs z1TestSettingValues.test_radio_setting_value_stringcs^Gdd„dtƒ‰tjddddd}| Ё‡fdd „}| |Ё| d Ё| ˆ|jd ЁdS) Nc@ѓ eZdZdS)z?TestSettingValues.test_validate_callback..TestExceptionNЉк__name__к __module__к __qualname__rrrrк TestException^ѓrErrr5Fr6cs|dkrˆƒ‚dS)Nкbarr)кvalЉrErrк test_validatedsџz?TestSettingValues.test_validate_callback..test_validateкbazrG)к Exceptionrr=rкset_validate_callbackrr)r r rJrrIrкtest_validate_callback]s   z(TestSettingValues.test_validate_callbackcCsTt dЁ}| Ё| | ЁЁ| dЁ| | ЁЁ| dЁ| | ЁЁdS)NFT)rrrк assertFalseкchangedrr rrrrк test_changedks   zTestSettingValues.test_changedN) rBrCrDrrrrr!r-r4r?rNrQrrrrrs  rc@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)кTestSettingContainerscst ddЁ}t ddЁ}t ddЁ‰t dd|Ё‰| ˆ ЁdЁ| ˆ ЁdЁ| ˆ Ё|gЁ| ˆ ЁdgЁˆ |Ё| ˆ  Ёd|fd|fgЁ| ˆd|Ёˆˆd<| ˆ Ё||ˆgЁ| ˆ Ёgd ЂЁ| d d „ˆDƒ||ˆgЁ‡‡fd d „}|  t |ЁdS)Nкs1z Setting 1кs2z Setting 2кs3z Setting 3r5z Foo Group)rSrTrUcSsg|]}|‘qSrr)к.0кxrrrк …szBTestSettingContainers.test_radio_setting_group..cs ˆˆd<dS)NrUrrЉкgrouprUrrкset_dupe‡s z@TestSettingContainers.test_radio_setting_group..set_dupe) rк RadioSettingкRadioSettingGrouprкget_nameк get_shortnamer кkeysкappendкitemsrкKeyError)r rSrTr[rrYrкtest_radio_setting_groupvs"    z.TestSettingContainers.test_radio_setting_groupcCs`t dЁ}t dd|Ё}| |j|Ёd|_| | ЁdЁ| dt|ƒЁ| dt|ƒЁdS)NTr5кFooFz foo:Falsez[RadioSetting foo:False])rrr\rr rr>кreprЉr rHкrsrrrкtest_radio_setting‹s z(TestSettingContainers.test_radio_settingcCsxt dЁ}t dЁ}t dd||Ё}| |d|Ё| |d|Ёd|d<d|d<| | ЁdЁ| | ЁdЁdS)NTFr5rerr)rrr\rr)r кval1кval2rhrrrкtest_radio_setting_multi”s  z.TestSettingContainers.test_radio_setting_multicshGdd„dtƒ‰t ddЁ‰ˆ ˆ ЁЁ‡‡‡fdd„}ˆ |ddЁˆ ˆ ЁЁˆ ˆˆjЁdS)Nc@r@)z@TestSettingContainers.test_apply_callback..TestExceptionNrArrrrrE rFrEr5recs*ˆ |ˆЁˆ |dЁˆ |dЁˆƒ‚)Nr5rG)r)кsettingкdata1кdata2ЉrErhr rrкtest_cbІs   z:TestSettingContainers.test_apply_callback..test_cbrG) rLrr\rOкhas_apply_callbackкset_apply_callbackr rкrun_apply_callback)r rqrrprкtest_apply_callbackŸs z)TestSettingContainers.test_apply_callbackcCs| tjtjddЁdS)Nzfoo%barre)rrкInvalidNameErrorr\)r rrrкtest_setting_banned_nameЏsџz.TestSettingContainers.test_setting_banned_namecCs(tjD]}| tjtjd|dЁqdS)Nzfoo%sbarre)rкBANNED_NAME_CHARACTERSrrvr\)r кcrrrк#test_setting_banned_name_charactersГs  џџz9TestSettingContainers.test_setting_banned_name_characterscCsBt dddЁ}t dd|Ё}| |jjЁd|_| |jjЁdS)Nrrщ кtestкTestr)rrr\rOr к initializedr rgrrrкtest_setting_deferredИs z+TestSettingContainers.test_setting_deferredN) rBrCrDrdrirlrurwrzrrrrrrRus   rR) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arк tests.unitrкchirprкBaseTestrrRrrrrкs& achirp-20240224/tests/unit/__pycache__/test_kguv8d.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000674414430373743025352 0ustar hibbyhibbyo уђ`d…у@sТddlZddlmmZddlZddlZddlZddl m Z ddl m Z ddl m Z ddl m Z ddlmZGdd„dƒZGd d „d ejƒZGd d „d eƒZGd d„deƒZGdd„deƒZdS)щN)кkguv8e)кkguv8d)к kguv8dplus)кkg935g)к directoryc@s$eZdZdd„Zdd„Zdd„ZdS)кFakeUV8DcCsd|_d|_||_|j|_dS)Nѓ)кwritebufкreadbufкrclassк_model)кselfr ЉrњN/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_kguv8d.pyк__init__ s zFakeUV8D.__init__c Cs”t|tƒ}|sJddt Ёvst tЁrt tЁnddt Ёvs$t |Ёr)t |Ёnddt Ёvs5t tЁr:t tЁndt |Ёdœ}tt |Ёƒ‚d}|d}d}|t j kr]|j d}n-|t j kred }n%|t j kr|d d …}t|jd ƒr~| dЁ |Ё}n |t jkr†dStd ƒ‚t dt|ƒЁ|}tdd„|Dƒƒd}|t d|Ё7}t|jdƒrС| dЁ |d d…Ё}|dd …|}|j|7_dS)Nz5assert %(py4)s {%(py4)s = %(py0)s(%(py1)s, %(py2)s) }к isinstanceкdataкbytes)кpy0кpy1кpy2кpy4щrs s@щщкdecryptzUnhandled commandкxxxBcss|]}|VqdSЉNr)к.0кxrrrк $s€z!FakeUV8D.write..щкBкencrypt)rrк @py_builtinsкlocalsк @pytest_arк_should_repr_global_nameк _safereprкAssertionErrorк_format_explanationrкCMD_IDr кCMD_RDкCMD_WRкhasattrr rкCMD_ENDк Exceptionкstructкpackкlenкsumr#r ) r rк @py_assert3к @py_format5кcmdкresponseкpacketкcsкpayloadrrrкwrites,˜      €  zFakeUV8D.writecCs"|jd|…}|j|d…|_|Sr)r )r кnкbufrrrкread,sz FakeUV8D.readN)к__name__к __module__к __qualname__rr<r?rrrrr s rc@s*eZdZejZdd„Zdd„Zdd„ZdS)к TestKGUV8DcCѓ t|jƒ}| |Ё}| ЁdSr)rкRCLASSк _identifyЉr кfкrrrrк test_identify5ѓ   zTestKGUV8D.test_identifycCrDr)rrEкsync_inrGrrrк test_download:rKzTestKGUV8D.test_downloadc CsPt|jƒ}tj tj tЁdddt |jЁЁ}| |Ё}|  |Ё|  ЁdS)Nz..кimagesz%s.img) rrEкosкpathкjoinкdirnameк__file__rкradio_class_idкset_pipeкsync_out)r rHкimgrIrrrк test_upload?s ў   zTestKGUV8D.test_uploadN) r@rArBrк KGUV8DRadiorErJrMrXrrrrrC2s  rCc@ѓeZdZejZdS)кTestKGUV8DPlusN)r@rArBrкKGUV8DPlusRadiorErrrrr[Iѓ r[c@rZ)к TestKGUV8ERN)r@rArBrк KGUV8ERadiorErrrrr^Mr]r^c@rZ)к TestKG935N)r@rArBrк KG935GRadiorErrrrr`Qr]r`)кbuiltinsr$к_pytest.assertion.rewriteк assertionкrewriter&rOr1кunittestк chirp.driversrrrrкchirprrкTestCaserCr[r^r`rrrrкs"     &chirp-20240224/tests/unit/__pycache__/test_bitwise.cpython-310-pytest-7.1.3.pyc0000644000175000017500000003651214562641115025601 0ustar hibbyhibbyo DAЫeє6у@s0ddlZddlmmZddlmZddlZddlmZddl Z ddl m Z ddl m Z Gdd„dej ƒZGdd „d eƒZGd d „d eƒZGd d „d eƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZdS) щN)кbytes)кmock)кbitwise)кmemmapc@ѓeZdZdd„ZdS)кBaseTestcCsN| ЁD] \}}t|tƒr| t||ƒ|Ёq| t|ƒt||ƒƒ|ЁqdS)N)кitemsк isinstanceкdictк_compare_structureкgetattrк assertEqualкtype)кselfкobjк primitiveкkeyкvalueЉrњO/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_bitwise.pyr s  ќzBaseTest._compare_structureN)к__name__к __module__к __qualname__r rrrrrѓ rc@r)кTestMemoryMapCoherencecCsBt dЁ}t d|Ё}| dt|jƒЁd|_| d| ЁЁdS)Nк00z char foo[2];к11)rк MemoryMaprкparser кstrкfooк get_packed)rкcharmmaprrrrкtest_byte_char_coherence%s  z/TestMemoryMapCoherence.test_byte_char_coherenceN)rrrr#rrrrr$rrc@sTeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dS)кTestBitwiseBaseIntTypescCsцt t|ƒЁ}t d||Ё}| t|jƒ|Ё| |j Ёt |ƒdЁd|_| t|jƒdЁ| |  Ёd| ЁdЁ||_| t|jƒ|Ё| |  Ё|Ёd|_| d|jdЁ| d|jdЁ| d|jd ЁdS) Nz%s foo;щrѓщщщg @g@) rкMemoryMapBytesrrrr кintr кsizeкlenr!)rкdatatypeк_datarкdatarrrrк _test_type3sz"TestBitwiseBaseIntTypes._test_typecCѓ| dddЁdS)Nкu8ѓ€щ€Љr1Љrrrrк test_type_u8Hѓz$TestBitwiseBaseIntTypes.test_type_u8cCr2)Nкu16sщr6r7rrrк test_type_u16Kr9z%TestBitwiseBaseIntTypes.test_type_u16cCr2)Nкu24s€щ€r6r7rrrк test_type_u24Nr9z%TestBitwiseBaseIntTypes.test_type_u24cCr2)Nкu32s€ьr6r7rrrк test_type_u32Qr9z%TestBitwiseBaseIntTypes.test_type_u32cCr2)Nкul16sr;r6r7rrrкtest_type_ul16Tr9z&TestBitwiseBaseIntTypes.test_type_ul16cCr2)Nкul24s€r>r6r7rrrкtest_type_ul24Wr9z&TestBitwiseBaseIntTypes.test_type_ul24cCr2)Nкul32s€rAr6r7rrrкtest_type_ul32Zr9z&TestBitwiseBaseIntTypes.test_type_ul32cCs\t tdƒЁ}t d|Ё}tdƒD]}| ||j|Ё|d|j|<q| d| ЁЁdS)Nsz u8 foo[4];щr)s) rr*rrrкranger r r!)rr0rкirrrкtest_int_array]s   z&TestBitwiseBaseIntTypes.test_int_arrayN) rrrr1r8r<r?rBrDrFrHrLrrrrr$2s r$c@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)кTestBitfieldTypescCs~d}t tdƒЁ}t ||Ё}| |jdЁ| |jdЁ| |j ЁdЁ| |j ЁdЁd|_d|_| |  ЁdЁdS)Nzu8 foo:4, bar:4;ѓщr)rIr%ѓ) rr*rrrr r кbarr,r!)rкdefnr0rrrrкtest_bitfield_u8gs z"TestBitfieldTypes.test_bitfield_u8cCsаd|}t t|ƒЁ}t ||Ё}| t|jƒdЁ| t|jƒdЁ| t|j ƒdЁ| |j  ЁdЁ| |j  ЁdЁ| |j   ЁdЁd|_d|_d|_ |d kr^| |  Ёd ЁdS| |  Ёd ЁdS) Nzu%s16 foo:4, bar:8, baz:4;rOщ#rIr%r)щr(кls!s!Љ rr*rrrr r+r rQкbazr,r!Љrкvariantr0rRrrrrк_test_bitfield_16sѓ z#TestBitfieldTypes._test_bitfield_16cCѓ| ddЁdS)Nкѓ4Љr[r7rrrкtest_bitfield_u16…ѓz#TestBitfieldTypes.test_bitfield_u16cCr])NrVs4r`r7rrrкtest_bitfield_ul16ˆrbz$TestBitfieldTypes.test_bitfield_ul16cCsаd|}t t|ƒЁ}t ||Ё}| t|jƒdЁ| t|jƒdЁ| t|j ƒdЁ| |j  ЁdЁ| |j  ЁdЁ| |j   ЁdЁd|_d|_d|_ |dkr^| |  Ёd ЁdS| |  Ёd ЁdS) Nzu%s24 foo:12, bar:6, baz:6;rIr(r)щ щrOrVsƒsƒrWrYrrrк_test_bitfield_24‹r\z#TestBitfieldTypes._test_bitfield_24cCr])Nr^s@ТЉrfr7rrrкtest_bitfield_u24rbz#TestBitfieldTypes.test_bitfield_u24cCr])NrVsТ@rgr7rrrкtest_bitfield_ul24 rbz$TestBitfieldTypes.test_bitfield_ul24N) rrrrSr[rarcrfrhrirrrrrMfs  rMc@ѓeZdZdd„Zdd„ZdS)к TestBitTypecCstd}t tdƒЁ}t ||Ё}dD]\}}| t|j|ƒ|ЁqtddƒD] }|d|j|<q&| |  ЁdЁdS)Nz bit foo[24];s€))rF)r%T)щTrщr)sUUU) rr*rrrr кboolr rJr!)rrRr0rrKкvrrrкtest_bit_arrayЅs  zTestBitType.test_bit_arraycCѓ| ttjddЁdS)Nz bit foo[23];s000)к assertRaisesк ValueErrorrrr7rrrкtest_bit_array_failЏѓzTestBitType.test_bit_array_failN)rrrrprtrrrrrkЄs rkc@s4eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd S) кTestBitwiseBCDTypesc Csвt t|ƒЁ}t ||Ё}| tt||ƒƒ|Ё| t||ƒ Ёt |ƒdЁt ||dƒ| |  Ёdt |ƒЁt ||dƒ|  dЁrQt |ƒdkrLdpMdd}n dt |ƒdkrZdp[d}|  Ё}| ||ЁdS) Nr%rr&щ*кbr)ѓѓB) rr*rrrr r+r r,r-кsetattrr!к startswith) rк definitionкnamer/rr0rкexpectedкrawrrrк _test_defДs    zTestBitwiseBCDTypes._test_defcCѓ| ddddЁdS)Nz bbcd foo;r rNrdЉrr7rrrк test_bbcdУѓzTestBitwiseBCDTypes.test_bbcdcCr‚)Nz lbcd foo;r rNrdrƒr7rrrк test_lbcdЦr…zTestBitwiseBCDTypes.test_lbcdcCr‚)Nz bbcd foo[2];r r_iвrƒr7rrrкtest_bbcd_arrayЩr…z#TestBitwiseBCDTypes.test_bbcd_arraycCr‚)Nz lbcd foo[2];r r_iT rƒr7rrrкtest_lbcd_arrayЬr…z#TestBitwiseBCDTypes.test_lbcd_arrayN)rrrrr„r†r‡rˆrrrrrvГs  rvc@s<eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd S)кTestBitwiseCharTypescCѓXt tdƒЁ}t d|Ё}| t|jƒdЁ| |j ЁdЁd|_| |  ЁdЁdS)Nѓcz char foo;кcr%кdѓdЉ rr*rrrr rr r,r!Љrr0rrrrк test_charбѓ  zTestBitwiseCharTypes.test_charcCrŠ)Nѓfoobarњ char foo[6];кfoobarщ0кbazfoosbazfoorrrrrк test_stringйr’z TestBitwiseCharTypes.test_stringcCs@t tdƒЁ}t d|Ё}tjrd}nd}| |t|j ƒЁdS)Nsџoobar1zstruct {char foo[7];} bar;uУПoobar1z \xffoobar1) rr*rrrкsixкPY3кassertInкreprrQ)rr0rrrrrкtest_string_invalid_charsсs  z.TestBitwiseCharTypes.test_string_invalid_charscCsBt tdƒЁ}t d|Ё}| tt|ddЁ| tt|ddЁdS)Nr“r”r кbazfoкbazfooo)rr*rrrrrrsr{rrrrкtest_string_wrong_lengthьs z-TestBitwiseCharTypes.test_string_wrong_lengthcCszt tdƒЁ}t d|Ё}| dt|jƒЁ| dtdƒЁd|_| dt|jƒЁdd„d Dƒ|_| d t|jƒЁdS) Nr“r”r•resbarfooкbarfoocSsg|]}t|ƒ‘qSr)кord)к.0rŒrrrк љszMTestBitwiseCharTypes.test_string_with_various_input_types..кfffbbb) rr*rrrr rr r-rrrrк$test_string_with_various_input_typesђs z9TestBitwiseCharTypes.test_string_with_various_input_typescCsFt tdƒЁ}t d|Ё}| d|j ЁЁ| d|jjddЁdS)Nr“r”r•FЉкasbytes)rr*rrrr r кget_rawrrrrкtest_string_get_rawќs z(TestBitwiseCharTypes.test_string_get_rawN) rrrr‘r˜rr rІrЊrrrrr‰аs  r‰c@sdeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z e j   e jdЁdd„ƒZdd„ZdS)кTestBitwiseStructTypescCs4t ||Ё}| ||Ё| | Ёt|ƒdЁdS)Nr%)rrr r r,r-)rr}r0rrrrrrs  z TestBitwiseStructTypes._test_defcCs"d}dddii}| |d|ЁdS)Nњstruct { u8 bar; } foo;r rQr5r4rƒЉrrRrrrrкtest_struct_one_element s z.TestBitwiseStructTypes.test_struct_one_elementcCs$d}ddddœi}| |d|ЁdS)Nњ struct { u8 bar; u16 baz; } foo;r r5r;)rQrXs€rƒr­rrrкtest_struct_two_elementssz/TestBitwiseStructTypes.test_struct_two_elementscCsBt tdƒЁ}d}t ||Ё}d|j_d|j_| |  ЁdЁdS)Nѓ..њstruct { u8 bar; u8 baz; } foo;щщ4r_) rr*rrrr rQrXr r!Љrr0rRrrrrкtest_struct_writess  z)TestBitwiseStructTypes.test_struct_writescCѓFt tdƒЁ}d}t ||Ё}| d| ЁЁ| d|jddЁdS)NrБrВz..FrЇЉrr*rrrr rЉrЕrrrкtest_struct_get_rawѓ  z*TestBitwiseStructTypes.test_struct_get_rawcCrЗ)Nѓ.rЌк.FrЇrИrЕrrrкtest_struct_get_raw_small"rКz0TestBitwiseStructTypes.test_struct_get_raw_smallcCsVt tdƒЁ}d}t ||Ё}| dЁ| d| ЁЁ| dЁ| d| ЁЁdS)NrЛrЌѓ1к2ѓ2)rr*rrrкset_rawr r!rЕrrrкtest_struct_set_raw)s   z*TestBitwiseStructTypes.test_struct_set_rawкerrorcCsHt dt dЁЁt dt dЁЁt dt dЁЁ| d|jЁdS)Nz0struct { u8 foo; u8 foo1:2, foo:4, foo3:2;} bar;ѓ€zstruct { u8 foo; u8 foo;} bar;z!struct { u8 foo; u8 foo[2];} bar;r()rrrr*r к call_count)rкmock_logrrrкtest_struct_duplicate2sџџџz,TestBitwiseStructTypes.test_struct_duplicatecCsжt tdƒЁ}d}t ||Ё}| dЁ| d|jjЁ| d|jj Ё|j dЁ| d|jjЁ| d|jj Ё|jj d Ё| d |jjЁ| d|jj Ё|  t |jd Ё|  t |jd Ё|  t |jd ЁdS)Ns...rЏѓЊщЊiЊЊѓЛщЛiЛЛѓЬщЬк1sABF) rr*rrrкfill_rawr r rQrXrrкAssertionErrorrЕrrrкtest_struct_fill_raw<s   z+TestBitwiseStructTypes.test_struct_fill_rawN)rrrrrЎrАrЖrЙrНrТrкpatchкobjectrкLOGrЧrбrrrrrЋs  rЋc@rj)кTestBitwiseSeekcCs&d}t |dЁ}| t|jƒdЁdS)Nz#seekto 4; char foo;sabcdZкZ)rrr rr ЉrrRrrrrк test_seektoPs zTestBitwiseSeek.test_seektocCs8d}t |dЁ}| t|jƒdЁ| t|jƒdЁdS)Nzchar foo; #seek 3; char bar;sAbcdZкArж)rrr rr rQrзrrrк test_seekUs zTestBitwiseSeek.test_seekN)rrrrиrкrrrrrеOs rеc@r)кTestBitwiseErrorscCrq)Nzu8 foor^)rrк SyntaxErrorrrr7rrrкtest_missing_semicolon]ruz(TestBitwiseErrors.test_missing_semicolonN)rrrrнrrrrrл\rrлc@rj)кTestBitwiseCommentscCѓt ddЁ}| d|jЁdS)Nzu8 foo; // testѓщЉrrr r Љrrrrrкtest_comment_inline_cppstylebѓ z0TestBitwiseComments.test_comment_inline_cppstylecCrп)Nz// Test this u8 foo;rрrсrтrуrrrкtest_comment_cppstylefrхz)TestBitwiseComments.test_comment_cppstyleN)rrrrфrцrrrrrоaѓ rоc@rj)кTestBitwiseStringEncoderscCѓ| dt dЁЁdS)Nѓfoobarњfoobar)r rкstring_straight_encoder7rrrкtest_encode_byteslѓџz+TestBitwiseStringEncoders.test_encode_bytescCrщ)Nrыrъ)r rкstring_straight_decoder7rrrкtest_decode_bytesprюz+TestBitwiseStringEncoders.test_decode_bytesN)rrrrэr№rrrrrшkrчrшc@r)кTestPathcCs\d}t |t dЁЁ}d|jdjd<d|jdj_| d|  dЁЁ| d|  dЁЁdS) Nz{u8 foo;u8 bar[2];struct { u8 foo; u8 bar[2]; u8 baz1:4, baz2:4; struct { u16 childitem; } child;} structure[2];rФщ{rrOiШz.structure[0].bar[1]zstructure[1].child.childitem) rrrr*к structurerQкchildк childitemr кget_path)rкfmtrrrrк test_get_pathvs  zTestPath.test_get_pathN)rrrrјrrrrrёurrё)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arrкunittestrr™кchirprrкTestCaserrr$rMrkrvr‰rЋrеrлrоrшrёrrrrкs&&    4>3L   chirp-20240224/tests/unit/__pycache__/test_baofeng_fmradio.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001063614430373743027237 0ustar hibbyhibbyo уђ`dEу@sЄddlZddlmmZddlZddlZddlZddl m Z ddl m Z ddl m Z ddlmZGdd„de jƒZGdd „d eƒZej d ЁGd d „d eƒƒZdS) щN)кbase)кbf_t1)кuv5r)кsettingscs†eZdZdZdZdZdZ‡fdd„Zdd„Zdd „Z d d „Z d d „Z dd„Z dd„Z dd„Zdd„Zddd„Zdd„Zdd„Z‡ZS)к FMRadioTestNкelement)rrcsF|jdur | dЁtj tj tЁdd|jЁ}| |Ё|_t ƒ  ЁS)Nz Base testz..кimages) кIMAGEкskipTestкosкpathкjoinкdirnameк__file__к RADIO_CLASSкradioкsuperкsetUp)кselfкimgЉк __class__ЉњW/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_baofeng_fmradio.pyrs  џ  zFMRadioTest.setUpcCs>t d|Ё}|jj}|j dЁD]}t||ƒ}q| |ЁdS)z(Set FM VFO as integer directly in memoryz>Hк.N)кstructкpackrк_memobjкMEMOBJкsplitкgetattrкset_raw)rкvalueк val_bytesкobjrrrrк set_fmvfo_raws  zFMRadioTest.set_fmvfo_rawcCs,|jj}|j dЁD]}t||ƒ}q t|ƒS)z*Get FM VFO as integer directly from memoryr)rrrrr кint)rr$rrrrк get_fmvfo_raw$s zFMRadioTest.get_fmvfo_rawcCs6|j Ё}|j\}}|||}| |t|jƒЁdS)zTCheck FM VFO from settings expected should be something like 106.1 N)rк get_settingsкSETTINGS_INDEXк assertEqualкfloatr")rкexpectedrкindexкnameкvforrrк check_fmvfo+s   zFMRadioTest.check_fmvfocCs6|j\}}|j Ё}|||}||_|j |ЁdS)zESet FM VFO via settings value is a float like 106.1 N)r)rr(r"к set_settings)rr"r-r.rr/rrrк set_fmvfo5s   zFMRadioTest.set_fmvfocCѓ| dЁ| dЁdS)Nщ^чY@Љr%r0Љrrrrкtest_get_original@s zFMRadioTest.test_get_originalcCs(| dЁ| d| ЁЁ| dЁdS)Nчfffff†Z@i›)r2r*r'r0r7rrrкtest_set_originalJs zFMRadioTest.test_set_originalcCr3)Nщ^r5r6r7rrrк test_get_2022Us zFMRadioTest.test_get_2022cCs<| dЁ| dЁ| dЁ| d| ЁЁ| dЁdS)Nr;r5r9i›)r%r0r2r*r'r7rrrк test_set_2022`s   zFMRadioTest.test_set_2022TcCsž|rd}nd}tdddƒD]?}d|krdkr&nn | |Ё| |Ёq | |Ё| tj|j|Ё|dkr9q | t|ddƒЁ| t|j|Ёq dS) zВTest the edges around the supported range. Make sure that we don't confuse old and new values on either side of the supported range as the wrong format. r;r4щ2iєщ щAщlN) кranger2r0r%к assertRaisesrкInvalidValueErrorr&кKeyError)rкnewкdefaultкdialrrrк _test_edgesps$   џџыzFMRadioTest._test_edgescCѓ| dЁdS)NFЉrIr7rrrкtest_edges_original’ѓzFMRadioTest.test_edges_originalcCrJ)NTrKr7rrrкtest_edges_2022•rMzFMRadioTest.test_edges_2022)T)к__name__к __module__к __qualname__r rrr)rr%r'r0r2r8r:r<r=rIrLrNк __classcell__rrrrr s"       "rc@ѓeZdZdZejZdZdZdS)кTestBFT1zBaofeng_BF-T1.img)щкfm_vfozsettings.fm_vfoN) rOrPrQr rкBFT1rr)rrrrrrT™s rTzThis radio needs fixingc@rS)кTestUV5RzBaofeng_UV-5R.img)щк fm_presetsrZN) rOrPrQr rк BaofengUV5Rrr)rrrrrrX s rX)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arr rкpytestк tests.unitrк chirp.driversrrкchirprкBaseTestrrTкmarkкskiprXrrrrкs"     chirp-20240224/tests/unit/__pycache__/test_directory.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001254214430373743026137 0ustar hibbyhibbyo уђ`dgу@sАddlZddlmmZddlZddlZddlZddl Z ddl Z ddl Z ddl Z ddl mZddlmZddlmZGdd„dejƒZGdd„dejƒZGd d „d ejƒZdS) щN)кbase)к chirp_common)к directorycsDeZdZdd„Z‡fdd„Zdd„Zdd„Zd d „Zd d „Z‡Z S) к TestDirectorycCst |jЁdSЉN)кshutilкrmtreeкtempdir)кselfЉr њQ/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_directory.pyкcleanUpszTestDirectory.cleanUpcsXtt|ƒ Ёt Ё|_t ЁGdd„dtj ƒ‰tj G‡fdd„dtj ƒƒ}||_ dS)Nc@seZdZdZdZdZdS)z&TestDirectory.setUp..FakeAliasкTaylorњBarmaster 2000кAN)к__name__к __module__к __qualname__кVENDORкMODELкVARIANTr r r r к FakeAliassrcs*eZdZdZdZdZ”gZedd„ƒZdS)z&TestDirectory.setUp..FakeRadioкDanzFoomaster 9000кRcSs|dkS)Nѓ thisisrawdatar )кclsк file_dataк image_filer r r к match_model$sz2TestDirectory.setUp..FakeRadio.match_modelN) rrrrrrкALIASESк classmethodrr Љrr r к FakeRadiosr") кsuperrкsetUpкtempfileкmkdtempr rкenable_reregistrationsrкAliasкregisterкCloneModeRadioк test_class)r r"Љк __class__r!r r$s  zTestDirectory.setUpcCs t |Ё}| t||jƒЁ|Sr)rкget_radio_by_imageк assertTrueк isinstancer+)r кtempfnкradior r r к_test_detect_finds_our_class*s z*TestDirectory._test_detect_finds_our_classcCsZtj |jdЁ}t|dƒ}| dЁ| ЁWdƒn1s!wY| |ЁdS)Nкtestfileкwbr)кosкpathкjoinr кopenкwriteкflushr3Љr кfnкfr r r кtest_detect_with_no_metadata/s    ўz*TestDirectory.test_detect_with_no_metadatacCs€tj |jdЁ}t|dƒ$}| dЁ| |jjdЁ| | dЁ ЁЁ|  ЁWdƒn1s4wY|  |ЁdS)Nr4r5rѓ-) r6r7r8r r9r:r+кMAGICк_make_metadatar;r3r<r r r к$test_detect_with_metadata_base_class6s   ќz2TestDirectory.test_detect_with_metadata_base_classc CsЮtj |jdЁ}t|dƒ6}| dЁ| |jjdЁ|jjd}t   t   |j |j|jdœЁ ЁЁ}| |Ё| ЁWdƒn1sFwY| |Ё}| d|j Ё| d|jЁ| d |jЁdS) Nr4r5rr@r)кvendorкmodelкvariantrrr)r6r7r8r r9r:r+rArкbase64к b64encodeкjsonкdumpsrrrкencoder;r3к assertEqual)r r=r>rк fake_metadatar2r r r к%test_detect_with_metadata_alias_class?s(   ўџќ  і z3TestDirectory.test_detect_with_metadata_alias_class) rrrr r$r3r?rCrNк __classcell__r r r,r rs  rc@ѓeZdZdd„ZdS)кTestDetectBruteForcecCsЂtj tЁ}tj |dddЁ}t |Ё}| dt|ƒЁ|D]0}g}t|dƒ  Ё}t j D]}t |dƒs4q,|  ||Ёr?| |Ёq,t|ƒdkrNtd||fƒ‚qdS) Nњ..кimagesz*.imgrкrbrщzDetection of %s failed: %s)r6r7кdirnameк__file__r8кglobкassertNotEqualкlenr9кreadrк RADIO_TO_DRVкhasattrrкappendк Exception)r r7к test_imagesкimageк detectionsкfiledatarr r r кtest_detect_allSs&      € џџјz$TestDetectBruteForce.test_detect_allN)rrrrdr r r r rQRѓ rQc@rP)к TestAliasMapc Cspi}tj ЁD],}|g|jD]#}| |jtƒЁd|j|jf}|  |||jЁ||j  |Ёqqt j t tj tj tЁdddddЁƒ Ёt jd}t| ЁƒD]b\}}| |tƒЁtdd„|Dƒƒ}| d Ёd }|D]D} z | d  d d Ё\} } Wnty|} | d } Ynw| | || |Bd| | || dfЁ|  | d||Ё||  | dЁqpqSdS)Nz%s%srRкchirpкsharezmodel_alias_map.yaml)кLoadercSsg|]}|d‘qS)rEr )к.0кxr r r к |sz0TestAliasMap.test_uniqueness..њ/rкaltњ rUz%s %s not found for %s %srE)rк DRV_TO_RADIOкvaluesrк setdefaultrкsetrrк assertNotInкaddкyamlкloadr9r6r7r8rVrWr[к FullLoaderкsortedкitemsкsplitк ValueErrorкassertIn) r кdirectory_modelsкrclassrк fullmodelкaliasesrDкmodelsк my_aliasesrEк alt_vendorк alt_modelr r r кtest_uniquenessksNџњў§  ў ўўэќzTestAliasMap.test_uniquenessN)rrrr†r r r r rfjrerf)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arrGrXrIr6rr%rvк tests.unitrrgrrкBaseTestrrQrfr r r r кs"   Cchirp-20240224/tests/unit/__pycache__/test_csv.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001671014563632616024733 0ustar hibbyhibbyo 4ЯeЗу@slddlZddlmmZddlZddlZddlZddl m Z ddl m Z dZ dZdZGdd„dejƒZdS) щN)к chirp_common)к generic_csvaLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,FRS 1,462.562500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 2,FRS 2,462.587500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, z'Location,Frequency 1,146.520 2,446.000 aБLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,RxDtcsCode,CrossMode,Mode,TStep,Skip,Power,Comment,URCALL,RPT1CALL,RPT2CALL,DVCODE 0,Nat Simplex,146.520000,,0.600000,TSQL,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,This is the national calling frequency on 2m,,,, 1,National Simp,446.000000,-,5.000000,DTCS,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,5.0W,This is NOT the UHF calling frequency,,,, csšeZdZ‡fdd„Z‡fdd„Zdd„Zd"dd „Zd d „Zd d „Zdd„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zd d!„Z‡ZS)#кTestCSVcstƒ Ёt ddЁ|_dS)Nz.csvz chirp-test)кsuperкsetUpкtempfileкmktempкtestfnЉкselfЉк __class__ЉњK/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_csv.pyrs z TestCSV.setUpcs2tƒ Ёz t |jЁWdStyYdSwЉN)rкtearDownкosкremover кFileNotFoundErrorr r rrrs  џzTestCSV.tearDowncCsќt|jddd }| tЁWdƒn1swYt |jЁ}| dЁ}| d|jЁ| d|j Ё| d|j Ё| d|j Ё| d|j Ё| d|j Ё| d |jЁ| d |jЁ| d |jЁ| d |jЁ| d |jЁ| d |jЁdS)Nкwњutf-8ЉкencodingщzFRS 1iФ$’кщ@KLч V@щкNNкNFMg)@)кopenr кwriteкCHIRP_CSV_LEGACYrкCSVRadioк get_memoryк assertEqualкnumberкnameкfreqкduplexкoffsetкtmodeкrtoneкctoneкdtcsк dtcs_polarityкmodeк tuning_stepЉr кfкcsvкmemrrrкtest_parse_legacy%s" џ  zTestCSV.test_parse_legacyrcCst|jd|d }| tЁWdƒn1swYt |jЁ}| dЁ}| d|jЁ| d|j Ё| d|j Ё| d|j Ё| d|j Ё| d|j Ё| d |jЁ| d |jЁ| d |jЁ| d |jЁ| d |jЁ| d |jЁ| dt|jƒЁ| d|jЁdS)Nrrrz National Simpщ€k•њ-rкDTCSrrrкFMg@z5.0Wz UHF calling)r r r!кCHIRP_CSV_MODERNrr#r$r%r&r'r(r)r*r+r,r-r.r/r0r1кstrкpowerкassertInкcomment)r кoutput_encodingr3r4r5rrrкtest_parse_modern7s& џ  zTestCSV.test_parse_moderncCstt Ё dЁƒ}| ddЁ| ddЁ| ddЁ| dЁt|jdd d }| d   |ЁЁWdƒn1s;wYt   |jЁ}|  dЁ}|  d |jЁ|  d Ё}|  d|jЁ| |jЁt|jdƒ}dd„| ЁDƒ}Wdƒn1s~wY|  ||ЁdS)Nк rz# This is a commentz# Test file with commentsщz# Test comment in the middlez# Comment at the endrr)кnewlinez щРЗЛrr7кrcSsg|]}| Ё‘qSr)кstrip)к.0кxrrrк Zsz2TestCSV.test_csv_with_comments..)кlistr;rGкsplitкinsertкappendr r r!кjoinrr#r$r%r(кsaveк readlines)r кlinesr3r4r5к read_linesrrrкtest_csv_with_commentsKs$    џ    џzTestCSV.test_csv_with_commentscCs|jdddS)Nz utf-8-sig)r@)rAr rrrкtest_parse_modern_bom]szTestCSV.test_parse_modern_bomcCspt|jddd }| tЁWdƒn1swYt |jЁ}| dЁ}| d|jЁ| d|j ЁdS)NrrrrrE) r r r!кCHIRP_CSV_MINIMALrr#r$r%r&r(r2rrrкtest_parse_minimal`s џ  zTestCSV.test_parse_minimalcCszt|jddd}| dЁ| dЁWdƒn1swYt |jЁ}| dЁ}| d|jЁ| d|jЁdS)NrrrzLocation,Frequency,Color z1,146.520,Red rrEЉ r r r!rr#r$r%r&r(r2rrrкtest_parse_unknown_fieldhs  ў  z TestCSV.test_parse_unknown_fieldcCs„t|jddd}| dЁ| dЁ| dЁWdƒn1s"wYt |jЁ}| dЁ}| d|jЁ| d|jЁdS) NrrrzLocation,Frequency,Power z 0,146.520,L1 z 1,146.520,5W rrErXr2rrrкtest_parse_unknown_powerqs   §  z TestCSV.test_parse_unknown_powercCstt dЁ}t Ё}d|_d|_tjddd|_| |Ё|  dЁ}|  dt |jƒЁ|  t t  dЁƒt |jƒЁdS)NrrEкLowщ)кwattsк17W)rr#rкMemoryr&r(к PowerLevelr=к set_memoryr$r%r<кintк watts_to_dBm)r r4кmrrrкtest_foreign_power{s    zTestCSV.test_foreign_powercCsFt Ё}d|_d|_t dЁ}| |Ё| dЁ}| tj |j ЁdS)NrrE) rr_r&r(rr#rar$r%кDEFAULT_POWER_LEVELr=)r rdrFкm2rrrкtest_default_power†s   zTestCSV.test_default_powercCs8t dЁ}| |Ё| |jЁt |jЁ}| |jЁSr)rr#rarPr r$r&)r r5кradiorrrк_write_and_reads     zTestCSV._write_and_readcCsHt Ё}d|_d|_d|_| |Ё}| |j|jЁ| |j|jЁdS)NrњThis is "The one"zWow, a Multi-line comment!)rr_r&r'r?rjr%Љr rdrgrrrкtest_escaped_string_chars–s z!TestCSV.test_escaped_string_charscCsLt Ё}d|_d|_d Ё|_| |Ё}| |j|jЁ| |j|jЁdS)NrrksThis is bЩd news)rr_r&r'кdecoder?rjr%rlrrrкtest_unicode_comment_charsŸs  z"TestCSV.test_unicode_comment_charscCslt Ё}d|_d|_d|_d|_d|_| |Ё}| d|jЁ| d|jЁ| d|jЁ| d|jЁdS)NrкCrossz DTCS->DTCSщщI) rr_r&r+к cross_moder.кrx_dtcsrjr%rlrrrкtest_cross_dtcsЈs zTestCSV.test_cross_dtcscCs>tjdd}t dЁ}| |Ёd|_| d| dЁjЁdS)Nкfoo)r'кbarr)rr_rr#rar'r%r$)r rdrirrrкtest_csv_memories_are_privateЕs   z%TestCSV.test_csv_memories_are_private)r)к__name__к __module__к __qualname__rrr6rArTrUrWrYrZrerhrjrmrorurxк __classcell__rrr rrs"          r)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arrrкunittestкchirprк chirp.driversrr"rVr;кTestCaserrrrrкs"  џџџchirp-20240224/tests/unit/__pycache__/test_import_logic.cpython-310-pytest-7.1.3.pyc0000644000175000017500000003370714503006465026623 0ustar hibbyhibbyo  eїGу@sЄddlZddlmmZddlmZddlm Z ddl m Z ddl m Z ddl m Z Gdd„de jƒZGd d „d ee jƒZGd d „d e jƒZGd d„de jƒZdS)щN)кmock)кbase)к import_logic)к chirp_common)кerrorsc@s,eZdZdd„Zdd„Zdd„Zdd„Zd S) к FakeRadiocCs\ttjdddtjdddgƒ|_tgdЂƒ|_d|_d|_tgd Ђƒ|_tgd Ђƒ|_dS) NкloщЉкwattsкhiщ2)ккToneкTSQLTF)кFMкAMкDV)rњ-њ+) кlistrк PowerLevelк POWER_LEVELSкTMODESк HAS_CTONEк HAS_RX_DTCSкMODESкDUPLEXES)кselfкargЉr њT/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_import_logic.pyк__init__ s џzFakeRadio.__init__cCsdS)Nњ filtered-namer )rкnamer r r!к filter_nameszFakeRadio.filter_namecCstj|ddS)NT)кempty)rкMemory)rкnumberr r r!к get_memoryѓzFakeRadio.get_memorycCs<t Ё}|j|_|j|_|j|_|j|_ |j |_ |j |_ |SЉN)rк RadioFeaturesrкvalid_power_levelsrк valid_tmodesrк valid_modesrкvalid_duplexesrк has_ctonerк has_rx_dtcsЉrкrfr r r!к get_featuresszFakeRadio.get_featuresN)к__name__к __module__к __qualname__r"r%r)r5r r r r!r s   rcs eZdZdZ‡fdd„Z‡ZS)кFakeDstarRadioFcstƒ Ё}|j|_|Sr+)кsuperr5кREQUIRES_CALL_LISTSкrequires_call_listsr3Љк __class__r r!r5's zFakeDstarRadio.get_features)r6r7r8r;r5к __classcell__r r r=r!r9$sr9c@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)к DstarTestscCsŒtdƒ}tjj|tjtjd-}||d_||d_t ||Ё| t |ƒt |ƒЁ| t |ƒt |ƒЁWdƒdS1s?wYdS)N)кget_urcall_listкget_repeater_call_listrArB) r9rкpatchкmultipleкDEFAULTк return_valuerкensure_has_callsк assertEqualкsorted)rкmemк ini_urcallsк ini_rptcallsк exp_urcallsк exp_rptcallsкradioкmocksr r r!к_test_ensure_has_calls.s§   "јz!DstarTests._test_ensure_has_callscCѓnt Ё}d|_d|_d|_gdЂ}gdЂ}t|ƒ}t|ƒ}|j|d<|j|d<|j|d<| |||||ЁdS)NкKK7DSњKD7RFI BњKD7RFI G)rrrrrrщЉrкDVMemoryк dv_urcallк dv_rpt1callк dv_rpt2callrrQЉrrJrKrLrMrNr r r!кtest_ensure_has_calls_empty<ѓ    џz&DstarTests.test_ensure_has_calls_emptycCrR)NrSrTrU)кFOOкBARrrrщщrWr\r r r!кtest_ensure_has_calls_partialKr^z(DstarTests.test_ensure_has_calls_partialcCsnt Ё}d|_d|_d|_gdЂ}gdЂ}t|ƒ}t|ƒ}|j|d<|j|d<|j|d<| |||||ЁdS)NrSrTrUЉr_r`кBAZкBATrЉr_r`rerrщrbrWr\r r r!к!test_ensure_has_calls_almost_fullZr^z,DstarTests.test_ensure_has_calls_almost_fullc Cѓvt Ё}d|_d|_d|_gdЂ}gdЂ}t|ƒ}t|ƒ}|j|d<|j|d<|j|d<| tj|j |||||ЁdS)NrSrTrUЉr_r`rerfкBOOMrgrhrbЉ rrXrYrZr[rк assertRaisesrк RadioErrorrQr\r r r!к!test_ensure_has_calls_urcall_fulliѓ    §z,DstarTests.test_ensure_has_calls_urcall_fullc Csvt Ё}d|_d|_d|_gdЂ}gdЂ}t|ƒ}t|ƒ}|j|d<|j|d<|j|d<| tj|j |||||ЁdS)NrSrTrUrdrhrbrmr\r r r!к#test_ensure_has_calls_rptcall_full1zrqz.DstarTests.test_ensure_has_calls_rptcall_full1c Crj)NrSrTrUrdrkrhrbrmr\r r r!к#test_ensure_has_calls_rptcall_full2‹rqz.DstarTests.test_ensure_has_calls_rptcall_full2N) r6r7r8rQr]rcrirprrrsr r r r!r@-s r@c@s<eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dd„Z dd„Zdd„Zdd„Zdd„Zdd „Zd!d"„Zd#d$„Zd%d&„Ze d'Ёe d(Ёe d)Ёe d*Ёe d+Ёe d,Ёd-d.„ƒƒƒƒƒƒZd/d0„Zej ed1Ёej ed2Ёd3d4„ƒƒZd5d6„Zd7d8„Zd9d:„Zd;d<„Z d=d>„Z!d?S)@кImportFieldTestscCs2t Ё}d|_t tdƒd|Ё| |jdЁdS)Nкfoor#)rr'r$rк _import_namerrH)rrJr r r!кtest_import_namežsz!ImportFieldTests.test_import_namecCsJtdƒ}| Ё}t Ё}|jd|_t |||Ё| |j|jdЁdS)Nr) rr5rr'r-кpowerrк _import_powerrH)rrOкsame_rfrJr r r!кtest_import_power_sameЄs  z'ImportFieldTests.test_import_power_samecCsDtdƒ}t Ё}t Ё}d|_t |||Ё| |j|jdЁdS)NrV) rrr,r'rxrryrHrЉrrOкsrc_rfrJr r r!кtest_import_power_no_srcЌs z)ImportFieldTests.test_import_power_no_srccCsЂtdƒ}t Ё}t Ё}d|_tj |dЁ(}t Ё|_d|j_ t  dЁt  dЁt  dЁg|j_ t   |||ЁWdƒn1sAwY| dt|jƒЁdS)Nr5TrVr iмк50W)rrr,r'rxrrCкobjectrFкhas_variable_powerкAutoNamedPowerLevelr-rryrHкstrЉrrOr}rJкmock_gfr r r!к!test_import_power_no_src_variableДs §љz2ImportFieldTests.test_import_power_no_src_variablecCs|tdƒ}| Ё}t Ё}|jd|_tj |dЁ}t  Ё|_ t   |||ЁWdƒn1s0wY|  |jdЁdS)Nrr5)rr5rr'r-rxrrCr€r,rFrryrHr„r r r!кtest_import_power_no_dstУs  ўz)ImportFieldTests.test_import_power_no_dstcCѓttdƒ}t Ё}tjdddtjdddtjdddg|_t Ё}|jd|_t |||Ё|  |j|j dЁdS) Nruщr кbarщ3кbazrVrЉ rrr,rr-r'rxrryrHrr|r r r!кtest_import_power_closestЭѓ   § z*ImportFieldTests.test_import_power_closestcCrˆ) Nruщr rŠr‹rŒrVrrr|r r r!кtest_import_power_closest_wattsкrz0ImportFieldTests.test_import_power_closest_wattscCѓJtdƒ}t Ё}d|_t Ё}d|_d|_t |||Ё|  |j dЁdS)NFrчY@) rrr,r1r'кtmodeкrtonerк _import_tonerHкctoner|r r r!кtest_import_tone_diffA_tsqlчѓz,ImportFieldTests.test_import_tone_diffA_tsqlcCѓPtdƒ}d|_t Ё}d|_t Ё}d|_d|_t  |||Ё|  |j dЁdS)NFTrr“) rrrr,r1r'r”r—rr–rHr•r|r r r!кtest_import_tone_diffB_tsqlёѓz,ImportFieldTests.test_import_tone_diffB_tsqlcCr’)NTкDTCSщ ) rrr,r2r'r”кrx_dtcsrк _import_dtcsrHкdtcsr|r r r!кtest_import_dtcs_diffA_dtcsќr™z,ImportFieldTests.test_import_dtcs_diffA_dtcscCrš)NTFrrž) rrrr,r2r'r”rЁrr rHrŸr|r r r!кtest_import_dtcs_diffB_dtcsrœz,ImportFieldTests.test_import_dtcs_diffB_dtcscCѓ<tdƒ}t Ё}d|_d|_t |d|Ё| |jdЁdS)NкAutoщ€ШГrЉrrr'кmodeкfreqrк _import_moderHЉrrOrJr r r!кtest_import_mode_valid_fmѓ z*ImportFieldTests.test_import_mode_valid_fmcCrЄ)NrЅi€ЈrrЇrЋr r r!кtest_import_mode_valid_amr­z*ImportFieldTests.test_import_mode_valid_amcCsBtdƒ}|j dЁt Ё}d|_d|_| tj tj |d|ЁdS)NrrЅi@w) rrкremoverr'rЈrЉrnrкDestNotCompatiblerЊrЋr r r!кtest_import_mode_invalid!s  џz)ImportFieldTests.test_import_mode_invalidcCѓPtdƒ}t Ё}d|_d|_d|_t |d|Ё| |jdЁ| |jdЁdS)NrІщ@№МкsplitrщР' Љ rrr'rЉкoffsetкduplexrк_import_duplexrHrЋr r r!кtest_import_duplex_vhf*ѓz'ImportFieldTests.test_import_duplex_vhfcCrВ)NrГrІrДrrЕrЖrЋr r r!кtest_import_duplex_negative4rЛz,ImportFieldTests.test_import_duplex_negativecCrВ)NiР‰Аi@ IrДri€–˜rЖrЋr r r!кtest_import_duplex_uhf>rЛz'ImportFieldTests.test_import_duplex_uhfcCs<tdƒ}t Ё}d|_d|_d|_| tjtj |d|ЁdS)NrІi€ЉЉrД) rrr'rЉrЗrИrnrrАrЙrЋr r r!кtest_import_duplex_too_big_vhfHs џz/ImportFieldTests.test_import_duplex_too_big_vhfcCs<tdƒ}t Ё}d|_d|_t |d|Ё| d|jЁdS)NrІкoffr)rrr'rЉrИrrЙrHrЋr r r!к$test_import_duplex_off_not_supportedQr­z5ImportFieldTests.test_import_duplex_off_not_supportedzchirp.import_logic._import_namez chirp.import_logic._import_powerzchirp.import_logic._import_tonezchirp.import_logic._import_dtcszchirp.import_logic._import_modez!chirp.import_logic._import_duplexc CsВtdƒ}t Ё} t Ё} tj | dЁ5} | | _tj |dЁ} || _t  || | Ё|   | ЁWdƒn1s8wY|   ЁWdƒn1sKwY|  || | ЁdS)Nкdupeкvalidate_memory) rrr,r'rrCr€rFrк import_memкassert_called_once_with) rrк mock_duplexк mock_modeк mock_dtcsк mock_toneк mock_powerк mock_namerOr}rJк mock_dupeкmock_valr r r!к_test_import_memYs  § њz!ImportFieldTests._test_import_memcCs| gЁdSr+)rЭЉrr r r!кtest_import_mempr*z ImportFieldTests.test_import_memr)к!check_set_memory_immutable_policycCsztdƒ}t Ё}t Ё}tj |dЁ }||_t  |||Ё|  |j|Ё|  |j ЁWdƒdS1s6wYdS)NrС) rrr,r'rrCr€rFrrУrФr()rк mock_checkкmock_getrOr}rJrЫr r r!к test_import_mem_checks_immutabless"ќz1ImportFieldTests.test_import_mem_checks_immutablecCs>tdƒ}t Ё}t Ё}tj|||tjd}| |tjЁdS)N)кmem_cls)rrr,r'rrУrXкassertIsInstance)rrOr}rJкmem2r r r!кtest_import_mem_with_classs џz+ImportFieldTests.test_import_mem_with_classcCsіtdƒ}t Ё}t Ё}d|_dg|_| tjtj |||Ёddg|_t   dЁ}t  |||Ё|  ЁWdƒn1s>wYt dƒ}t   dЁ%}d|_t  |||Ё|  Ёd|_t  |||Ё| ЁWdƒdS1stwYdS)Nrrz#chirp.import_logic.ensure_has_callsFT)rrr,rXrЈrrnrrАrУrrCкassert_not_calledr9r;к assert_called)rrOr}rJкmock_er r r!кtest_import_mem_dstar_logic‡s, џ   ў  "љz,ImportFieldTests.test_import_mem_dstar_logiccCs| t dЁgЁdSЉNкTest)rЭrкValidationWarningrЮr r r!кtest_import_mem_with_warningsЅsz.ImportFieldTests.test_import_mem_with_warningscCs| tj|jt dЁgЁdSrм)rnrrАrЭrкValidationErrorrЮr r r!кtest_import_mem_with_errorsЈs ўz,ImportFieldTests.test_import_mem_with_errorsc sFt Ё‰dˆ_t Ё‰dˆ_tdƒ‰tdƒ‰t ˆЁ}t ˆЁ}t |ddЁt |ddЁt |ddЁg‰t |ddЁt |ddЁt |d d Ёg}tjjˆd |gd tjjˆd |gd tjj|d ˆd tjj|d |d tjj|d|dgd tjj|dˆdgd tj |dЁtj |dЁ‡‡‡‡‡fdd„ƒƒƒƒƒƒƒƒ}|ƒdS)NrVrarкAкBкCк1к2rbк3кget_mapping_models)rFк get_mappingsкget_memory_mappingsкremove_memory_from_mappingкadd_memory_to_mappingcs4t ˆˆˆˆЁ| ˆˆdЁ| ˆˆdЁdS)NrVr)rк import_bankrФ)кmock_addк mock_removeкrestЉк dst_banksкdst_memк dst_radioкsrc_memк src_radior r!к_testРsz0ImportFieldTests.test_import_bank.._test) rr'r(rк BankModelкBankrrCr€)rкdst_bmкsrc_bmк src_banksrїr rёr!кtest_import_bank­sL     ў   ў џ џ џ џ џ џ  $ z!ImportFieldTests.test_import_bankN)"r6r7r8rwr{r~r†r‡rŽr‘r˜r›rЂrЃrЌrЎrБrКrМrНrОrРrrCrЭrЯr€rrгrзrлrпrсr§r r r r!rtsH                 rt)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкunittestrк tests.unitrкchirprrrкRadiorкIcomDstarSupportr9кBaseTestr@rtr r r r!кs&     pchirp-20240224/tests/unit/__pycache__/test_cli.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000324414411666552024703 0ustar hibbyhibbyo Xl'dУу@sXddlZddlmmZddlZddlZddlmZddl m Z Gdd„dej ƒZ dS)щN)кmock)кmainc@s8eZdZdd„Zdd„Zdd„Zedd„ƒZd d „Zd S) кTestCLIc Cs~g|_g|_|j t dЁЁ|j tjjtd|jdЁ|jD]}| Ёq t j   t j   t j   t j   tЁdddЁЁЁ|_dS)Nzsys.exitкprint)кnewz..кimageszIcom_IC-2820H.img)к stdout_linesкpatchesкappendrкpatchкobjectrк fake_printкstartкosкpathкjoinкabspathкdirnameк__file__кtestfileЉкselfr ЉrњK/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_cli.pyкsetUp s џ  ўџ џz TestCLI.setUpcCs|jD]}| ЁqdSЉN)r кstoprrrrкtearDowns  џzTestCLI.tearDowncGs|D] }|j t|ƒЁqdSr)rr кstr)rкaкirrrr sџzTestCLI.fake_printcCs d |jЁS)Nк )rr)rrrrкstdout!s zTestCLI.stdoutcCs,d|jddg}tj|d| d|jЁdS)Nz--mmapz --get-memr)кargsz147.56)rrкassertInr")rr#rrrкtest_cli_simple%s zTestCLI.test_cli_simpleN) к__name__к __module__к __qualname__rrr кpropertyr"r%rrrrrs  r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arrкunittestrк chirp.clirкTestCaserrrrrкs "  chirp-20240224/tests/unit/__pycache__/test_network_sources.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000200614430373743027361 0ustar hibbyhibbyo уђ`dу@sPddlZddlmmZddlZddlmZddlm Z Gdd„dej ƒZ dS)щN)кmock)кdmrmarcc@seZdZdd„ZdS)к TestDMRMARCcCstt Ё}| t ЁddddœЁ| Ё}| |jddЁt|jŽD]}|  |Ё}|  d|j Ё| |j dЁq"dS) Nкportlandкoregonк)кcityкstateкcountryщщкDMRiсѕ) rк DMRMARCRadioкdo_fetchrк MagicMockк get_featuresк assertGreaterк memory_boundsкrangeк get_memoryк assertEqualкmodeкfreq)кselfкrкfкiкmЉrњW/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_network_sources.pyкtest_marc_works s ў ќzTestDMRMARC.test_marc_worksN)к__name__к __module__к __qualname__r rrrrr s r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкunittestrк chirp.sourcesrкTestCaserrrrrкs"  chirp-20240224/tests/unit/__pycache__/test_kguv920.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000473714411666553025354 0ustar hibbyhibbyo Xl'dЯу@sfddlZddlmmZddlZddlZddlm Z ddl m Z Gdd„dƒZ Gdd„dej ƒZdS)щN)к kguv920pa)кmemmapc@ѓ$eZdZdd„Zdd„Zdd„ZdS)к FakeSerialcCsd|_d|_dS)Nѓ)кibufкobuf)кselfЉr њO/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_kguv920.pyк__init__s zFakeSerial.__init__cCsЊt|tƒ}|sJddt Ёvst tЁrt tЁnddt Ёvs$t |Ёr)t |Ёnddt Ёvs5t tЁr:t tЁndt |Ёdœ}tt |Ёƒ‚d}|j |7_ dS)Nz5assert %(py4)s {%(py4)s = %(py0)s(%(py1)s, %(py2)s) }к isinstanceкbкbytes)кpy0кpy1кpy2кpy4) r rк @py_builtinsкlocalsк @pytest_arк_should_repr_global_nameк _safereprкAssertionErrorк_format_explanationr)r rк @py_assert3к @py_format5r r r кwrites˜zFakeSerial.writecCs8td|t|jƒfƒ|jd|…}|j|d…|_|S)Nzread %i (rem %i))кprintкlenr)r кnкrr r r кread"szFakeSerial.readN)к__name__к __module__к __qualname__r rr"r r r r rs rc@r)к TestClonec CsPtƒ}t ddddttjjƒt tjjЁdЁ|_t |jƒt |Ё}|  ЁdS)NкBBBB10sBrщ) rкstructкpackrrкKGUV920PARadioк_modelк _str_encoderrк _identifyЉr кsкdr r r к test_identify*s §   zTestClone.test_identifycCs<tƒ}t ddddЁ}|d|_t |Ё}| dddЁdS)NкxxxB16sBщsrщщ )rr)r*rrr+к _do_download)r r0кonerespr1r r r к test_download4s   zTestClone.test_downloadcCsPtƒ}t ddddЁt ddddЁ|_t |Ё}t dЁ|_|  dddЁdS)Nz>xxxBHBr5rr4s r6) rr)r*rrr+rкMemoryMapBytesк_mmapк _do_uploadr/r r r к test_upload;sџ  zTestClone.test_uploadN)r#r$r%r2r9r=r r r r r&)s r&)кbuiltinsrк_pytest.assertion.rewriteк assertionкrewriterr)кunittestк chirp.driversrкchirprrкTestCaser&r r r r кs "  chirp-20240224/tests/unit/__pycache__/test_icom_clone.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001041714430373743026241 0ustar hibbyhibbyo уђ`dHу @sTddlZddlmmZddlZddlmZddl m Z ddl m Z ddlm Z ddlZddlZddlZddl mZe ЁGdd„dƒZGd d „d ejƒZGd d „d eƒZej ej ej eЁЁd ddЁZe eЁD]:Zej ej  eЁЁ\Z!Z"ze #e!ЁZ$Wn e%y‹Yqmwe$j&rqmde!Z'ee'eejfe(e!edƒej)e*j+e'<qmdS)щN)кicom_clone_simulator)кmemmap)кicw32)кbytes)к directoryc@s<eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd S)кBaseIcomCloneTestcCs2t |jЁdƒ|_t |jЁ|_|j |jЁdSЉN)rк get_radioк RADIO_IDENTкradiorк FakeIcomRadioк simulatorкset_pipeЉкselfЉrњR/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_icom_clone.pyкsetUpszBaseIcomCloneTest.setUpcCs$tj tj tЁЁ}tj |d|ЁS)Nкimages)кosкpathкdirnameкabspathк__file__кjoin)rкfilenameк tests_baserrrкimage_filename$sz BaseIcomCloneTest.image_filenamecCs|j | |ЁЁdSr)r кload_from_filer)rrrrrкload_from_test_image(ѓz&BaseIcomCloneTest.load_from_test_imagecCs€|j Ё}t| |Ёdƒ }| Ё}Wdƒn1swY|dd…d|j Ёdkr2dS||d|…dkr>d SdS) Nкrbщјџџџiњџџџѓ%02xrщщѓIcomCloneFormat3щ)r к get_memsizeкopenrкreadк get_model)rrкendкfкdatarrrк image_version+s  џџzBaseIcomCloneTest.image_versioncCsЬ|j}| |Ё|j Ё| |Ё}|dkr6d dd„|jjdd…DƒЁ}| |d|jjdd…ЁdS|dkrH| d|jjd d…ЁdS|durdt |jt j ƒrUdS| |j  Ёt |jjƒЁdSdS) Nr$ѓcss|] }dt|ƒVqdS)r#N)кord)к.0кcrrrк <s€џz1BaseIcomCloneTest.test_sync_in..s0001r"r'r&i№џџџ)к IMAGE_FILErr кsync_inr/rк_modelк assertEqualк_mmapк isinstancerк ICW32ERadior(кlen)rк test_fileкimg_verк endstringrrrк test_sync_in5s     џ њzBaseIcomCloneTest.test_sync_incCsRt tdƒ|j ЁЁ|j_tdƒ|jjd<|j Ё| d|jj dd…ЁdS)Nѓsabcdefghщ2щ:) rкMemoryMapBytesrr r(r9кsync_outr8r к_memoryrrrrк test_sync_outIs џ zBaseIcomCloneTest.test_sync_outN) к__name__к __module__к __qualname__rrrr/r@rGrrrrrs rc@seZdZdd„Zdd„ZdS)кTestRawRadioDatacCsNt dЁdƒ}| tdƒddЁ}| d|Ё| tdƒddЁ}| d|ЁdS)Nњ Icom_IC-2730AѓўTsџђFѓџ)rr к get_payloadrr8)rr кpayloadrrrкtest_get_payloadRs  z!TestRawRadioData.test_get_payloadcCs,t dЁdƒ}| tdƒЁ}| d|ЁdS)NrLrNrM)rr кprocess_frame_payloadrr8)rr r.rrrкtest_process_frame_payloadZsz+TestRawRadioData.test_process_frame_payloadN)rHrIrJrQrSrrrrrKQs rKcseZdZ‡fdd„Z‡ZS)кTestAdapterMetacstt|ƒ ||||ЁSr)кsuperrTк__new__)кclsкnameкparentsкdctЉк __class__rrrVar zTestAdapterMeta.__new__)rHrIrJrVк __classcell__rrr[rrT`srTz..rz Icom_*.imgzTest_%s)r r5),кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкsysкtestsrкchirprк chirp.driversrrкglobrкunittestrкimport_driversrкTestCaserKкtyperTrrrrrкtest_file_globк image_fileкsplitextкbasenameкbaseк_extr r к Exceptionк _raw_framesк class_nameкdictкmodulesrHк__dict__rrrrкsB"     3ў џ ўџѓchirp-20240224/tests/unit/__pycache__/test_icf.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001242214437323573024674 0ustar hibbyhibbyo щІ}dXу@s‚ddlZddlmmZddlZddlZddlZddl Z ddl m Z ddl m Z mZmZGdd„de jƒZGdd„de jƒZdS)щN)к directory)кic2820кicfкid31c@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)к TestFileICFcCst Ё|_dSЉN)кtempfileкmkdtempкtempdirЉкselfЉr њK/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_icf.pyкsetUpszTestFileICF.setUpcCst |jЁdSr)кshutilкrmtreer r r r rкcleanUpszTestFileICF.cleanUpc Csшtj |jdЁ}t|ddd }| dЁ| dЁ| dЁ| dЁ| ЁWdƒn1s2wYt |Ё\}}|  d d d d d dœ|Ёzt   |ЁWnt yl}z|  dt|ƒЁWYd}~dSd}~ww| dЁdS)Nњtest.icfкwњ Љкnewlinez$12345678 #Foo=somefoovalue #Bar=123 њK0000000020015C70000020800000E400202020202020202020202020202020200040810204 њK00000020200810204081020408102040810204081020015B9903E821700000E4284C614772 њ #CD=fakehash s4Vxк somefoovalueщ{щ кfakehash)кmodelкFooкBarк recordsizeкCDzUnknown file formatz(Directory failed to reject unknown model)кosкpathкjoinr кopenкwriteкflushrк read_fileк assertEqualrкget_radio_by_imageк ExceptionкassertInкstrкfail)r кfnкfкicfdataкmmapкer r rкtest_read_icf_data_modern s0     љ ќќ€џz%TestFileICF.test_read_icf_data_moderncCsˆtj |jdЁ}t|ddd}| dЁ| dЁ| dЁ| ЁWdƒn1s-wYt |Ё\}}|  dd d œ|ЁdS) Nrrrrz 29700001 # z'00001008BBB7C0000927C04351435143512020 z'00101020202020202020202020202020202020 s)pщ)rr") r$r%r&r r'r(r)rr*r+)r r1r2r3r4r r rкtest_read_icf_data_old:s    ќџџz"TestFileICF.test_read_icf_data_oldc Csђtj |jdЁ}t|ddd }| dЁ| dЁ| dЁ| dЁ| ЁWdƒn1s2wYt |Ё}tj |jd Ё}t|ddd$}|  |Ёt   |Ё\}}|  d d d |  Ёd ddœ|ЁWdƒdS1srwYdS)Nz test1.icfrrrz#33220001 #MapRev=2 #EtcData=000006 rrrz test2.icfщщкк 9674E1C86BA17D36DB9D3D8A144F1081rЉкMapRevкEtcDataкCommentrr#r")r$r%r&r r'r(r)rк ID31Radioкsaverr*r+к get_model)r кfn1r2кrкfn2r3r4r r rкtest_read_write_icfGs.     ї  ћћ"§zTestFileICF.test_read_write_icfc CsВtj tj tЁdddЁ}t |Ё}tj |jdЁ}t|ddd.|  |Ёt   |Ё\}}|  dd d |  Ёd d d œ|Ё| t |ЁtjЁWdƒdS1sRwYdS)Nњ..кimageszIcom_ID-31A.imgrrrrщщr;к 9F240F598EF20683726ED252278C61D0rr=)r$r%r&кdirnameк__file__rrAr r'rBrr*r+rCкassertIsInstancerr,Љr кimg_filerEr1r3r4r r rкtest_read_img_write_icf_modernas*џ  ћћ џ"ѓz*TestFileICF.test_read_img_write_icf_modernc CsАtj tj tЁdddЁ}t |Ё}tj |jdЁ}t|ddd-|  |Ёt   |Ё\}}|  dd d |  Ёd d œ|Ё| t |ЁtjЁWdƒdS1sQwYdS) NrHrIzIcom_IC-2820H.imgrrrrrJrr;r7)r>r?r@rr")r$r%r&rMrNrк IC2820Radior r'rBrr*r+rCrOrr,rPr r rкtest_read_img_write_icf_oldws(џ  ќќ џ"іz'TestFileICF.test_read_img_write_icf_oldN) к__name__к __module__к __qualname__rrr6r8rGrRrTr r r rrs  rc@s,eZdZdd„Zdd„Zdd„Zdd„Zd S) к TestCloneICFcCѓHtj dЁ}| d|jЁ| d|jЁ| d|jЁ| d|jЁdS)Nsўўюяр§щющящрѓЉrкIcfFrameкparser+кsrcкdstкcmdкpayloadЉr r2r r rкtest_frame_parseŒѓ zTestCloneICF.test_frame_parsecCstj dЁ}| |ЁdS)Nsўўюяр)rr_r`к assertIsNonerer r rкtest_frame_parse_no_end“s z$TestCloneICF.test_frame_parse_no_endcCrY)Ns ўўюяр§rZr[r\r]r^rer r rк!test_frame_parse_trailing_garbage—rgz.TestCloneICF.test_frame_parse_trailing_garbagecCs.t tjtjtjЁ}d|_| d| ЁЁdS)Nssўўюяр§)rr_кADDR_PCк ADDR_RADIOк CMD_CLONE_IDrdr+кpackrer r rк test_packžszTestCloneICF.test_packN)rUrVrWrfrirjror r r rrX‹s  rX)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arr$rrкunittestкchirprк chirp.driversrrrкTestCaserrXr r r rкs" rchirp-20240224/tests/unit/__pycache__/test_alinco_clone.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001160114430373743026553 0ustar hibbyhibbyo уђ`dЌу@s†ddlZddlmmZddlZddlZddlZddlm Z ddl m Z ddl m Z ddl mZGdd„dƒZGdd „d ejƒZdS) щN)кmock)к directory)кalinco)кmemmapc@s8eZdZdZdd„Zdd„Zdd„Zdd „Zd d „Zd S) кFakeAlincoSerialz4Behaves like a Serial with an Alinco radio connectedcCs&t t|dƒ ЁЁ|_g|_d|_dS)Nкrbѓ)rкMemoryMapBytesкopenкreadкimageкreadbufкident)кselfr ЉrњT/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_alinco_clone.pyк__init__s zFakeAlincoSerial.__init__cCst dt|jƒЁ|_dS)zZero the mmap before an uploadѓN)rr кlenr Љrrrrкzero"szFakeAlincoSerial.zerocCsVd|vr | dЁ}nd|vr| dЁ}ntd|ƒ‚|ddkr#d}nd}t|d|…dƒ}|||d…}|dkrot |j|||…Ё}d|jvrU|j d |ЁdS|dkrc|j d |ЁdS|j d ||fЁdS|dkrЃt  ||dd…  ЁЁ}t |ƒ|krtd |t |ƒfƒ‚||j|<|dkrЁ|j d ЁdSdStd||fƒ‚)NѓRѓWzUnable to handle RW command %rщщщ@щsDJ175s%s s %s s %04X:%s zExpected %i, got %iѓOK zUnable to handle command %s: %r) кindexк Exceptionкintкbinasciiкhexlifyr rr кappendк unhexlifyкrstripr)rкdataкcmdindexк block_sizeкaddrкcmdкchunkrrrк _handle_rw&s8      џ џzFakeAlincoSerial._handle_rwcCsК|j |Ёd}| dЁr| Ё|_|j |Ёd S| dЁr,| Ё|_|j |Ёd S| dЁr>| Ё|_|j |Ёd S| dЁrJ| |Ёd S| dЁrW|j dЁd Std|ƒ‚) z7Write to the radio (i.e. buffer some response for read)rsDRsAL~DJ-G7sDJsAL~FsAL~EsOKOKOKOKOKOKOKOKOKOKzUnable to handle %rN)r r#к startswithкstriprr,r)rr&к ident_ackrrrкwriteHs          zFakeAlincoSerial.writecCs@t|jdƒ|kr|j dЁStd|t|jdƒ|jdfƒ‚)z6Read from the radio (i.e. generate a radio's response)rzRead of %i not match %i %r)rr кpopr)rкlengthrrrr _s  џzFakeAlincoSerial.readN) к__name__к __module__к __qualname__к__doc__rrr,r0r rrrrrs" rc@sDeZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dS)кAlincoCloneTestcCs6t|ƒ}||ƒ}| Ё|js| |jtjЁdSdSЉN)rкsync_inкNEEDS_COMPAT_SERIALкassertIsInstanceк_mmaprr )rкrclassr кpipeкradiorrrк_test_alinco_downloadis џz%AlincoCloneTest._test_alinco_downloadcCs^t|ƒ}| Ё||ƒ}||_| Ёt|dƒ Ё}| |d|j…|j  Ёd|j…ЁdS)Nri) rrr>кsync_outr r к assertEqualк_memsizer к get_packed)rr=r r>r?к ref_imagerrrк_test_alinco_uploadpsџz#AlincoCloneTest._test_alinco_uploadcCspt |Ё}tj tj tЁddd|Ё}t dЁ|  ||Ё|  ||ЁWdƒdS1s1wYdS)Nz..кimagesz%s.imgz time.sleep) rкradio_class_idкosкpathкjoinкdirnameк__file__rкpatchrFr@)rr=rr rrrк _test_alincozs ў  "ўzAlincoCloneTest._test_alincocCѓ| tjЁdSr8)rOrк AlincoDJG7EGrrrrк test_djg7ƒѓzAlincoCloneTest.test_djg7cCrPr8)rOrк DR235Radiorrrrк test_dr235†rSzAlincoCloneTest.test_dr235cCrPr8)rOrк DJ175Radiorrrrк test_dj175‰szAlincoCloneTest.test_dj175cCsPdd„tj ЁDƒ}|D]}ttƒ}|dƒ}||_| Ё| |j|j Ёq dS)NcSsg|] }|jdkr|‘qS)кAlinco)кVENDOR)к.0кxrrrк ‘s џz.) rк DRV_TO_RADIOкvaluesrrMr>к _identifyrBrк_model)rкalincosr=r>r?rrrкtest_all_alinco_identifyŽsћz(AlincoCloneTest.test_all_alinco_identifyN) r3r4r5r@rFrOrRrUrWrbrrrrr7hs   r7)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arr!rIкunittestrкchirprк chirp.driversrrrкTestCaser7rrrrкs"    Nchirp-20240224/tests/unit/__pycache__/base.cpython-310.pyc0000644000175000017500000000170214430373743022010 0ustar hibbyhibbyo уђ`d9у@sDddlZddlZddlZe deЁdd„e_Gdd„dejƒZdS)щNкignorecCѓ|SЉNЉ)кxrrњG/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/base.pyкѓrc@seZdZdd„Zdd„ZdS)кBaseTestcCsdd„td<g|_dS)NcSrrr)кsrrrr r z BaseTest.setUp..к_)к __builtins__кmocks)кselfrrrкsetUp s  zBaseTest.setUpcCs|jD]}| ЁqdSr)rкstop)rкmrrrкtearDowns  џzBaseTest.tearDownN)к__name__к __module__к __qualname__rrrrrrr s r )кbuiltinsкunittestкwarningsк simplefilterкWarningr кTestCaser rrrrкs   chirp-20240224/tests/unit/__pycache__/test_util.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000252014411666553025106 0ustar hibbyhibbyo Xl'd}у@sHddlZddlmmZddlmZddlm Z Gdd„de j ƒZ dS)щN)кutil)кbasec@s,eZdZdd„Zdd„Zdd„Zdd„Zd S) к TestUtilscCѓt dЁdS)Nк00000000000000ЉrкhexprintЉкselfЉr њL/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_util.pyкtest_hexprint_with_stringѓz#TestUtils.test_hexprint_with_stringcCr)Ns00000000000000rr r r r кtest_hexprint_with_bytes rz"TestUtils.test_hexprint_with_bytescCѓd}| |t dЁЁdS)NzP000: 00 00 00 00 00 00 00 00 ........ 008: 00 ........ s Љк assertEqualrrЉr кexpectedr r r кtest_hexprint_short szTestUtils.test_hexprint_shortcCr)Nz(000: 00 00 00 00 00 00 00 00 ........ srrr r r кtest_hexprint_evenszTestUtils.test_hexprint_evenN)к__name__к __module__к __qualname__r rrrr r r r rs  r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкchirprк tests.unitrкBaseTestrr r r r кs& chirp-20240224/tests/unit/__pycache__/test_th9800.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000603414430373743025066 0ustar hibbyhibbyo уђ`dцу@sZddlZddlmmZddlZddlZddlm Z Gdd„dƒZ Gdd„dej ƒZ dS)щN)кth9800c@s(eZdZdZdd„Zdd„Zdd„ZdS) кFake9800sTH9800џџV14xџџџџcCsd|_d|j|_dS)NѓѓA)кwritebufкidentкreadbuf)кselfЉr њN/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_th9800.pyк__init__ szFake9800.__init__c Csфt|tƒ}|sJddt Ёvst tЁrt tЁnddt Ёvs$t |Ёr)t |Ёnddt Ёvs5t tЁr:t tЁndt |Ёdœ}tt |Ёƒ‚d}|j |7_ |  dЁra|j d7_ dS|  dЁrv|j |7_ |j d 7_ dS|d krу|j }t |ƒ}d }||k}|sвt  d |fd ||fЁd t Ёvsžt t ЁrЃt t Ёnd dt ЁvsЏt |ЁrДt |Ёndt |Ёt |Ёt |Ёdœ}dd|i} tt | Ёƒ‚d}}}}|j d 7_ dS|dkr№|j d7_ dSdS)Nz5assert %(py4)s {%(py4)s = %(py0)s(%(py1)s, %(py2)s) }к isinstanceкdataкbytes)кpy0кpy1кpy2кpy4ѓRs„WѓWrr)њ==)zM%(py5)s {%(py5)s = %(py0)s(%(py3)s {%(py3)s = %(py1)s.readbuf }) } == %(py8)sкlenr )rrкpy3кpy5кpy8zassert %(py10)sкpy10sENDWs123)r rк @py_builtinsкlocalsк @pytest_arк_should_repr_global_nameк _safereprкAssertionErrorк_format_explanationrк startswithrrк_call_reprcompare) r rк @py_assert3к @py_format5к @py_assert2к @py_assert4к @py_assert7к @py_assert6к @py_format9к @py_format11r r r кwrites˜  РџzFake9800.writecCs"|jd|…}|j|d…|_|SЉN)r)r кnкbufr r r кreadsz Fake9800.readN)к__name__к __module__к __qualname__rr r-r1r r r r rs  rc@s$eZdZdd„Zdd„Zdd„ZdS)к TestTH9800cCs:tƒ}t |Ё}t |Ё}| |j|Ё| d|jЁdS)Ns PROGRAMA)rrкTYTTH9800Radioк _identifyк assertEqualrr)r кfкrrr r r к test_identify%s   zTestTH9800.test_identifycCstƒ}t |Ё}| ЁdSr.)rrr6кsync_in)r r9r:r r r к test_download,s  zTestTH9800.test_downloadcCs@tƒ}tj tj tЁdddЁ}t |Ё}| |Ё|  ЁdS)Nz..кimageszTYT_TH-9800.img) rкosкpathкjoinкdirnameк__file__rr6кset_pipeкsync_out)r r9кimgr:r r r к test_upload1sџ   zTestTH9800.test_uploadN)r2r3r4r;r=rGr r r r r5$s r5) кbuiltinsrк_pytest.assertion.rewriteк assertionкrewriterr?кunittestк chirp.driversrrкTestCaser5r r r r кs " chirp-20240224/tests/unit/__pycache__/test_repeaterbook.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001705714435611074026620 0ustar hibbyhibbyo Љwd:&у@sŒddlZddlmmZddlZddlZddlZddl Z ddl Z ddl Z ddl m Z ddl Z ddlmZddlmZGdd„de jƒZdS)щN)кmock)к chirp_common)к repeaterbookc@sЄeZdZdd„Zdd„Zdd„Zejjdd„ƒZ ejjd d „ƒZ ejjd d „ƒZ ejjd d„ƒZ dd„Z dd„Zdd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS) кTestRepeaterbookcCstj |j|ЁSЉN)кosкpathкjoinкtempdir)кselfкfnЉr њT/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_repeaterbook.pyк fake_configszTestRepeaterbook.fake_configcCsVt Ё|_g|_|j t d|jЁЁ|jD]}| Ёqt j   t j   t ЁdЁ|_dS)Nz#chirp.platform.Platform.config_filezrb-united_states-oregon.json)кtempfileкmkdtempr кpatchesкappendrкpatchrкstartrrr кdirnameк__file__кtestfileЉr кpr r rкsetUps  џ   џzTestRepeaterbook.setUpcCs$|jD]}| Ёqt |jЁdSr)rкstopкshutilкrmtreer rr r rкtearDowns  zTestRepeaterbook.tearDownc Csіt Ё}| t|jdЁ| t ЁddddddœЁ| dЁ}| |t j Ё|  Ё}|  t |jƒdЁt|jŽD]>}| |Ё}|jd krv| |t jЁ| d |jЁ| d t|jƒЁ| d t|jƒЁ| |j|jЁ| d |jЁdSq8td ƒ‚)Nrњ United StatesкOregonщ-щ†џџџщdЉкcountryкstateкlatкlonкdistщкDVzCQCQCQ щкzDid not find any DV results)rк RepeaterBookк assertRaisesк IndexErrorк get_memoryкdo_fetchrк MagicMockкassertIsInstancerкMemoryк get_featuresк assertGreaterкsumк memory_boundsкrangeкmodeкDVMemoryк assertEqualк dv_urcallкlenк dv_rpt1callк dv_rpt2callкassertNotEqualк Exception)r кrbкmкfкir r rкtest_get_oregon#s2 ћ   љ z TestRepeaterbook.test_get_oregonc Csjt Ё}| t|jdЁ| t ЁddddddœЁ| dЁ}| |t j Ё|  Ё}|  t |jƒdЁdS)Nrr кWyomingr"r#r%r+Љrr/r0r1r2r3rr4r5rr6r7r8r9r:Љr rErFrGr r rкtest_get_wyoming@ѓ ћ z!TestRepeaterbook.test_get_wyomingc Cslt Ё}| t|jdЁ| t ЁdddddddœЁ| dЁ}| |t j Ё|  Ё}|  t |jƒd ЁdS) Nrr r!r"r#r$кgmrs)r&r'r(r)r*кserviceщrKrLr r rкtest_get_oregon_gmrsPs њ z%TestRepeaterbook.test_get_oregon_gmrsc Csjt Ё}| t|jdЁ| t ЁddddddœЁ| dЁ}| |t j Ё|  Ё}|  t |jƒdЁdS) Nrк AustraliaкALLiцџџџщ…i Nr%r+rKrLr r rкtest_get_australiaarNz#TestRepeaterbook.test_get_australiacCsTt Ё}tj |dЁ}|j|_| t Ё|ЁWdƒ|S1s#wY|S)Nкget_data) rr/rrкobjectrк return_valuer3r4)r кparamsrEкgdr r rк_test_with_mockedqs ў§z"TestRepeaterbook._test_with_mockedcCs6dddddddœ}| |Ё}| t| ЁjƒdЁdS) Nr r!r"r#rкtowerЉr&r'r(r)r*кfilterщ)r\r8r9r7r:)r rZrEr r rк test_filterxsћ zTestRepeaterbook.test_filtercCsЌdddddddœ}| t|ƒЁ}| t| ЁjƒdЁd |d <| t|ƒЁ}| t| Ёjƒt| ЁjƒЁd |d <d|d <d |d<| t|ƒЁ}| t| ЁjƒdЁdS)Nr r!r"r#rr]r^r`r$r*rQr(itџџџr)щџџџџ)r\кdictr8r9r7r:к assertLessr>)r rZкrb1кrb2кrb3r r rк test_distance‚s&ћ џzTestRepeaterbook.test_distancec CsŠt Ё}t dЁ2}d|j_t Ё}| |dddЁ}| |Ё|j   Ё|  gt   t j |jdЁЁЁWdƒdS1s>wYdS)Nњ requests.getiєкUSкORr.r)rr/rrrYк status_coder4rWк assertIsNoneк send_failк assert_calledr>rкlistdirrr r )r rEкmock_getкstatusкrr r rкtest_get_data_500™s    џ"љz"TestRepeaterbook.test_get_data_500cCsВt Ё}t dЁF}d|j_dg|jj_t Ё}| |dddЁ}|  |Ёt   t j   |jdЁЁ}| dt|ƒЁ| |d  d ЁЁ|j ЁWdƒdS1sRwYdS) NriщШsfoorjrkr.rrQrкtmp)rr/rrrYrlк iter_contentr4rWrmrrprr r r>r@к assertTrueкendswithrnroЉr rErqrrrsкfilesr r rкtest_get_data_json_failЅs   џ "єz(TestRepeaterbook.test_get_data_json_failcCsЌt Ё}t dЁC}d|j_t ddiЁ Ёg|jj _t  Ё}|  |dddЁ}|  |Ёt  t j |jdЁЁ}| dt|ƒЁ|j ЁWdƒdS1sOwYdS) Nriruкcountrrjrkr.r)rr/rrrYrlкjsonкdumpsкencoderwr4rWrmrrprr r r>r@rnrorzr r rкtest_get_data_no_resultsЕs" џ џ џ "ѕz)TestRepeaterbook.test_get_data_no_resultscCsєt |jЁ}| dt|ƒЁt Ё}t dЁY}d|j _ t   ddiЁ  Ёg|j j_ t Ё}| |dddЁ}| |Ёt tj |jd ЁЁ}| dt|ƒЁ| |d d ЁЁ| tj |Ё|dЁ|j ЁWdƒdS1sswYdS) Nrrirur}rQrjrkr.rrv)rrpr r>r@rr/rrrYrlr~rr€rwr4rWкassertIsNotNonerr к assertFalseryкbasenamernкassert_not_called)r r{rErqrrrsr r rкtest_get_data_got_resultsФs*  џ џ џ "ѓz*TestRepeaterbook.test_get_data_got_resultsc Csжt tj |jdЁЁtj |jdtj |jЁЁ}t|dƒ }| dЁWdƒn1s.wYt   Ё}t   dЁЅ}|  t  ЁdddЁ}| ||Ё| Ёtj}tj}tj Ёtjdd }t j  t d Ё#} |j| j_|| _|| jj_|  t  ЁdddЁ}| ЁWdƒn1swYtj Ёtjd d }t j  t d Ё#} |j| j_|| _|| jj_|  t  ЁdddЁ}| ЁWdƒn1sЬwYWdƒdSWdƒdS1sфwYdS) Nrкwкfoorir r!r.щ)кdaysкdatetimer")rкmkdirrr r r„rкopenкwriterr/rrrWr4r>r…r‹к timedeltaкnowrXк fromtimestamprYro) r к cache_filerGrErqrsкreal_timedeltaк real_datetimeкfutureкmock_dtr r rк test_get_data_honors_cache_rulesиsL  ў  џ     џ љ    џ љь"ьz1TestRepeaterbook.test_get_data_honors_cache_rulesN)к__name__к __module__к __qualname__rrrкpytestкmarkкnetworkrIrMrRrVr\rarhrtr|rr†r—r r r rrs(        r)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arr‹r~rrrкunittestrr›кchirprк chirp.sourcesrкTestCaserr r r rкs"   chirp-20240224/tests/unit/__pycache__/test_bandplan.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000333014430373743025705 0ustar hibbyhibbyo уђ`dlу@sRddlZddlmmZddlZddlmZGdd„dƒZ Gdd„dej ƒZ dS)щNЉкbandplanc@s,eZdZdd„Zdd„Zdd„Zdd„Zd S) к FakeConfigcCs ||_dSЉNr)кselfrЉrњP/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_bandplan.pyк__init__ѓ zFakeConfig.__init__cCsdS)NTrЉrкoptкsecrrrк is_defined ѓzFakeConfig.is_definedcCsdSrrr rrrкget rzFakeConfig.getcCs ||jkSrrr rrrкget_boolr zFakeConfig.get_boolN)к__name__к __module__к __qualname__r rrrrrrrrs  rc@seZdZdd„ZdS)к BandPlanTestcCs4t tdƒЁ}gdЂ}| |dd„| ЁDƒЁdS)Nк north_america)z 10 Meter Bandz 6 Meter Bandz 2 Meter Bandz1.25 Meter Bandz70 Centimeter Bandz33 Centimeter Bandz23 Centimeter Bandz13 Centimeter BandcSsg|]}|j‘qSr)кname)к.0кbrrrк !sz8BandPlanTest.test_get_repeater_bands..)rк BandPlansrк assertEqualкget_repeater_bands)rкplansкexpectedrrrкtest_get_repeater_bandss  џz$BandPlanTest.test_get_repeater_bandsN)rrrr rrrrrs r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкunittestкchirprrкTestCaserrrrrкs" chirp-20240224/tests/unit/__pycache__/test_wxui_radiothread.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001124214541530706027466 0ustar hibbyhibbyo ›А†eху@sцddlZddlmmZddlZddlZddlm Z e   Ёej d<Z e   Ёej d<e   Ёej d<e   Ёej d<e   Ёej d<de j jj_e   Ёej d <dd lmZdd lmZdd lmZGd d„dejƒZGdd„dejƒZdS)щN)кmockкwxzwx.libzwx.lib.scrolledpanelzwx.lib.sized_controlsz wx.richtext)NNzchirp.wxui.developer)кbase)кclone)к radiothreadcs<eZdZ‡fdd„Zdd„Zdd„Zdd„Zd d „Z‡ZS) кTestRadioThreadcstƒ ЁdS)N)кsuperкsetUp)кselfЉк __class__ЉњX/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_wxui_radiothread.pyr szTestRadioThread.setUpcCsTt Ё}t Ё}t |ddgiЁ}| | |ЁЁ|j dЁ| |j |jj ЁdS)Nк get_memoryщ ) rк MagicMockrкRadioJobк assertIsNoneкdispatchrкassert_called_once_withк assertEqualкresultк return_valueЉr кradioкeditorкjobr r rк test_radiojobs  zTestRadioThread.test_radiojobcCs\t Ё}tdƒ|j_t Ё}t |ddgiЁ}| | |ЁЁ|j  dЁ|  |j tЁdS)Nњ some errorrr) rrк ValueErrorrк side_effectrrrrrкassertIsInstancerrr r rкtest_radiojob_exception s  z'TestRadioThread.test_radiojob_exceptionc Csˆt Ё}tdƒ|j_t Ё}gdЂ|j_t |Ё}t Ё}| |ddЁ}| |d|Ё}| |dЁ}|  Ёt |j j |j j |jj gƒsTt dЁt |j j |j j |jj gƒrB| Ё| dЁ| | ЁЁ|j  dЁ|j  |Ё|j Ё| d |jjЁ||||g}tt||jjƒƒD]\} \} } | d d } | | | jЁqŒ|j tjtjd d tjtjd d tjtjd d tjtjd d gЁdS)Nr)FTTTrrк set_memoryк get_featuresgš™™™™™Й?щщrF)кblockT)rrrr$r кradio_thread_eventrк RadioThreadкsubmitкstartкallrкcalledr#кtimeкsleepкendкjoinк assertFalseкis_aliverrк call_countк enumerateкzipкcall_args_listкidкassert_has_callsкcallкANY) r rrкthreadкmemкjob1idкjob2idкjob3idкexpected_orderкiкjobidr:rr r rк test_thread)sP    ў §ў     џџ  ќzTestRadioThread.test_threadcCsЊt Ё}tdƒ|j_t Ё}t |Ё}t Ё}| |ddЁ| |d|Ё| |dЁ| Ё|  Ё|  dЁ|  |  ЁЁ|j  Ё|j Ё|j Ёtj ЁdS)Nrrrr#r$r%)rrrr$r rr)r*r0r+r1r2r3rкassert_not_calledr#rк PostEvent)r rrr<r=r r rкtest_thread_abort_priority[s        z*TestRadioThread.test_thread_abort_priority) к__name__к __module__к __qualname__r rr"rDrGк __classcell__r r r rrs   2rc@s8eZdZejddddd„ƒZejddddd„ƒZd S) к TestClonezplatform.systemкLinux)rcCsPtjdddtjdddtjdddg}| gdЂd d „t|tjd DƒЁdS) Nz /dev/cu.zedzMy ZedЉкdeviceк descriptionz /dev/cu.abcz Some devicez/dev/cu.serialк)zSome device (cu.abc)z cu.serialzMy Zed (cu.zed)cSѓg|]}t |Ё‘qSr Љrк port_labelЉк.0кpr r rк „ѓџz2TestClone.test_sort_ports_unix..ЉкkeyЉrrrкsortedrк port_sort_keyЉr кsystemкportsr r rкtest_sort_ports_unixvs џџџћ џќzTestClone.test_sort_ports_unixкWindowscCs\tjdddtjdddtjdddtjdd dg}| gd Ђd d „t|tjd DƒЁdS)NкCOM7zSome serial devicerNкCOM17zSome other deviceкCNC0zSome weird deviceкCOM4rQ)zCNC0: Some weird devicergzCOM7: Some serial devicezCOM17: Some other devicecSrRr rSrUr r rrX˜rYz5TestClone.test_sort_ports_windows..rZr\r_r r rкtest_sort_ports_windows‡s&џџџџљ  џћz!TestClone.test_sort_ports_windowsN)rHrIrJrкpatchrbrhr r r rrLus    rL)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкsysr.кunittestrrкmodulesrкlibкneweventкNewCommandEventrк tests.unitrк chirp.wxuirrкBaseTestrrLr r r rкs"     achirp-20240224/tests/unit/__pycache__/test_yaesu_clone.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001623414430373743026443 0ustar hibbyhibbyo уђ`dѓу@sddlZddlmmZddlmZddlZddlZddl Z ddl m Z ddl m Z ddl mZddl mZddl mZGdd „d e jƒZGd d „d ƒZGd d „d e jƒZGdd„dƒZGdd„deƒZGdd„deƒZGdd„de jƒZGdd„deƒZGdd„deƒZdS)щN)кbytes)к directory)кft60)кft4)к yaesu_clone)кmemmapc@s4eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd S) кTestYaesuChecksumc CsОt dddЁ}| d| |ЁЁ| d| |ЁЁz | Ё}d|d<Wn+tyNz t d|dd…Ё}Wnt yKt  d|dd…Ё}YnwYnw|  |Ё| d | |ЁЁdS) Nrщщщ*щŠњщѓщ_) rк YaesuChecksumк assertEqualк get_existingкget_calculatedкget_byte_compatibleкAttributeErrorrк MemoryMapк TypeErrorкMemoryMapBytesкupdate)кselfкmmapкcsЉrњS/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/unit/test_yaesu_clone.pyк_test_checksums    ў€ћ z TestYaesuChecksum._test_checksumcCst dЁ}| |ЁdSЉNz...*)rrr Љrrrrrкtest_with_MemoryMap"s z%TestYaesuChecksum.test_with_MemoryMapcCst tdƒЁ}| |ЁdSЉNs...*)rrrr r"rrrкtest_with_MemoryMapBytes&sz*TestYaesuChecksum.test_with_MemoryMapBytescCѓ| dЁdSr$Љr Љrrrrкtest_with_bytes*ѓz!TestYaesuChecksum.test_with_bytescCr&r!r'r(rrrк test_with_str-r*zTestYaesuChecksum.test_with_strN)к__name__к __module__к __qualname__r r#r%r)r+rrrrr s  rc@s,eZdZdd„Zdd„Zdd„Zdd„Zd S) кFakeFT60cCѓd|_d|_dSЉNѓЉкreadbufкwritebufr(rrrк__init__2ѓ zFakeFT60.__init__cCs.|jd7_tdƒD] }|jd7_q dS)NsiРs@)r4кrange)rкirrrкstart_download6s џzFakeFT60.start_downloadcCst|tƒ}|sJddt Ёvst tЁrt tЁnddt Ёvs$t |Ёr)t |Ёnddt Ёvs5t tЁr:t tЁndt |Ёdœ}tt |Ёƒ‚d}||j |_ |j |7_ t |ƒdkrp|j   dЁrn|j d7_ dSdSt |ƒd vr|j d7_ dSt d ƒ‚) Nњ5assert %(py4)s {%(py4)s = %(py0)s(%(py1)s, %(py2)s) }к isinstanceкdatarЉкpy0кpy1кpy2кpy4rsAH017ѓ)щщ@к Unhandled)r<rк @py_builtinsкlocalsк @pytest_arк_should_repr_global_nameк _safereprкAssertionErrorк_format_explanationr4r5кlenк startswithк Exception)rr=к @py_assert3к @py_format5rrrкwrite;s˜   џ zFakeFT60.writecCѓ"|jd|…}|j|d…|_|SЉNЉr4ЉrкnкbufrrrкreadKѓz FakeFT60.readN)r,r-r.r6r:rSrZrrrrr/1s  r/c@seZdZdd„Zdd„ZdS)кTestFT60cCsDtƒ}| Ёt |Ё}| Ё| dt|jƒЁ| |jdЁdS)NiСsС)r/r:rк FT60Radioкsync_inrrNr5Љrкfкrrrrк test_downloadRs  zTestFT60.test_downloadcCs@tƒ}tj tj tЁdddЁ}t |Ё}| |Ё|  ЁdS)Nњ..кimageszYaesu_FT-60.img) r/кosкpathкjoinкdirnameк__file__rr]кset_pipeкsync_out)rr`кimgrarrrк test_upload[sџ   zTestFT60.test_uploadN)r,r-r.rbrmrrrrr\Qs r\c@s,eZdZejjZdd„Zdd„Zdd„Z dS)кFakeFTX4cCr0r1r3r(rrrr6gr7zFakeFTX4.__init__c CsRt|tƒ}|sJddt Ёvst tЁrt tЁnddt Ёvs$t |Ёr)t |Ёnddt Ёvs5t tЁr:t tЁndt |Ёdœ}tt |Ёƒ‚d}||j |_ |  dЁr_|j d7_ nA|dkrl|j |j 7_ n4|  d Ёrd |d d…d }|j |tt   |d d…Ёgƒ7_ n|  d Ёr•n |d kršntd|ƒ‚|j d7_ dS)Nr;r<rYrr>sPROGRAMsQXѓѓRѓWrssENDz Unhandled %rrC)r<rrGrHrIrJrKrLrMr4rOкIDrк checkSum8rP)rrYrQrRкresprrrrSks˜   (  zFakeFTX4.writecCrTrUrVrWrrrrZr[z FakeFTX4.readN) r,r-r.rкYaesuFT4XERadioкid_strrrr6rSrZrrrrrnds  rnc@seZdZejjZdS)к FakeFT25RNЉr,r-r.rкYaesuFT25RRadiorvrrrrrrrw…s rwc@s eZdZejjdd…dZdS)кFakeFT25R_AsianNщџџџџrrxrrrrrz‰srzc@s.eZdZejZeZdd„Zdd„Z dd„Z dS)кTestFTX4cCs2| Ё}| |Ё}| Ё| |jd|jЁdS)Nr{)кFAKEкRCLASSr^rrrкsubtyper_rrrrb‘s zTestFTX4.test_downloadcCsR| Ё}t |jЁ}tj tj tЁddd|Ё}| |Ё}|  |Ё|  ЁdS)Nrcrdz%s.img) r}rкradio_class_idr~rerfrgrhrirjrk)rr`кfnrlrarrrrm—s  џ   zTestFTX4.test_uploadcCsf| Ё}| |Ё}| Ё| |jd|jЁt ddЁ}| |Ё| |Ё}| |jd|jЁdS)Nr{z.imgr) r}r~r^rrrrкtempfileкmktempкsave)rr`rarrrrкtest_download_open s    zTestFTX4.test_download_openN) r,r-r.rrur~rnr}rbrmr…rrrrr|s  r|c@seZdZejZeZdS)кTestFT25N)r,r-r.rryr~rwr}rrrrr†Аsr†c@seZdZeZdS)кTestFT25_AsianN)r,r-r.rzr}rrrrr‡Еsr‡)кbuiltinsrGк_pytest.assertion.rewriteк assertionкrewriterIrrer‚кunittestкchirprк chirp.driversrrrrкTestCaserr/r\rnrwrzr|r†r‡rrrrкs$&     $ !#chirp-20240224/tests/unit/__init__.py0000644000175000017500000000000014411666130016256 0ustar hibbyhibbychirp-20240224/tests/unit/test_settings.py0000644000175000017500000001622414560403070017432 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from tests.unit import base from chirp import settings class TestSettingValues(base.BaseTest): def _set_and_test(self, rsv, *values): for value in values: rsv.set_value(value) self.assertEqual(rsv.get_value(), value) def _set_and_catch(self, rsv, *values): for value in values: self.assertRaises(settings.InvalidValueError, rsv.set_value, value) def test_radio_setting_value_integer(self): value = settings.RadioSettingValueInteger(0, 10, 5) value.initialize() self.assertEqual(value.get_value(), 5) self._set_and_test(value, 1, 0, 10) self._set_and_catch(value, -1, 11) def test_radio_setting_value_float(self): value = settings.RadioSettingValueFloat(1.0, 10.5, 5.0) value.initialize() self.assertEqual(value.get_value(), 5.0) self._set_and_test(value, 2.5, 1.0, 10.5) self._set_and_catch(value, 0.9, 10.6, -1.5) def test_radio_setting_value_boolean(self): value = settings.RadioSettingValueBoolean(True) value.initialize() self.assertTrue(value.get_value()) self._set_and_test(value, True, False) def test_radio_setting_value_list(self): opts = ["Abc", "Def", "Ghi"] value = settings.RadioSettingValueList(opts, "Abc") value.initialize() self.assertEqual(value.get_value(), "Abc") self.assertEqual(int(value), 0) self._set_and_test(value, "Def", "Ghi", "Abc") self._set_and_catch(value, "Jkl", "Xyz") self.assertEqual(value.get_options(), opts) def test_radio_setting_value_list_by_index(self): opts = ["Abc", "Def", "Ghi"] value = settings.RadioSettingValueList(opts, current_index=1) value.initialize() self.assertEqual(value.get_value(), "Def") self.assertEqual(int(value), 1) self._set_and_test(value, "Def", "Ghi", "Abc") self._set_and_catch(value, "Jkl", "Xyz") self.assertEqual(value.get_options(), opts) # Make sure we int() the index, as we may pass a bitwise object value = settings.RadioSettingValueList(opts, current_index='1') value.initialize() self.assertEqual(value.get_value(), "Def") value.set_index(0) self.assertEqual(value.get_value(), 'Abc') # Same here, int() the index value.set_index('0') self.assertEqual(value.get_value(), 'Abc') self.assertRaises(IndexError, value.set_index, 7) def test_radio_setting_value_string(self): value = settings.RadioSettingValueString(1, 5, "foo", autopad=False) value.initialize() self.assertEqual(value.get_value(), "foo") self.assertEqual(str(value), "foo") self._set_and_test(value, "a", "abc", "abdef") self._set_and_catch(value, "", "abcdefg") def test_validate_callback(self): class TestException(Exception): pass value = settings.RadioSettingValueString(0, 5, "foo", autopad=False) value.initialize() def test_validate(val): if val == "bar": raise TestException() value.set_validate_callback(test_validate) value.set_value("baz") self.assertRaises(TestException, value.set_value, "bar") def test_changed(self): value = settings.RadioSettingValueBoolean(False) value.initialize() self.assertFalse(value.changed()) value.set_value(False) self.assertFalse(value.changed()) value.set_value(True) self.assertTrue(value.changed()) class TestSettingContainers(base.BaseTest): def test_radio_setting_group(self): s1 = settings.RadioSetting("s1", "Setting 1") s2 = settings.RadioSetting("s2", "Setting 2") s3 = settings.RadioSetting("s3", "Setting 3") group = settings.RadioSettingGroup("foo", "Foo Group", s1) self.assertEqual(group.get_name(), "foo") self.assertEqual(group.get_shortname(), "Foo Group") self.assertEqual(group.values(), [s1]) self.assertEqual(group.keys(), ["s1"]) group.append(s2) self.assertEqual(group.items(), [("s1", s1), ("s2", s2)]) self.assertEqual(group["s1"], s1) group["s3"] = s3 self.assertEqual(group.values(), [s1, s2, s3]) self.assertEqual(group.keys(), ["s1", "s2", "s3"]) self.assertEqual([x for x in group], [s1, s2, s3]) def set_dupe(): group["s3"] = s3 self.assertRaises(KeyError, set_dupe) def test_radio_setting(self): val = settings.RadioSettingValueBoolean(True) rs = settings.RadioSetting("foo", "Foo", val) self.assertEqual(rs.value, val) rs.value = False self.assertEqual(val.get_value(), False) self.assertEqual('foo:False', str(rs)) self.assertEqual('[RadioSetting foo:False]', repr(rs)) def test_radio_setting_multi(self): val1 = settings.RadioSettingValueBoolean(True) val2 = settings.RadioSettingValueBoolean(False) rs = settings.RadioSetting("foo", "Foo", val1, val2) self.assertEqual(rs[0], val1) self.assertEqual(rs[1], val2) rs[0] = False rs[1] = True self.assertEqual(val1.get_value(), False) self.assertEqual(val2.get_value(), True) def test_apply_callback(self): class TestException(Exception): pass rs = settings.RadioSetting("foo", "Foo") self.assertFalse(rs.has_apply_callback()) def test_cb(setting, data1, data2): self.assertEqual(setting, rs) self.assertEqual(data1, "foo") self.assertEqual(data2, "bar") raise TestException() rs.set_apply_callback(test_cb, "foo", "bar") self.assertTrue(rs.has_apply_callback()) self.assertRaises(TestException, rs.run_apply_callback) def test_setting_banned_name(self): self.assertRaises(settings.InvalidNameError, settings.RadioSetting, "foo%bar", "Foo") def test_setting_banned_name_characters(self): for c in settings.BANNED_NAME_CHARACTERS: self.assertRaises(settings.InvalidNameError, settings.RadioSetting, "foo%sbar" % c, "Foo") def test_setting_deferred(self): val = settings.RadioSettingValueInteger(0, 10, 12) rs = settings.RadioSetting('test', 'Test', val) self.assertFalse(rs.value.initialized) rs.value = 1 self.assertTrue(rs.value.initialized) chirp-20240224/tests/unit/test_import_logic.py0000644000175000017500000004376714503004432020271 0ustar hibbyhibbyfrom unittest import mock from tests.unit import base from chirp import import_logic from chirp import chirp_common from chirp import errors class FakeRadio(chirp_common.Radio): def __init__(self, arg): self.POWER_LEVELS = list([chirp_common.PowerLevel('lo', watts=5), chirp_common.PowerLevel('hi', watts=50)]) self.TMODES = list(['', 'Tone', 'TSQL']) self.HAS_CTONE = True self.HAS_RX_DTCS = False self.MODES = list(['FM', 'AM', 'DV']) self.DUPLEXES = list(['', '-', '+']) def filter_name(self, name): return 'filtered-name' def get_memory(self, number): return chirp_common.Memory(number, empty=True) def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_power_levels = self.POWER_LEVELS rf.valid_tmodes = self.TMODES rf.valid_modes = self.MODES rf.valid_duplexes = self.DUPLEXES rf.has_ctone = self.HAS_CTONE rf.has_rx_dtcs = self.HAS_RX_DTCS return rf class FakeDstarRadio(FakeRadio, chirp_common.IcomDstarSupport): REQUIRES_CALL_LISTS = False def get_features(self): rf = super().get_features() rf.requires_call_lists = self.REQUIRES_CALL_LISTS return rf class DstarTests(base.BaseTest): def _test_ensure_has_calls(self, mem, ini_urcalls, ini_rptcalls, exp_urcalls, exp_rptcalls): radio = FakeDstarRadio(None) with mock.patch.multiple( radio, get_urcall_list=mock.DEFAULT, get_repeater_call_list=mock.DEFAULT) as mocks: mocks['get_urcall_list'].return_value = ini_urcalls mocks['get_repeater_call_list'].return_value = ini_rptcalls import_logic.ensure_has_calls(radio, mem) self.assertEqual(sorted(ini_urcalls), sorted(exp_urcalls)) self.assertEqual(sorted(ini_rptcalls), sorted(exp_rptcalls)) def test_ensure_has_calls_empty(self): mem = chirp_common.DVMemory() mem.dv_urcall = 'KK7DS' mem.dv_rpt1call = 'KD7RFI B' mem.dv_rpt2call = 'KD7RFI G' ini_urcalls = ['', '', '', '', ''] ini_rptcalls = ['', '', '', '', ''] exp_urcalls = list(ini_urcalls) exp_rptcalls = list(ini_rptcalls) exp_urcalls[0] = mem.dv_urcall exp_rptcalls[0] = mem.dv_rpt1call exp_rptcalls[1] = mem.dv_rpt2call self._test_ensure_has_calls(mem, ini_urcalls, ini_rptcalls, exp_urcalls, exp_rptcalls) def test_ensure_has_calls_partial(self): mem = chirp_common.DVMemory() mem.dv_urcall = 'KK7DS' mem.dv_rpt1call = 'KD7RFI B' mem.dv_rpt2call = 'KD7RFI G' ini_urcalls = ['FOO', 'BAR', '', '', ''] ini_rptcalls = ['FOO', 'BAR', '', '', ''] exp_urcalls = list(ini_urcalls) exp_rptcalls = list(ini_rptcalls) exp_urcalls[2] = mem.dv_urcall exp_rptcalls[2] = mem.dv_rpt1call exp_rptcalls[3] = mem.dv_rpt2call self._test_ensure_has_calls(mem, ini_urcalls, ini_rptcalls, exp_urcalls, exp_rptcalls) def test_ensure_has_calls_almost_full(self): mem = chirp_common.DVMemory() mem.dv_urcall = 'KK7DS' mem.dv_rpt1call = 'KD7RFI B' mem.dv_rpt2call = 'KD7RFI G' ini_urcalls = ['FOO', 'BAR', 'BAZ', 'BAT', ''] ini_rptcalls = ['FOO', 'BAR', 'BAZ', '', ''] exp_urcalls = list(ini_urcalls) exp_rptcalls = list(ini_rptcalls) exp_urcalls[4] = mem.dv_urcall exp_rptcalls[3] = mem.dv_rpt1call exp_rptcalls[4] = mem.dv_rpt2call self._test_ensure_has_calls(mem, ini_urcalls, ini_rptcalls, exp_urcalls, exp_rptcalls) def test_ensure_has_calls_urcall_full(self): mem = chirp_common.DVMemory() mem.dv_urcall = 'KK7DS' mem.dv_rpt1call = 'KD7RFI B' mem.dv_rpt2call = 'KD7RFI G' ini_urcalls = ['FOO', 'BAR', 'BAZ', 'BAT', 'BOOM'] ini_rptcalls = ['FOO', 'BAR', 'BAZ', '', ''] exp_urcalls = list(ini_urcalls) exp_rptcalls = list(ini_rptcalls) exp_urcalls[4] = mem.dv_urcall exp_rptcalls[3] = mem.dv_rpt1call exp_rptcalls[4] = mem.dv_rpt2call self.assertRaises(errors.RadioError, self._test_ensure_has_calls, mem, ini_urcalls, ini_rptcalls, exp_urcalls, exp_rptcalls) def test_ensure_has_calls_rptcall_full1(self): mem = chirp_common.DVMemory() mem.dv_urcall = 'KK7DS' mem.dv_rpt1call = 'KD7RFI B' mem.dv_rpt2call = 'KD7RFI G' ini_urcalls = ['FOO', 'BAR', 'BAZ', 'BAT', ''] ini_rptcalls = ['FOO', 'BAR', 'BAZ', 'BAT', ''] exp_urcalls = list(ini_urcalls) exp_rptcalls = list(ini_rptcalls) exp_urcalls[4] = mem.dv_urcall exp_rptcalls[3] = mem.dv_rpt1call exp_rptcalls[4] = mem.dv_rpt2call self.assertRaises(errors.RadioError, self._test_ensure_has_calls, mem, ini_urcalls, ini_rptcalls, exp_urcalls, exp_rptcalls) def test_ensure_has_calls_rptcall_full2(self): mem = chirp_common.DVMemory() mem.dv_urcall = 'KK7DS' mem.dv_rpt1call = 'KD7RFI B' mem.dv_rpt2call = 'KD7RFI G' ini_urcalls = ['FOO', 'BAR', 'BAZ', 'BAT', ''] ini_rptcalls = ['FOO', 'BAR', 'BAZ', 'BAT', 'BOOM'] exp_urcalls = list(ini_urcalls) exp_rptcalls = list(ini_rptcalls) exp_urcalls[4] = mem.dv_urcall exp_rptcalls[3] = mem.dv_rpt1call exp_rptcalls[4] = mem.dv_rpt2call self.assertRaises(errors.RadioError, self._test_ensure_has_calls, mem, ini_urcalls, ini_rptcalls, exp_urcalls, exp_rptcalls) class ImportFieldTests(base.BaseTest): def test_import_name(self): mem = chirp_common.Memory() mem.name = 'foo' import_logic._import_name(FakeRadio(None), None, mem) self.assertEqual(mem.name, 'filtered-name') def test_import_power_same(self): radio = FakeRadio(None) same_rf = radio.get_features() mem = chirp_common.Memory() mem.power = same_rf.valid_power_levels[0] import_logic._import_power(radio, same_rf, mem) self.assertEqual(mem.power, same_rf.valid_power_levels[0]) def test_import_power_no_src(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() mem = chirp_common.Memory() mem.power = None import_logic._import_power(radio, src_rf, mem) self.assertEqual(mem.power, radio.POWER_LEVELS[1]) def test_import_power_no_src_variable(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() mem = chirp_common.Memory() mem.power = None with mock.patch.object(radio, 'get_features') as mock_gf: mock_gf.return_value = chirp_common.RadioFeatures() mock_gf.return_value.has_variable_power = True mock_gf.return_value.valid_power_levels = [ chirp_common.AutoNamedPowerLevel(1), chirp_common.AutoNamedPowerLevel(50), chirp_common.AutoNamedPowerLevel(1500)] import_logic._import_power(radio, src_rf, mem) self.assertEqual('50W', str(mem.power)) def test_import_power_no_dst(self): radio = FakeRadio(None) src_rf = radio.get_features() # Steal a copy before we stub out mem = chirp_common.Memory() mem.power = src_rf.valid_power_levels[0] with mock.patch.object(radio, 'get_features') as mock_gf: mock_gf.return_value = chirp_common.RadioFeatures() import_logic._import_power(radio, src_rf, mem) self.assertEqual(mem.power, None) def test_import_power_closest(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() src_rf.valid_power_levels = [ chirp_common.PowerLevel('foo', watts=7), chirp_common.PowerLevel('bar', watts=51), chirp_common.PowerLevel('baz', watts=1), ] mem = chirp_common.Memory() mem.power = src_rf.valid_power_levels[0] import_logic._import_power(radio, src_rf, mem) self.assertEqual(mem.power, radio.POWER_LEVELS[0]) def test_import_power_closest_watts(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() src_rf.valid_power_levels = [ chirp_common.PowerLevel('foo', watts=20), chirp_common.PowerLevel('bar', watts=51), chirp_common.PowerLevel('baz', watts=1), ] mem = chirp_common.Memory() mem.power = src_rf.valid_power_levels[0] import_logic._import_power(radio, src_rf, mem) self.assertEqual(mem.power, radio.POWER_LEVELS[0]) def test_import_tone_diffA_tsql(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() src_rf.has_ctone = False mem = chirp_common.Memory() mem.tmode = 'TSQL' mem.rtone = 100.0 import_logic._import_tone(radio, src_rf, mem) self.assertEqual(mem.ctone, 100.0) def test_import_tone_diffB_tsql(self): radio = FakeRadio(None) radio.HAS_CTONE = False src_rf = chirp_common.RadioFeatures() src_rf.has_ctone = True mem = chirp_common.Memory() mem.tmode = 'TSQL' mem.ctone = 100.0 import_logic._import_tone(radio, src_rf, mem) self.assertEqual(mem.rtone, 100.0) def test_import_dtcs_diffA_dtcs(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() src_rf.has_rx_dtcs = True mem = chirp_common.Memory() mem.tmode = 'DTCS' mem.rx_dtcs = 32 import_logic._import_dtcs(radio, src_rf, mem) self.assertEqual(mem.dtcs, 32) def test_import_dtcs_diffB_dtcs(self): radio = FakeRadio(None) radio.HAS_RX_DTCS = True src_rf = chirp_common.RadioFeatures() src_rf.has_rx_dtcs = False mem = chirp_common.Memory() mem.tmode = 'DTCS' mem.dtcs = 32 import_logic._import_dtcs(radio, src_rf, mem) self.assertEqual(mem.rx_dtcs, 32) def test_import_mode_valid_fm(self): radio = FakeRadio(None) mem = chirp_common.Memory() mem.mode = 'Auto' mem.freq = 146000000 import_logic._import_mode(radio, None, mem) self.assertEqual(mem.mode, 'FM') def test_import_mode_valid_am(self): radio = FakeRadio(None) mem = chirp_common.Memory() mem.mode = 'Auto' mem.freq = 18000000 import_logic._import_mode(radio, None, mem) self.assertEqual(mem.mode, 'AM') def test_import_mode_invalid(self): radio = FakeRadio(None) radio.MODES.remove('AM') mem = chirp_common.Memory() mem.mode = 'Auto' mem.freq = 1800000 self.assertRaises(import_logic.DestNotCompatible, import_logic._import_mode, radio, None, mem) def test_import_duplex_vhf(self): radio = FakeRadio(None) mem = chirp_common.Memory() mem.freq = 146000000 mem.offset = 146600000 mem.duplex = 'split' import_logic._import_duplex(radio, None, mem) self.assertEqual(mem.duplex, '+') self.assertEqual(mem.offset, 600000) def test_import_duplex_negative(self): radio = FakeRadio(None) mem = chirp_common.Memory() mem.freq = 146600000 mem.offset = 146000000 mem.duplex = 'split' import_logic._import_duplex(radio, None, mem) self.assertEqual(mem.duplex, '-') self.assertEqual(mem.offset, 600000) def test_import_duplex_uhf(self): radio = FakeRadio(None) mem = chirp_common.Memory() mem.freq = 431000000 mem.offset = 441000000 mem.duplex = 'split' import_logic._import_duplex(radio, None, mem) self.assertEqual(mem.duplex, '+') self.assertEqual(mem.offset, 10000000) def test_import_duplex_too_big_vhf(self): radio = FakeRadio(None) mem = chirp_common.Memory() mem.freq = 146000000 mem.offset = 246000000 mem.duplex = 'split' self.assertRaises(import_logic.DestNotCompatible, import_logic._import_duplex, radio, None, mem) def test_import_duplex_off_not_supported(self): radio = FakeRadio(None) mem = chirp_common.Memory() mem.freq = 146000000 mem.duplex = 'off' import_logic._import_duplex(radio, None, mem) self.assertEqual('', mem.duplex) @mock.patch('chirp.import_logic._import_name') @mock.patch('chirp.import_logic._import_power') @mock.patch('chirp.import_logic._import_tone') @mock.patch('chirp.import_logic._import_dtcs') @mock.patch('chirp.import_logic._import_mode') @mock.patch('chirp.import_logic._import_duplex') def _test_import_mem(self, errors, mock_duplex, mock_mode, mock_dtcs, mock_tone, mock_power, mock_name): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() mem = chirp_common.Memory() with mock.patch.object(mem, 'dupe') as mock_dupe: mock_dupe.return_value = mem with mock.patch.object(radio, 'validate_memory') as mock_val: mock_val.return_value = errors import_logic.import_mem(radio, src_rf, mem) mock_val.assert_called_once_with(mem) mock_dupe.assert_called_once_with() mock_duplex.assert_called_once_with(radio, src_rf, mem) def test_import_mem(self): self._test_import_mem([]) @mock.patch.object(FakeRadio, 'get_memory') @mock.patch.object(FakeRadio, 'check_set_memory_immutable_policy') def test_import_mem_checks_immutable(self, mock_check, mock_get): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() mem = chirp_common.Memory() with mock.patch.object(mem, 'dupe') as mock_dupe: mock_dupe.return_value = mem import_logic.import_mem(radio, src_rf, mem) mock_check.assert_called_once_with(mock_get.return_value, mem) mock_get.assert_called_once_with(mem.number) def test_import_mem_with_class(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() mem = chirp_common.Memory() mem2 = import_logic.import_mem(radio, src_rf, mem, mem_cls=chirp_common.DVMemory) self.assertIsInstance(mem2, chirp_common.DVMemory) def test_import_mem_dstar_logic(self): radio = FakeRadio(None) src_rf = chirp_common.RadioFeatures() mem = chirp_common.DVMemory() mem.mode = 'DV' # non-DSTAR radio exposes only FM, so DV is not compatible radio.MODES = ['FM'] self.assertRaises(import_logic.DestNotCompatible, import_logic.import_mem, radio, src_rf, mem) # non-DSTAR radio exposes DV, so it is compatible, but obviously # no call list manipulation needed. radio.MODES = ['FM', 'DV'] with mock.patch('chirp.import_logic.ensure_has_calls') as mock_e: import_logic.import_mem(radio, src_rf, mem) mock_e.assert_not_called() # A real D-STAR radio gets the full treatment, depending on the # required call lists flag radio = FakeDstarRadio(None) with mock.patch('chirp.import_logic.ensure_has_calls') as mock_e: radio.REQUIRES_CALL_LISTS = False import_logic.import_mem(radio, src_rf, mem) mock_e.assert_not_called() radio.REQUIRES_CALL_LISTS = True import_logic.import_mem(radio, src_rf, mem) mock_e.assert_called() def test_import_mem_with_warnings(self): self._test_import_mem([chirp_common.ValidationWarning('Test')]) def test_import_mem_with_errors(self): self.assertRaises(import_logic.DestNotCompatible, self._test_import_mem, [chirp_common.ValidationError('Test')]) def test_import_bank(self): dst_mem = chirp_common.Memory() dst_mem.number = 1 src_mem = chirp_common.Memory() src_mem.number = 2 dst_radio = FakeRadio(None) src_radio = FakeRadio(None) dst_bm = chirp_common.BankModel(dst_radio) src_bm = chirp_common.BankModel(src_radio) dst_banks = [chirp_common.Bank(dst_bm, 0, 'A'), chirp_common.Bank(dst_bm, 1, 'B'), chirp_common.Bank(dst_bm, 2, 'C'), ] src_banks = [chirp_common.Bank(src_bm, 1, '1'), chirp_common.Bank(src_bm, 2, '2'), chirp_common.Bank(src_bm, 3, '3'), ] @mock.patch.object(dst_radio, 'get_mapping_models', return_value=[dst_bm]) @mock.patch.object(src_radio, 'get_mapping_models', return_value=[src_bm]) @mock.patch.object(dst_bm, 'get_mappings', return_value=dst_banks) @mock.patch.object(src_bm, 'get_mappings', return_value=src_banks) @mock.patch.object(src_bm, 'get_memory_mappings', return_value=[src_banks[0]]) @mock.patch.object(dst_bm, 'get_memory_mappings', return_value=[dst_banks[1]]) @mock.patch.object(dst_bm, 'remove_memory_from_mapping') @mock.patch.object(dst_bm, 'add_memory_to_mapping') def _test(mock_add, mock_remove, *rest): import_logic.import_bank(dst_radio, src_radio, dst_mem, src_mem) mock_remove.assert_called_once_with(dst_mem, dst_banks[1]) mock_add.assert_called_once_with(dst_mem, dst_banks[0]) _test() chirp-20240224/tests/Python3_Driver_Testing.md0000644000175000017500000015434114566340166020117 0ustar hibbyhibby## Status | Driver | Tester | Tested | Byte Clean | "Market Share" | | ------ | ------ | ------ | ---------- | -------------- | | ARRL_Travel_Plus | | | | 0.00% | | Abbree_AR-518 | [@KC9HI](https://github.com/KC9HI) | 16-Dec-2022 | Yes | 0.24% | | Abbree_AR-63 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.03% | | Abbree_AR-730 | [@KC9HI](https://github.com/KC9HI) | 17-Aug-2023 | Yes | | | Abbree_AR-869 | [Implied by Radtel_RT-490](#user-content-Radtel_RT-490) | 11-Nov-2023 | Yes | 0.01% | | Abbree_AR-F5 | [@KC9HI](https://github.com/KC9HI) | 09-Aug-2023 | Yes | | | Alinco_DJ-G7EG | [@HB9UF](https://github.com/HB9UF) | 09-Dec-2022 | Yes | 0.44% | | Alinco_DJ-G7T | [Reported working](https://chirp.danplanet.com/issues/10567) | 09-May-2023 | Yes | | | Alinco_DJ175 | [Implied by Alinco_DR235T](#user-content-Alinco_DR235T) | 12-Dec-2022 | Yes | 0.03% | | Alinco_DJ596 | [Implied by Alinco_DR235T](#user-content-Alinco_DR235T) | 12-Dec-2022 | Yes | 0.02% | | Alinco_DR03T | [Implied by Alinco_DR235T](#user-content-Alinco_DR235T) | 12-Dec-2022 | Yes | 0.01% | | Alinco_DR06T | [Implied by Alinco_DR235T](#user-content-Alinco_DR235T) | 12-Dec-2022 | Yes | 0.01% | | Alinco_DR135T | [Implied by Alinco_DR235T](#user-content-Alinco_DR235T) | 12-Dec-2022 | Yes | 0.04% | | Alinco_DR235T | [@kk7ds](https://github.com/kk7ds) | 12-Dec-2022 | Yes | 0.02% | | Alinco_DR435T | [Implied by Alinco_DR235T](#user-content-Alinco_DR235T) | 12-Dec-2022 | Yes | 0.02% | | AnyTone_5888UV | [@kk7ds](https://github.com/kk7ds) | 9-Dec-2022 | Yes | 0.14% | | AnyTone_5888UVIII | [@bschuler42](https://github.com/bschuler42) | 9-Jan-2023 | Yes | 0.04% | | AnyTone_778UV | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.17% | | AnyTone_778UV_VOX | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.23% | | AnyTone_OBLTR-8R | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.02% | | AnyTone_TERMN-8R | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.02% | | Anysecu_AC-580 | [Implied by Radioddity_GS-5B](#user-content-Radioddity_GS-5B) | 17-Mar-2023 | Yes | | | Anysecu_UV-A37 | [@KC9HI](https://github.com/KC9HI) | 5-Jun-2023 | Yes | | | Anysecu_WP-9900 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.03% | | BTECH_FRS-A1 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.01% | | BTECH_FRS-B1 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.04% | | BTECH_GMRS-20V2 | [@KC9HI](https://github.com/KC9HI) | 13-Nov-2022 | Yes | 0.03% | | BTECH_GMRS-50V2 | [@KC9HI](https://github.com/KC9HI) | 15-Feb-2023 | Yes | 0.00% | | BTECH_GMRS-50X1 | [@KC9HI](https://github.com/KC9HI) | 13-Nov-2022 | Yes | 0.13% | | BTECH_GMRS-V1 | [@KC9HI](https://github.com/KC9HI) | 10-Dec-2022 | Yes | 0.16% | | BTECH_GMRS-V2 | [@KC9HI](https://github.com/KC9HI) | 10-Dec-2022 | Yes | 0.16% | | BTECH_MURS-V1 | [@KC9HI](https://github.com/KC9HI) | 10-Dec-2022 | Yes | 0.04% | | BTECH_MURS-V2 | [@KC9HI](https://github.com/KC9HI) | 2-Mar-2023 | Yes | 0.00% | | BTECH_UV-2501 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.02% | | BTECH_UV-2501+220 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.02% | | BTECH_UV-25X2 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.15% | | BTECH_UV-25X2_G2 | [@KC9HI](https://github.com/KC9HI) | 23-Apr-2023 | Yes | | | BTECH_UV-25X4 | [@KC9HI](https://github.com/KC9HI) | 10-Nov-2022 | Yes | 0.11% | | BTECH_UV-25X4_G2 | [@KC9HI](https://github.com/KC9HI) | 23-Apr-2023 | Yes | | | BTECH_UV-5001 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.03% | | BTECH_UV-50X2 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.13% | | BTECH_UV-50X2_G2 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.00% | | BTECH_UV-50X3 | [@KC9HI](https://github.com/KC9HI) | 10-Dec-2022 | Yes | 0.06% | | BTECH_UV-5X3 | [@KC9HI](https://github.com/KC9HI) | 9-Dec-2022 | Yes | 0.43% | | Baofeng_5RM | [@vdwel](https://github.com/vdwel) | 7-Dec-2023 | Yes | | | Baofeng_5RX | [@KC9HI](https://github.com/KC9HI) | 16-Jan-2024 | Yes | | | Baofeng_BF-1901 | [@cetinajero](https://github.com/cetinajero) | 3-Jul-2023 | Yes | | | Baofeng_BF-1904 | [@cetinajero](https://github.com/cetinajero) | 3-Jul-2023 | Yes | | | Baofeng_BF-888 | [@kk7ds](https://github.com/kk7ds) | 13-Feb-2019 | Yes | **15.53%** | | Baofeng_BF-A58 | [@KC9HI](https://github.com/KC9HI) | 3-Dec-2022 | Yes | **1.46%** | | Baofeng_BF-A58S | [@KC9HI](https://github.com/KC9HI) | 3-Dec-2022 | Yes | 0.59% | | Baofeng_BF-F8HP | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | **6.33%** | | Baofeng_BF-M4 | [@cetinajero](https://github.com/cetinajero) | 8-May-2023 | Yes | | | Baofeng_BF-T1 | [@KC9HI](https://github.com/KC9HI) | 10-Dec-2022 | Yes | 0.76% | | Baofeng_BF-T20 | [@KC9HI](https://github.com/KC9HI) | 15-Dec-2023 | Yes | | | Baofeng_BF-T20FRS | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2023 | Yes | | | Baofeng_BF-T8 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.42% | | Baofeng_BF-V8A | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.03% | | Baofeng_F-11 | [Implied by Baofeng_UV-5R](#user-content-Baofeng_UV-5R) | 18-Nov-2022 | Yes | 0.12% | | Baofeng_GT-3WP | [@KC9HI](https://github.com/KC9HI) | 3-Dec-2022 | Yes | 0.43% | | Baofeng_GT-5R | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | 0.68% | | Baofeng_UV-13Pro | [@vdwel](https://github.com/vdwel) | 21-Feb-2024 | Yes | | | Baofeng_UV-17 | [@vdwel](https://github.com/vdwel) | 27-Nov-2023 | Yes | | | Baofeng_UV-17Pro | [@vdwel](https://github.com/vdwel) | 27-Nov-2023 | Yes | | | Baofeng_UV-17ProGPS | [@vdwel](https://github.com/vdwel) | 27-Nov-2023 | Yes | | | Baofeng_UV-3R | [@yarda](https://github.com/yarda) | 26-Sep-2022 | Yes | 0.45% | | Baofeng_UV-5R | [@lekv](https://github.com/lekv) | 23-Oct-2022 | Yes | **28.81%** | | Baofeng_UV-6 | [Implied by Baofeng_UV-5R](#user-content-Baofeng_UV-5R) | 18-Nov-2022 | Yes | 0.46% | | Baofeng_UV-6R | [@KC9HI](https://github.com/KC9HI) | 10-Dec-2022 | Yes | 0.71% | | Baofeng_UV-82 | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | **8.78%** | | Baofeng_UV-82HP | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | **2.38%** | | Baofeng_UV-82WP | [@KC9HI](https://github.com/KC9HI) | 3-Dec-2022 | Yes | 0.32% | | Baofeng_UV-9G | [@KC9HI](https://github.com/KC9HI) | 3-Dec-2022 | Yes | 0.65% | | Baofeng_UV-9R | [@KC9HI](https://github.com/KC9HI) | 3-Dec-2022 | Yes | **2.52%** | | Baofeng_UV-B5 | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | 0.35% | | Baofeng_UV-S9X3 | [@KC9HI](https://github.com/KC9HI) | 22-Aug-2023 | Yes | | | Baofeng_W31E | [@KC9HI](https://github.com/KC9HI) | 14-Aug-2023 | Yes | | | Baojie_BJ-218 | [Implied by LUITON_LT-725UV](#user-content-LUITON_LT-725UV) | 16-Feb-2023 | Yes | 0.29% | | Baojie_BJ-318 | [@KC9HI](https://github.com/KC9HI) | 2-Jan-2023 | Yes | 0.10% | | Baojie_BJ-9900 | | | Yes | 0.02% | | Baojie_BJ-UV55 | | | Yes | 0.03% | | Boblov_X3Plus | | | | 0.02% | | Boristone_8RS | [Implied by Radtel_RT-490](#user-content-Radtel_RT-490) | 11-Nov-2023 | Yes | 0.00% | | CRT_Micron_UV | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.08% | | CRT_Micron_UV_V2 | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.10% | | Cignus_XTR-5 | [Implied by Radioddity_GS-5B](#user-content-Radioddity_GS-5B) | 17-Mar-2023 | Yes | | | Commander_KG-UV | | | | 0.00% | | Explorer_QRZ-1 | [Implied by TYT_TH-UV88](#user-content-TYT_TH-UV88) | 5-Dec-2022 | Yes | 0.04% | | Feidaxin_FD-150A | | | | 0.02% | | Feidaxin_FD-160A | | | | 0.01% | | Feidaxin_FD-268A | | | | 0.01% | | Feidaxin_FD-268B | | | | 0.01% | | Feidaxin_FD-288A | | | | 0.01% | | Feidaxin_FD-288B | | | | 0.01% | | Feidaxin_FD-450A | | | | 0.01% | | Feidaxin_FD-460A | | | | 0.01% | | Feidaxin_FD-460UH | | | | 0.01% | | Generic_CSV | [@kk7ds](https://github.com/kk7ds) | 4-Dec-2022 | | | | HamGeek_HG-590 | [Implied by Radtel_RT-490](#user-content-Radtel_RT-490) | 11-Nov-2023 | Yes | 0.00% | | Hiroyasu_HI-8811 | [@KC9HI](https://github.com/KC9HI) | 4-Jun-2023 | Yes | | | HobbyPCB_RS-UV3 | [@kk7ds](https://github.com/kk7ds) | 9-Dec-2022 | Yes | 0.02% | | Icom_IC-208H | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.05% | | Icom_IC-2100H | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.04% | | Icom_IC-2200H | [@kk7ds](https://github.com/kk7ds) | 24-Oct-2022 | Yes | 0.05% | | Icom_IC-2300H | [Reported working](https://chirp.danplanet.com/issues/10264) | 13-Jan-2022 | Yes | 0.08% | | Icom_IC-2720H | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.02% | | Icom_IC-2730A | [Reported working](https://chirp.danplanet.com/issues/10261) | 17-Dec-2022 | Yes | 0.21% | | Icom_IC-2820H | [@kk7ds](https://github.com/kk7ds) | 22-Oct-2022 | Yes | 0.04% | | Icom_IC-7000 | [Reported working](https://chirp.danplanet.com/issues/10510) | 10-Apr-2023 | Yes | 0.03% | | Icom_IC-7100 | Mike W | 16-Feb-2023 | Yes | 0.06% | | Icom_IC-7200 | [@kk7ds](https://github.com/kk7ds) | 22-Oct-2022 | Yes | | | Icom_IC-7300 | [@kk7ds](https://github.com/kk7ds) | 22-Oct-2022 | Yes | 0.03% | | Icom_IC-746 | [Reported working](https://chirp.danplanet.com/issues/10346) | 3-Feb-2023 | Yes | | | Icom_IC-7610 | [@kk7ds](https://github.com/kk7ds) | 24-Oct-2022 | Yes | 0.00% | | Icom_IC-910 | [@mfncooper](https://github.com/mfncooper) | 1-Oct-2021 | Yes | 0.00% | | Icom_IC-91_92AD | [@kk7ds](https://github.com/kk7ds) | 23-Nov-2022 | Yes | 0.03% | | Icom_IC-E90 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.04% | | Icom_IC-P7 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.01% | | Icom_IC-Q7A | [@KC9HI](https://github.com/KC9HI) | 20-Nov-2022 | Yes | 0.01% | | Icom_IC-T70 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.03% | | Icom_IC-T7H | [Reported working](https://chirp.danplanet.com/issues/10752) | 30-Jul-2023 | Yes | 0.02% | | Icom_IC-T8A | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.01% | | Icom_IC-U82 | [Implied by Icom_IC-V82](#user-content-Icom_IC-V82) | 25-Jan-2023 | Yes | | | Icom_IC-V80 | [@kk7ds](https://github.com/kk7ds) | 16-Feb-2023 | Yes | 0.00% | | Icom_IC-V82 | [@kk7ds](https://github.com/kk7ds) | 25-Jan-2023 | Yes | | | Icom_IC-V86 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.04% | | Icom_IC-W32A | [Reported working](https://chirp.danplanet.com/issues/10238) | 12-Dec-2022 | Yes | 0.02% | | Icom_IC-W32E | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 12-Dec-2022 | Yes | 0.01% | | Icom_ID-31A | [@kk7ds](https://github.com/kk7ds) | 1-Dec-2022 | Yes | 0.01% | | Icom_ID-4100 | [@n8sqt](https://github.com/n8sqt) | 18-Dec-2022 | Yes | 0.00% | | Icom_ID-51 | [Implied by Icom_ID-31A](#user-content-Icom_ID-31A) | 1-Dec-2022 | Yes | 0.02% | | Icom_ID-5100 | [@kk7ds](https://github.com/kk7ds) | 17-Dec-2022 | Yes | 0.00% | | Icom_ID-51_Plus | [Implied by Icom_ID-31A](#user-content-Icom_ID-31A) | 1-Dec-2022 | Yes | 0.02% | | Icom_ID-51_Plus2 | [Implied by Icom_ID-31A](#user-content-Icom_ID-31A) | 17-Dec-2022 | Yes | 0.00% | | Icom_ID-800H_v2 | [@kk7ds](https://github.com/kk7ds) | 22-Oct-2022 | Yes | 0.01% | | Icom_ID-80H | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/icf.py) | 22-Oct-2022 | Yes | 0.01% | | Icom_ID-880H | [@kk7ds](https://github.com/kk7ds) | 22-Oct-2022 | Yes | 0.02% | | Intek_HR-2040 | [Implied by AnyTone_5888UV](#user-content-AnyTone_5888UV) | 9-Dec-2022 | Yes | 0.02% | | Intek_KT-980HP | [Implied by Baofeng_BF-F8HP](#user-content-Baofeng_BF-F8HP) | 18-Nov-2022 | Yes | 0.04% | | JJCC_JC-8629 | [Implied by Radtel_RT-490](#user-content-Radtel_RT-490) | 11-Nov-2023 | Yes | | | Jetstream_JT220M | [Implied by Alinco_DR235T](#user-content-Alinco_DR235T) | 12-Dec-2022 | Yes | 0.01% | | Jetstream_JT270M | [Implied by Jetstream_JT270M](#user-content-Jetstream_JT270M) | 13-Dec-2022 | Yes | 0.01% | | Jetstream_JT270MH | [@kk7ds](https://github.com/kk7ds) | 13-Dec-2022 | Yes | 0.01% | | Jianpai_8800_Plus | [Implied by Radtel_RT-490](#user-content-Radtel_RT-490) | 11-Nov-2023 | Yes | 0.01% | | KYD_IP-620 | | | | 0.02% | | KYD_NC-630A | | | | 0.02% | | Kenwood_HMK | [Implied by Generic_CSV](#user-content-Generic_CSV) | 4-Dec-2022 | | 0.00% | | Kenwood_ITM | | | | 0.00% | | Kenwood_TH-D7 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 12-Dec-2022 | Yes | 0.00% | | Kenwood_TH-D72_clone_mode | [@kk7ds](https://github.com/kk7ds) | 28-Nov-2022 | Yes | 0.02% | | Kenwood_TH-D72_live_mode | [@kk7ds](https://github.com/kk7ds) | 21-Oct-2022 | Yes | 0.00% | | Kenwood_TH-D74_clone_mode | [@kk7ds](https://github.com/kk7ds) | 30-Nov-2022 | Yes | 0.00% | | Kenwood_TH-D74_live_mode | [@kk7ds](https://github.com/kk7ds) | 20-Oct-2022 | Yes | 0.00% | | Kenwood_TH-D75 | [Reported working](https://chirp.danplanet.com/issues/11122) | 114-Feb-2024 | Yes | | | Kenwood_TH-D7G | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 12-Dec-2022 | Yes | 0.00% | | Kenwood_TH-F6 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.03% | | Kenwood_TH-F7 | [@sv1](https://github.com/sv1) | 19-Oct-2022 | Yes | 0.03% | | Kenwood_TH-G71 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 12-Dec-2022 | Yes | 0.01% | | Kenwood_TH-K2 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 12-Dec-2022 | Yes | 0.00% | | Kenwood_TK-2140K | [Implied by Kenwood_TK-3140K](#user-content-Kenwood_TK-3140K) | 2-Feb-2023 | Yes | | | Kenwood_TK-2180 | [@kk7ds](https://github.com/kk7ds) | 4-Dec-2022 | Yes | 0.04% | | Kenwood_TK-260 | | | | 0.02% | | Kenwood_TK-260G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.02% | | Kenwood_TK-270 | | | | 0.02% | | Kenwood_TK-270G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.02% | | Kenwood_TK-272 | | | | 0.01% | | Kenwood_TK-272G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.02% | | Kenwood_TK-278 | | | | 0.02% | | Kenwood_TK-278G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-3140K | [@kk7ds](https://github.com/kk7ds) | 2-Feb-2023 | Yes | | | Kenwood_TK-3140K2 | [Implied by Kenwood_TK-3140K](#user-content-Kenwood_TK-3140K) | 2-Feb-2023 | Yes | | | Kenwood_TK-3140K3 | [Implied by Kenwood_TK-3140K](#user-content-Kenwood_TK-3140K) | 2-Feb-2023 | Yes | | | Kenwood_TK-3180K | [@kk7ds](https://github.com/kk7ds) | 4-Dec-2022 | Yes | 0.03% | | Kenwood_TK-3180K2 | [Implied by Kenwood_TK-3180K](#user-content-Kenwood_TK-3180K) | 4-Dec-2022 | Yes | 0.01% | | Kenwood_TK-360 | | | | 0.02% | | Kenwood_TK-360G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-370 | | | | 0.02% | | Kenwood_TK-370G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.02% | | Kenwood_TK-372 | | | | 0.01% | | Kenwood_TK-372G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-378 | | | | 0.01% | | Kenwood_TK-378G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-388G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.00% | | Kenwood_TK-7102 | [@kk7ds](https://github.com/kk7ds) | 15-Feb-2019 | Yes | 0.02% | | Kenwood_TK-7108 | [@kk7ds](https://github.com/kk7ds) | 15-Feb-2019 | Yes | 0.01% | | Kenwood_TK-7160K | [@kk7ds](https://github.com/kk7ds) | 27-Jan-2023 | Yes | | | Kenwood_TK-7160M | [Implied by Kenwood_TK-7160K](#user-content-Kenwood_TK-7160K) | 27-Jan-2023 | Yes | | | Kenwood_TK-7180 | [@kk7ds](https://github.com/kk7ds) | 18-Oct-2022 | Yes | 0.01% | | Kenwood_TK-7180E | [Implied by Kenwood_TK-7180](#user-content-Kenwood_TK-7180) | 18-Oct-2022 | Yes | 0.00% | | Kenwood_TK-760 | [@kk7ds](https://github.com/kk7ds) | 5-Dec-2022 | Yes | 0.02% | | Kenwood_TK-760G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.03% | | Kenwood_TK-762 | [Implied by Kenwood_TK-760](#user-content-Kenwood_TK-760) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-762G | [@kk7ds](https://github.com/kk7ds) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-768 | [Implied by Kenwood_TK-760](#user-content-Kenwood_TK-760) | 5-Dec-2022 | Yes | 0.00% | | Kenwood_TK-768G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-8102 | [@kk7ds](https://github.com/kk7ds) | 15-Feb-2019 | Yes | 0.02% | | Kenwood_TK-8108 | [@kk7ds](https://github.com/kk7ds) | 15-Feb-2019 | Yes | 0.01% | | Kenwood_TK-8160K | [Implied by Kenwood_TK-7160K](#user-content-Kenwood_TK-7160K) | 27-Jan-2023 | Yes | | | Kenwood_TK-8160M | [Implied by Kenwood_TK-7160K](#user-content-Kenwood_TK-7160K) | 27-Jan-2023 | Yes | | | Kenwood_TK-8180 | [@kk7ds](https://github.com/kk7ds) | 18-Oct-2022 | Yes | 0.02% | | Kenwood_TK-8180E | [Implied by Kenwood_TK-8180](#user-content-Kenwood_TK-8180) | 18-Dec-2022 | Yes | 0.00% | | Kenwood_TK-860 | [Implied by Kenwood_TK-760](#user-content-Kenwood_TK-760) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-860G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.02% | | Kenwood_TK-862 | [Implied by Kenwood_TK-760](#user-content-Kenwood_TK-760) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-862G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-868 | [Implied by Kenwood_TK-760](#user-content-Kenwood_TK-760) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TK-868G | [Implied by Kenwood_TK-762G](#user-content-Kenwood_TK-762G) | 5-Dec-2022 | Yes | 0.01% | | Kenwood_TM-271 | [Implied by Kenwood_TM-281](#user-content-Kenwood_TM-281) | 23-Oct-2022 | Yes | 0.01% | | Kenwood_TM-281 | [@kk7ds](https://github.com/kk7ds) | 23-Oct-2022 | Yes | 0.02% | | Kenwood_TM-471 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 12-Dec-2022 | Yes | 0.00% | | Kenwood_TM-D700 | [@kk7ds](https://github.com/kk7ds) | 20-Oct-2022 | Yes | 0.01% | | Kenwood_TM-D710 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 22-Oct-2022 | Yes | 0.01% | | Kenwood_TM-D710G | [@kk7ds](https://github.com/kk7ds) | 22-Oct-2022 | Yes | 0.01% | | Kenwood_TM-D710G_CloneMode | [@kk7ds](https://github.com/kk7ds) | 22-Oct-2022 | Yes | 0.00% | | Kenwood_TM-D710_CloneMode | | | Yes | 0.00% | | Kenwood_TM-G707 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 12-Dec-2022 | Yes | 0.01% | | Kenwood_TM-V7 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/kenwood_live.py) | 12-Dec-2022 | Yes | 0.01% | | Kenwood_TM-V71 | [@kk7ds](https://github.com/kk7ds) | 21-Oct-2022 | Yes | 0.04% | | Kenwood_TS-2000 | ZS6CRW | 10-Jan-2022 | Yes | 0.03% | | Kenwood_TS-480_CloneMode | | | | 0.00% | | Kenwood_TS-480_LiveMode | | | Yes | 0.00% | | Kenwood_TS-590SG_CloneMode | | | | 0.00% | | Kenwood_TS-590S_CloneMode | | | | 0.00% | | Kenwood_TS-590S_SG_LiveMode | | | Yes | 0.00% | | Kenwood_TS-850 | | | Yes | 0.00% | | LUITON_LT-316 | [Implied by Retevis_RT22](#user-content-Retevis_RT22) | 9-Dec-2022 | Yes | 0.04% | | LUITON_LT-580_UHF | [@KC9HI](https://github.com/KC9HI) | 8-Dec-2022 | Yes | 0.01% | | LUITON_LT-580_VHF | [@KC9HI](https://github.com/KC9HI) | 8-Dec-2022 | Yes | 0.01% | | LUITON_LT-588UV | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.01% | | LUITON_LT-725UV | [@KC9HI](https://github.com/KC9HI) | 11-Dec-2022 | Yes | 0.02% | | Lanchonlh_HG-UV98 | | | Yes | 0.00% | | Leixen_VV-898 | [Implied by Jetstream_JT270MH](#user-content-Jetstream_JT270MH) | 13-Dec-2022 | Yes | 0.16% | | Leixen_VV-898E | | | Yes | 0.02% | | Leixen_VV-898E_Dual_Bank | [Implied by Leixen_VV-898S_Dual_Bank](#user-content-Leixen_VV-898S_Dual_Bank) | 10-Feb-2024 | Yes | | | Leixen_VV-898S | [@READ10](https://github.com/READ10) | 19-Dec-2022 | Yes | 0.08% | | Leixen_VV-898S_Dual_Bank | [Reported working](https://chirp.danplanet.com/issues/4069) | 10-Feb-2024 | Yes | | | MMLradio_JC-8629 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2023 | Yes | 0.01% | | MTC_UV-5R-3 | [Implied by BTECH_UV-5X3](#user-content-BTECH_UV-5X3) | 9-Dec-2022 | Yes | 0.02% | | Maverick_RA-100 | [@cetinajero](https://github.com/cetinajero) | 7-Jul-2023 | Yes | | | Maverick_RA-425 | [@cetinajero](https://github.com/cetinajero) | 7-Jul-2023 | Yes | | | Midland_DBR2500 | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.05% | | Polmar_DB-50M | [Implied by AnyTone_5888UV](#user-content-AnyTone_5888UV) | 9-Dec-2022 | Yes | 0.03% | | Powerwerx_DB-750X | [Implied by AnyTone_5888UV](#user-content-AnyTone_5888UV) | 9-Dec-2022 | Yes | 0.01% | | Puxing_PX-2R | | | | 0.05% | | Puxing_PX-777 | | | Yes | 0.11% | | Puxing_PX-888K | [Reported working](https://chirp.danplanet.com/issues/10544) | 09-May-2023 | Yes | 0.07% | | Q-MAC_HF-90_v300_or_earlier | [@fthain](https://github.com/fthain) | 9-Mar-2023 | Yes | | | Q-MAC_HF-90_v301_or_later | [@fthain](https://github.com/fthain) | 9-Mar-2023 | Yes | | | QYT_KT-8R | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.09% | | QYT_KT-UV980 | [Implied by WACCOM_MINI-8900](#user-content-WACCOM_MINI-8900) | 11-Nov-2022 | Yes | 0.04% | | QYT_KT-WP12 | [Implied by Anysecu_WP-9900](#user-content-Anysecu_WP-9900) | 11-Nov-2022 | Yes | 0.02% | | QYT_KT5800 | [Implied by BTECH_UV-25X2](#user-content-BTECH_UV-25X2) | 11-Nov-2022 | Yes | 0.01% | | QYT_KT7900D | [Implied by BTECH_UV-25X4](#user-content-BTECH_UV-25X4) | 11-Nov-2022 | Yes | 0.37% | | QYT_KT8900 | [Implied by LUITON_LT-588UV](#user-content-LUITON_LT-588UV) | 11-Nov-2022 | Yes | 0.42% | | QYT_KT8900D | [Implied by BTECH_UV-25X2](#user-content-BTECH_UV-25X2) | 11-Nov-2022 | Yes | 0.52% | | QYT_KT8900R | [Implied by BTECH_UV-2501+220](#user-content-BTECH_UV-2501+220) | 11-Nov-2022 | Yes | 0.13% | | QYT_KT980PLUS | [Implied by BTECH_UV-25X2](#user-content-BTECH_UV-25X2) | 11-Nov-2022 | Yes | 0.09% | | Quansheng_TG-UV2+ | [Reported working](https://chirp.danplanet.com/issues/10398) | 26-Feb-2023 | Yes | 0.05% | | Quansheng_UV-K5 | [@sq5bpf](https://github.com/sq5bpf) | 29-May-2023 | Yes | | | Quansheng_UV-K5_egzumer | [@egzumer](https://github.com/egzumer) | 23-Jan-2024 | Yes | | | RT_Systems_CSV | | | | | | Radioddity_DB25-G | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.17% | | Radioddity_GA-2S | [@KC9HI](https://github.com/KC9HI) | 4-Dec-2022 | Yes | 0.19% | | Radioddity_GA-510 | [@kk7ds](https://github.com/kk7ds) | 21-Oct-2022 | Yes | 0.42% | | Radioddity_GS-5B | [@lunapiercook](https://github.com/lunapiercook) | 5-Mar-2023 | Yes | | | Radioddity_R2 | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.04% | | Radioddity_UV-5G | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | 0.47% | | Radioddity_UV-5RX3 | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | 0.90% | | Radioddity_UV-82X3 | [@KC9HI](https://github.com/KC9HI) | 18-Nov-2022 | Yes | 0.05% | | Radtel_RT-470 | [@KC9HI](https://github.com/KC9HI) | 2-Apr-2023 | Yes | 0.00% | | Radtel_RT-470L | [@KC9HI](https://github.com/KC9HI) | 5-May-2023 | Yes | | | Radtel_RT-470X | [@KC9HI](https://github.com/KC9HI) | 10-Aug-2023 | Yes | | | Radtel_RT-490 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2023 | Yes | 0.08% | | Radtel_T18 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.07% | | Retevis_H777S | [@KC9HI](https://github.com/KC9HI) | 22-Dec-2022 | Yes | | | Retevis_H777_Plus | [@KC9HI](https://github.com/KC9HI) | 4-Dec-2022 | Yes | 0.06% | | Retevis_RA685 | [@KC9HI](https://github.com/KC9HI) | 19-Nov-2022 | Yes | 0.25% | | Retevis_RA79 | [@KC9HI](https://github.com/KC9HI) | 27-Oct-2023 | Yes | | | Retevis_RA85 | [@KC9HI](https://github.com/KC9HI) | 19-Nov-2022 | Yes | 0.05% | | Retevis_RA89 | [@KC9HI](https://github.com/KC9HI) | 23-Nov-2023 | Yes | | | Retevis_RB15 | [@KC9HI](https://github.com/KC9HI) | 18-Dec-2022 | Yes | 0.01% | | Retevis_RB17 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.02% | | Retevis_RB17A | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.01% | | Retevis_RB17P | [@KC9HI](https://github.com/KC9HI) | 18-Dec-2022 | Yes | 0.02% | | Retevis_RB17V | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.01% | | Retevis_RB18 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.04% | | Retevis_RB19 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.00% | | Retevis_RB19P | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.01% | | Retevis_RB23 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.00% | | Retevis_RB26 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.04% | | Retevis_RB27 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.09% | | Retevis_RB27B | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.02% | | Retevis_RB27V | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.01% | | Retevis_RB28 | [@KC9HI](https://github.com/KC9HI) | 9-Feb-2023 | Yes | 0.00% | | Retevis_RB28B | [@KC9HI](https://github.com/KC9HI) | 27-Jan-2023 | Yes | | | Retevis_RB29 | [@KC9HI](https://github.com/KC9HI) | 24-Dec-2022 | Yes | 0.00% | | Retevis_RB615 | [@KC9HI](https://github.com/KC9HI) | 18-Dec-2022 | Yes | 0.01% | | Retevis_RB617 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.02% | | Retevis_RB618 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.16% | | Retevis_RB619 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.01% | | Retevis_RB627B | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.05% | | Retevis_RB628 | [@KC9HI](https://github.com/KC9HI) | 10-Feb-2023 | Yes | | | Retevis_RB628B | [@KC9HI](https://github.com/KC9HI) | 28-Jan-2023 | Yes | | | Retevis_RB629 | [@KC9HI](https://github.com/KC9HI) | 24-Dec-2022 | Yes | 0.00% | | Retevis_RB75 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.02% | | Retevis_RB85 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.02% | | Retevis_RB87 | [@KC9HI](https://github.com/KC9HI) | 10-Mar-2023 | Yes | | | Retevis_RT1 | [@KC9HI](https://github.com/KC9HI) | 11-Dec-2022 | Yes | 0.08% | | Retevis_RT15 | [@KC9HI](https://github.com/KC9HI) | 18-Feb-2023 | Yes | 0.00% | | Retevis_RT16 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.02% | | Retevis_RT19 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.00% | | Retevis_RT20 | [@k9ps-paul](https://github.com/k9ps-paul) | 7-Sep-2023 | Yes | | | Retevis_RT21 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.20% | | Retevis_RT21V | [@KC9HI](https://github.com/KC9HI) | 24-Jul-2023 | Yes | 0.00% | | Retevis_RT22 | [@KC9HI](https://github.com/KC9HI) | 9-Dec-2022 | Yes | 0.53% | | Retevis_RT22FRS | [@KC9HI](https://github.com/KC9HI) | 9-Dec-2022 | Yes | 0.04% | | Retevis_RT22S | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.04% | | Retevis_RT23 | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.04% | | Retevis_RT24 | [@KC9HI](https://github.com/KC9HI) | 22-Dec-2022 | Yes | 0.31% | | Retevis_RT24V | [@KC9HI](https://github.com/KC9HI) | 27-Aug-2023 | Yes | | | Retevis_RT26 | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.03% | | Retevis_RT29_UHF | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.03% | | Retevis_RT29_VHF | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.02% | | Retevis_RT40B | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.00% | | Retevis_RT47 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.00% | | Retevis_RT47V | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.00% | | Retevis_RT6 | [@KC9HI](https://github.com/KC9HI) | 3-Dec-2022 | Yes | 0.04% | | Retevis_RT619 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.00% | | Retevis_RT622 | [@KC9HI](https://github.com/KC9HI) | 9-Dec-2022 | Yes | 0.09% | | Retevis_RT647 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.00% | | Retevis_RT668 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.03% | | Retevis_RT68 | [@KC9HI](https://github.com/KC9HI) | 28-Nov-2022 | Yes | 0.03% | | Retevis_RT76 | [@KC9HI](https://github.com/KC9HI) | 30-Nov-2022 | Yes | 0.02% | | Retevis_RT76P | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.04% | | Retevis_RT85 | [@KC9HI](https://github.com/KC9HI) | 5-Dec-2022 | Yes | 0.22% | | Retevis_RT86 | [@KC9HI](https://github.com/KC9HI) | 17-Feb-2023 | Yes | | | Retevis_RT87 | [@KC9HI](https://github.com/KC9HI) | 17-Dec-2022 | Yes | 0.03% | | Retevis_RT9000D_136-174 | [@KC9HI](https://github.com/KC9HI) | 8-Dec-2022 | Yes | 0.01% | | Retevis_RT9000D_220-260 | [@KC9HI](https://github.com/KC9HI) | 8-Dec-2022 | Yes | 0.01% | | Retevis_RT9000D_400-490 | [@KC9HI](https://github.com/KC9HI) | 8-Dec-2022 | Yes | 0.01% | | Retevis_RT9000D_66-88 | [@KC9HI](https://github.com/KC9HI) | 8-Dec-2022 | Yes | 0.00% | | Retevis_RT95 | [@KC9HI](https://github.com/KC9HI) | 13-Nov-2022 | Yes | 0.08% | | Retevis_RT95_VOX | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.15% | | Retevis_RT98 | [@KC9HI](https://github.com/KC9HI) | 14-Dec-2022 | Yes | 0.05% | | Rugged_RH5R-V2 | | | | 0.05% | | Ruyage_UV58Plus | [@KC9HI](https://github.com/KC9HI) | 18-Mar-2023 | Yes | | | Sainsonic_AP510 | | | | 0.00% | | SenhaiX_8800 | [Implied by Radioddity_GS-5B](#user-content-Radioddity_GS-5B) | 17-Mar-2023 | Yes | | | Socotran_FB-8629 | [Implied by Radtel_RT-490](#user-content-Radtel_RT-490) | 11-Nov-2023 | Yes | 0.00% | | Socotran_JC-8629 | [Implied by Radtel_RT-490](#user-content-Radtel_RT-490) | 11-Nov-2023 | Yes | | | TDXone_TD-Q8A | [@KC9HI](https://github.com/KC9HI) | 18-Dec-2022 | | 0.02% | | TIDRADIO_TD-H3 | [@songjunbiao](https://github.com/songjunbiao) | 1-Dec-2023 | Yes | | | TIDRADIO_TD-H3-GMRS | [@songjunbiao](https://github.com/songjunbiao) | 1-Dec-2023 | Yes | | | TIDRADIO_TD-H3-HAM | [@songjunbiao](https://github.com/songjunbiao) | 1-Dec-2023 | Yes | | | TIDRADIO_TD-H6 | [@kk7ds](https://github.com/kk7ds) | 21-Oct-2022 | Yes | 0.43% | | TIDRADIO_TD-H8 | [@Sandmann34](https://github.com/Sandmann34) | 7-Feb-2023 | Yes | | | TIDRADIO_TD-H8-GMRS | [@Sandmann34](https://github.com/Sandmann34) | 7-Feb-2023 | Yes | | | TIDRADIO_TD-H8-HAM | [@Sandmann34](https://github.com/Sandmann34) | 7-Feb-2023 | Yes | | | TID_TD-M8 | [Implied by Retevis_RT22](#user-content-Retevis_RT22) | 9-Dec-2022 | Yes | 0.04% | | TID_TD-UV68 | [@Sandmann34](https://github.com/Sandmann34) | 7-Feb-2023 | Yes | | | TYT_TH-350 | | | Yes | 0.07% | | TYT_TH-7800 | [Reported working](https://chirp.danplanet.com/issues/10585) | 4-Jul-2023 | Yes | 0.13% | | TYT_TH-7800_File | | | | 0.00% | | TYT_TH-9800 | [Reported working](https://chirp.danplanet.com/issues/10755) | 30-Jul-2023 | Yes | 0.65% | | TYT_TH-9800_File | | | Yes | 0.00% | | TYT_TH-UV3R | | | Yes | 0.04% | | TYT_TH-UV3R-25 | | | Yes | 0.02% | | TYT_TH-UV8000 | [@KC9HI](https://github.com/KC9HI) | 6-Jan-2023 | Yes | 0.31% | | TYT_TH-UV88 | [@KC9HI](https://github.com/KC9HI) | 5-Dec-2022 | Yes | 0.51% | | TYT_TH-UVF1 | [@kk7ds](https://github.com/kk7ds) | 13-Dec-2022 | Yes | 0.06% | | TYT_TH-UVF8D | [@MELERIX](https://github.com/MELERIX) | 2-Feb-2023 | Yes | 0.05% | | TYT_TH9000_144 | [Implied by Retevis_RT9000D_136-174](#user-content-Retevis_RT9000D_136-174) | 8-Dec-2022 | Yes | 0.06% | | TYT_TH9000_220 | [Implied by Retevis_RT9000D_220-260](#user-content-Retevis_RT9000D_220-260) | 8-Dec-2022 | Yes | 0.04% | | TYT_TH9000_440 | [Implied by Retevis_RT9000D_400-490](#user-content-Retevis_RT9000D_400-490) | 8-Dec-2022 | Yes | 0.04% | | Talkpod_A36plus | [@KC9HI](https://github.com/KC9HI) | 12-Jun-2023 | Yes | | | Talkpod_A36plus_8w | [@KC9HI](https://github.com/KC9HI) | 16-Feb-2024 | Yes | | | Vertex_Standard_FTL-1011 | | | | 0.02% | | Vertex_Standard_FTL-2011 | | | | 0.05% | | Vertex_Standard_FTL-7011 | | | | 0.03% | | Vertex_Standard_FTL-8011 | | | | 0.01% | | Vertex_Standard_VXA-700 | | | | 0.02% | | WACCOM_MINI-8900 | [@KC9HI](https://github.com/KC9HI) | 11-Nov-2022 | Yes | 0.12% | | WLN_KD-C1 | [Implied by Retevis_RT22](#user-content-Retevis_RT22) | 9-Dec-2022 | Yes | **1.73%** | | Wouxun_KG-1000G | [@mrtjr1](https://github.com/mrtjr1) | 23-jan-2023 | Yes | | | Wouxun_KG-1000G_Plus | [@mrtjr1](https://github.com/mrtjr1) | 23-jan-2023 | Yes | 0.00% | | Wouxun_KG-816 | [Implied by Wouxun_KG-UV6](#user-content-Wouxun_KG-UV6) | 11-Dec-2022 | Yes | 0.07% | | Wouxun_KG-818 | [Implied by Wouxun_KG-UV6](#user-content-Wouxun_KG-UV6) | 11-Dec-2022 | Yes | 0.04% | | Wouxun_KG-935G | [@mrtjr1](https://github.com/mrtjr1) | 4-Jan-2022 | Yes | 0.05% | | Wouxun_KG-935G_Plus | [@mrtjr1](https://github.com/mrtjr1) | 7-Feb-2023 | Yes | | | Wouxun_KG-UV6 | [@KC9HI](https://github.com/KC9HI) | 11-Dec-2022 | Yes | 0.19% | | Wouxun_KG-UV8D | Unit tested; needs confirm | 24-Dec-2022 | Yes | 0.24% | | Wouxun_KG-UV8D_Plus | Unit tested; needs confirm | 2-Jan-2022 | Yes | 0.08% | | Wouxun_KG-UV8E | W5EGL | 2-Jan-2022 | Yes | 0.05% | | Wouxun_KG-UV8H | [@mrtjr1](https://github.com/mrtjr1) | 27-Mar-2023 | Yes | 0.01% | | Wouxun_KG-UV920P-A | [@KC9HI](https://github.com/KC9HI) | 22-Dec-2022 | Yes | 0.04% | | Wouxun_KG-UV980P | [@mrtjr1](https://github.com/mrtjr1) | 23-jan-2023 | Yes | 0.01% | | Wouxun_KG-UV9D_Plus | [@samwich](https://github.com/samwich) | 10-Jan-2023 | Yes | 0.39% | | Wouxun_KG-UV9GX | [@mrtjr1](https://github.com/mrtjr1) | 27-Mar-2023 | Yes | | | Wouxun_KG-UV9G_Pro | [@mrtjr1](https://github.com/mrtjr1) | 25-Apr-2023 | Yes | | | Wouxun_KG-UV9K | [@mrtjr1](https://github.com/mrtjr1) | 14-Apr-2023 | Yes | | | Wouxun_KG-UV9PX | [@mrtjr1](https://github.com/mrtjr1) | 20-Jan-2022 | Yes | | | Wouxun_KG-UVD1P | [Implied by Wouxun_KG-UV6](#user-content-Wouxun_KG-UV6) | 11-Dec-2022 | Yes | 0.35% | | Yaesu_FT-1500M | [@f3sty](https://github.com/f3sty) | 05-Dec-2022 | Yes | 0.02% | | Yaesu_FT-1802M | | | Yes | 0.02% | | Yaesu_FT-1D_R | [Implied by Yaesu_FT3D_R](#user-content-Yaesu_FT3D_R) | 30-Dec-2022 | Yes | 0.03% | | Yaesu_FT-25R | [Implied by Yaesu_FT-4XE](#user-content-Yaesu_FT-4XE) | 24-Dec-2022 | Yes | 0.01% | | Yaesu_FT-2800M | [Reported working](https://chirp.danplanet.com/issues/10616) | 05-Jun-2023 | Yes | 0.03% | | Yaesu_FT-2900R_1900R | [Reported working](https://chirp.danplanet.com/issues/10274) | 14-Jan-2023 | Yes | 0.05% | | Yaesu_FT-2900R_1900RTXMod_Opened_Xmit | [Implied by Yaesu_FT-2900R_1900R](#user-content-Yaesu_FT-2900R_1900R) | 14-Jan-2023 | Yes | | | Yaesu_FT-450 | [@WCurlew](https://github.com/WCurlew) | 03-Nov-2023 | Yes | | | Yaesu_FT-450D | [@Old-Phart](https://github.com/Old-Phart) | 01-Jun-2023 | Yes | 0.01% | | Yaesu_FT-4VR | [Implied by Yaesu_FT-4XE](#user-content-Yaesu_FT-4XE) | 24-Dec-2022 | Yes | 0.01% | | Yaesu_FT-4XE | Unit tested; needs confirm | 24-Dec-2022 | Yes | 0.14% | | Yaesu_FT-4XR | [Implied by Yaesu_FT-4XE](#user-content-Yaesu_FT-4XE) | 24-Dec-2022 | Yes | 0.11% | | Yaesu_FT-50 | [Reported working](https://chirp.danplanet.com/issues/10824) | 5-Sep-2023 | Yes | 0.04% | | Yaesu_FT-60 | N0EYE | 9-Jan-2023 | Yes | 0.49% | | Yaesu_FT-65E | [@kwirk](https://github.com/kwirk) | 27-Jan-2023 | Yes | 0.08% | | Yaesu_FT-65R | [Reported working](https://chirp.danplanet.com/issues/10266) | 13-Jan-2022 | Yes | 0.18% | | Yaesu_FT-70D | [@n8sqt](https://github.com/n8sqt) | 05-Dec-2022 | Yes | 0.27% | | Yaesu_FT-7100M | | | Yes | 0.03% | | Yaesu_FT-7800_7900 | [@kk7ds](https://github.com/kk7ds) | 24-Oct-2022 | Yes | 0.14% | | Yaesu_FT-8100 | [Reported working](https://chirp.danplanet.com/issues/10904) | 19-Oct-2023 | Yes | 0.01% | | Yaesu_FT-817 | [@kk7ds](https://github.com/kk7ds) | 14-Feb-2019 | Yes | 0.04% | | Yaesu_FT-817ND | [Implied by Yaesu_FT-817](#user-content-Yaesu_FT-817) | 14-Feb-2019 | Yes | 0.07% | | Yaesu_FT-817ND_US | [Implied by Yaesu_FT-817](#user-content-Yaesu_FT-817) | 14-Feb-2019 | Yes | 0.02% | | Yaesu_FT-818 | [@thomasrussellmurphy](https://github.com/thomasrussellmurphy) | 4-Feb-2023 | Yes | 0.05% | | Yaesu_FT-818ND_US | [Implied by Yaesu_FT-817](#user-content-Yaesu_FT-817) | 14-Feb-2019 | Yes | 0.02% | | Yaesu_FT-857_897 | [Implied by Yaesu_FT-817](#user-content-Yaesu_FT-817) | 14-Feb-2019 | Yes | 0.25% | | Yaesu_FT-857_897_US | [Implied by Yaesu_FT-817](#user-content-Yaesu_FT-817) | 14-Feb-2019 | Yes | 0.08% | | Yaesu_FT-8800 | [@kk7ds](https://github.com/kk7ds) | 24-Oct-2022 | Yes | 0.08% | | Yaesu_FT-8900 | [Reported working](https://chirp.danplanet.com/issues/10753) | 30-Jul-2023 | Yes | 0.11% | | Yaesu_FT-90 | [Reported working](https://chirp.danplanet.com/issues/10386) | 22-Feb-2023 | Yes | 0.02% | | Yaesu_FT2D_R | [Implied by Yaesu_FT3D_R](#user-content-Yaesu_FT3D_R) | 30-Dec-2022 | Yes | 0.02% | | Yaesu_FT2D_Rv2 | [Implied by Yaesu_FT3D_R](#user-content-Yaesu_FT3D_R) | 30-Dec-2022 | Yes | | | Yaesu_FT3D_R | [@kk7ds](https://github.com/kk7ds) | 30-Dec-2022 | Yes | 0.03% | | Yaesu_FTM-3200D_R | | | Yes | 0.02% | | Yaesu_FTM-350 | [@kk7ds](https://github.com/kk7ds) | 4-Dec-2022 | Yes | 0.02% | | Yaesu_FTM-7250D_R | | | Yes | 0.04% | | Yaesu_VX-170 | | | Yes | 0.03% | | Yaesu_VX-2 | [@thomasrussellmurphy](https://github.com/thomasrussellmurphy) | 20-Jan-2023 | Yes | 0.04% | | Yaesu_VX-3 | [@kk7ds](https://github.com/kk7ds) | 15-Feb-2019 | Yes | 0.08% | | Yaesu_VX-5 | [Probably works](https://github.com/kk7ds/chirp/blob/py3/chirp/drivers/yaesu_clone.py) | 12-Dec-2022 | Yes | 0.07% | | Yaesu_VX-6 | [@dominickpastore](https://github.com/dominickpastore) | 10-Dec-2022 | Yes | 0.16% | | Yaesu_VX-7 | [@kk7ds](https://github.com/kk7ds) | 15-Feb-2019 | Yes | 0.09% | | Yaesu_VX-8DR | [@kk7ds](https://github.com/kk7ds) | 15-Feb-2019 | Yes | 0.03% | | Yaesu_VX-8GE | [Implied by Yaesu_VX-8DR](#user-content-Yaesu_VX-8DR) | 15-Feb-2019 | Yes | 0.01% | | Yaesu_VX-8R | [Implied by Yaesu_VX-8DR](#user-content-Yaesu_VX-8DR) | 15-Feb-2019 | Yes | 0.03% | | Yedro_YC-M04VUS | [Implied by Retevis_RT95](#user-content-Retevis_RT95) | 13-Nov-2022 | Yes | 0.02% | | Zastone_ZT-X6 | [Implied by Retevis_RT22](#user-content-Retevis_RT22) | 9-Dec-2022 | Yes | 0.11% | ## Stats **Drivers:** 449 **Tested:** 87% (395/54) (93% of usage stats) **Byte clean:** 91% (410/39) ## Meaning of this testing The goal here is not necessarily to test the drivers themselves in terms of actual functionality, but rather to validate the Python 3 conversion work required of nearly all drivers. Thus, we are not trying to comprehensively test these models so much as make sure they work at least as well as they do on the Python 2 branch. Uncovering and reporting new bugs is definitely welcome, but for the purpoes of this effort, "no worse than the legacy branch" is good enough. There are multiple levels of confirmation in the matrix above: * Tested with real hardware (i.e. a person listed in the "Tester" column) using roughly the procedure below. * An "implied by (model)" link means that another model was tested, and it is so similar, that the model on that line can be considered tested as well. * A "probably works" link means that the driver has not been tested with real hardware, nor is it substantially similar to another model, but shares a common base that entirely provides the cloning routines with other drivers that have been tested with real hardware, such that confidence is high that it will work. Only drivers with test images in the tree (or live drivers) should be marked with this class. * A "unit tested" link means that the driver has not been tested with real hardware, nor does it share common cloning routines with another radio. However, synthetic simulation tests have been added to exercise the parts of the cloning routines that are likely to fail under python3. This is the lowest-confidence status and a real confirmation is needed. If you have a model listed in this matrix with either "implied" or "probably works" status, an actual confirmation with real hardware is welcome and can replace the weaker reference. ## Minimal test procedure For the purposes of the Python 3 effort, a "tested" radio means at least the following procedure was followed: 1. Download from the radio 1. Make some change to a memory 1. If the radio has settings support, make sure settings load and tweak one setting 1. Upload to the radio 1. Confirm that the changes stick and look correct, or at least are not a regression from the master py2 branch. The drivers are all passing the automated tests, but tests with real hardware and serial ports is important, especially around bytes-vs-string safety. To update this document, add/edit entries in `tests/py3_driver_testers.txt` and then run `tox -e makesupported`. Commit the result (including the changes to this `.md` file) and submit a PR. The "Byte Clean" flag refers to whether or not the radio has set the `NEEDS_COMPAT_SERIAL = False` flag on the radio class, and thus uses `MemoryMapBytes` exclusively internally. Whenever possible, all radios that are fixed for py3 should do so with this flag set to False and with the byte-native memory map. chirp-20240224/tests/test_drivers.py0000644000175000017500000000102514450510547016270 0ustar hibbyhibbyfrom chirp import directory from tests import load_tests __builtins__['_'] = lambda s: s class TestSuiteAdapter(object): """Adapter for pytest since it doesn't support the loadTests() protocol""" def __init__(self, locals): self.locals = locals def loadTestsFromTestCase(self, test_cls): self.locals[test_cls.__name__] = test_cls @staticmethod def addTests(tests): pass directory.import_drivers() adapter = TestSuiteAdapter(locals()) load_tests(adapter, None, None, suite=adapter) chirp-20240224/tests/__pycache__/0000755000175000017500000000000014566340177015423 5ustar hibbyhibbychirp-20240224/tests/__pycache__/__init__.cpython-310.pyc0000644000175000017500000000630114522657306021660 0ustar hibbyhibbyo Љ^Keу@sЮddlZddlZddlZddlZddlZddlmZddlmZddlm Z ddlm Z ddlm Z ddlm Z ddlm Z dd lmZdd lmZe d ЁZGd d „d eƒZdd„Zddd„Zddd„ZdS)щN)к directory)к test_banks)кtest_brute_force)к test_clone)к test_copy_all)к test_detect)к test_edges)к test_features)к test_settingsк testadaptercseZdZ‡fdd„Z‡ZS)кTestAdapterMetacstt|ƒ ||||ЁSЉN)кsuperr к__new__)кclsкnameкparentsкdctЉк __class__ЉњF/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/__init__.pyrszTestAdapterMeta.__new__)к__name__к __module__к __qualname__rк __classcell__rrrrr sr c Cslz |dƒ}| Ё}Wnty'}ztd||fƒ|gWYd}~Sd}~ww|jr3||ƒ}| ЁS|gS)Nz!Failed to get features for %s: %s)к get_featuresк Exceptionкprintкhas_sub_devicesкget_sub_devices)кrclassк testimageкradioкrfкerrrк_get_sub_devicess €њr&c Cs„|st Ё}dtjvrtjd Ё}nt dЁ}dd„|Dƒ}tj tj t ЁЁ}tj  |dЁ}t tj  |dЁЁ}dd„|Dƒ}|d krGd}t j t j tjtjtjtjtjtjtjf }| ЁD]`\}}t |Ё} t| d ƒrp| j } | j! d Ёd } t"| |ƒ} | | gk} t#| ƒD]8\} }t$|t%ƒs’|j&}|D])}t'd |j(t )|Ёf|f| | rЇ| nd|dœƒ}t*t+j,| ƒ|ƒ}| -| .|ЁЁq”q†q_|S)Nк CHIRP_TESTIMGztests/images/*.imgcSs$g|]}tj tj |ЁЁd‘qSЉrЉкosкpathкsplitextкbasenameЉк.0кimgrrrк 7s$z_load_tests..кimagesк*cSs&i|]}|tj tj |ЁЁd“qSr(r)r.rrrк <s&z_load_tests..ztest*.pyк _orig_rclassк.щџџџџz%s_%s)к RADIO_CLASSк SUB_DEVICEк TEST_IMAGE)/кunittestк TestSuiter*кenvironкsplitкglobr+кdirnameкabspathк__file__кjoinrк TestCaseEdgesкTestBitwiseStrictrкTestCaseBruteForcerк TestCaseBanksrкTestCaseDetectrк TestCaseCloner кTestCaseSettingsr кTestCaseFeaturesrкTestCaseCopyAllкitemsrк get_radioкhasattrr5rr&к enumerateк isinstanceкtyperr rкradio_class_idкgetattrкpytestкmarkкaddTestsкloadTestsFromTestCase)кloaderкtestsкpatternкsuiter2кbaseкdriver_test_casesкimageкtestr!кmoduleкsubdevsк has_subdevsкindexкdeviceкcaseкtcrrrк _load_tests/s`  ј     џ ўќі§rhc CsNz t||||dWSty&}zddl}td|ƒt| Ёƒ‚d}~ww)N)r\rzFailed to load: %s)rhrк tracebackrк format_exc)rYrZr[r\r%rirrrк load_testses  €ќrkr )r?кloggingr*r;rUкchirprrZrrrrrrr r к getLoggerкLOGrRr r&rhrkrrrrкs&           6chirp-20240224/tests/__pycache__/test_settings.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000461514522135043025005 0ustar hibbyhibbyo КHeіу@sTddlZddlmmZddlmZddlmZddl m Z Gdd„de j ƒZ dS)щN)к chirp_common)кsettings)кbasec@sPeZdZdd„Ze dЁdd„ƒZe dЁdd„ƒZdd „Zd d „Z d d „Z dS)кTestCaseSettingscCsdSЉN)кradioк get_settingsк assertFalseкrfк has_settingsк assertTrue)кselfrЉrњK/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_settings.pyкtest_has_settingssz"TestCaseSettings.test_has_settingsr cCs|j Ё}| |tЁdSr)rrкassertIsInstanceкlist)r кlstrrrкtest_get_settingss z"TestCaseSettings.test_get_settingscCs6|j Ё}|j |Ё|j Ё}tt|j||ƒƒdSr)rrк set_settingsrкmapкcompare_settings)r кoкnrrrкtest_same_settingss   z#TestCaseSettings.test_same_settingsc Csdzt|tjƒr t‚tt|j||ƒƒWdSty1| | Ё| Ёd| Ё| ЁfЁYdSw)Nz#Setting value changed from %r to %r) к isinstancerкRadioSettingValueк StopIterationrrrк assertEqualк get_value)r кaкbrrrrs   џ џџz!TestCaseSettings.compare_settingscCs@t|jjŽD]}|j |Ё}|js|j t |ЁЁdSqdSr) кranger к memory_boundsrк get_memoryкemptyк set_memoryrк FrozenMemory)r кiкmrrrкtest_memory_extra_frozen's ўўz)TestCaseSettings.test_memory_extra_frozencCsZt|jjŽD]$}|j |Ё}|js*| |jtt j fdЁ|jD] }| |t j dЁqqdS)Nz-mem.extra must be a list or RadioSettingGroupz,mem.extra items must be RadioSetting objects) r"r r#rr$r%rкextrarrкRadioSettingGroupк RadioSetting)r r(r)кerrrкtest_memory_extra_flat1s § ў€јz'TestCaseSettings.test_memory_extra_flatN) к__name__к __module__к __qualname__rrкrequires_featurerrrr*r/rrrrrs   r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкchirprrкtestsrк DriverTestrrrrrкs&  chirp-20240224/tests/__pycache__/test_detect.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000422114556146133024417 0ustar hibbyhibbyo >ЬИeоу@sxddlZddlmmZddlZddlZddlm Z ddl Z ddl m Z ddl m Z ddlmZGdd„dejƒZdS)щN)кmock)к directory)кlogger)кbasec@sdeZdZdd„Zejjejdkdde   dЁdd„ƒƒZ ejjejdkdde   dЁd d „ƒƒZ d S) кTestCaseDetectcCsЈt tjdЁ}t |jЁ}| g| ЁdЁWdƒn1s!wYt |dƒr1|  |jЁ}t |j |j ƒrB| |j |j ЁdS| ||jd|j|j |jfЁdS)Nz chirp.driversz6Drivers should not log warnings/errors for good imagesк _orig_rclassz'Image %s detected as %s but expected %s)rк log_historyкloggingкWARNINGrкget_radio_by_imageк TEST_IMAGEк assertEqualк get_historyкhasattrrк isinstanceкradioк __class__кassertIsInstanceк RADIO_CLASS)кselfкhistoryrЉrњI/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_detect.pyк test_detect s   џў   ўџzTestCaseDetect.test_detect)щщ zrequires python3.10 or higher)кreasonzbuiltins.printcCsH|jtjd|j ddЁWdƒn1swY| ЁdS)NЉкlevelѓzfoo.img)к assertNoLogsr кDEBUGrк match_modelкassert_not_called)rк mock_printrrrк"test_match_model_is_quiet_no_match sџ z1TestCaseDetect.test_match_model_is_quiet_no_matchc Csz|jtjd(t|jdƒ}|j | Ё|jЁWdƒn1s#wYWdƒn1s2wY| ЁdS)Nrкrb) r r r!кopenr rr"кreadr#)rr$кfrrrк$test_match_model_is_quiet_with_match(sџ€џ z3TestCaseDetect.test_match_model_is_quiet_with_matchN) к__name__к __module__к __qualname__rкpytestкmarkкskipifкsysк version_inforкpatchr%r*rrrrr sџ џr)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arr r1кunittestrr.кchirprrкtestsrк DriverTestrrrrrкs"    chirp-20240224/tests/__pycache__/test_copy_all.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000326314430373554024756 0ustar hibbyhibbyo уђ`dXу@s\ddlZddlmmZddlZddlmZddl m Z ddl m Z Gdd„de j ƒZdS)щN)к generic_csv)к import_logic)кbasecs(eZdZdZ‡fdd„Zdd„Z‡ZS)кTestCaseCopyAllzCopy Memories From CSVcs2tƒ Ёtj tj |jЁdЁ}t |Ё|_ dS)NzGeneric_CSV.csv) кsuperкsetUpкosкpathкjoinкdirnameк TEST_IMAGErкCSVRadioк src_radio)кselfкcsvfileЉк __class__ЉњK/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_copy_all.pyr s џzTestCaseCopyAll.setUpc Cs|j Ё}|j}t|jjdt|jjdd|jjdƒƒD]}|j |Ё}|js/d|j vr/qn|  dЁt|d|dƒD]A}|j |Ё}|jrKq?zt j |j||d|id}t   |j|j||ЁWn t jymYq?w|j |Ё|j |Ё}| ||Ёq?dS)Nrщ щкfreqz*No channels with mutable freq found to useкnumber)к overrides)rк get_featuresк memory_boundsкrangeкrfкminкradioк get_memoryкemptyк immutableкskipTestrк import_memк import_bankкDestNotCompatibleк set_memoryкassertEqualMem) rкsrc_rfкboundsк dst_numberкcur_memrкsrc_memкdst_memкret_memrrrк test_copysD   џџ   џў§џ  эzTestCaseCopyAll.test_copy)к__name__к __module__к __qualname__к__doc__rr0к __classcell__rrrrrs r)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arrк chirp.driversrкchirprкtestsrк DriverTestrrrrrкs "   chirp-20240224/tests/__pycache__/test_edges.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001633514561124223024237 0ustar hibbyhibbyo uЈФeэу@s†ddlZddlmmZddlZddlmZddl m Z ddl m Z ddl m Z ddl mZGdd„dejƒZGd d „d ejƒZdS) щN)кmock)кbitwise)к chirp_common)кerrors)кbasec@s\eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd d„Z dd„Z dd„Z dd„Z dS)к TestCaseEdgescCsH| Ё}d|_|j |jЁ|_|j |Ё|j |jЁ}| ||ЁdS)NСXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)кget_memкnameкradioк filter_nameк set_memoryк get_memoryкnumberкassertEqualMem)кselfкmкnЉrњH/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_edges.pyк test_longname s  zTestCaseEdges.test_longnamecCsˆ| Ё}d dd„ttdƒtdƒdƒDƒЁ}tdt|ƒdƒD]"}|j |||d…Ё|_|j |Ё|j  |j Ё}|  ||ЁqdS) NкcSsg|]}t|ƒ‘qSr)кchrЉк.0кxrrrк sz.TestCaseEdges.test_badname..њ к~щrщ) r кjoinкrangeкordкlenr r r r rrr)rrкasciiкirrrrк test_badnames& ќzTestCaseEdges.test_badnamec CsА| Ё}t|jjr |jjpdgƒ}|jjD]@\}}||t|dƒfD]1}z||_Wntj y9|  dЁYnw|j   |ЁrAq#|j   |Ё|j  |jЁ}| ||Ёq#qdS)Nщ iшzTest memory has immutable freq)r кminкrfкhas_tuning_stepкvalid_tuning_stepsк valid_bandsкintкfreqrкImmutableValueErrorкskipTestr кvalidate_memoryr rrr)rrкmin_stepкlowкhighr/rrrrкtest_bandedgess( џџ џ  ѕџzTestCaseEdges.test_bandedgesc Csмddgddgddgdœ}| Ё}|jjD]W\}}t| ЁƒD]L\}}||ks*||kr+q|D]<}t |Ё}||jjvr;q-z||_Wntj yO|  dЁYnw||_ |j   |Ё|j  |jЁ} |j|| d gd q-qqdS) Niњ–БidЏБiњ9“idR“iђ;l3i\Tl3)i@†Єi@)†i€a3zTest channel has immutable freqк tuning_stepЉкignore)r r*r-кlistкitemsrк required_stepr,r/r0r1r7r r rrr) rк odd_stepsrr4r5кbandкtotestкtestfreqкsteprrrrк test_oddsteps2s2§   џ є§џzTestCaseEdges.test_oddstepscCsz|jjd}|d}t|jjŽD]*}|j |Ё}|jr:d|_||_|j |Ё|j |Ё}|  ||jd|ЁdSqdS)NrFzORadio returned an unexpected frequency whensetting previously-empty location %i) r*r-r"к memory_boundsr rкemptyr/r к assertEqual)rк firstbandr@кlocrrrrкtest_empty_to_notMs"     џџјўzTestCaseEdges.test_empty_to_notcCsjt|jjŽD],}|j |Ё}d|jvrq|js2d|_|j |Ё|j |Ё}| |jd|ЁdSqdS)NrDTz@Radio returned non-empty memory when asked to delete location %i) r"r*rCr rк immutablerDr к assertTrue)rrGrrrrкtest_delete_memory\s     џџљћz TestCaseEdges.test_delete_memoryc Cs|jjs | dЁ|jj\}}|jjD]t}|j |Ё}|jr!d|_z|`Wn ty.Ynw|j dkrA|j dkrA|j d7_ n|j dkrO|jj dd|_ z|j  |ЁWn t j yaYqw|j |Ё}|j||dgd| ||jko}|knd ||jfЁqdS) NzRadio has no specialsFi€ЄПieЭiˆrr r8z/Special memory %s maps into memory bounds at %i)r*кvalid_special_chansr1rCr rrDкextraкAttributeErrorr/r-r rк RadioErrorrк assertFalser)rкloкhir кm1кm2rrrкtest_get_set_specialsks<     џ § џўцz#TestCaseEdges.test_get_set_specialscCsJ|jj\}}t||dƒD]}|j |Ё}| d|jd||jfЁq dS)Nrrz;Non-special memory %i should not have extd_number set to %r)r*rCr"r rrEк extd_number)rrQrRr&rrrrкtest_check_regular_not_specialŽs   џџўz,TestCaseEdges.test_check_regular_not_specialcCsN|jjdkr | dЁt|jjŽD]}|j |Ё}| |j  Ё|jdЁqdS)NzKG-UV8EzNThe UV8E driver is so broken it does not even parse its own test image cleanlyz.)rkrbrPкcalledкcall_args_list)rкmock_logrnrrкtest_bitwise_errorsПs џz%TestBitwiseStrict.test_bitwise_errors)r]r^r_rbreкpytestкmarkкxfailrкpatchкobjectrк ProcessorrprsкLOGrxк __classcell__rrrnrr`Ќs   џ  џ r`)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arryкunittestrкchirprrrкtestsrк DriverTestrr`rrrrкs"     #chirp-20240224/tests/__pycache__/test_banks.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000721314430373554024251 0ustar hibbyhibbyo уђ`dЉу@sHddlZddlmmZddlmZddlm Z Gdd„de j ƒZ dS)щN)к chirp_common)кbasec@sheZdZe dЁddd„ƒZe dЁdd„ƒZe dЁdd„ƒZe d Ёd d „ƒZe d Ёd d„ƒZ dS)к TestCaseBanksкhas_bank_namesкTcCsŽ|j Ё}| Ё}|D]}| | ЁtdЁ| |Ёq | ЁD]$}| | Ё  | Ё ЁЁd| Ё|fЁ|  | Ё| Ё  ЁdЁq dS)Nz#Bank model returned non-string namez-Bank name %r did not stick after set_name(%r)z$Bank stored with trailing whitespace) кradioкget_bank_modelк get_mappingsкassertIsInstanceкget_nameкstrкset_nameк assertTrueкlowerк startswithк assertEqualкrstrip)кselfкtestnameкbmкbanksкbankЉrњH/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_banks.pyкtest_bank_namess$  џ  џўџљzTestCaseBanks.test_bank_namescCsd}| |ЁdS)NzNot possibly this longЉr)rrrrrкtest_bank_names_toolongsz%TestCaseBanks.test_bank_names_toolongcCs| dЁdS)Nzfoo r)rrrrк&test_bank_names_no_trailing_whitespacesz4TestCaseBanks.test_bank_names_no_trailing_whitespaceкhas_bankcCsv|jjd}t Ё}||_|jjddd|_d|_|j  |Ёd|_|j  |Ё|j  Ё}z|j }Wn t y?d}Ynw|  |Ё}|rQ| dt|ƒdЁn | dt|ƒdЁ| Ё}| ||dЁ| |d|  |ЁdЁ| |dd „| |dЁDƒd Ё| ||dЁ|sЊ| |d|  |Ёd Ё| |d d „| |dЁDƒd Ё|sЙ| t |j||dЁdSdS)Nrщ †TFz1Freshly-created memory has no banks but it shouldz/Freshly-created memory has banks and should notz$Memory does not claim bank after addcSѓg|]}|j‘qSrЉкnumberЉк.0кxrrrк Iѓ џz1TestCaseBanks.test_bank_store..z$Bank does not claim memory after addzMemory claims bank after removecSr rr!r#rrrr&Qr'zBank claims memory after remove)кrfк memory_boundsrкMemoryr"к valid_bandsкfreqкemptyrк set_memoryrкchannelAlwaysHasBankк Exceptionкget_memory_mappingsкassertNotEqualкlenrr кadd_memory_to_mappingкassertInкget_mapping_memoriesкremove_memory_from_mappingк assertNotInк assertRaises)rкlocкmemкmodelr/к mem_banksrrrrкtest_bank_store#sb      џ  џ џџ  џўџ џџ§ џќzTestCaseBanks.test_bank_storeкhas_bank_indexc CsШ|jjd}t Ё}||_|jjddd|_|j |Ё|j  Ё}|  Ё}|  Ё}|  ||dЁt |ŽD]}| ||d|Ё| || ||dЁdЁq7| |dЁ}| |tt |ŽƒdЁdS)NrrzBank index not persistedz'Suggested bank index not in valid range)r(r)rr*r"r+r,rr.rr кget_index_boundsr4кrangeкset_memory_indexrкget_memory_indexкget_next_mapping_indexr5кlist)rr:r;r<rк index_boundsкiкsuggested_indexrrrкtest_bank_index]s$    џџzTestCaseBanks.test_bank_indexN)r) к__name__к __module__к __qualname__rкrequires_featurerrrr>rIrrrrrs    9r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкchirprкtestsrк DriverTestrrrrrкs& chirp-20240224/tests/__pycache__/test_drivers.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000241214450510600024610 0ustar hibbyhibbyo g‘Ђdу@stddlZddlmmZddlmZddlm Z dd„e d<Gdd„de ƒZ e  Ёe eƒƒZe edded dS) щN)к directory)к load_testscCs|SЉNЉ)кsrrњJ/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_drivers.pyкsrк_c@s,eZdZdZdd„Zdd„Zedd„ƒZdS) кTestSuiteAdapterzDAdapter for pytest since it doesn't support the loadTests() protocolcCs ||_dSr)кlocals)кselfr rrrк__init__ s zTestSuiteAdapter.__init__cCs||j|j<dSr)r к__name__)r кtest_clsrrrкloadTestsFromTestCase sz&TestSuiteAdapter.loadTestsFromTestCasecCsdSrr)кtestsrrrкaddTestsszTestSuiteAdapter.addTestsN)rк __module__к __qualname__к__doc__r rк staticmethodrrrrrr s r )кsuite)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкchirprrrк __builtins__кobjectr кimport_driversr кadapterrrrrкs&   chirp-20240224/tests/__pycache__/conftest.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000200614522135043023723 0ustar hibbyhibbyo КHeу@s6ddlZddlmmZddlZddlZdd„ZdS)щNcCs„tj tj tЁdЁ}t|ƒ}dd„| ЁDƒ}Wdƒn1s#wYd}|D]}|j|vr?tj j |d}|  |Ёq,dS)Nz xfails.txtcSsg|] }| dЁs| Ё‘qS)њ#)к startswithкstrip)к.0кxЉrњF/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/conftest.pyк sz1pytest_collection_modifyitems..zpTest marked for XFAIL in tests/xfails.txt, but did not fail. If this test is now fixed, remove it from the file.)кreason) кosкpathкjoinкdirnameк__file__кopenк readlinesкnodeidкpytestкmarkкxfailк add_marker)кconfigкitemsкxfailsкfкlinesкmsgкitemrrrrкpytest_collection_modifyitemss џ  €§r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arr rrrrrrкs" chirp-20240224/tests/__pycache__/icom_clone_simulator.cpython-310.pyc0000644000175000017500000001247414430373743024335 0ustar hibbyhibbyo уђ`d†у@spddlZddlmZddlZddlmZddlZe eЁZ e ЁZ ej e _ e   e ejЁЁGdd„deƒZdS)щNЉкbytes)кicfc@sreZdZddd„Zdd„Zdd„Zdd „Zd d „Zed d „ƒZ dd„Z dd„Z dd„Z dd„Z dd„Zdd„ZdS)к FakeIcomRadioNcCs8tdƒ|_||_|stdƒ| Ё|_dS| |ЁdS)Nѓѓ)rк_bufferк_radioк get_memsizeк_memoryкload_from_file)кselfкradioкmapfileЉrњR/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/icom_clone_simulator.pyк__init__"s zFakeIcomRadio.__init__cCsTt|dƒ}t| Ёƒ|_Wdƒn1swYt dt|jƒ|fЁdS)NкrbzInitialized %i bytes from %s)кopenrкreadr кLOGкdebugкlen)r кfilenameкfrrrr *s џ џzFakeIcomRadio.load_from_filecCs"|jd|…}|j|d…|_|S)z2read() from radio, so here we synthesize responsesNЉr)r кcountкchunkrrrr0szFakeIcomRadio.readcCs|j|7_dSЉNr)r кdatarrrкqueue6szFakeIcomRadio.queuecCs tdddd|gƒ|tdgƒS)Nщўщящющ§r)r кcmdкpayloadrrrк make_response:sќћћzFakeIcomRadio.make_responsecCs|j Ёdkr dSdS)NiкIкH)r r Љr rrrк address_fmtBszFakeIcomRadio.address_fmtcCs*t dЁd}td|j Ё|ƒD]v}t|j|d…ƒdkrnhtt  d|j ||Ёƒ}g}d}|D]}|  dd„td|ƒDƒЁ||7}q1|j|||…D]}|  d d„td|ƒDƒЁ||7}qO|d Ad d @}|  d d„td|ƒDƒЁ|  |  tjt|ƒЁЁq|  |  tjtgƒЁЁdS)NzClone from radio startedщrщњ>%sBcsѓ|]}|VqdSrrЉк.0кxrrrк Yѓ€z-FakeIcomRadio.do_clone_out..s%02Xcsr/rrr0rrrr3\r4iџџщщџcsr/rrr0rrrr3`r4)rrкranger r rr rкstructкpackr+кextendr r'rк CMD_CLONE_DATк CMD_CLONE_END)r кsizeкaddrкheaderrкcsкbyteкvxrrrк do_clone_outIs( џ  zFakeIcomRadio.do_clone_outcCst dЁtdƒ|_dS)NzClone to radio startedr)rrrr r*rrrк do_clone_inds zFakeIcomRadio.do_clone_incsќ|jdkrd}nd}dd„‰t‡‡fdd„tdtˆƒd ƒDƒƒ}t d |j|d|…Ё\}}||d …}t|ƒ|krFt d |t|ƒfЁt|jƒ}||krXt d ||fЁt|jƒ|krut d||fЁ|jtdƒ||7_|j|7_dS)Nr(щщcSs"tdt|dƒt|dƒfdƒS)Nz%s%srr5r,)кintкchr)кhexcharsrrrк hex_to_bytens"z0FakeIcomRadio.do_clone_data..hex_to_bytecs g|] }ˆˆ||d…ƒ‘qS)щr)r1кiЉrJк payload_hexrrк qsџz/FakeIcomRadio.do_clone_data..rrKr.щџџџџz+Invalid frame size: expected %i, but got %iz!Frame goes back to %04x from %04xz!Filling gap between %04x and %04xr) r+rr7rr8кunpackrrr )r rNк header_lenк payload_bytesr>r=rк expected_addrrrMrк do_clone_datahs4 џџ  џ џџzFakeIcomRadio.do_clone_datacCs| | tjtdgƒЁЁdS)Nr)r r'rк CMD_CLONE_OKrr*rrrк do_clone_endŠszFakeIcomRadio.do_clone_endcCsPt|tƒs Jd|jƒ‚| dЁr|dd…}| dЁs|d}|dd…}t d|Ёt d |Ё|j Ёtd ƒ}|d krN| |  d|ЁЁt|ƒS|t j kr[|  Ёt|ƒS|t j krh| Ёt|ƒS|t jkrv| |Ёt|ƒS|t jkrƒ| Ёt|ƒS|t jkr‘t d Ёt|ƒSt d |Ё| |  dtdgƒЁЁt|ƒS)z-write() to radio, so here we process requestszBytes required, %s receivedsўўўr5Nr-rErPzReceived command: %xz Full frame: %rsщрzGot hispeed kickerzUnknown command %ir)к isinstancerк __class__к startswithrrr к get_modelr r'rк CMD_CLONE_OUTrCк CMD_CLONE_INrDr;rUr<rWкCMD_CLONE_HISPEEDкinfor)r rr%r&кmodelrrrкwritesHџџ   џ  џ ђ є і  ј њ §zFakeIcomRadio.writecCsdSrrr*rrrкflushЕszFakeIcomRadio.flushr)к__name__к __module__к __qualname__rr rr r'кpropertyr+rCrDrUrWrbrcrrrrr!s  " (r)кsysкbuiltinsrr8к chirp.driversrкloggingк getLoggerrdrкlogкERRORкlevelк addHandlerк StreamHandlerкstdoutкobjectrrrrrкs   chirp-20240224/tests/__pycache__/base.cpython-310.pyc0000644000175000017500000001225414522657306021037 0ustar hibbyhibbyo Љ^Ket!у@s`ddlZddlZddlZddlZddlmZddlmZe eЁZ Gdd„dej ƒZ dd„Z dS)щN)к chirp_common)к bandplan_nacsReZdZdZdZdZ‡fdd„Zdd„Zdd„Zdd „Z d d „Z dd d „Z ‡Z S)к DriverTestNcsЎtƒ Ёg|_dtjvr*|jjs*| tj j d|j dЁ| tj j dt dƒdЁ| |j Ё|_|j Ё|_|jdurM|j Ё|j|_|j Ё|_dS|j|_|j|_dS)NкCHIRP_TEST_BITWISE_STRICT_BYTESz'chirp.bitwise.DataElement._compat_bytes)к side_effectz$chirp.bitwise.string_straight_encodez1string_straight_encode not allowed in strict mode)кsuperкsetUpкpatchesкosкenvironк RADIO_CLASSкNEEDS_COMPAT_SERIALк use_patchкunittestкmockкpatchк _strict_bytesкAssertionErrorк TEST_IMAGEкparentк get_featuresк parent_rfк SUB_DEVICEкget_sub_devicesкradioкrf)кselfЉк __class__ЉњB/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/base.pyrs,  џ ў џў   zDriverTest.setUpcCs|j |Ё| ЁdSЉN)r кappendкstartЉrrrrr r+s  zDriverTest.use_patchcCs|jD]}| ЁqdSr!)r кstopr$rrr кtearDown/s  џzDriverTest.tearDowncCs"|sJdƒ‚t|tƒsJdƒ‚|S)z3Enforce strict get_raw() behavior returning bytes()z#asbytes must be True in strict modezType should be bytes here)к isinstanceкbytes)rкbsкasbytesrrr r3s zDriverTest._strict_bytesc Csвz#|j dЁ}d|jvr|j |jЁ|_d|jvrd|_|jr"|WSWn ty,Ynwt Ё}d}|j j D]Њ\}}||_ |j j rcdd„|j j Dƒ}|t |ƒ}|||_|j t|jdƒ7_ n|j d |krq|j d 7_ |j d kr€d |j jvr€d |_nz |j jd|_Wn ty’Ynwt|j jŽd d …D]C}||_|j |Ё}t |Ё\} } | rд| sд|j |Ё|j |jЁ}z|`Wn tyЭYnw|S| sм|S|d7}qq7| dЁd S)z.Attempt to build a suitable memory for testingщкnameкduplexкrcSsg|]}|dkr|‘qS)r+rЉк.0кxrrr к Wsџz&DriverTest.get_mem..iшi@Bi€УЩкAMNщ zfNo mutable memory locations found - unable to run this test because I don't have a memory to test with)rк get_memoryк immutableк filter_namer,r-к ExceptionrкMemoryrк valid_bandsкfreqкvalid_tuning_stepsкlenк tuning_stepкintк valid_modesкmodeк IndexErrorкrangeк memory_boundsкnumberкvalidate_memoryкsplit_validation_msgsк set_memoryкextraкAttributeErrorкfail) rкmкattemptкband_loкband_hiкstepsк step_indexкiкmsgsкwarningsкerrorsrrr кget_mem9s`   џ џ   џ   џ   ыzDriverTest.get_memc Cs4|jdkr |j dЁ\}}i}i}t|j ЁƒD]й\}} |r#||vr#q|dkr(q|dkr-q|dkr2q|dkrD|jjs;q|j  | Ё  Ё} n‘|dkrM|jj sMq|dkrv|jd ksv|jd kr_|jj rv|jdkrh|d ksv|jdkru|d kru|jj rvq|d kr|jj rŒ|jd ks|jdkrŒ|d ksq|d krБ|jd krš|jj rБ|jdkrЃ|d ksБ|jdkrА|d krА|jj rБq|dkrУ|jj rТ|jdkrТ|d ksУq|dkrЫ|jsЫq|dkrе|jdkrеq|jtjvrр||jvsх||jvrцq| ||<|j|||<q| ||dЁ|jr|jr| dd„|jDƒdd„|jDƒdЁdSdSdS)NкCrossz->кpowerrIr6r,r>кrtoneкToneкTSQLкctoneкdtcsкDTCSкrx_dtcsкoffsetк cross_modez$Memories have unexpected differencescSѓg|]}| Ё‘qSrЉкget_namer/rrr r2Ыѓz-DriverTest.assertEqualMem..cSrbrrcr/rrr r2Ьrez&Memories have different mem.extra keys)кtmoderaкsplitкlistк__dict__кitemsrкhas_namerr7кrstripкhas_tuning_stepк has_ctoneк has_rx_dtcsr-r;rкALL_GMRS_FREQSr6к assertEqualrI) rкaкbкignoreкtx_modeкrx_modeкa_valsкb_valsкkкvrrr кassertEqualMem„sz   џ  џ  џўџzDriverTest.assertEqualMemr!) к__name__к __module__к __qualname__r rrrrr&rrVr{к __classcell__rrrr r s Krcs‡fdd„}|S)Ncst ˆЁ‡‡fdd„ƒ}|S)Ncs8t|jˆƒrˆ|g|ЂRi|ЄŽdS| dˆЁdS)NzFeature %s not supported)кgetattrrкskipTest)rrrry)кflagкfnrr кwrapsвs z.requires_feature..inner..wraps)к functoolsr„)rƒr„Љr‚)rƒr кinnerбszrequires_feature..innerr)r‚r‡rr†r кrequires_featureаs rˆ) r…кloggingr rкchirprrк getLoggerr|кLOGкTestCaserrˆrrrr кs    Echirp-20240224/tests/__pycache__/test_features.cpython-310-pytest-7.1.3.pyc0000644000175000017500000000205114430373554024764 0ustar hibbyhibbyo уђ`dху@sHddlZddlmmZddlmZddlm Z Gdd„de j ƒZ dS)щN)кmock)кbasec@seZdZdd„ZdS)кTestCaseFeaturescCsP| tjdddd„dЁ|j Ё}dD]}t||ƒ}|dur%| |tЁqdS)Nz builtins._TcSs|S)NЉ)кsrrњK/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_features.pyк sz/TestCaseFeatures.test_prompts..)кcreateк side_effect)кinfoк experimentalк pre_downloadк pre_upload)к use_patchrкpatchкradioк get_promptsкgetattrкassertIsInstanceкstr)кselfкpromptsкpкpromptrrrк test_promptss џ   €§zTestCaseFeatures.test_promptsN)к__name__к __module__к __qualname__rrrrrrs r) кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкunittestrкtestsrк DriverTestrrrrrкs& chirp-20240224/tests/__pycache__/test_brute_force.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001167714522135043025452 0ustar hibbyhibbyo КHeсу@sfddlZddlmmZddlZddlmZddlm Z ddl m Z e  e ЁZGdd„de jƒZdS)щN)к chirp_common)кerrors)кbasec@sveZdZdd„Zdd„Ze dЁdd„ƒZe dЁd d „ƒZe d Ёd d „ƒZ e dЁdd„ƒZ e dЁdd„ƒZ dS)кTestCaseBruteForcecKs‚|j |Ё}|r dS|j t |ЁЁ|j |jЁ}|jdkr5|jdvr5|j|j t |jdƒ|_ d|_|j ||fi|ЄŽdS)Nкsplit)њ-њ+к1) кradioкvalidate_memoryк set_memoryrк FrozenMemoryк get_memoryкnumberкduplexкfreqкoffsetкintкassertEqualMem)кselfкmкkwargsкmsgsкret_mЉrњN/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_brute_force.pyкset_and_compare s џz"TestCaseBruteForce.set_and_comparec CsЌ| Ё}tjD]L}|jjD]E}|tjvrq |dvrq ||_|dkr"n|dkr*||_n|dvr:|jjr6||_ n ||_n|  d|Ёz|  |ЁWq t j yRYq wqdS)N)кDTCSzDTCS-RкCrossккTone)кTSQLzTSQL-RzUnknown tone mode `%s')кget_memrкTONESкrfк valid_tmodesк TONE_MODESкtmodeкrtoneк has_ctoneкctoneкfailrrкUnsupportedToneError)rrкtoner'rrrк test_tones0   §ыџzTestCaseBruteForce.test_toneкhas_dtcscCsZ| Ё}d|_|jjD] }||_| |Ёq |jjsdS|jjD] }||_| |Ёq dS)Nr) r"r'r$кvalid_dtcs_codesкdtcsrкhas_dtcs_polarityкvalid_dtcs_polsк dtcs_polarity)rrкcodeкpolrrrк test_dtcs;s    ўzTestCaseBruteForce.test_dtcsк has_crosscCsH| Ё}d|_d|_d|_d|_d|_|jjD] }||_|  |ЁqdS)NrgY@gЭЬЬЬЬЬZ@iњi) r"r'r(r*r1кrx_dtcsr$кvalid_cross_modesк cross_moder)rrr;rrrк test_crossJs  ўzTestCaseBruteForce.test_crossкvalid_duplexescCsВ| Ё}d|jvr| dЁ|jjD]5}|dvrq|dkr1| |jjdЁ|jjddd|_n t   t |j ƒd Ё|_||_ |j|d gd q|jjrW| d|jjd ЁdSdS) Nrњ Test memory has immutable duplex)rrrrrzDRadio supports split but does not set can_odd_split=True in featuresrщi †щrЉкignorez:Radio claims can_odd_split but split not in valid_duplexes)r"к immutableкskipTestr$r=к assertTrueк can_odd_splitк valid_bandsrrкto_kHzrк tuning_steprrкassertIn)rrrrrrк test_duplexXs&    џ џџzTestCaseBruteForce.test_duplexк valid_skipscCs‚| Ё}|jj\}}ttd|ƒtd|ƒƒD])}|jjdD] }| Ё}d|jvr+d|_ ||_ ||_ |  |Ё|j  |j ЁqqdS)Nщщr@кemptyF)r"r$к memory_boundsкrangeкmaxкminrLкduperCrOrкskiprr к erase_memory)rкmemкloкhiкirUrrrrк test_skiprs   ї§zTestCaseBruteForce.test_skipк valid_modesc s8ˆ Ё}d|jvrˆ dЁ‡fdd„}‡fdd„}‡fdd„}d }ˆjjD]s}ˆ |tjd Ё| Ё}|d krdt ˆj tj ƒrdt  Ё}z||j ƒ||jƒ||jƒWntycˆjjr`‚ Ynw|d krv||jd ƒrv|jd 7_||_ˆj |Ёrt d|ˆj |ЁfЁq&ˆj|dgd|d7}q&dS)Nкmoder>cѓ"ˆj Ё}||d<ˆj |ЁdSЉNr)r кget_urcall_listкset_urcall_listЉкcallкlstЉrrrк ensure_urcallŒѓ z3TestCaseBruteForce.test_mode..ensure_urcallcr^r_)r кget_repeater_call_listкset_repeater_call_listrbrerrкensure_rptcall‘rgz4TestCaseBruteForce.test_mode..ensure_rptcallcs,ˆjjD]\}}||kr||krdSqdS)NTF)r$rG)rrXrYrerrк freq_is_ok–s €z0TestCaseBruteForce.test_mode..freq_is_okrzRadio exposes non-standard modeкDVкFMiсѕzFailed to validate %s: %srIrAr?)r"rCrDr$r\rJrкMODESrTк isinstancer кIcomDstarSupportкDVMemoryк dv_urcallк dv_rpt1callк dv_rpt2callк IndexErrorкrequires_call_listsrr]r кLOGкwarningr)rrrfrjrkк successesr]кtmprrerк test_mode†sL       џџџ   њ  џ мzTestCaseBruteForce.test_modeN) к__name__к __module__к __qualname__rr.rкrequires_featurer7r<rKr[r{rrrrr s    r)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкloggingкchirprrкtestsrк getLoggerr|rwк DriverTestrrrrrкs "    chirp-20240224/tests/__pycache__/test_clone.cpython-310-pytest-7.1.3.pyc0000644000175000017500000001104614430373554024252 0ustar hibbyhibbyo уђ`d( у@sИddlZddlmmZddlZddlZddlm Z ddl m Z ddl m Z ddl mZe eЁZGdd„dƒZGdd „d eƒZGd d „d eƒZGd d „d eƒZGdd„dejƒZdS)щN)кmock)к chirp_common)кerrors)кbasec@s<eZdZdd„Zdd„Zdd„Zdd„Zd d „Zd d „Zd S)к SerialNonecCѓdS)NѓЉЉкselfкsizer r њH/var/lib/jenkins/jobs/chirp-sdist-py3/workspace/repo/tests/test_clone.pyкread ѓzSerialNone.readcCst|tƒs tdƒ‚dS)NzRadio wrote non-bytes to serial)к isinstanceкbytesк TypeErrorЉr кdatar r r кwrites џzSerialNone.writecCѓdSЉNr )r кrater r r к setBaudraterzSerialNone.setBaudratecCrrr )r кtimeoutr r r к setTimeoutrzSerialNone.setTimeoutcCrrr )r кparityr r r к setParityrzSerialNone.setParitycCs|jj ddЁS)NкSerialк)к __class__к__name__кreplaceЉr r r r к__str__ѓzSerialNone.__str__N) r!к __module__к __qualname__rrrrrr$r r r r r s rc@seZdZdd„Zdd„ZdS)к SerialErrorcCѓtdƒ‚)NкFooЉк Exceptionr r r r r"ѓzSerialError.readcCr))NкBarr+rr r r r%r-zSerialError.writeN)r!r&r'rrr r r r r(!s r(c@ѓeZdZdd„ZdS)к SerialGarbagecCs*g}td|ƒD] }| |dЁqt|ƒS)Nrщ)кrangeкappendr)r r кbufкir r r r*szSerialGarbage.readNЉr!r&r'rr r r r r0)ѓ r0c@r/)кSerialShortGarbagecCs d|dS)Nѓщr r r r r r2s zSerialShortGarbage.readNr6r r r r r81r7r8csDeZdZ‡fdd„Zdd„Zdd„Zdd„Zd d „Zd d „Z‡Z S) к TestCaseClonecs€tƒ Ёt|jtjƒ|_t|jtjƒ|_|js |js |  dЁt j ‰‡fdd„}g|_ |  t  dЁЁ|  t jd|dЁdS)NzDoes not support clonecs ˆƒdS)Niшr r Љк real_timer r к fake_timeAs z&TestCaseClone.setUp..fake_timez time.sleepz time.time)к side_effect)кsuperкsetUprкradiorк LiveRadioкliveкCloneModeRadioкcloneкskipTestкtimeкpatchesк use_patchrкpatch)r r>Љr r<r rA7s      џzTestCaseClone.setUpcCsДt dЁ|jj}| |Ё|_||j_dd„|j_d}|jtj |d |j  ЁWdƒn1s3wYd}|jtj |d|j  ЁWdƒdS1sSwYdS)Nz:Initializing radio with fake serial; Radio should not failcSr)NTr )кsr r r кQsz1TestCaseClone._test_with_serial..zNClone should have failed and raised an exception that inherits from RadioError)кmsg) кLOGкinfoкparentк_mmapк RADIO_CLASSrBк status_fnк assertRaisesrк RadioErrorкsync_inкsync_out)r кserialк orig_mmaprOr r r к_test_with_serialIs    џ "џzTestCaseClone._test_with_serialcCѓ| tƒЁdSr)r\r(r#r r r кtest_clone_serial_error]r%z%TestCaseClone.test_clone_serial_errorcCr]r)r\rr#r r r кtest_clone_serial_none`r%z$TestCaseClone.test_clone_serial_nonecCr]r)r\r0r#r r r кtest_clone_serial_garbagecr%z'TestCaseClone.test_clone_serial_garbagecCr]r)r\r8r#r r r кtest_clone_serial_short_garbagefr%z-TestCaseClone.test_clone_serial_short_garbage) r!r&r'rAr\r^r_r`raк __classcell__r r rLr r;6s r;)кbuiltinsк @py_builtinsк_pytest.assertion.rewriteк assertionкrewriteк @pytest_arкloggingrHкunittestrкchirprrкtestsrк getLoggerr!rPrr(r0r8к DriverTestr;r r r r кs"     chirp-20240224/tests/conftest.py0000644000175000017500000000102014522135005015363 0ustar hibbyhibbyimport os import pytest def pytest_collection_modifyitems(config, items): xfails = os.path.join(os.path.dirname(__file__), 'xfails.txt') with open(xfails) as f: lines = [x.strip() for x in f.readlines() if not x.startswith('#')] msg = ('Test marked for XFAIL in tests/xfails.txt, but did not fail. ' 'If this test is now fixed, remove it from the file.') for item in items: if item.nodeid in lines: mark = pytest.mark.xfail(reason=msg) item.add_marker(mark) chirp-20240224/tests/__init__.py0000644000175000017500000000717714522657251015334 0ustar hibbyhibbyimport glob import logging import os import unittest import pytest from chirp import directory from tests import test_banks from tests import test_brute_force from tests import test_clone from tests import test_copy_all from tests import test_detect from tests import test_edges from tests import test_features from tests import test_settings LOG = logging.getLogger('testadapter') class TestAdapterMeta(type): def __new__(cls, name, parents, dct): return super(TestAdapterMeta, cls).__new__(cls, name, parents, dct) def _get_sub_devices(rclass, testimage): try: radio = rclass(None) rf = radio.get_features() except Exception as e: print('Failed to get features for %s: %s' % (rclass, e)) # FIXME: If the driver fails to run get_features with no memobj # we should not arrest the test load. This appears to happen for # the Puxing777 for some reason, and not all the time. Figure that # out, but until then, assume crash means "no sub devices". return [rclass] if rf.has_sub_devices: # Radios with sub-devices may need to look at the image to determine # what those are. That's slow, so only do it for these. radio = rclass(testimage) return radio.get_sub_devices() else: return [rclass] def _load_tests(loader, tests, pattern, suite=None): if not suite: suite = unittest.TestSuite() if 'CHIRP_TESTIMG' in os.environ: images = os.environ['CHIRP_TESTIMG'].split() else: images = glob.glob("tests/images/*.img") tests = [os.path.splitext(os.path.basename(img))[0] for img in images] base = os.path.dirname(os.path.abspath(__file__)) base = os.path.join(base, 'images') images = glob.glob(os.path.join(base, "*")) tests = {img: os.path.splitext(os.path.basename(img))[0] for img in images} if pattern == 'test*.py': # This default is meaningless for us pattern = None driver_test_cases = (test_edges.TestCaseEdges, test_edges.TestBitwiseStrict, test_brute_force.TestCaseBruteForce, test_banks.TestCaseBanks, test_detect.TestCaseDetect, test_clone.TestCaseClone, test_settings.TestCaseSettings, test_features.TestCaseFeatures, test_copy_all.TestCaseCopyAll) for image, test in tests.items(): rclass = directory.get_radio(test) if hasattr(rclass, '_orig_rclass'): rclass = rclass._orig_rclass module = rclass.__module__.split('.')[-1] subdevs = _get_sub_devices(rclass, image) has_subdevs = subdevs != [rclass] for index, device in enumerate(subdevs): if not isinstance(device, type): device = device.__class__ for case in driver_test_cases: tc = TestAdapterMeta( "%s_%s" % (case.__name__, directory.radio_class_id(device)), (case,), {'RADIO_CLASS': rclass, 'SUB_DEVICE': index if has_subdevs else None, 'TEST_IMAGE': image}) tc = getattr(pytest.mark, module)(tc) suite.addTests(loader.loadTestsFromTestCase(tc)) return suite def load_tests(loader, tests, pattern, suite=None): try: return _load_tests(loader, tests, pattern, suite=suite) except Exception as e: import traceback print('Failed to load: %s' % e) print(traceback.format_exc()) raise chirp-20240224/tests/test_copy_all.py0000644000175000017500000000353014430171343016412 0ustar hibbyhibbyimport os from chirp.drivers import generic_csv from chirp import import_logic from tests import base class TestCaseCopyAll(base.DriverTest): "Copy Memories From CSV" def setUp(self): super().setUp() csvfile = os.path.join(os.path.dirname(self.TEST_IMAGE), 'Generic_CSV.csv') self.src_radio = generic_csv.CSVRadio(csvfile) def test_copy(self): src_rf = self.src_radio.get_features() bounds = src_rf.memory_bounds for dst_number in range(self.rf.memory_bounds[0], min(self.rf.memory_bounds[0] + 10, self.rf.memory_bounds[1])): cur_mem = self.radio.get_memory(dst_number) if not cur_mem.empty and 'freq' in cur_mem.immutable: # Keep looking continue else: break else: self.skipTest('No channels with mutable freq found to use') for number in range(bounds[0], bounds[1]): src_mem = self.src_radio.get_memory(number) if src_mem.empty: continue try: dst_mem = import_logic.import_mem(self.radio, src_rf, src_mem, overrides={ "number": dst_number}) import_logic.import_bank(self.radio, self.src_radio, dst_mem, src_mem) except import_logic.DestNotCompatible: continue self.radio.set_memory(dst_mem) ret_mem = self.radio.get_memory(dst_number) self.assertEqualMem(dst_mem, ret_mem) chirp-20240224/tests/test_settings.py0000644000175000017500000000436614522135005016455 0ustar hibbyhibbyfrom chirp import chirp_common from chirp import settings from tests import base class TestCaseSettings(base.DriverTest): def test_has_settings(self): return settings = self.radio.get_settings() if settings: self.assertFalse(self.rf.has_settings, 'Radio returned settings but has_settings=False') else: self.assertTrue(self.rf.has_settings, 'Radio returned no settings but has_settings=True') @base.requires_feature('has_settings') def test_get_settings(self): lst = self.radio.get_settings() self.assertIsInstance(lst, list) @base.requires_feature('has_settings') def test_same_settings(self): o = self.radio.get_settings() self.radio.set_settings(o) n = self.radio.get_settings() list(map(self.compare_settings, o, n)) def compare_settings(self, a, b): try: if isinstance(a, settings.RadioSettingValue): raise StopIteration list(map(self.compare_settings, a, b)) except StopIteration: self.assertEqual(a.get_value(), b.get_value(), 'Setting value changed from %r to %r' % ( a.get_value(), b.get_value())) def test_memory_extra_frozen(self): # Find the first non-empty memory and try to set it back as a # FrozenMemory to make sure the driver does not try to modify # any of the settings. for i in range(*self.rf.memory_bounds): m = self.radio.get_memory(i) if not m.empty: self.radio.set_memory(chirp_common.FrozenMemory(m)) break def test_memory_extra_flat(self): for i in range(*self.rf.memory_bounds): m = self.radio.get_memory(i) if not m.empty: self.assertIsInstance( m.extra, (list, settings.RadioSettingGroup), 'mem.extra must be a list or RadioSettingGroup') for e in m.extra: self.assertIsInstance( e, settings.RadioSetting, 'mem.extra items must be RadioSetting objects') chirp-20240224/tests/test_brute_force.py0000644000175000017500000001571614566340166017133 0ustar hibbyhibbyimport logging from chirp import chirp_common from chirp import errors from tests import base LOG = logging.getLogger(__name__) class TestCaseBruteForce(base.DriverTest): def set_and_compare(self, m, **kwargs): msgs = self.radio.validate_memory(m) if msgs: # If the radio correctly refuses memories it can't # store, don't fail return self.radio.set_memory(chirp_common.FrozenMemory(m)) ret_m = self.radio.get_memory(m.number) # Damned Baofeng radios don't seem to properly store # shift and direction, so be gracious here if m.duplex == "split" and ret_m.duplex in ["-", "+"]: ret_m.offset = ret_m.freq + \ (ret_m.offset * int(ret_m.duplex + "1")) ret_m.duplex = "split" self.assertEqualMem(m, ret_m, **kwargs) def test_tone(self): m = self.get_mem() for tone in chirp_common.TONES: for tmode in self.rf.valid_tmodes: if tmode not in chirp_common.TONE_MODES: continue elif tmode in ["DTCS", "DTCS-R", "Cross"]: continue # We'll test DCS and Cross tones separately m.tmode = tmode if tmode == "": pass elif tmode == "Tone": m.rtone = tone elif tmode in ["TSQL", "TSQL-R"]: if self.rf.has_ctone: m.ctone = tone else: m.rtone = tone else: self.fail("Unknown tone mode `%s'" % tmode) try: self.set_and_compare(m) except errors.UnsupportedToneError: # If a radio doesn't support a particular tone value, # don't punish it pass @base.requires_feature('has_dtcs') def test_dtcs(self): m = self.get_mem() m.tmode = "DTCS" for code in self.rf.valid_dtcs_codes: m.dtcs = code self.set_and_compare(m) if not self.rf.has_dtcs_polarity: return for pol in self.rf.valid_dtcs_pols: m.dtcs_polarity = pol self.set_and_compare(m) @base.requires_feature('has_cross') def test_cross(self): m = self.get_mem() m.tmode = "Cross" # No fair asking a radio to detect two identical tones as Cross instead # of TSQL m.rtone = 100.0 m.ctone = 107.2 m.dtcs = 506 m.rx_dtcs = 516 for cross_mode in self.rf.valid_cross_modes: m.cross_mode = cross_mode self.set_and_compare(m) @base.requires_feature('valid_duplexes') def test_duplex(self): m = self.get_mem() if 'duplex' in m.immutable: self.skipTest('Test memory has immutable duplex') for duplex in self.rf.valid_duplexes: assert duplex in ["", "-", "+", "split", "off"] if duplex == 'split': self.assertTrue(self.rf.can_odd_split, 'Radio supports split but does not set ' 'can_odd_split=True in features') m.offset = self.rf.valid_bands[0][1] - 100000 else: m.offset = chirp_common.to_kHz(int(m.tuning_step) * 2) m.duplex = duplex # Ignore the offset because we do some fudging on this and we # don't necessarily know the best step to use. What we care about # is duplex here. self.set_and_compare(m, ignore=['offset']) if self.rf.can_odd_split: self.assertIn('split', self.rf.valid_duplexes, 'Radio claims can_odd_split but split not in ' 'valid_duplexes') @base.requires_feature('valid_skips') def test_skip(self): mem = self.get_mem() lo, hi = self.rf.memory_bounds # Walk through several memories, specifically across 8 and 16, # as many radio use bitfields for skip flags. for i in range(max(5, lo), min(25, hi)): # Walk through the skip flags twice each, to make sure we can # toggle them on..off..on for skip in self.rf.valid_skips * 2: m = mem.dupe() if 'empty' not in m.immutable: m.empty = False m.number = i m.skip = skip self.set_and_compare(m) # Delete the memory each time because some radios are # dynamically allocated and will run out of space here. self.radio.erase_memory(m.number) @base.requires_feature('valid_modes') def test_mode(self): m = self.get_mem() if 'mode' in m.immutable: self.skipTest('Test memory has immutable duplex') def ensure_urcall(call): lst = self.radio.get_urcall_list() lst[0] = call self.radio.set_urcall_list(lst) def ensure_rptcall(call): lst = self.radio.get_repeater_call_list() lst[0] = call self.radio.set_repeater_call_list(lst) def freq_is_ok(freq): for lo, hi in self.rf.valid_bands: if freq > lo and freq < hi: return True return False successes = 0 for mode in self.rf.valid_modes: self.assertIn(mode, chirp_common.MODES, 'Radio exposes non-standard mode') tmp = m.dupe() if mode == "DV" and \ isinstance(self.radio, chirp_common.IcomDstarSupport): tmp = chirp_common.DVMemory() try: ensure_urcall(tmp.dv_urcall) ensure_rptcall(tmp.dv_rpt1call) ensure_rptcall(tmp.dv_rpt2call) except IndexError: if self.rf.requires_call_lists: raise else: # This radio may not do call lists at all, # so let it slide pass if mode == "FM" and freq_is_ok(tmp.freq + 100000000): # Some radios don't support FM below approximately 30MHz, # so jump up by 100MHz, if they support that tmp.freq += 100000000 tmp.mode = mode if self.rf.validate_memory(tmp): # A result (of error messages) from validate means the radio # thinks this is invalid, so don't fail the test LOG.warning('Failed to validate %s: %s' % ( tmp, self.rf.validate_memory(tmp))) continue # Ignore tuning_step because changing modes may cause step changes # in some radios self.set_and_compare(tmp, ignore=['tuning_step']) successes += 1 chirp-20240224/tests/test_detect.py0000644000175000017500000000373614556146076016106 0ustar hibbyhibbyimport logging import sys from unittest import mock import pytest from chirp import directory from chirp import logger from tests import base class TestCaseDetect(base.DriverTest): def test_detect(self): with logger.log_history(logging.WARNING, 'chirp.drivers') as history: radio = directory.get_radio_by_image(self.TEST_IMAGE) self.assertEqual([], history.get_history(), 'Drivers should not log warnings/errors for ' 'good images') if hasattr(radio, '_orig_rclass'): radio = radio._orig_rclass(self.TEST_IMAGE) if isinstance(self.radio, radio.__class__): # If we are a sub-device of the detected class then that's fine. # There's no good way for us to know that other than checking, so # the below assertion is just for show. self.assertIsInstance(self.radio, radio.__class__) else: self.assertIsInstance(radio, self.RADIO_CLASS, "Image %s detected as %s but expected %s" % ( self.TEST_IMAGE, radio.__class__, self.RADIO_CLASS)) @pytest.mark.skipif(sys.version_info < (3, 10), reason="requires python3.10 or higher") @mock.patch('builtins.print') def test_match_model_is_quiet_no_match(self, mock_print): with self.assertNoLogs(level=logging.DEBUG): self.radio.match_model(b'', 'foo.img') mock_print.assert_not_called() @pytest.mark.skipif(sys.version_info < (3, 10), reason="requires python3.10 or higher") @mock.patch('builtins.print') def test_match_model_is_quiet_with_match(self, mock_print): with self.assertNoLogs(level=logging.DEBUG): with open(self.TEST_IMAGE, 'rb') as f: self.radio.match_model(f.read(), self.TEST_IMAGE) mock_print.assert_not_called() chirp-20240224/MANIFEST.in0000644000175000017500000000044314430171343013573 0ustar hibbyhibbyinclude chirp/share/*.desktop include chirp/share/*.png include chirp/share/*.svg include chirp/share/*.ico include chirp/share/*.1 include chirp/stock_configs/* include chirp/locale/*/LC_MESSAGES/*.mo exclude chirp/locale/* include COPYING include *requirements.txt graft tests graft tools chirp-20240224/test-requirements.txt0000644000175000017500000000025014411666130016274 0ustar hibbyhibby# https://github.com/pytest-dev/pytest/issues/10428 pytest==7.1.3 pytest-xdist pytest-html six pep8 pyserial future requests pyyaml pywin32; platform_system=="Windows" chirp-20240224/COPYING0000644000175000017500000010451314411666130013075 0ustar hibbyhibby GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . chirp-20240224/PKG-INFO0000644000175000017500000000062114566340177013145 0ustar hibbyhibbyMetadata-Version: 2.1 Name: chirp Version: 20240224 Summary: A cross-platform cross-radio programming tool Home-page: https://chirp.danplanet.com Requires-Python: >=3.7,<4 License-File: COPYING Requires-Dist: pyserial Requires-Dist: requests Requires-Dist: six Requires-Dist: importlib-resources; python_version < "3.10" Requires-Dist: yattag Provides-Extra: wx Requires-Dist: wxPython; extra == "wx" chirp-20240224/chirp.egg-info/0000755000175000017500000000000014566340177014650 5ustar hibbyhibbychirp-20240224/chirp.egg-info/top_level.txt0000644000175000017500000000000614566340176017375 0ustar hibbyhibbychirp chirp-20240224/chirp.egg-info/PKG-INFO0000644000175000017500000000062114566340176015743 0ustar hibbyhibbyMetadata-Version: 2.1 Name: chirp Version: 20240224 Summary: A cross-platform cross-radio programming tool Home-page: https://chirp.danplanet.com Requires-Python: >=3.7,<4 License-File: COPYING Requires-Dist: pyserial Requires-Dist: requests Requires-Dist: six Requires-Dist: importlib-resources; python_version < "3.10" Requires-Dist: yattag Provides-Extra: wx Requires-Dist: wxPython; extra == "wx" chirp-20240224/chirp.egg-info/requires.txt0000644000175000017500000000013414566340176017245 0ustar hibbyhibbypyserial requests six yattag [:python_version < "3.10"] importlib-resources [wx] wxPython chirp-20240224/chirp.egg-info/dependency_links.txt0000644000175000017500000000000114566340176020715 0ustar hibbyhibby chirp-20240224/chirp.egg-info/entry_points.txt0000644000175000017500000000011414566340176020141 0ustar hibbyhibby[console_scripts] chirp = chirp.wxui:chirpmain chirpc = chirp.cli.main:main chirp-20240224/chirp.egg-info/SOURCES.txt0000644000175000017500000004653114566340177016545 0ustar hibbyhibbyCOPYING MANIFEST.in README.md requirements.txt setup.cfg setup.py test-requirements.txt chirp/__init__.py chirp/bandplan.py chirp/bandplan_au.py chirp/bandplan_iaru_r1.py chirp/bandplan_iaru_r2.py chirp/bandplan_iaru_r3.py chirp/bandplan_na.py chirp/bitwise.py chirp/bitwise_grammar.py chirp/chirp_common.py chirp/detect.py chirp/directory.py chirp/errors.py chirp/import_logic.py chirp/logger.py chirp/memmap.py chirp/platform.py chirp/pyPEG.py chirp/settings.py chirp/util.py chirp.egg-info/PKG-INFO chirp.egg-info/SOURCES.txt chirp.egg-info/dependency_links.txt chirp.egg-info/entry_points.txt chirp.egg-info/requires.txt chirp.egg-info/top_level.txt chirp/cli/__init__.py chirp/cli/main.py chirp/drivers/__init__.py chirp/drivers/alinco.py chirp/drivers/anytone.py chirp/drivers/anytone778uv.py chirp/drivers/anytone_ht.py chirp/drivers/anytone_iii.py chirp/drivers/ap510.py chirp/drivers/baofeng_common.py chirp/drivers/baofeng_uv17.py chirp/drivers/baofeng_uv17Pro.py chirp/drivers/baofeng_uv3r.py chirp/drivers/baofeng_wp970i.py chirp/drivers/bf_t1.py chirp/drivers/bf_t8.py chirp/drivers/bj9900.py chirp/drivers/bjuv55.py chirp/drivers/boblov_x3plus.py chirp/drivers/btech.py chirp/drivers/fake.py chirp/drivers/fd268.py chirp/drivers/ft1500m.py chirp/drivers/ft1802.py chirp/drivers/ft1d.py chirp/drivers/ft2800.py chirp/drivers/ft2900.py chirp/drivers/ft2d.py chirp/drivers/ft4.py chirp/drivers/ft450d.py chirp/drivers/ft50.py chirp/drivers/ft60.py chirp/drivers/ft70.py chirp/drivers/ft7100.py chirp/drivers/ft7800.py chirp/drivers/ft8100.py chirp/drivers/ft817.py chirp/drivers/ft818.py chirp/drivers/ft857.py chirp/drivers/ft90.py chirp/drivers/ftlx011.py chirp/drivers/ftm3200d.py chirp/drivers/ftm350.py chirp/drivers/ftm7250d.py chirp/drivers/ga510.py chirp/drivers/generic_csv.py chirp/drivers/generic_tpe.py chirp/drivers/gmrsuv1.py chirp/drivers/gmrsv2.py chirp/drivers/h777.py chirp/drivers/hf90.py chirp/drivers/hg_uv98.py chirp/drivers/hobbypcb.py chirp/drivers/ic208.py chirp/drivers/ic2100.py chirp/drivers/ic2200.py chirp/drivers/ic2300.py chirp/drivers/ic2720.py chirp/drivers/ic2730.py chirp/drivers/ic2820.py chirp/drivers/ic9x.py chirp/drivers/ic9x_icf.py chirp/drivers/ic9x_icf_ll.py chirp/drivers/ic9x_ll.py chirp/drivers/icf.py chirp/drivers/icomciv.py chirp/drivers/icp7.py chirp/drivers/icq7.py chirp/drivers/ict70.py chirp/drivers/ict7h.py chirp/drivers/ict8.py chirp/drivers/icv80.py chirp/drivers/icv86.py chirp/drivers/icw32.py chirp/drivers/icx8x.py chirp/drivers/icx90.py chirp/drivers/id31.py chirp/drivers/id51.py chirp/drivers/id5100.py chirp/drivers/id51plus.py chirp/drivers/id800.py chirp/drivers/id880.py chirp/drivers/idrp.py chirp/drivers/iradio_uv_5118.py chirp/drivers/iradio_uv_5118plus.py chirp/drivers/kenwood_d7.py chirp/drivers/kenwood_hmk.py chirp/drivers/kenwood_itm.py chirp/drivers/kenwood_live.py chirp/drivers/kg935g.py chirp/drivers/kguv8d.py chirp/drivers/kguv8dplus.py chirp/drivers/kguv8e.py chirp/drivers/kguv920pa.py chirp/drivers/kguv980p.py chirp/drivers/kguv9dplus.py chirp/drivers/kyd.py chirp/drivers/kyd_IP620.py chirp/drivers/leixen.py chirp/drivers/lt725uv.py chirp/drivers/mml_jc8810.py chirp/drivers/mursv1.py chirp/drivers/puxing.py chirp/drivers/puxing_px888k.py chirp/drivers/radioddity_r2.py chirp/drivers/radtel_rt490.py chirp/drivers/radtel_t18.py chirp/drivers/retevis_rb15.py chirp/drivers/retevis_rb17p.py chirp/drivers/retevis_rb28.py chirp/drivers/retevis_rt1.py chirp/drivers/retevis_rt21.py chirp/drivers/retevis_rt22.py chirp/drivers/retevis_rt23.py chirp/drivers/retevis_rt26.py chirp/drivers/retevis_rt76p.py chirp/drivers/retevis_rt87.py chirp/drivers/retevis_rt98.py chirp/drivers/rh5r_v2.py chirp/drivers/tdh8.py chirp/drivers/tdxone_tdq8a.py chirp/drivers/template.py chirp/drivers/tg_uv2p.py chirp/drivers/th350.py chirp/drivers/th7800.py chirp/drivers/th9000.py chirp/drivers/th9800.py chirp/drivers/th_uv3r.py chirp/drivers/th_uv3r25.py chirp/drivers/th_uv8000.py chirp/drivers/th_uv88.py chirp/drivers/th_uvf8d.py chirp/drivers/thd72.py chirp/drivers/thd74.py chirp/drivers/thuv1f.py chirp/drivers/tk270.py chirp/drivers/tk3140.py chirp/drivers/tk760.py chirp/drivers/tk760g.py chirp/drivers/tk8102.py chirp/drivers/tk8160.py chirp/drivers/tk8180.py chirp/drivers/tmd710.py chirp/drivers/tmv71.py chirp/drivers/tmv71_ll.py chirp/drivers/ts2000.py chirp/drivers/ts480.py chirp/drivers/ts590.py chirp/drivers/ts850.py chirp/drivers/uv5r.py chirp/drivers/uv5x3.py chirp/drivers/uv6r.py chirp/drivers/uvb5.py chirp/drivers/uvk5.py chirp/drivers/uvk5_egzumer.py chirp/drivers/vgc.py chirp/drivers/vx170.py chirp/drivers/vx2.py chirp/drivers/vx3.py chirp/drivers/vx5.py chirp/drivers/vx510.py chirp/drivers/vx6.py chirp/drivers/vx7.py chirp/drivers/vx8.py chirp/drivers/vxa700.py chirp/drivers/wouxun.py chirp/drivers/wouxun_common.py chirp/drivers/yaesu_clone.py chirp/locale/de/LC_MESSAGES/CHIRP.mo chirp/locale/el/LC_MESSAGES/CHIRP.mo chirp/locale/en_US/LC_MESSAGES/CHIRP.mo chirp/locale/es/LC_MESSAGES/CHIRP.mo chirp/locale/fr/LC_MESSAGES/CHIRP.mo chirp/locale/hu/LC_MESSAGES/CHIRP.mo chirp/locale/it/LC_MESSAGES/CHIRP.mo chirp/locale/ja_JP/LC_MESSAGES/CHIRP.mo chirp/locale/nl/LC_MESSAGES/CHIRP.mo chirp/locale/pl/LC_MESSAGES/CHIRP.mo chirp/locale/pt_BR/LC_MESSAGES/CHIRP.mo chirp/locale/ru/LC_MESSAGES/CHIRP.mo chirp/locale/tr_TR/LC_MESSAGES/CHIRP.mo chirp/locale/uk_UA/LC_MESSAGES/CHIRP.mo chirp/locale/zh_CN/LC_MESSAGES/CHIRP.mo chirp/share/chirp-logo.png chirp/share/chirp.desktop chirp/share/chirp.ico chirp/share/chirp.png chirp/share/chirp.svg chirp/share/chirpw.1 chirp/share/plus-icon.png chirp/share/welcome_screen.png chirp/sources/__init__.py chirp/sources/base.py chirp/sources/dmrmarc.py chirp/sources/przemienniki.py chirp/sources/radioreference.py chirp/sources/repeaterbook.py chirp/stock_configs/AU NZ UHF Citizens Band.csv chirp/stock_configs/DE Freenet Frequencies.csv chirp/stock_configs/EU LPD and PMR Channels.csv chirp/stock_configs/FR Marine VHF Channels.csv chirp/stock_configs/GR Marine VHF Channels.csv chirp/stock_configs/PL Calling Frequencies and Simplex.csv chirp/stock_configs/SE Jaktradio 155MHz.csv chirp/stock_configs/SE NO KDR444.csv chirp/stock_configs/UK Business Radio Simple Light Frequencies.csv chirp/stock_configs/US 60 meter channels (Center).csv chirp/stock_configs/US 60 meter channels (Dial).csv chirp/stock_configs/US CA Railroad Channels.csv chirp/stock_configs/US Calling Frequencies.csv chirp/stock_configs/US FRS and GMRS Channels.csv chirp/stock_configs/US MURS Channels.csv chirp/stock_configs/US Marine VHF Channels.csv chirp/stock_configs/US NOAA Weather Alert.csv chirp/wxui/__init__.py chirp/wxui/__main__.py chirp/wxui/bankedit.py chirp/wxui/clone.py chirp/wxui/common.py chirp/wxui/config.py chirp/wxui/developer.py chirp/wxui/fips.py chirp/wxui/main.py chirp/wxui/memedit.py chirp/wxui/printing.py chirp/wxui/query_sources.py chirp/wxui/radioinfo.py chirp/wxui/radiothread.py chirp/wxui/report.py chirp/wxui/settingsedit.py tests/Python3_Driver_Testing.md tests/__init__.py tests/base.py tests/conftest.py tests/icom_clone_simulator.py tests/model_stats.tsv tests/py3_driver_testers.txt tests/test_banks.py tests/test_brute_force.py tests/test_clone.py tests/test_copy_all.py tests/test_detect.py tests/test_drivers.py tests/test_edges.py tests/test_features.py tests/test_settings.py tests/xfails.txt tests/__pycache__/__init__.cpython-310.pyc tests/__pycache__/base.cpython-310.pyc tests/__pycache__/conftest.cpython-310-pytest-7.1.3.pyc tests/__pycache__/icom_clone_simulator.cpython-310.pyc tests/__pycache__/test_banks.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_brute_force.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_clone.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_copy_all.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_detect.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_drivers.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_edges.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_features.cpython-310-pytest-7.1.3.pyc tests/__pycache__/test_settings.cpython-310-pytest-7.1.3.pyc tests/images/Abbree_AR-518.img tests/images/Abbree_AR-63.img tests/images/Abbree_AR-730.img tests/images/Abbree_AR-F5.img tests/images/Alinco_DJ-G7EG.img tests/images/Alinco_DJ175.img tests/images/Alinco_DJ596.img tests/images/Alinco_DR235T.img tests/images/AnyTone_5888UV.img tests/images/AnyTone_5888UVIII.img tests/images/AnyTone_778UV.img tests/images/AnyTone_OBLTR-8R.img tests/images/AnyTone_TERMN-8R.img tests/images/Anysecu_UV-A37.img tests/images/Anysecu_WP-9900.img tests/images/BTECH_FRS-A1.img tests/images/BTECH_FRS-B1.img tests/images/BTECH_GMRS-20V2.img tests/images/BTECH_GMRS-50V2.img tests/images/BTECH_GMRS-50X1.img tests/images/BTECH_GMRS-V1.img tests/images/BTECH_GMRS-V2.img tests/images/BTECH_MURS-V1.img tests/images/BTECH_MURS-V2.img tests/images/BTECH_UV-2501+220.img tests/images/BTECH_UV-25X2.img tests/images/BTECH_UV-25X2_G2.img tests/images/BTECH_UV-25X4.img tests/images/BTECH_UV-25X4_G2.img tests/images/BTECH_UV-5001.img tests/images/BTECH_UV-50X2.img tests/images/BTECH_UV-50X2_G2.img tests/images/BTECH_UV-50X3.img tests/images/BTECH_UV-5X3.img tests/images/Baofeng_5RM.img tests/images/Baofeng_5RX.img tests/images/Baofeng_BF-1904.img tests/images/Baofeng_BF-888.img tests/images/Baofeng_BF-A58S.img tests/images/Baofeng_BF-T1.img tests/images/Baofeng_BF-T20.img tests/images/Baofeng_BF-T20FRS.img tests/images/Baofeng_BF-T8.img tests/images/Baofeng_F-11.img tests/images/Baofeng_UV-13Pro.img tests/images/Baofeng_UV-17.img tests/images/Baofeng_UV-17Pro.img tests/images/Baofeng_UV-17ProGPS.img tests/images/Baofeng_UV-3R.img tests/images/Baofeng_UV-5R.img tests/images/Baofeng_UV-6R.img tests/images/Baofeng_UV-9G.img tests/images/Baofeng_UV-B5.img tests/images/Baofeng_UV-S9X3.img tests/images/Baofeng_W31E.img tests/images/Baojie_BJ-9900.img tests/images/Boblov_X3Plus.img tests/images/CRT_Micron_UV.img tests/images/Explorer_QRZ-1.img tests/images/Feidaxin_FD-268A.img tests/images/Feidaxin_FD-268B.img tests/images/Feidaxin_FD-288B.img tests/images/Generic_CSV.csv tests/images/Hiroyasu_HI-8811.img tests/images/Icom_IC-208H.img tests/images/Icom_IC-2100H.img tests/images/Icom_IC-2200H.img tests/images/Icom_IC-2300H.img tests/images/Icom_IC-2720H.img tests/images/Icom_IC-2730A.img tests/images/Icom_IC-2820H.img tests/images/Icom_IC-E90.img tests/images/Icom_IC-P7.img tests/images/Icom_IC-Q7A.img tests/images/Icom_IC-T70.img tests/images/Icom_IC-T7H.img tests/images/Icom_IC-T8A.img tests/images/Icom_IC-U82.img tests/images/Icom_IC-V80.img tests/images/Icom_IC-V82.img tests/images/Icom_IC-V86.img tests/images/Icom_IC-W32A.img tests/images/Icom_IC-W32E.img tests/images/Icom_ID-31A.img tests/images/Icom_ID-4100.img tests/images/Icom_ID-51.img tests/images/Icom_ID-5100.img tests/images/Icom_ID-51_Plus.img tests/images/Icom_ID-51_Plus2.img tests/images/Icom_ID-800H_v2.img tests/images/Icom_ID-80H.img tests/images/Icom_ID-880H.img tests/images/Jetstream_JT220M.img tests/images/Jetstream_JT270M.img tests/images/Jetstream_JT270MH.img tests/images/KYD_IP-620.img tests/images/KYD_NC-630A.img tests/images/Kenwood_HMK.hmk tests/images/Kenwood_TH-D72_clone_mode.img tests/images/Kenwood_TH-D74_clone_mode.img tests/images/Kenwood_TH-D75.img tests/images/Kenwood_TK-272G.img tests/images/Kenwood_TK-3140K.img tests/images/Kenwood_TK-3180K2.img tests/images/Kenwood_TK-7160K.img tests/images/Kenwood_TK-760G.img tests/images/Kenwood_TK-8102.img tests/images/Kenwood_TK-8180.img tests/images/Kenwood_TM-D710G_CloneMode.img tests/images/Kenwood_TM-D710_CloneMode.img tests/images/Kenwood_TS-480_CloneMode.img tests/images/LUITON_LT-580_UHF.img tests/images/LUITON_LT-580_VHF.img tests/images/LUITON_LT-725UV.img tests/images/Lanchonlh_HG-UV98.img tests/images/Leixen_VV-898.img tests/images/Leixen_VV-898S.img tests/images/MMLradio_JC-8629.img tests/images/Midland_DBR2500.img tests/images/Polmar_DB-50M.img tests/images/Puxing_PX-2R.img tests/images/Puxing_PX-777.img tests/images/Puxing_PX-888K.img tests/images/Q-MAC_HF-90_v300_or_earlier.img tests/images/Q-MAC_HF-90_v301_or_later.img tests/images/QYT_KT-8R.img tests/images/QYT_KT-WP12.img tests/images/QYT_KT7900D.img tests/images/QYT_KT8900D.img tests/images/Quansheng_TG-UV2+.img tests/images/Quansheng_UV-K5.img tests/images/Quansheng_UV-K5_egzumer.img tests/images/Radioddity_GA-510.img tests/images/Radioddity_GS-5B.img tests/images/Radioddity_R2.img tests/images/Radioddity_UV-5G.img tests/images/Radtel_RT-470.img tests/images/Radtel_RT-470L.img tests/images/Radtel_RT-470X.img tests/images/Radtel_RT-490.img tests/images/Radtel_T18.img tests/images/Retevis_H777S.img tests/images/Retevis_RA685.img tests/images/Retevis_RA79.img tests/images/Retevis_RA85.img tests/images/Retevis_RA89.img tests/images/Retevis_RB15.img tests/images/Retevis_RB17.img tests/images/Retevis_RB17A.img tests/images/Retevis_RB17P.img tests/images/Retevis_RB17V.img tests/images/Retevis_RB18.img tests/images/Retevis_RB19.img tests/images/Retevis_RB19P.img tests/images/Retevis_RB23.img tests/images/Retevis_RB26.img tests/images/Retevis_RB27.img tests/images/Retevis_RB27B.img tests/images/Retevis_RB27V.img tests/images/Retevis_RB28.img tests/images/Retevis_RB28B.img tests/images/Retevis_RB29.img tests/images/Retevis_RB615.img tests/images/Retevis_RB617.img tests/images/Retevis_RB618.img tests/images/Retevis_RB619.img tests/images/Retevis_RB627B.img tests/images/Retevis_RB628.img tests/images/Retevis_RB628B.img tests/images/Retevis_RB629.img tests/images/Retevis_RB75.img tests/images/Retevis_RB85.img tests/images/Retevis_RB87.img tests/images/Retevis_RT1.img tests/images/Retevis_RT15.img tests/images/Retevis_RT16.img tests/images/Retevis_RT19.img tests/images/Retevis_RT20.img tests/images/Retevis_RT21.img tests/images/Retevis_RT22.img tests/images/Retevis_RT22FRS.img tests/images/Retevis_RT22S.img tests/images/Retevis_RT23.img tests/images/Retevis_RT24.img tests/images/Retevis_RT24V.img tests/images/Retevis_RT26.img tests/images/Retevis_RT29_UHF.img tests/images/Retevis_RT29_VHF.img tests/images/Retevis_RT40B.img tests/images/Retevis_RT47.img tests/images/Retevis_RT47V.img tests/images/Retevis_RT619.img tests/images/Retevis_RT622.img tests/images/Retevis_RT647.img tests/images/Retevis_RT668.img tests/images/Retevis_RT68.img tests/images/Retevis_RT76.img tests/images/Retevis_RT86.img tests/images/Retevis_RT87.img tests/images/Retevis_RT9000D_136-174.img tests/images/Retevis_RT9000D_220-260.img tests/images/Retevis_RT9000D_400-490.img tests/images/Retevis_RT9000D_66-88.img tests/images/Retevis_RT95.img tests/images/Rugged_RH5R-V2.img tests/images/Ruyage_UV58Plus.img tests/images/SenhaiX_8800.img tests/images/TDXone_TD-Q8A.img tests/images/TIDRADIO_TD-H3.img tests/images/TIDRADIO_TD-H8-GMRS.img tests/images/TIDRADIO_TD-H8-HAM.img tests/images/TIDRADIO_TD-H8.img tests/images/TYT_TH-350.img tests/images/TYT_TH-7800.img tests/images/TYT_TH-9800.img tests/images/TYT_TH-UV3R-25.img tests/images/TYT_TH-UV3R.img tests/images/TYT_TH-UV8000.img tests/images/TYT_TH-UV88.img tests/images/TYT_TH-UVF1.img tests/images/TYT_TH-UVF8D.img tests/images/TYT_TH9000_144.img tests/images/Talkpod_A36plus.img tests/images/Talkpod_A36plus_8w.img tests/images/Vertex_Standard_FTL-2011.img tests/images/Vertex_Standard_VXA-700.img tests/images/WACCOM_MINI-8900.img tests/images/Wouxun_KG-1000G.img tests/images/Wouxun_KG-1000G_Plus.img tests/images/Wouxun_KG-816.img tests/images/Wouxun_KG-818.img tests/images/Wouxun_KG-935G.img tests/images/Wouxun_KG-935G_Plus.img tests/images/Wouxun_KG-UV6.img tests/images/Wouxun_KG-UV8D.img tests/images/Wouxun_KG-UV8D_Plus.img tests/images/Wouxun_KG-UV8E.img tests/images/Wouxun_KG-UV8H.img tests/images/Wouxun_KG-UV920P-A.img tests/images/Wouxun_KG-UV980P.img tests/images/Wouxun_KG-UV9D_Plus.img tests/images/Wouxun_KG-UV9GX.img tests/images/Wouxun_KG-UV9G_Pro.img tests/images/Wouxun_KG-UV9K.img tests/images/Wouxun_KG-UV9PX.img tests/images/Wouxun_KG-UVD1P.img tests/images/Yaesu_FT-1500M.img tests/images/Yaesu_FT-1802M.img tests/images/Yaesu_FT-1D_R.img tests/images/Yaesu_FT-25R.img tests/images/Yaesu_FT-2800M.img tests/images/Yaesu_FT-2900R_1900R.img tests/images/Yaesu_FT-450.img tests/images/Yaesu_FT-450D.img tests/images/Yaesu_FT-4VR.img tests/images/Yaesu_FT-4XE.img tests/images/Yaesu_FT-4XR.img tests/images/Yaesu_FT-50.img tests/images/Yaesu_FT-60.img tests/images/Yaesu_FT-65E.img tests/images/Yaesu_FT-65R.img tests/images/Yaesu_FT-70D.img tests/images/Yaesu_FT-7100M.img tests/images/Yaesu_FT-7800_7900.img tests/images/Yaesu_FT-8100.img tests/images/Yaesu_FT-817.img tests/images/Yaesu_FT-817ND.img tests/images/Yaesu_FT-817ND_US.img tests/images/Yaesu_FT-818.img tests/images/Yaesu_FT-857_897.img tests/images/Yaesu_FT-857_897_US.img tests/images/Yaesu_FT-8800.img tests/images/Yaesu_FT-8900.img tests/images/Yaesu_FT-90.img tests/images/Yaesu_FT2D_R.img tests/images/Yaesu_FT3D_R.img tests/images/Yaesu_FTM-3200D_R.img tests/images/Yaesu_FTM-350.img tests/images/Yaesu_FTM-7250D_R.img tests/images/Yaesu_VX-2.img tests/images/Yaesu_VX-3.img tests/images/Yaesu_VX-5.img tests/images/Yaesu_VX-6.img tests/images/Yaesu_VX-7.img tests/images/Yaesu_VX-8DR.img tests/images/Yaesu_VX-8GE.img tests/images/Yaesu_VX-8R.img tests/unit/__init__.py tests/unit/base.py tests/unit/rb-united_states-oregon.json tests/unit/test_alinco_clone.py tests/unit/test_bandplan.py tests/unit/test_baofeng_fmradio.py tests/unit/test_bitwise.py tests/unit/test_chirp_common.py tests/unit/test_cli.py tests/unit/test_csv.py tests/unit/test_directory.py tests/unit/test_icf.py tests/unit/test_icom_clone.py tests/unit/test_import_logic.py tests/unit/test_kguv8d.py tests/unit/test_kguv920.py tests/unit/test_logger.py tests/unit/test_mappingmodel.py tests/unit/test_network_sources.py tests/unit/test_repeaterbook.py tests/unit/test_settings.py tests/unit/test_th9800.py tests/unit/test_util.py tests/unit/test_wxui_radiothread.py tests/unit/test_yaesu_clone.py tests/unit/__pycache__/__init__.cpython-310.pyc tests/unit/__pycache__/base.cpython-310.pyc tests/unit/__pycache__/test_alinco_clone.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_bandplan.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_baofeng_fmradio.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_bitwise.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_chirp_common.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_cli.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_csv.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_directory.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_icf.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_icom_clone.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_import_logic.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_kguv8d.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_kguv920.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_logger.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_mappingmodel.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_network_sources.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_repeaterbook.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_settings.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_th9800.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_util.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_wxui_radiothread.cpython-310-pytest-7.1.3.pyc tests/unit/__pycache__/test_yaesu_clone.cpython-310-pytest-7.1.3.pyc tools/Makefile tools/check_commit.sh tools/check_for_bug.sh tools/checkpatch.sh tools/cpep8.blacklist tools/cpep8.exceptions tools/cpep8.manifest tools/cpep8.py tools/fast-driver.py tools/icomsio.sh tools/py3_driver_progress.py tools/serialsniff.cchirp-20240224/README.md0000644000175000017500000000053314411666130013316 0ustar hibbyhibby# CHIRP Project This is the official git repository for the __[CHIRP](https://chirp.danplanet.com)__ project. When submitting PRs, please squash commits into logical units in a fashion similar to what is currently expected by the project on the mailing list. For Python3 driver testing status, see [this file](tests/Python3_Driver_Testing.md). chirp-20240224/setup.cfg0000644000175000017500000000027214566340177013673 0ustar hibbyhibby[bdist_rpm] requires = pyserial packager = Dan Smith description = A frequency tool for Icom D-STAR Repeaters vendor = KK7DS [egg_info] tag_build = tag_date = 0 chirp-20240224/chirp/0000755000175000017500000000000014566340177013156 5ustar hibbyhibbychirp-20240224/chirp/chirp_common.py0000644000175000017500000017705314563632215016214 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import base64 import json import inspect import logging import math import re import sys from chirp import errors, memmap, CHIRP_VERSION LOG = logging.getLogger(__name__) SEPCHAR = "," # 50 Tones TONES = ( 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8, 136.5, 141.3, 146.2, 151.4, 156.7, 159.8, 162.2, 165.5, 167.9, 171.3, 173.8, 177.3, 179.9, 183.5, 186.2, 189.9, 192.8, 196.6, 199.5, 203.5, 206.5, 210.7, 218.1, 225.7, 229.1, 233.6, 241.8, 250.3, 254.1, ) OLD_TONES = tuple(set(TONES) - set([159.8, 165.5, 171.3, 177.3, 183.5, 189.9, 196.6, 199.5, 206.5, 229.1, 254.1])) def VALIDTONE(v): return isinstance(v, float) and 50 < v < 300 # 104 DTCS Codes DTCS_CODES = ( 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754, ) # 512 Possible DTCS Codes ALL_DTCS_CODES = tuple([((a * 100) + (b * 10) + c) for a in range(0, 8) for b in range(0, 8) for c in range(0, 8)]) CROSS_MODES = ( "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS", "Tone->" ) # This is the "master" list of modes, and in general things should not be # added here without significant consideration. These must remain stable and # universal to allow importing memories between different radio vendors and # models. MODES = ("WFM", "FM", "NFM", "AM", "NAM", "DV", "USB", "LSB", "CW", "RTTY", "DIG", "PKT", "NCW", "NCWR", "CWR", "P25", "Auto", "RTTYR", "FSK", "FSKR", "DMR", "DN") TONE_MODES = ( "", "Tone", "TSQL", "DTCS", "DTCS-R", "TSQL-R", "Cross", ) TUNING_STEPS = ( 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 125.0, 200.0, # Need to fix drivers using this list as an index! 9.0, 1.0, 2.5, ) # These are the default for RadioFeatures.valid_tuning_steps COMMON_TUNING_STEPS = (5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0) SKIP_VALUES = ("", "S", "P") CHARSET_UPPER_NUMERIC = "ABCDEFGHIJKLMNOPQRSTUVWXYZ 1234567890" CHARSET_ALPHANUMERIC = \ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 1234567890" CHARSET_ASCII = "".join([chr(x) for x in range(ord(" "), ord("~") + 1)]) CHARSET_1252 = bytes( [x for x in range(0x20, 0x100) if x not in [0x7F, 0x81, 0x8D, 0x8F, 0x90, 0x9D, 0xA0, 0xAD]] ).decode('cp1252') # http://aprs.org/aprs11/SSIDs.txt APRS_SSID = ( "0 Your primary station usually fixed and message capable", "1 generic additional station, digi, mobile, wx, etc", "2 generic additional station, digi, mobile, wx, etc", "3 generic additional station, digi, mobile, wx, etc", "4 generic additional station, digi, mobile, wx, etc", "5 Other networks (Dstar, Iphones, Androids, Blackberry's etc)", "6 Special activity, Satellite ops, camping or 6 meters, etc", "7 walkie talkies, HT's or other human portable", "8 boats, sailboats, RV's or second main mobile", "9 Primary Mobile (usually message capable)", "10 internet, Igates, echolink, winlink, AVRS, APRN, etc", "11 balloons, aircraft, spacecraft, etc", "12 APRStt, DTMF, RFID, devices, one-way trackers*, etc", "13 Weather stations", "14 Truckers or generally full time drivers", "15 generic additional station, digi, mobile, wx, etc") APRS_POSITION_COMMENT = ( "off duty", "en route", "in service", "returning", "committed", "special", "priority", "custom 0", "custom 1", "custom 2", "custom 3", "custom 4", "custom 5", "custom 6", "EMERGENCY") # http://aprs.org/symbols/symbolsX.txt APRS_SYMBOLS = ( "Police/Sheriff", "[reserved]", "Digi", "Phone", "DX Cluster", "HF Gateway", "Small Aircraft", "Mobile Satellite Groundstation", "Wheelchair", "Snowmobile", "Red Cross", "Boy Scouts", "House QTH (VHF)", "X", "Red Dot", "0 in Circle", "1 in Circle", "2 in Circle", "3 in Circle", "4 in Circle", "5 in Circle", "6 in Circle", "7 in Circle", "8 in Circle", "9 in Circle", "Fire", "Campground", "Motorcycle", "Railroad Engine", "Car", "File Server", "Hurricane Future Prediction", "Aid Station", "BBS or PBBS", "Canoe", "[reserved]", "Eyeball", "Tractor/Farm Vehicle", "Grid Square", "Hotel", "TCP/IP", "[reserved]", "School", "PC User", "MacAPRS", "NTS Station", "Balloon", "Police", "TBD", "Recreational Vehicle", "Space Shuttle", "SSTV", "Bus", "ATV", "National WX Service Site", "Helicopter", "Yacht/Sail Boat", "WinAPRS", "Human/Person", "Triangle", "Mail/Postoffice", "Large Aircraft", "WX Station", "Dish Antenna", "Ambulance", "Bicycle", "Incident Command Post", "Dual Garage/Fire Dept", "Horse/Equestrian", "Fire Truck", "Glider", "Hospital", "IOTA", "Jeep", "Truck", "Laptop", "Mic-Repeater", "Node", "Emergency Operations Center", "Rover (dog)", "Grid Square above 128m", "Repeater", "Ship/Power Boat", "Truck Stop", "Truck (18 wheeler)", "Van", "Water Station", "X-APRS", "Yagi at QTH", "TDB", "[reserved]" ) def watts_to_dBm(watts): """Converts @watts in watts to dBm""" return 10 * math.log10(watts) + 30 def dBm_to_watts(dBm): """Converts @dBm from dBm to watts""" return round(math.pow(10, dBm / 10) / 1000, 1) class PowerLevel: """Represents a power level supported by a radio""" def __init__(self, label, watts=0, dBm=0): if watts: dBm = watts_to_dBm(watts) self._power = float(dBm) self._label = label def __str__(self): return str(self._label) def __int__(self): return int(self._power) def __float__(self): return self._power def __sub__(self, val): return float(self) - float(val) def __add__(self, val): return float(self) + float(val) def __eq__(self, val): if val is not None: return float(self) == float(val) return False def __lt__(self, val): return float(self) < float(val) def __gt__(self, val): return float(self) > float(val) def __bool__(self): return int(self) != 0 def __repr__(self): return "%s (%i dBm)" % (self._label, self._power) class AutoNamedPowerLevel(PowerLevel): """A power level that is simply named by its value in watts""" def __init__(self, watts): fmt = ('%iW' if watts >= 10 else '%.1fW') super().__init__(fmt % watts, watts=watts) def parse_power(powerstr): if powerstr.isdigit(): # All digits means watts watts = int(powerstr) else: match = re.match(r'^\s*([0-9.]+)\s*([Ww]?)\s*$', powerstr) if not match: raise ValueError('Invalid power specification: %r' % powerstr) if match.group(2).lower() in ('', 'w'): watts = float(match.group(1)) else: raise ValueError('Unknown power units in %r' % powerstr) return AutoNamedPowerLevel(watts) def parse_freq(freqstr): """Parse a frequency string and return the value in integral Hz""" freqstr = freqstr.strip() if freqstr == "": return 0 elif freqstr.endswith(" MHz"): return parse_freq(freqstr.split(" ")[0]) elif freqstr.endswith(" kHz"): return int(freqstr.split(" ")[0]) * 1000 if "." in freqstr: mhz, khz = freqstr.split(".") if mhz == "": mhz = 0 khz = khz.ljust(6, "0") if len(khz) > 6: raise ValueError("Invalid kHz value: %s", khz) mhz = int(mhz) * 1000000 khz = int(khz) else: mhz = int(freqstr) * 1000000 khz = 0 return mhz + khz def format_freq(freq): """Format a frequency given in Hz as a string""" return "%i.%06i" % (freq / 1000000, freq % 1000000) class ImmutableValueError(ValueError): pass class Memory: """Base class for a single radio memory""" freq = 0 number = 0 extd_number = "" name = "" vfo = 0 rtone = 88.5 ctone = 88.5 dtcs = 23 rx_dtcs = 23 tmode = "" cross_mode = "Tone->Tone" dtcs_polarity = "NN" skip = "" power = None duplex = "" offset = 600000 mode = "FM" tuning_step = 5.0 comment = "" empty = False immutable = [] # A RadioSettingGroup of additional settings supported by the radio, # or an empty list if none extra = [] def __init__(self, number=0, empty=False, name=""): self.freq = 0 self.number = number self.extd_number = "" self.name = name self.vfo = 0 self.rtone = 88.5 self.ctone = 88.5 self.dtcs = 23 self.rx_dtcs = 23 self.tmode = "" self.cross_mode = "Tone->Tone" self.dtcs_polarity = "NN" self.skip = "" self.power = None self.duplex = "" self.offset = 600000 self.mode = "FM" self.tuning_step = 5.0 self.comment = "" self.empty = empty self.immutable = [] _valid_map = { "rtone": VALIDTONE, "ctone": VALIDTONE, "dtcs": ALL_DTCS_CODES, "rx_dtcs": ALL_DTCS_CODES, "tmode": TONE_MODES, "dtcs_polarity": ["NN", "NR", "RN", "RR"], "cross_mode": CROSS_MODES, "mode": MODES, "duplex": ["", "+", "-", "split", "off"], "skip": SKIP_VALUES, "empty": [True, False], "dv_code": [x for x in range(0, 100)], } def __repr__(self): ident, vals = self.debug_dump() return '' % ( ident, ','.join('%s=%r' % item for item in vals)) def debug_diff(self, other, delim='/'): my_ident, my_vals = self.debug_dump() my_vals = dict(my_vals) om_ident, om_vals = other.debug_dump() om_vals = dict(om_vals) diffs = [] if my_ident != om_ident: diffs.append('ident=%s%s%s' % (my_ident, delim, om_ident)) for k in sorted(my_vals.keys() | om_vals.keys()): myval = my_vals.get(k, '') omval = om_vals.get(k, '') if myval != omval: diffs.append('%s=%r%s%r' % (k, myval, delim, omval)) return ','.join(diffs) def debug_dump(self): vals = [(k, v) for k, v in self.__dict__.items() if k not in ('extra', 'number', 'extd_number')] for extra in self.extra: vals.append(('extra.%s' % extra.get_name(), str(extra.value))) if self.extd_number: ident = '%s(%i)' % (self.extd_number, self.number) else: ident = str(self.number) return ident, vals def dupe(self): """Return a deep copy of @self""" mem = self.__class__() for k, v in list(self.__dict__.items()): mem.__dict__[k] = v return mem def clone(self, source): """Absorb all of the properties of @source""" for k, v in list(source.__dict__.items()): self.__dict__[k] = v CSV_FORMAT = ["Location", "Name", "Frequency", "Duplex", "Offset", "Tone", "rToneFreq", "cToneFreq", "DtcsCode", "DtcsPolarity", "RxDtcsCode", "CrossMode", "Mode", "TStep", "Skip", "Power", "Comment", "URCALL", "RPT1CALL", "RPT2CALL", "DVCODE"] def __setattr__(self, name, val): if not hasattr(self, name): raise ValueError("No such attribute `%s'" % name) if name in self.immutable: raise ImmutableValueError("Field %s is not " % name + "mutable on this memory") if name in self._valid_map: valid = self._valid_map[name] if callable(valid): if not valid(val): raise ValueError("`%s' is not a valid value for `%s'" % ( val, name)) elif val not in self._valid_map[name]: raise ValueError("`%s' is not in valid list: %s" % (val, self._valid_map[name])) self.__dict__[name] = val def format_freq(self): """Return a properly-formatted string of this memory's frequency""" return format_freq(self.freq) def parse_freq(self, freqstr): """Set the frequency from a string""" self.freq = parse_freq(freqstr) return self.freq def __str__(self): if self.tmode == "Tone": tenc = "*" else: tenc = " " if self.tmode == "TSQL": tsql = "*" else: tsql = " " if self.tmode == "DTCS": dtcs = "*" else: dtcs = " " if self.duplex == "": dup = "/" else: dup = self.duplex return \ "Memory %s: %s%s%s %s (%s) r%.1f%s c%.1f%s d%03i%s%s [%.2f]" % \ (self.number if self.extd_number == "" else self.extd_number, format_freq(self.freq), dup, format_freq(self.offset), self.mode, self.name, self.rtone, tenc, self.ctone, tsql, self.dtcs, dtcs, self.dtcs_polarity, self.tuning_step) def to_csv(self): """Return a CSV representation of this memory""" return [ "%i" % self.number, "%s" % self.name, format_freq(self.freq), "%s" % self.duplex, format_freq(self.offset), "%s" % self.tmode, "%.1f" % self.rtone, "%.1f" % self.ctone, "%03i" % self.dtcs, "%s" % self.dtcs_polarity, "%03i" % self.rx_dtcs, "%s" % self.cross_mode, "%s" % self.mode, "%.2f" % self.tuning_step, "%s" % self.skip, "%s" % self.power, "%s" % self.comment, "", "", "", ""] @classmethod def _from_csv(cls, _line): line = _line.strip() if line.startswith("Location"): raise errors.InvalidMemoryLocation("Non-CSV line") vals = line.split(SEPCHAR) if len(vals) < 11: raise errors.InvalidDataError("CSV format error " + "(14 columns expected)") if vals[10] == "DV": mem = DVMemory() else: mem = Memory() mem.really_from_csv(vals) return mem def really_from_csv(self, vals): """Careful parsing of split-out @vals""" try: self.number = int(vals[0]) except Exception: raise errors.InvalidDataError( "Location '%s' is not a valid integer" % vals[0]) self.name = vals[1] try: self.freq = float(vals[2]) except Exception: raise errors.InvalidDataError("Frequency is not a valid number") if vals[3].strip() in ["+", "-", ""]: self.duplex = vals[3].strip() else: raise errors.InvalidDataError("Duplex is not +,-, or empty") try: self.offset = float(vals[4]) except Exception: raise errors.InvalidDataError("Offset is not a valid number") self.tmode = vals[5] if self.tmode not in TONE_MODES: raise errors.InvalidDataError("Invalid tone mode `%s'" % self.tmode) try: self.rtone = float(vals[6]) except Exception: raise errors.InvalidDataError("rTone is not a valid number") if self.rtone not in TONES: raise errors.InvalidDataError("rTone is not valid") try: self.ctone = float(vals[7]) except Exception: raise errors.InvalidDataError("cTone is not a valid number") if self.ctone not in TONES: raise errors.InvalidDataError("cTone is not valid") try: self.dtcs = int(vals[8], 10) except Exception: raise errors.InvalidDataError("DTCS code is not a valid number") if self.dtcs not in DTCS_CODES: raise errors.InvalidDataError("DTCS code is not valid") try: self.rx_dtcs = int(vals[8], 10) except Exception: raise errors.InvalidDataError("DTCS Rx code is not a valid number") if self.rx_dtcs not in DTCS_CODES: raise errors.InvalidDataError("DTCS Rx code is not valid") if vals[9] in ["NN", "NR", "RN", "RR"]: self.dtcs_polarity = vals[9] else: raise errors.InvalidDataError("DtcsPolarity is not valid") if vals[10] in MODES: self.mode = vals[10] else: raise errors.InvalidDataError("Mode is not valid") try: self.tuning_step = float(vals[11]) except Exception: raise errors.InvalidDataError("Tuning step is invalid") try: self.skip = vals[12] except Exception: raise errors.InvalidDataError("Skip value is not valid") return True class DVMemory(Memory): """A Memory with D-STAR attributes""" dv_urcall = "CQCQCQ" dv_rpt1call = "" dv_rpt2call = "" dv_code = 0 def __str__(self): string = Memory.__str__(self) string += " <%s,%s,%s>" % (self.dv_urcall, self.dv_rpt1call, self.dv_rpt2call) return string def to_csv(self): return [ "%i" % self.number, "%s" % self.name, format_freq(self.freq), "%s" % self.duplex, format_freq(self.offset), "%s" % self.tmode, "%.1f" % self.rtone, "%.1f" % self.ctone, "%03i" % self.dtcs, "%s" % self.dtcs_polarity, "%s" % self.mode, "%.2f" % self.tuning_step, "%s" % self.skip, "%s" % self.comment, "%s" % self.dv_urcall, "%s" % self.dv_rpt1call, "%s" % self.dv_rpt2call, "%i" % self.dv_code] def really_from_csv(self, vals): Memory.really_from_csv(self, vals) self.dv_urcall = vals[15].rstrip()[:8] self.dv_rpt1call = vals[16].rstrip()[:8] self.dv_rpt2call = vals[17].rstrip()[:8] try: self.dv_code = int(vals[18].strip()) except Exception: self.dv_code = 0 def FrozenMemory(source): class _FrozenMemory(source.__class__): def __init__(self, source): self.__dict__['_frozen'] = False for k, v in source.__dict__.items(): if k == '_frozen': continue setattr(self, k, v) self.__dict__['_frozen'] = True for i in self.extra: i.set_frozen() def __setattr__(self, k, v): if self._frozen: # This should really be an error, but we have a number of # drivers that make modifications during set_memory(). So this # just has to be a warning for now. Later it could turn into # a TypeError. caller = inspect.getframeinfo(inspect.stack()[1][0]) LOG.warning( '%s@%i: Illegal set on attribute %s - Fix this driver!' % ( caller.filename, caller.lineno, k)) super().__setattr__(k, v) def dupe(self): m = Memory() m.clone(self) delattr(m, '_frozen') return m return _FrozenMemory(source) class MemoryMapping(object): """Base class for a memory mapping""" def __init__(self, model, index, name): self._model = model self._index = index self._name = name def __str__(self): return self.get_name() def __repr__(self): return "%s-%s" % (self.__class__.__name__, self._index) def get_name(self): """Returns the mapping name""" return self._name def get_index(self): """Returns the immutable index (string or int)""" return self._index def __eq__(self, other): return self.get_index() == other.get_index() class MappingModel(object): """Base class for a memory mapping model""" def __init__(self, radio, name): self._radio = radio self._name = name def get_name(self): return self._name def get_num_mappings(self): """Returns the number of mappings in the model (should be callable without consulting the radio""" raise NotImplementedError() def get_mappings(self): """Return a list of mappings""" raise NotImplementedError() def add_memory_to_mapping(self, memory, mapping): """Add @memory to @mapping.""" raise NotImplementedError() def remove_memory_from_mapping(self, memory, mapping): """Remove @memory from @mapping. Shall raise exception if @memory is not in @bank""" raise NotImplementedError() def get_mapping_memories(self, mapping): """Return a list of memories in @mapping""" raise NotImplementedError() def get_memory_mappings(self, memory): """Return a list of mappings that @memory is in""" raise NotImplementedError() class Bank(MemoryMapping): """Base class for a radio's Bank""" class NamedBank(Bank): """A bank that can have a name""" def set_name(self, name): """Changes the user-adjustable bank name""" self._name = name class BankModel(MappingModel): """A bank model where one memory is in zero or one banks at any point""" def __init__(self, radio, name='Banks'): super(BankModel, self).__init__(radio, name) class MappingModelIndexInterface: """Interface for mappings with index capabilities""" def get_index_bounds(self): """Returns a tuple (lo,hi) of the min and max mapping indices""" raise NotImplementedError() def get_memory_index(self, memory, mapping): """Returns the index of @memory in @mapping""" raise NotImplementedError() def set_memory_index(self, memory, mapping, index): """Sets the index of @memory in @mapping to @index""" raise NotImplementedError() def get_next_mapping_index(self, mapping): """Returns the next available mapping index in @mapping, or raises Exception if full""" raise NotImplementedError() class MTOBankModel(BankModel): """A bank model where one memory can be in multiple banks at once """ pass def console_status(status): """Write a status object to the console""" import logging from chirp import logger if not logger.is_visible(logging.WARN): return import sys import os sys.stdout.write("\r%s" % status) if status.cur == status.max: sys.stdout.write(os.linesep) class RadioPrompts: """Radio prompt strings""" info = None experimental = None pre_download = None pre_upload = None display_pre_upload_prompt_before_opening_port = True def BOOLEAN(v): assert v in (True, False) def LIST(v): assert hasattr(v, '__iter__') def INT(min=0, max=None): def checkint(v): assert isinstance(v, int) assert v >= min if max is not None: assert v <= max return checkint def STRING(v): assert isinstance(v, str) def NTUPLE(size): def checktuple(v): assert len(v) == size return checktuple def TONELIST(v): assert all(VALIDTONE(x) for x in v) class RadioFeatures: """Radio Feature Flags""" _valid_map = { # General "has_bank_index": BOOLEAN, "has_dtcs": BOOLEAN, "has_rx_dtcs": BOOLEAN, "has_dtcs_polarity": BOOLEAN, "has_mode": BOOLEAN, "has_offset": BOOLEAN, "has_name": BOOLEAN, "has_bank": BOOLEAN, "has_bank_names": BOOLEAN, "has_tuning_step": BOOLEAN, "has_ctone": BOOLEAN, "has_cross": BOOLEAN, "has_infinite_number": BOOLEAN, "has_nostep_tuning": BOOLEAN, "has_comment": BOOLEAN, "has_settings": BOOLEAN, "has_variable_power": BOOLEAN, # Attributes "valid_modes": LIST, "valid_tmodes": LIST, "valid_duplexes": LIST, "valid_tuning_steps": LIST, "valid_bands": LIST, "valid_skips": LIST, "valid_power_levels": LIST, "valid_characters": STRING, "valid_name_length": INT(), "valid_cross_modes": LIST, "valid_tones": TONELIST, "valid_dtcs_pols": LIST, "valid_dtcs_codes": LIST, "valid_special_chans": LIST, "has_sub_devices": BOOLEAN, "memory_bounds": NTUPLE(2), "can_odd_split": BOOLEAN, "can_delete": BOOLEAN, # D-STAR "requires_call_lists": BOOLEAN, "has_implicit_calls": BOOLEAN, } def __setattr__(self, name, val): if name.startswith("_"): self.__dict__[name] = val return elif name not in list(self._valid_map.keys()): raise ValueError("No such attribute `%s'" % name) try: self._valid_map[name](val) except AssertionError: raise ValueError('Invalid value %r for attribute %r' % ( val, name)) self.__dict__[name] = val def __getattr__(self, name): raise AttributeError("pylint is confused by RadioFeatures") def init(self, attribute, default, doc=None): """Initialize a feature flag @attribute with default value @default, and documentation string @doc""" self.__setattr__(attribute, default) self.__docs[attribute] = doc def get_doc(self, attribute): """Return the description of @attribute""" return self.__docs[attribute] def __init__(self): self.__docs = {} self.init("has_bank_index", False, "Indicates that memories in a bank can be stored in " + "an order other than in main memory") self.init("has_dtcs", True, "Indicates that DTCS tone mode is available") self.init("has_rx_dtcs", False, "Indicates that radio can use two different " + "DTCS codes for rx and tx") self.init("has_dtcs_polarity", True, "Indicates that the DTCS polarity can be changed") self.init("has_mode", True, "Indicates that multiple emission modes are supported") self.init("has_offset", True, "Indicates that the TX offset memory property is supported") self.init("has_name", True, "Indicates that an alphanumeric memory name is supported") self.init("has_bank", True, "Indicates that memories may be placed into banks") self.init("has_bank_names", False, "Indicates that banks may be named") self.init("has_tuning_step", True, "Indicates that memories store their tuning step") self.init("has_ctone", True, "Indicates that the radio keeps separate tone frequencies " + "for repeater and CTCSS operation") self.init("has_cross", False, "Indicates that the radios supports different tone modes " + "on transmit and receive") self.init("has_infinite_number", False, "Indicates that the radio is not constrained in the " + "number of memories that it can store") self.init("has_nostep_tuning", False, "Indicates that the radio does not require a valid " + "tuning step to store a frequency") self.init("has_comment", False, "Indicates that the radio supports storing a comment " + "with each memory") self.init("has_settings", False, "Indicates that the radio supports general settings") self.init("has_variable_power", False, "Indicates the radio supports any power level between the " "min and max in valid_power_levels") self.init("valid_modes", list(MODES), "Supported emission (or receive) modes") self.init("valid_tmodes", [], "Supported tone squelch modes") self.init("valid_duplexes", ["", "+", "-"], "Supported duplex modes") self.init("valid_tuning_steps", list(COMMON_TUNING_STEPS), "Supported tuning steps") self.init("valid_bands", [], "Supported frequency ranges") self.init("valid_skips", ["", "S"], "Supported memory scan skip settings") self.init("valid_power_levels", [], "Supported power levels") self.init("valid_characters", CHARSET_UPPER_NUMERIC, "Supported characters for a memory's alphanumeric tag") self.init("valid_name_length", 6, "The maximum number of characters in a memory's " + "alphanumeric tag") self.init("valid_cross_modes", list(CROSS_MODES), "Supported tone cross modes") self.init("valid_tones", list(TONES), "Support Tones") self.init("valid_dtcs_pols", ["NN", "RN", "NR", "RR"], "Supported DTCS polarities") self.init("valid_dtcs_codes", list(DTCS_CODES), "Supported DTCS codes") self.init("valid_special_chans", [], "Supported special channel names") self.init("has_sub_devices", False, "Indicates that the radio behaves as two semi-independent " + "devices") self.init("memory_bounds", (0, 1), "The minimum and maximum channel numbers") self.init("can_odd_split", False, "Indicates that the radio can store an independent " + "transmit frequency") self.init("can_delete", True, "Indicates that the radio can delete memories") self.init("requires_call_lists", True, "[D-STAR] Indicates that the radio requires all callsigns " + "to be in the master list and cannot be stored " + "arbitrarily in each memory channel") self.init("has_implicit_calls", False, "[D-STAR] Indicates that the radio has an implied " + "callsign at the beginning of the master URCALL list") def is_a_feature(self, name): """Returns True if @name is a valid feature flag name""" return name in list(self._valid_map.keys()) def __getitem__(self, name): return self.__dict__[name] def validate_memory(self, mem): """Return a list of warnings and errors that will be encountered if trying to set @mem on the current radio""" msgs = [] lo, hi = self.memory_bounds if not self.has_infinite_number and \ (mem.number < lo or mem.number > hi) and \ mem.extd_number not in self.valid_special_chans: msg = ValidationWarning("Location %i is out of range" % mem.number) msgs.append(msg) if (self.valid_modes and mem.mode not in self.valid_modes and 'mode' not in mem.immutable and mem.mode != "Auto"): msg = ValidationError("Mode %s not supported" % mem.mode) msgs.append(msg) if self.valid_tmodes and mem.tmode not in self.valid_tmodes: msg = ValidationError("Tone mode %s not supported" % mem.tmode) msgs.append(msg) else: if mem.tmode == "Cross": if self.valid_cross_modes and \ mem.cross_mode not in self.valid_cross_modes: msg = ValidationError("Cross tone mode %s not supported" % mem.cross_mode) msgs.append(msg) if self.valid_tones and mem.rtone not in self.valid_tones: msg = ValidationError("Tone %.1f not supported" % mem.rtone) msgs.append(msg) if self.valid_tones and mem.ctone not in self.valid_tones: msg = ValidationError("Tone %.1f not supported" % mem.ctone) msgs.append(msg) if self.has_dtcs_polarity and \ mem.dtcs_polarity not in self.valid_dtcs_pols: msg = ValidationError("DTCS Polarity %s not supported" % mem.dtcs_polarity) msgs.append(msg) if self.valid_dtcs_codes and \ mem.dtcs not in self.valid_dtcs_codes: msg = ValidationError("DTCS Code %03i not supported" % mem.dtcs) msgs.append(msg) if self.valid_dtcs_codes and \ mem.rx_dtcs not in self.valid_dtcs_codes: msg = ValidationError("DTCS Code %03i not supported" % mem.rx_dtcs) msgs.append(msg) if self.valid_duplexes and mem.duplex not in self.valid_duplexes: msg = ValidationError("Duplex %s not supported" % mem.duplex) msgs.append(msg) ts = mem.tuning_step if self.valid_tuning_steps and ts not in self.valid_tuning_steps and \ not self.has_nostep_tuning: msg = ValidationError("Tuning step %.2f not supported" % ts) msgs.append(msg) if self.valid_bands: valid = False for lo, hi in self.valid_bands: if lo <= mem.freq < hi: valid = True break if not valid: msg = ValidationError( ("Frequency {freq} is out " "of supported range").format(freq=format_freq(mem.freq))) msgs.append(msg) if self.valid_bands and \ self.valid_duplexes and \ mem.duplex in ["split", "-", "+"]: if mem.duplex == "split": freq = mem.offset elif mem.duplex == "-": freq = mem.freq - mem.offset elif mem.duplex == "+": freq = mem.freq + mem.offset valid = False for lo, hi in self.valid_bands: if lo <= freq < hi: valid = True break if not valid: msg = ValidationError( ("Tx freq {freq} is out " "of supported range").format(freq=format_freq(freq))) msgs.append(msg) if mem.power and self.valid_power_levels: if self.has_variable_power: if (mem.power < min(self.valid_power_levels) or mem.power > max(self.valid_power_levels)): msg = ValidationWarning( "Power level %s is out of radio's range" % mem.power) msgs.append(msg) else: if mem.power not in self.valid_power_levels: msg = ValidationWarning( "Power level %s not supported" % mem.power) msgs.append(msg) if self.valid_tuning_steps and not self.has_nostep_tuning: try: required_step(mem.freq, self.valid_tuning_steps) except errors.InvalidDataError as e: msgs.append(ValidationError(e)) if self.valid_characters: for char in mem.name: if char not in self.valid_characters: msgs.append(ValidationWarning("Name character " + "`%s'" % char + " not supported")) break return msgs class ValidationMessage(str): """Base class for Validation Errors and Warnings""" pass class ValidationWarning(ValidationMessage): """A non-fatal warning during memory validation""" pass class ValidationError(ValidationMessage): """A fatal error during memory validation""" pass def split_validation_msgs(msgs): """Split a list of msgs into warnings,errors""" return ([x for x in msgs if isinstance(x, ValidationWarning)], [x for x in msgs if isinstance(x, ValidationError)]) class Alias(object): VENDOR = "Unknown" MODEL = "Unknown" VARIANT = "" class Radio(Alias): """Base class for all Radio drivers""" BAUD_RATE = 9600 # Whether or not we should use RTS/CTS flow control HARDWARE_FLOW = False # Whether or not we should assert DTR when opening the serial port WANTS_DTR = True # Whether or not we should assert RTS when opening the serial port WANTS_RTS = True ALIASES = [] NEEDS_COMPAT_SERIAL = True FORMATS = [] def status_fn(self, status): """Deliver @status to the UI""" console_status(status) def __init__(self, pipe): self.errors = [] self.pipe = pipe def get_features(self): """Return a RadioFeatures object for this radio""" return RadioFeatures() @classmethod def get_name(cls): """Return a printable name for this radio""" return "%s %s" % (cls.VENDOR, cls.MODEL) @classmethod def get_prompts(cls): """Return a set of strings for use in prompts""" return RadioPrompts() def set_pipe(self, pipe): """Set the serial object to be used for communications""" self.pipe = pipe def get_memory(self, number): """Return a Memory object for the memory at location @number Constructs and returns a generic Memory object for the given location in the radio's memory. The memory should accurately represent what is actually stored in the radio as closely as possible. If the radio does not support changing some attributes of the location in question, the Memory.immutable list should be set appropriately. NB: No changes to the radio's memory should occur as a result of calling get_memory(). """ pass def erase_memory(self, number): """Erase memory at location @number""" mem = Memory() mem.number = number mem.empty = True self.set_memory(mem) def get_memories(self, lo=None, hi=None): """Get all the memories between @lo and @hi""" pass def set_memory(self, memory): """Set the memory object @memory This method should copy generic attributes from @memory to the radio's memory. It should not modify @memory and it should reproduce the generic attributes on @memory in the radio's memory as faithfully as the radio allows. Attributes that can't be copied exactly should be warned in validate_memory() with ValidationWarnings if a substitution will be made, or ValidationError if truly incompatible. In the latter case, set_memory() will not be called. """ pass def get_mapping_models(self): """Returns a list of MappingModel objects (or an empty list)""" if hasattr(self, "get_bank_model"): # FIXME: Backwards compatibility for old bank models bank_model = self.get_bank_model() if bank_model: return [bank_model] return [] def get_raw_memory(self, number): """Return a raw string describing the memory at @number""" pass def filter_name(self, name): """Filter @name to just the length and characters supported""" rf = self.get_features() if rf.valid_characters == rf.valid_characters.upper(): # Radio only supports uppercase, so help out here name = name.upper() return "".join([x for x in name[:rf.valid_name_length] if x in rf.valid_characters]) def get_sub_devices(self): """Return a list of sub-device Radio objects, if RadioFeatures.has_sub_devices is True""" return [] def validate_memory(self, mem): """Return a list of warnings and errors that will be encountered if trying to set @mem on the current radio""" rf = self.get_features() return rf.validate_memory(mem) def get_settings(self): """Returns a RadioSettings list containing one or more RadioSettingGroup or RadioSetting objects. These represent general setting knobs and dials that can be adjusted on the radio. If this function is implemented, the has_settings RadioFeatures flag should be True and set_settings() must be implemented as well.""" pass def set_settings(self, settings): """Accepts the top-level RadioSettingGroup returned from get_settings() and adjusts the values in the radio accordingly. This function expects the entire RadioSettingGroup hierarchy returned from get_settings(). If this function is implemented, the has_settings RadioFeatures flag should be True and get_settings() must be implemented as well.""" pass @classmethod def supports_format(cls, fmt): """Returns true if file format @fmt is supported by this radio. This really should not be overridden by implementations without a good reason (like excluding one). """ return fmt in cls.FORMATS def check_set_memory_immutable_policy(self, existing, new): """Checks whether or not a new memory will violate policy. Some radios have complex requirements for which fields of which memories can be modified at any given point. For the most part, radios require certain physical memory slots to have immutable fields (such as labels on call channels), and this default implementation checks that policy. However, other radios have more fine-grained rules in order to comply with FCC type acceptance, which requires overriding this behavior. ** This should almost never be overridden in your driver. ** This must not communicate with the radio, if implemented on a live- mode driver. """ for field in existing.immutable: if getattr(existing, field) != getattr(new, field): raise ImmutableValueError( 'Field %s is not mutable on this memory' % field) class ExternalMemoryProperties: """A mixin class that provides external memory property support. This is for use by drivers that have some way of storing additional memory properties externally (i.e. in metadata or a separate region) that cannot be loaded/updated during get_memory()/set_memory(). Implementing this is much less ideal than supporting those properties directly, so this should only be used when absolutely necessary. """ def get_memory_extra(self, memory): """Update @memory with extra fields. This is called after get_memory() and is passed the result for augmentation from external storage. """ return memory def set_memory_extra(self, memory): """Update external storage of properties from @memory. This is called after set_memory() with the same memory object to record additional properties in external storage. """ pass def erase_memory_extra(self, number): """Erase external storage for @memory. This is called after erase_memory() to clear external storage for memory @number. """ pass def link_device_metadata(self, devices): """Link sub-device metadata with parent. This is called after get_sub_devices() to make sure that the sub-device instances use a reference into the main radio's metadata. In most cases, this does not need to be overridden. """ # Link metadata of the sub-devices into the main by variant name # so that they are both included in a later save of the parent. for sub in devices: self._metadata.setdefault(sub.VARIANT, {}) sub._metadata = self._metadata[sub.VARIANT] class FileBackedRadio(Radio): """A file-backed radio stores its data in a file""" FILE_EXTENSION = 'dat' def save(self, filename): """Save the radio's memory map to @filename""" pass def load(self, filename): """Load the radio's memory map object from @filename""" pass class DetectableInterface: DETECTED_MODELS = None @classmethod def detect_from_serial(cls, pipe): """Communicate with the radio via serial to determine proper class Returns an in implementation of CloneModeRadio if detected, or raises RadioError if not. If NotImplemented is raised, we assume that no detection is possible or necessary. """ assert cls.DETECTED_MODELS is None, ( 'Class has detected models but no detect_from_serial() ' 'implementation') raise NotImplementedError() @classmethod def detected_models(cls): return list(cls.DETECTED_MODELS or []) class CloneModeRadio(FileBackedRadio, ExternalMemoryProperties, DetectableInterface): """A clone-mode radio does a full memory dump in and out and we store an image of the radio into an image file""" FILE_EXTENSION = "img" MAGIC = b'\x00\xffchirp\xeeimg\x00\x01' _memsize = 0 def __init__(self, pipe): self.errors = [] self._mmap = None self._memobj = None self._metadata = {} if isinstance(pipe, str): self.pipe = None self.load_mmap(pipe) elif isinstance(pipe, memmap.MemoryMapBytes): self.pipe = None self._mmap = pipe self.process_mmap() else: FileBackedRadio.__init__(self, pipe) def get_memsize(self): """Return the radio's memory size""" return self._memsize @classmethod def match_model(cls, filedata, filename): """Given contents of a stored file (@filedata), return True if this radio driver handles the represented model""" # Unless the radio driver does something smarter, claim # support if the data is the same size as our memory. # Ideally, each radio would perform an intelligent analysis to # make this determination to avoid model conflicts with # memories of the same size. return cls._memsize and len(filedata) == cls._memsize def sync_in(self): """Initiate a radio-to-PC clone operation""" pass def sync_out(self): """Initiate a PC-to-radio clone operation""" pass def save(self, filename): """Save the radio's memory map to @filename""" self.save_mmap(filename) def load(self, filename): """Load the radio's memory map object from @filename""" self.load_mmap(filename) def process_mmap(self): """Process a newly-loaded or downloaded memory map""" pass @classmethod def _strip_metadata(cls, raw_data): try: idx = raw_data.index(cls.MAGIC) except ValueError: LOG.debug('Image data has no metadata blob') return raw_data, {} # Find the beginning of the base64 blob raw_metadata = raw_data[idx + len(cls.MAGIC):] metadata = {} try: metadata = json.loads(base64.b64decode(raw_metadata).decode()) except ValueError as e: LOG.error('Failed to parse decoded metadata blob: %s' % e) except TypeError as e: LOG.error('Failed to decode metadata blob: %s' % e) if metadata: LOG.debug('Loaded metadata: %s' % metadata) return raw_data[:idx], metadata def _make_metadata(self): # Always generate these directly from our in-memory state base = { 'rclass': self.__class__.__name__, 'vendor': self.VENDOR, 'model': self.MODEL, 'variant': self.VARIANT, 'chirp_version': CHIRP_VERSION, } # Any other properties take a back seat to the above extra = {k: v for k, v in self._metadata.items() if k not in base} extra.update(base) return base64.b64encode(json.dumps(extra).encode()) def load_mmap(self, filename): """Load the radio's memory map from @filename""" mapfile = open(filename, "rb") data = mapfile.read() if self.MAGIC in data: data, self._metadata = self._strip_metadata(data) if ('chirp_version' in self._metadata and is_version_newer(self._metadata.get('chirp_version'))): LOG.warning('Image is from version %s but we are %s' % ( self._metadata.get('chirp_version'), CHIRP_VERSION)) if self.NEEDS_COMPAT_SERIAL: self._mmap = memmap.MemoryMap(data) else: self._mmap = memmap.MemoryMapBytes(bytes(data)) mapfile.close() self.process_mmap() def save_mmap(self, filename): """ try to open a file and write to it If IOError raise a File Access Error Exception """ try: mapfile = open(filename, "wb") mapfile.write(self._mmap.get_byte_compatible().get_packed()) if filename.lower().endswith(".img"): mapfile.write(self.MAGIC) mapfile.write(self._make_metadata()) mapfile.close() except IOError: raise Exception("File Access Error") def get_mmap(self): """Return the radio's memory map object""" return self._mmap @property def metadata(self): return dict(self._metadata) @metadata.setter def metadata(self, values): self._metadata.update(values) def get_memory_extra(self, memory): rf = self.get_features() if not rf.has_comment and isinstance(memory.number, int): self._metadata.setdefault('mem_extra', {}) memory.comment = self._metadata['mem_extra'].get( '%04i_comment' % memory.number, '') return memory def set_memory_extra(self, memory): rf = self.get_features() if not rf.has_comment and isinstance(memory.number, int): self._metadata.setdefault('mem_extra', {}) key = '%04i_comment' % memory.number if not memory.comment: self._metadata['mem_extra'].pop(key, None) else: self._metadata['mem_extra'][key] = memory.comment def erase_memory_extra(self, number): rf = self.get_features() if not rf.has_comment and isinstance(number, int): self._metadata.setdefault('mem_extra', {}) self._metadata['mem_extra'].pop('%04i_comment' % number, None) class LiveRadio(Radio, DetectableInterface): """Base class for all Live-Mode radios""" pass class NetworkSourceRadio(Radio): """Base class for all radios based on a network source""" def do_fetch(self): """Fetch the source data from the network""" pass class IcomDstarSupport: """Base interface for radios supporting Icom's D-STAR technology""" MYCALL_LIMIT = (1, 1) URCALL_LIMIT = (1, 1) RPTCALL_LIMIT = (1, 1) def get_urcall_list(self): """Return a list of URCALL callsigns""" return [] def get_repeater_call_list(self): """Return a list of RPTCALL callsigns""" return [] def get_mycall_list(self): """Return a list of MYCALL callsigns""" return [] def set_urcall_list(self, calls): """Set the URCALL callsign list""" pass def set_repeater_call_list(self, calls): """Set the RPTCALL callsign list""" pass def set_mycall_list(self, calls): """Set the MYCALL callsign list""" pass class ExperimentalRadio: """Interface for experimental radios""" @classmethod def get_experimental_warning(cls): return ("This radio's driver is marked as experimental and may " + "be unstable or unsafe to use.") class Status: """Clone status object for conveying clone progress to the UI""" name = "Job" msg = "Unknown" max = 100 cur = 0 def __str__(self): try: pct = (self.cur / float(self.max)) * 100 nticks = int(pct) // 10 ticks = "=" * nticks except ValueError: pct = 0.0 ticks = "?" * 10 return "|%-10s| %2.1f%% %s" % (ticks, pct, self.msg) def is_fractional_step(freq): """Returns True if @freq requires a 12.5 kHz or 6.25 kHz step""" return not is_5_0(freq) and (is_12_5(freq) or is_6_25(freq)) def is_5_0(freq): """Returns True if @freq is reachable by a 5 kHz step""" return (freq % 5000) == 0 def is_10_0(freq): """Returns True if @freq is reachable by a 10 kHz step""" return (freq % 10000) == 0 def is_12_5(freq): """Returns True if @freq is reachable by a 12.5 kHz step""" return (freq % 12500) == 0 def is_6_25(freq): """Returns True if @freq is reachable by a 6.25 kHz step""" return (freq % 6250) == 0 def is_2_5(freq): """Returns True if @freq is reachable by a 2.5 kHz step""" return (freq % 2500) == 0 def is_8_33(freq): """Returns True if @freq is reachable by a 8.33 kHz step""" return (freq % 25000) in [0, 8330, 16660] def is_1_0(freq): """Returns True if @freq is reachable by a 1.0 kHz step""" return (freq % 1000) == 0 def is_0_5(freq): """Returns True if @freq is reachable by a 0.5 kHz step""" return (freq % 500) == 0 def make_is(stephz): def validator(freq): return freq % stephz == 0 return validator def required_step(freq, allowed=None): """Returns the simplest tuning step that is required to reach @freq""" if allowed is None: allowed = [5.0, 10.0, 12.5, 6.25, 2.5, 8.33] # These should be in order of most common to least common steps = { 5.0: make_is(5000), 10.0: make_is(10000), 12.5: make_is(12500), 6.25: make_is(6250), 2.5: make_is(2500), 1.0: make_is(1000), 0.5: make_is(500), 0.25: make_is(250), 8.33: is_8_33, } for step, validate in steps.items(): if step in allowed and validate(freq): return step raise errors.InvalidDataError("Unable to find a supported " + "tuning step for %s" % format_freq(freq)) def fix_rounded_step(freq): """Some radios imply the last bit of 12.5 kHz and 6.25 kHz step frequencies. Take the base @freq and return the corrected one""" try: required_step(freq) return freq except errors.InvalidDataError: pass try: required_step(freq + 500) return freq + 500 except errors.InvalidDataError: pass try: required_step(freq + 250) return freq + 250 except errors.InvalidDataError: pass try: required_step(freq + 750) return float(freq + 750) except errors.InvalidDataError: pass try: required_step(freq + 330) return float(freq + 330) except errors.InvalidDataError: pass try: required_step(freq + 660) return float(freq + 660) except errors.InvalidDataError: pass raise errors.InvalidDataError("Unable to correct rounded frequency " + format_freq(freq)) def _name(name, len, just_upper): """Justify @name to @len, optionally converting to all uppercase""" if just_upper: name = name.upper() return name.ljust(len)[:len] def name6(name, just_upper=True): """6-char name""" return _name(name, 6, just_upper) def name8(name, just_upper=False): """8-char name""" return _name(name, 8, just_upper) def name16(name, just_upper=False): """16-char name""" return _name(name, 16, just_upper) def to_GHz(val): """Convert @val in GHz to Hz""" return val * 1000000000 def to_MHz(val): """Convert @val in MHz to Hz""" return val * 1000000 def to_kHz(val): """Convert @val in kHz to Hz""" return val * 1000 def from_GHz(val): """Convert @val in Hz to GHz""" return val // 100000000 def from_MHz(val): """Convert @val in Hz to MHz""" return val // 100000 def from_kHz(val): """Convert @val in Hz to kHz""" return val // 100 def split_to_offset(mem, rxfreq, txfreq): """Set the freq, offset, and duplex fields of a memory based on a separate rx/tx frequency. """ if abs(txfreq - rxfreq) > to_MHz(70): mem.freq = rxfreq mem.offset = txfreq mem.duplex = 'split' else: offset = txfreq - rxfreq if offset < 0: mem.duplex = '-' elif offset > 0: mem.duplex = '+' mem.offset = abs(offset) def split_tone_decode(mem, txtone, rxtone): """ Set tone mode and values on @mem based on txtone and rxtone specs like: None, None, None "Tone", 123.0, None "DTCS", 23, "N" """ txmode, txval, txpol = txtone rxmode, rxval, rxpol = rxtone mem.dtcs_polarity = "%s%s" % (txpol or "N", rxpol or "N") if not txmode and not rxmode: # No tone return if txmode == "Tone" and not rxmode: mem.tmode = "Tone" mem.rtone = txval return if txmode == rxmode == "Tone" and txval == rxval: # TX and RX same tone -> TSQL mem.tmode = "TSQL" mem.ctone = txval return if txmode == rxmode == "DTCS" and txval == rxval: mem.tmode = "DTCS" mem.dtcs = txval return mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode or "", rxmode or "") if txmode == "Tone": mem.rtone = txval elif txmode == "DTCS": mem.dtcs = txval if rxmode == "Tone": mem.ctone = rxval elif rxmode == "DTCS": mem.rx_dtcs = rxval def split_tone_encode(mem): """ Returns TX, RX tone specs based on @mem like: None, None, None "Tone", 123.0, None "DTCS", 23, "N" """ txmode = '' rxmode = '' txval = None rxval = None if mem.tmode == "Tone": txmode = "Tone" txval = mem.rtone elif mem.tmode == "TSQL": txmode = rxmode = "Tone" txval = rxval = mem.ctone elif mem.tmode == "DTCS": txmode = rxmode = "DTCS" txval = rxval = mem.dtcs elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": txval = mem.rtone elif txmode == "DTCS": txval = mem.dtcs if rxmode == "Tone": rxval = mem.ctone elif rxmode == "DTCS": rxval = mem.rx_dtcs if txmode == "DTCS": txpol = mem.dtcs_polarity[0] else: txpol = None if rxmode == "DTCS": rxpol = mem.dtcs_polarity[1] else: rxpol = None return ((txmode, txval, txpol), (rxmode, rxval, rxpol)) def sanitize_string(astring, validcharset=CHARSET_ASCII, replacechar='*'): myfilter = ''.join( [ [replacechar, chr(x)][chr(x) in validcharset] for x in range(256) ]) return astring.translate(myfilter) def is_version_newer(version): """Return True if version is newer than ours""" def get_version(v): if v.startswith('daily-'): _, stamp = v.split('-', 1) ver = (int(stamp),) elif '.' in v: ver = tuple(int(p) for p in v.split('.')) else: ver = (0,) LOG.debug('Parsed version %r to %r' % (v, ver)) return ver from chirp import CHIRP_VERSION try: version = get_version(version) except ValueError as e: LOG.error('Failed to parse version %r: %s' % (version, e)) version = (0,) try: my_version = get_version(CHIRP_VERSION) except ValueError as e: LOG.error('Failed to parse my version %r: %s' % (CHIRP_VERSION, e)) my_version = (0,) return version > my_version def http_user_agent(): ver = sys.version_info return 'chirp/%s (Python %i.%i.%i on %s)' % ( CHIRP_VERSION, ver.major, ver.minor, ver.micro, sys.platform) def urlretrieve(url, fn): """Grab an URL and save it in a specified file""" import urllib.request import urllib.error headers = { 'User-Agent': http_user_agent(), } req = urllib.request.Request(url, headers=headers) resp = urllib.request.urlopen(req) with open(fn, 'wb') as f: f.write(resp.read()) def mem_from_text(text): m = Memory() freqs = re.findall(r'\b(\d{1,3}\.\d{2,6})\b', text) if not freqs: raise ValueError('Unable to find a frequency') m.freq = parse_freq(freqs[0]) offset = re.search(r'([+-])\s*(\d\.\d{1,3}|\d)\b', text) duplex = re.search(r'\W([+-])\W', text[text.index(freqs[0]):]) if len(freqs) > 1 and not offset: split_to_offset(m, m.freq, parse_freq(freqs[1])) else: if offset: m.duplex = offset.group(1) m.offset = parse_freq(offset.group(2)) # Only look for the first +/- after the frequency, which would be # by far the most common arrangement if offset is None and duplex: m.duplex = duplex.group(1) tones = re.findall(r'\b(\d{2,3}\.\d|D\d{3})\b', text) if tones and len(tones) <= 2: txrx = [] for val in tones: if '.' in val: mode = 'Tone' tone = float(val) elif 'D' in val: mode = 'DTCS' tone = int(val[1:]) else: continue txrx.append((mode, tone, 'N')) if len(txrx) == 1: txrx.append(('', 88.5, 'N')) split_tone_decode(m, txrx[0], txrx[1]) return m def mem_to_text(mem): pieces = [format_freq(mem.freq)] if mem.duplex == 'split': pieces.append(format_freq(mem.offset)) elif mem.duplex in ('-', '+'): pieces.append('%s%i.%3.3s' % (mem.duplex, mem.offset / 1000000, '%03i' % (mem.offset % 1000000))) txrx = split_tone_encode(mem) for mode, tone, pol in txrx: if mode == 'Tone': pieces.append('%.1f' % tone) elif mode == 'DTCS': pieces.append('D%03i' % tone) return '[%s]' % '/'.join(pieces) chirp-20240224/chirp/locale/0000755000175000017500000000000014566340177014415 5ustar hibbyhibbychirp-20240224/chirp/locale/ja_JP/0000755000175000017500000000000014566340177015400 5ustar hibbyhibbychirp-20240224/chirp/locale/ja_JP/LC_MESSAGES/0000755000175000017500000000000014566340177017165 5ustar hibbyhibbychirp-20240224/chirp/locale/ja_JP/LC_MESSAGES/CHIRP.mo0000644000175000017500000003537514566340175020402 0ustar hibbyhibbyо• п ˜ 9™ г ;щ +%рQп2^q wƒ‡–œ Ђ%­глђћ   " 0<CRdˆœГЩмѓ5 IWhqx }‡ ЅЏ Р Ьйс цё  7H^gx– ДОЧтчэ  '=RY ` †’ ЄАУпѓ3љ*-(X&?Ј ш$є $2 ;FL]qИƒ<Ml‚•š ЏЙ Ш в мъ§ 2M3m5Ёз чѕ§^ d№p<ažЛк п щ іL/_ЃГЦлы %'@h†”™7Ё!йћc ap 1в m!9r!=Ќ!9ъ"˜$$Н$й$ ь$і$ % % %'%U@% –%Ѓ%Ж% Н%Ч%Ы%ч% ї% &&!&(&!;&F]&Є&!З&$й&ў&'-'@'S'g'†'Ÿ'И' д'р'№' ї' (!(0(?( ^(h( ‚( (™(И(з($ч(' )4)E)d)!k),),К)ч) ю)(ћ)$* 4*2>* q* ~*‹*-Ё*!Я*ё*ѕ*6+<+C+_+{+!‘+-Г+'с+ ,C,=Z,=˜,=ж,b-w-A- Я-й-р-і-§- ..*-.X.q.x/M‘/п/ћ/0040J0Z0p0ƒ0Ÿ0О0 з0ф0ы0* 1151Cg1CЋ1я1 222я&24424уg56K7<‚7 П7Э7р7і78œ8DИ8§89!59W9v9"•9'И9'р9":$+:P: T:a: h:Au:7З:я:і:'V$qO8"WRGI,ž@|PSZX_Ž15Ts –•DgN/‚Yy(k™b+~)jŸ}›>c #ˆQFlœr;&*:€7 ”ui‰%pšvd]K`Šf—m0M=.\6t<‘ ˜U„2?‡† “B4^zELn o-{aw‹3[AH’e 9!xŒJhƒC…%i Memories and shift all up%i Memories and shift all up%i Memory%i Memories%i Memory and shift block up%i Memories and shift block up%s has not been saved. Save before closing?1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to download image from device. It will may not work if you turn on the radio with the cable already attached 1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to upload the image to device. It will may not work if you turn on the radio with the cable already attachedA new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllBandplanBandsBanksCloseClose fileCluster %i memoryCluster %i memoriesCommentCommunicate with radioCompleteCopyCountryCustom PortCustom...CutDTCS PolarityDTMF decodeDeleteDeveloper ModeDisable reportingDo not prompt again for %sDownloadDownload from radioDownload from radio...Download instructionsDriver informationEnable Automatic EditsEnter FrequencyEnter custom port:Error communicating with radioExperimental driverExport to CSVExport to CSV...FM RadioFilterFindFind NextFind...Finished radio job %sFrequencyGetting settingsGoto MemoryGoto Memory:Goto...HelpHelp Me...Hide empty memoriesImportImport from file...Import not recommendedInsert Row AboveInternal driver errorLatitudeLoading settingsLogo string 1 (12 characters)Logo string 2 (12 characters)LongitudeMemoriesMemory %i is not deletableModeModelMore than one port found: %sMove DownMove UpNew WindowNew version availableNo empty rows below!NumberOffsetOnly memory tabs may be exportedOpenOpen RecentOpen Stock ConfigOpen a fileOpen in new windowOpen stock config directoryOverwrite memories?PastePasted memories will overwrite %s existing memoriesPasted memories will overwrite memories %sPasted memories will overwrite memory %sPasted memory will overwrite memory %sPlease be sure to quit CHIRP before installing the new version!Please waitPlug in your cable and then click OKPortPowerPrint PreviewPrintingPropertiesRadioRefresh requiredRefreshed memory %sReporting enabledReporting helps the CHIRP project know which radio models and OS platforms to spend our limited efforts on. We would really appreciate if you left it enabled. Really disable reporting?Restart RequiredRestore %i tabRestore %i tabsRestore tabs on startRetrieved settingsSaveSave before closing?Save fileSaved settingsScanlistsScramblerSecurity RiskSelect Bandplan...Select a bandplanServiceSettingsShow extra fieldsShow image backup locationSort %i memorySort %i memoriesSort %i memory ascendingSort %i memories ascendingSort %i memory descendingSort %i memories descendingSort by column:Sort memoriesSortingSuccessThe recommended procedure for importing memories is to open the source file and copy/paste memories from it into your target image. If you continue with this import function, CHIRP will replace all memories in your currently-open file with those in %(file)s. Would you like to open this file to copy/paste memories across, or proceed with the import?This MemoryThis image is missing firmware information. It may have been generated with an old or modified version of CHIRP. It is advised that you download a fresh image from your radio and use that going forward for the best safety and compatibility.This is an experimental driver for the Quansheng UV-K5. It may harm your radio, or worse. Use at your own risk. Before attempting to do any changes please download the memory image from the radio with chirp and keep it. This can be later used to recover the original settings. some details are not yet implementedThis memory and shift all upThis memory and shift block upToneTone ModeTone SquelchTuning StepUSB Port FinderUnable to determine port for your cable. Check your drivers and connections.Unplug your cable (if needed) and then click OKUpload instructionsUpload to radioUpload to radio...Use fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterValuesVendorViewWelcomeWould you like CHIRP to install a desktop icon for you?Your cable appears to be on port:disabledenabledProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2023-12-03 11:04+0900 Last-Translator: weboo Language-Team: Japanese Language: ja_JP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; %i фЛЖх‰Šщ™Єу—уІх…ЈфН“у‚’фИŠц–Йх‘уЋу‚Зуƒ•уƒˆ%i фЛЖх‰Šщ™Єу—уІх…ЈфН“у‚’фИŠц–Йх‘уЋу‚Зуƒ•уƒˆ%i фЛЖуЎх†…хЎЙу‚’х‰Šщ™Є%i фЛЖуЎх†…хЎЙу‚’х‰Šщ™Є%i фЛЖх‰Šщ™Єу—уІу‚АуƒЋуƒМуƒ—у‚’фИŠц–Йх‘уЋу‚Зуƒ•уƒˆ%i фЛЖх‰Šщ™Єу—уІу‚АуƒЋуƒМуƒ—у‚’фИŠц–Йх‘уЋу‚Зуƒ•уƒˆ%s уЏфПх­˜у•у‚ŒуІу„уОу›у‚“у€‚фПх­˜у—уОу™у‹яМŸ1. ч„ЁчЗšцЉŸуЎщ›ЛцКу‚’у‚ЊуƒГ 2. уƒ—уƒ­у‚АуƒЉуƒŸуƒГу‚Ау‚БуƒМуƒ–уƒЋу‚’цŽЅчЖš 3. у‚Гуƒу‚Џу‚ПуŒу—уЃу‹у‚ŠуЈцŽЅчЖšу•у‚ŒуІу„у‚‹у‹чЂКшЊ 4. OKуƒœу‚ПуƒГу‚’цŠМу—уІч„ЁчЗšцЉŸу‹у‚‰уƒ€у‚ІуƒГуƒ­уƒМуƒ‰у‚’щ–‹хЇ‹ у‚БуƒМуƒ–уƒЋу‚’цŽЅчЖšу—уŸчŠЖц…‹уЇщ›ЛцКу‚ЊуƒГуЋу™у‚‹уЈу†уОух‹•у‹уЊу„х ДхˆуŒу‚у‚ŠуОу™у€‚ 1. ч„ЁчЗšцЉŸуЎщ›ЛцКу‚’у‚ЊуƒГ 2. уƒ—уƒ­у‚АуƒЉуƒŸуƒГу‚Ау‚БуƒМуƒ–уƒЋу‚’цŽЅчЖš 3. у‚Гуƒу‚Џу‚ПуŒу—уЃу‹у‚ŠуЈцŽЅчЖšу•у‚ŒуІу„у‚‹у‹чЂКшЊ 4. OKуƒœу‚ПуƒГу‚’цŠМу—уІч„ЁчЗšцЉŸуИу‚Ђуƒƒуƒ—уƒ­уƒМуƒ‰у‚’щ–‹хЇ‹ у‚БуƒМуƒ–уƒЋу‚’цŽЅчЖšу—уŸчŠЖц…‹уЇщ›ЛцКу‚ЊуƒГуЋу™у‚‹уЈу†уОух‹•у‹уЊу„х ДхˆуŒу‚у‚ŠуОу™у€‚ц–Ау—у„уƒуƒМу‚ИуƒЇуƒГуЎCHIRPуŒхˆЉч”ЈхЏшƒНуЇу™у€‚уЇуу‚‹у у‘ц—Љуц›Дц–Ау•у‚Œу‚‹у“уЈу‚’уŠх‹Їу‚у—уОу™у€‚фЛŠу™уц›Дц–Ау—уОу™у‹яМŸу“уЎу‚Ђуƒ—уƒЊуЋуЄу„уІCHIRP уЋуЄу„уІу™уЙуІуƒуƒГуƒ‰уƒ—уƒЉуƒГуƒуƒГуƒ‰уƒуƒГу‚Џщ–‰у˜у‚‹уƒ•у‚Ёу‚ЄуƒЋу‚’щ–‰у˜у‚‹%i фЛЖу‚’хŒфИ€у‚АуƒЋуƒМуƒ—уЋуОуЈу‚у‚‹%i фЛЖу‚’хŒфИ€у‚АуƒЋуƒМуƒ—уЋуОуЈу‚у‚‹у‚ГуƒЁуƒГуƒˆч„ЁчЗšцЉŸуИцŽЅчЖšхЎŒфК†у‚Гуƒ”уƒМх›НуƒуƒМуƒˆу‚’ц‰‹х‹•уЇшЈ­хЎšу‚Ћу‚Йу‚Пуƒ ...хˆ‡у‚Šх–у‚ŠDTCSцЅЕц€ЇDTMF уƒ‡у‚ГуƒМуƒ‰х‰Šщ™Єщ–‹ч™Кш€…уƒЂуƒМуƒ‰шЈКц–­уƒЌуƒуƒМуƒˆщ€фПЁу‚’хœц­ЂцЌЁх›žу‹у‚‰ %s уЋцŽЅчЖšу™у‚‹щš›уЋуƒ—уƒ­уƒГуƒ—уƒˆу‚’шЁЈчЄКу—уЊу„уƒ€у‚ІуƒГуƒ­уƒМуƒ‰ч„ЁчЗšцЉŸу‹у‚‰уƒ€у‚ІуƒГуƒ­уƒМуƒ‰ч„ЁчЗšцЉŸу‹у‚‰уƒ€у‚ІуƒГуƒ­уƒМуƒ‰...уƒ€у‚ІуƒГуƒ­уƒМуƒ‰ц‰‹щ †уƒ‰уƒЉу‚ЄуƒуƒМцƒ…х Бх€Єу‚’ш‡Њх‹•шЈ­хЎšх‘ЈцГЂц•Ау‚’х…ЅхŠ›уƒуƒМуƒˆу‚’х…ЅхŠ›:ч„ЁчЗšцЉŸуЈуЎщ€šфПЁу‚ЈуƒЉуƒМхЎŸщЈ“чš„уƒ‰уƒЉу‚ЄуƒуƒМCSVуЋу‚Ју‚Џу‚ЙуƒуƒМуƒˆCSVуЋу‚Ју‚Џу‚ЙуƒуƒМуƒˆ...FMуƒЉу‚Иу‚Њуƒ•у‚ЃуƒЋу‚ПуƒМцЄœчДЂцЌЁу‚’цЄœчДЂцЄœчДЂ...%s уЎх‡Іч†уŒхЎŒфК†у—уОу—уŸх‘ЈцГЂц•А(MHz)шЈ­хЎšу‚’х–хО—у—уІу„уОу™шЁŒчЇЛх‹•цŒ‡хЎšу—уŸшЁŒуЋчЇЛх‹•:шЁŒчЇЛх‹•...уƒ˜уƒЋуƒ—уƒуƒМуƒˆуŒфИц˜ŽуЎх Дхˆ...чЉКуЎуƒЁуƒЂуƒЊуƒМу‚’щžшЁЈчЄКу‚ЄуƒГуƒуƒМуƒˆуƒ•у‚Ёу‚ЄуƒЋу‹у‚‰у‚ЄуƒГуƒуƒМуƒˆ...у‚ЄуƒГуƒуƒМуƒˆуЏцŽЈхЅЈу•у‚ŒуОу›у‚“фИŠуЋ1шЁŒшПНхŠ х†…щƒЈуƒ‰уƒЉу‚ЄуƒуƒМу‚ЈуƒЉуƒМчЗЏхКІшЈ­хЎšу‚’уƒ­уƒМуƒ‰у—уІу„уОу™шЕЗх‹•уƒЁуƒƒу‚ЛуƒМу‚ИяМ‘яМˆхŠшЇ’12ц–‡х­—яМ‰шЕЗх‹•уƒЁуƒƒу‚ЛуƒМу‚ИяМ’яМˆхŠшЇ’12ц–‡х­—яМ‰шЛНхКІуƒЁуƒЂуƒЊуƒМуƒЁуƒЂуƒЊуƒМ %i уЏх‰Šщ™ЄуЇууОу›у‚“х—фПЁуƒЂуƒМуƒ‰уƒЂуƒ‡уƒЋ2уЄфЛЅфИŠуЎуƒуƒМуƒˆуŒшІ‹уЄу‹у‚ŠуОу—уŸ: %sфИ‹уЋчЇЛх‹•фИŠуЋчЇЛх‹•ц–АшІу‚Іу‚ЃуƒГуƒ‰у‚Іц–Ау—у„уƒуƒМу‚ИуƒЇуƒГуŒхˆЉч”ЈхЏшƒНуЇу™чЉКуЎшЁŒуŒшІ‹уЄу‹у‚ŠуОу›у‚“шЁŒу‚Њуƒ•у‚ЛуƒƒуƒˆуƒЁуƒЂуƒЊуƒМу‚Пуƒ–уЎуПу‚Ју‚Џу‚ЙуƒуƒМуƒˆуЇууОу™щ–‹уцœ€шП‘фНПуЃуŸуƒ•у‚Ёу‚ЄуƒЋуƒ†уƒГуƒ—уƒЌуƒМуƒˆу‚’щ–‹ууƒ•у‚Ёу‚ЄуƒЋу‚’щ–‹уц–Ау—у„у‚Іу‚ЃуƒГуƒ‰у‚ІуЇщ–‹ууƒ†уƒГуƒ—уƒЌуƒМуƒˆуƒ‡у‚ЃуƒЌу‚ЏуƒˆуƒЊу‚’щ–‹ууƒЁуƒЂуƒЊуƒМу‚’фИŠц›Иуу—уОу™у‹яМŸуƒšуƒМу‚ЙуƒˆуƒšуƒМу‚Йуƒˆу™у‚‹уЈ %s фЛЖуЎуƒЁуƒЂуƒЊуƒМуŒфИŠц›Иуу•у‚ŒуОу™уƒšуƒМу‚Йуƒˆу™у‚‹уЈуƒЁуƒЂуƒЊуƒМ %s уŒфИŠц›Иуу•у‚ŒуОу™уƒšуƒМу‚Йуƒˆу™у‚‹уЈуƒЁуƒЂуƒЊуƒМ %s уŒфИŠц›Иуу•у‚ŒуОу™уƒšуƒМу‚Йуƒˆу™у‚‹уЈуƒЁуƒЂуƒЊуƒМ %s уŒфИŠц›Иуу•у‚ŒуОу™ц–Ау—у„уƒуƒМу‚ИуƒЇуƒГу‚’у‚ЄуƒГу‚ЙуƒˆуƒМуƒЋу™у‚‹х‰уЋхП…уšCHIRPу‚’чЕ‚фК†у—уІуу у•у„у€‚уŠхО…уЁуу у•у„у‚БуƒМуƒ–уƒЋу‚’цŽЅчЖšу—уІOKу‚’у‚ЏуƒЊуƒƒу‚Џу—уІуу у•у„у€‚уƒуƒМуƒˆх‡КхŠ›хАхˆЗуƒ—уƒЌуƒ“уƒЅуƒМхАхˆЗуƒ—уƒ­уƒ‘уƒ†у‚Ѓч„ЁчЗšцЉŸц›Дц–АуŒхП…шІуЇу™%s фЛЖуЎуƒЁуƒЂуƒЊуƒМу‚’х–хО—у—уОу—уŸшЈКц–­уƒЌуƒуƒМуƒˆщ€фПЁшЈКц–­уƒЌуƒуƒМуƒˆуЏу€CHIRPуƒ—уƒ­у‚Иу‚Їу‚ЏуƒˆуŒуЉуЎч„ЁчЗšцЉŸу‚„OSуЋщ™у‚‰у‚ŒуŸуƒЊу‚НуƒМу‚Йу‚’фНПу†уЙуу‹у‚’хˆЄц–­у™у‚‹уЎуЋхНЙчЋ‹уЁуОу™у€‚у“уЎуОуОцœ‰хŠЙуЋу—уІуŠу„уІу„уŸу у‘у‚‹уЈцœ‰у‚Šщ›Ѓу„уЇу™у€‚цœЌхН“уЋч„ЁхŠЙуЋу—уОу™у‹яМŸх†шЕЗх‹•уŒхП…шІуЇу™цœ€шП‘щ–‰у˜уŸ%iх€‹уЎу‚Пуƒ–у‚’щ–‹уцœ€шП‘щ–‰у˜уŸ%iх€‹уЎу‚Пуƒ–у‚’щ–‹ушЕЗх‹•ц™‚уЋу‚Пуƒ–у‚’хОЉх…ƒшЈ­хЎšу‚’х–хО—у—уОу—уŸфПх­˜фПх­˜у—уОу™у‹яМŸуƒ•у‚Ёу‚ЄуƒЋуЋфПх­˜шЈ­хЎšу‚’фПх­˜у‚Йу‚­уƒЃуƒГуƒЊу‚Йуƒˆу‚Йу‚ЏуƒЉуƒГуƒ–уƒЋу‚Лу‚­уƒЅуƒЊуƒ†у‚ЃуƒЊу‚Йу‚ЏуƒуƒГуƒ‰уƒ—уƒЉуƒГу‚’щИцŠž...уƒуƒГуƒ‰уƒ—уƒЉуƒГщИцŠžу‚ЕуƒМуƒ“у‚ЙшЈ­хЎšшПНхŠ уƒ•у‚ЃуƒМуƒЋуƒ‰у‚’шЁЈчЄКу‚ЄуƒЁуƒМу‚ИуЎуƒуƒƒу‚Џу‚Ђуƒƒуƒ—у‚’шЁЈчЄКфИІуГц›ПуˆяМˆ%i фЛЖяМ‰фИІуГц›ПуˆяМˆ%i фЛЖяМ‰ц˜‡щ †уЋфИІуГц›ПуˆяМˆ%i фЛЖяМ‰ц˜‡щ †уЋфИІуГц›ПуˆяМˆ%i фЛЖяМ‰щ™щ †уЋфИІуГц›ПуˆяМˆ%i фЛЖяМ‰щ™щ †уЋфИІуГц›ПуˆяМˆ%i фЛЖяМ‰у‚ЋуƒЉуƒ у‚’щИцŠžфИІуГц›ПуˆфИІуГц›ПуˆфИ­цˆхŠŸцŽЈхЅЈу•у‚Œу‚‹уƒЁуƒЂуƒЊуƒМуЎу‚ЄуƒГуƒуƒМуƒˆц–ЙцГ•уЏу€у‚НуƒМу‚Йуƒ•у‚Ёу‚ЄуƒЋу‚’щ–‹уу€уу“у‹у‚‰цŒ‡хЎšх Дц‰€уЋуƒЁуƒЂуƒЊуƒМу‚’у‚Гуƒ”уƒМяМ†уƒšуƒМу‚Йуƒˆу™у‚‹у“уЈуЇу™у€‚у“уЎуОуОу“уЎу‚ЄуƒГуƒуƒМуƒˆцЉŸшƒНу‚’чЖšшЁŒу™у‚‹уЈу€CHIRPуЏчОхœЈщ–‹у„уІу„у‚‹уƒ•у‚Ёу‚ЄуƒЋуЋу‚у‚‹у™уЙуІуЎуƒЁуƒЂуƒЊуƒМу‚’ %(file)s х†…уЎу‚‚уЎуЋчНЎуц›уˆуОу™у€‚у“уЎуƒ•у‚Ёу‚ЄуƒЋу‚’щ–‹у„уІу€ŒуƒЁуƒЂуƒЊу€у‚’у‚Гуƒ”уƒМяМ†уƒšуƒМу‚Йуƒˆу—уОу™у‹яМŸуу‚ŒуЈу‚‚у‚ЄуƒГуƒуƒМуƒˆу‚’чЖšу‘уОу™у‹яМŸу“уЎшЁŒуЎх†…хЎЙу‚’х‰Šщ™Єу“уЎу‚ЄуƒЁуƒМу‚ИуЋуЏуƒ•у‚ЁуƒМуƒ у‚Іу‚Їу‚Ђцƒ…х БуŒхЋуОу‚ŒуІу„уОу›у‚“у€‚ц—ЇуƒуƒМу‚ИуƒЇуƒГуОуŸуЏу‚Ћу‚Йу‚Пуƒ уƒуƒМу‚ИуƒЇуƒГуЎCHIRPуЇфНœцˆу•у‚ŒуŸхЏшƒНц€ЇуŒу‚у‚ŠуОу™у€‚уƒ‡уƒМу‚ПфПх…ЈуЈфК’ц›ц€ЇуЎуŸу‚уЋц–АуŸуЋч„ЁчЗšцЉŸу‹у‚‰уƒ€у‚ІуƒГуƒ­уƒМуƒ‰у—ч›Ду™у“уЈу‚’уŠх‹Їу‚у—уОу™у€‚Quansheng UV-K5 ч”ЈуЏхЎŸщЈ“чš„уЊуƒ‰уƒЉу‚ЄуƒуƒМуЇу™у€‚ ч„ЁчЗšцЉŸуŒц­ЃхИИуЋх‹•фНœу—уЊууЊу‚‹хЏшƒНц€ЇуŒу‚у‚ŠуОу™у€‚у™уЙуІш‡ЊхЗБшВЌфЛЛуЇу”хˆЉч”Јуу у•у„у€‚ хЄ‰ц›Ду‚’шЁŒу†х‰уЋч„ЁчЗšцЉŸу‹у‚‰уƒ€у‚ІуƒГуƒ­уƒМуƒ‰у—уŸуƒ‡уƒМу‚Пу‚’фПх­˜у—уІуŠуу‚ˆу†уЋу—уІуу у•у„у€‚ уƒуƒƒу‚Џу‚Ђуƒƒуƒ—уŒу‚у‚ŒуАх•щЁŒуŒч™Кч”Ÿу—уІу‚‚у‚ЊуƒЊу‚ИуƒŠуƒЋуЎчŠЖц…‹уЋцˆЛу™у“уЈуŒуЇууОу™у€‚ у„ууЄу‹уЎшЈ­хЎšуЋщ–Ђу—уІуЏуОу хЎŸшЃ…у•у‚ŒуІу„уОу›у‚“у€‚у“уЎшЁŒу‚’х‰Šщ™Єу—уІх…ЈфН“у‚’фИŠц–Йх‘уЋу‚Зуƒ•уƒˆу“уЎшЁŒу‚’х‰Šщ™Єу—уІу‚АуƒЋуƒМуƒ—у‚’фИŠц–Йх‘уЋу‚Зуƒ•уƒˆуƒˆуƒМуƒГ(Hz)уƒˆуƒМуƒГуƒЂуƒМуƒ‰уƒˆуƒМуƒГу‚Йу‚БуƒЋуƒу‚Йуƒ†уƒƒуƒ—(kHz)USBуƒуƒМуƒˆцЄœх‡КуƒуƒМуƒˆу‚’цЄœх‡КуЇууОу›у‚“уЇу—уŸу€‚уƒ‰уƒЉу‚ЄуƒуƒМуŒу‚ЄуƒГу‚ЙуƒˆуƒМуƒЋу•у‚ŒуІу„у‚‹у‹уЈцŽЅчЖšчŠЖц…‹у‚’у‚‚у†фИ€хКІчЂКшЊу—уІуу у•у„у€‚у‚БуƒМуƒ–уƒЋу‚’цŠœу„уІу‹у‚‰OKу‚’у‚ЏуƒЊуƒƒу‚Џу—уІуу у•у„у€‚у‚Ђуƒƒуƒ—уƒ­уƒМуƒ‰ц‰‹щ †ч„ЁчЗšцЉŸуЋу‚Ђуƒƒуƒ—уƒ­уƒМуƒ‰ч„ЁчЗšцЉŸуЋу‚Ђуƒƒуƒ—уƒ­уƒМуƒ‰...х›КхЎšхЙ…уƒ•у‚ЉуƒГуƒˆу‚’фНПч”ЈхЄЇуу„уƒ•у‚ЉуƒГуƒˆу‚’фНПч”Јх€ЄуЏ %i bitуЋу—уІуу у•у„х€ЄуЏ %.4f фЛЅфИŠуЋу—уІуу у•у„х€ЄуЏ %.4f фЛЅфИ‹уЋу—уІуу у•у„х€ЄуЏ %i цЁуЋу—уІуу у•у„х€ЄуЏ 0 фЛЅфИŠуЋу—уІуу у•у„х€ЄуƒЁуƒМу‚ЋуƒМшЁЈчЄКу‚ˆу†у“ууƒ‡у‚Йу‚Џуƒˆуƒƒуƒ—уЋCHIRPуЎу‚Ђу‚Єу‚ГуƒГу‚’шЈ­хЎšу—уОу™у‹яМŸу‚уЊуŸуЎу‚БуƒМуƒ–уƒЋуŒфНПч”Ју—уІу„у‚‹уƒуƒМуƒˆ:ч„ЁхŠЙцœ‰хŠЙchirp-20240224/chirp/locale/en_US/0000755000175000017500000000000014566340177015426 5ustar hibbyhibbychirp-20240224/chirp/locale/en_US/LC_MESSAGES/0000755000175000017500000000000014566340177017213 5ustar hibbyhibbychirp-20240224/chirp/locale/en_US/LC_MESSAGES/CHIRP.mo0000644000175000017500000000064714566340175020422 0ustar hibbyhibbyо•4L`af-m› HelpImportProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2011-11-29 16:07-0800 Last-Translator: Dan Smith Language-Team: English Language: en_US MIME-Version: 1.0 Content-Type: text/plain; charset=ASCII Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); HelpImportchirp-20240224/chirp/locale/pl/0000755000175000017500000000000014566340177015030 5ustar hibbyhibbychirp-20240224/chirp/locale/pl/LC_MESSAGES/0000755000175000017500000000000014566340177016615 5ustar hibbyhibbychirp-20240224/chirp/locale/pl/LC_MESSAGES/CHIRP.mo0000644000175000017500000005462014566340175020024 0ustar hibbyhibbyо•”o Ш-Щ+ї#*р9п^њY _k oy˜ЎРвлсчыѓ ]JoКЬм№џ (H,Mz‚•І ЌЗПжпф ьіњ џ  $(/A>€ ’ŸБКУ оџ29Vqˆ ГЬъ§&EY y‡u 7@X^1e— œІ.М ыѕњ  $ ) 4 8 7L „ ‹ Ђ Ј ­ Й Ъ р 'ѕ !+!9P9Y9_9e9 i9#w9›9QЂ9Gє9<:O:_:t:ƒ:š:3Љ:н::ф: ;*;C;]; e; r;|; ›;І;­; В;П;Ц;Ю; п;ы;ў;<<c<|< –<Ђ< И<Ф<Ь<,ц<==1=G="O=!r= ”= Е=Р=л=*љ=$$>I>Y>o>!‹>­>(Ч>№> ?z?5Œ?!Т?ф?ь?@@B@Q@Z@"m@9@Ъ@л@р@ѕ@AA A(A,AICAA–AБAИA НAШAпAљA6BKBbB}B*–BСBнB№BљBC.C=CLC8\C•C”ДCIE^EvEE:œE&зEўEF FFF)F&GFnFF ‘F›FЖFеF)юF G&G5G ;GIG_G2uGЈGТGЪGфG HH H5H'KHsHŠH›H#АHдH шHѓH4љH&.I'UI&}I?ЄI8фIK'-KUKZK4^K“K ЄKЏKОKЭKрK шK,єK!Lж:L@MRMnM‡MœMЛMЯMтьMЯNхNјNџN O(O .rшeШљОїзƒ1SџœИ<•0HŽќ=І n6э-zВC8a”ёкыЧ Ц:ис  NŠŸ(Йѓгž[Џc!чGФOНЈ юУ|dпAРь‘ЋR`„)АkY IFє˜ЊX›h–t%(value)s must be between %(min)i and %(max)i%s has not been saved. Save before closing?(none)...and %i more1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to download image from device. It will may not work if you turn on the radio with the cable already attached 1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to upload the image to device. It will may not work if you turn on the radio with the cable already attachedA new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllAll FilesAll supported formats|AmateurAn error has occurredApplying settingsAvailable modulesBandplanBandsBanksBinBrowserBuilding Radio BrowserCanadaChanging this setting requires refreshing the settings from the image, which will happen now.Channels with equivalent TX and RX %s are represented by tone mode of "%s"Chirp Image FilesChoice RequiredChoose %s DTCS CodeChoose %s ToneChoose Cross ModeChoose duplexChoose the module to load from issue %i:CityClone completed, checking for spurious bytesCloningCloning from radioCloning to radioCloseClose fileCommentCommunicate with radioCompleteCopyCountryCustom...CutDTCSDTCS PolarityDV MemoryDanger AheadDecDeleteDeveloper ModeDeveloper state is now %s. CHIRP must be restarted to take effectDiff Raw MemoriesDigital CodeDisable reportingDisabledDistanceDo not prompt again for %sDouble-click to change bank nameDownloadDownload from radioDownload instructionsDuplexEdit details for %i memoriesEdit details for memory %iEnable Automatic EditsEnabledEnter FrequencyEnter Offset (MHz)Enter TX Frequency (MHz)Enter a new name for bank %s:Enter custom port:Erased memory %sError applying settingsError communicating with radioExperimental driverExport can only write CSV filesExport to CSVExtraFREE repeater database, which provides most up-to-date information about repeaters in Europe. No account is required.Failed to load radio browserFailed to parse resultFeaturesFile does not exist: %sFilesFilterFilter results with location matching this stringFindFind NextFinished radio job %sFound empty list value for %(name)s: %(value)rFrequencyGMRSGetting settingsGoto MemoryGoto Memory:HelpHelp Me...HexHide empty memoriesIf set, sort results by distance from these coordinatesImportImport not recommendedIndexInfoInformationInsert Row AboveInstall desktop icon?Interact with driverInvalid %(value)s (use decimal degrees)Invalid EntryInvalid ZIP codeInvalid edit: %sInvalid or unsupported module fileInvalid value: %rIssue number:LIVELatitudeLength must be %iLimit BandsLimit ModesLimit StatusLimit results to this distance (km) from coordinatesLoad module from issueLoading modules can be extremely dangerous, leading to damage to your computer, radio, or both. NEVER load a module from a source you do not trust, and especially not from anywhere other than the main CHIRP website (chirp.danplanet.com). Loading a module from another source is akin to giving them direct access to your computer and everything on it! Proceed despite this risk?Loading settingsLongitudeMemoriesMemory %i is not deletableMemory must be in a bank to be editedMemory {num} not in bank {bank}ModeModelModesModuleModule LoadedModule loaded successfullyMore than one port found: %sMove DownMove UpNew WindowNew version availableNo empty rows below!No modules foundNo modules found in issue %iNo resultsNo results!NumberOffsetOnly certain bandsOnly certain modesOnly memory tabs may be exportedOnly working repeatersOpenOpen RecentOpen Stock ConfigOpen a fileOpen a moduleOpen debug logOpen in new windowOpen stock config directoryOptional: -122.0000Optional: 100Optional: 45.0000Optional: County, Hospital, etc.Overwrite memories?ParsingPastePasted memories will overwrite %s existing memoriesPasted memories will overwrite memories %sPasted memories will overwrite memory %sPasted memory will overwrite memory %sPlease be sure to quit CHIRP before installing the new version!Please note that developer mode is intended for use by developers of the CHIRP project, or under the direction of a developer. It enables behaviors and functions that can damage your computer and your radio if not used with EXTREME care. You have been warned! Proceed anyway?Please waitPlug in your cable and then click OKPortPowerPress enter to set this in memoryPrint PreviewPrintingPropertiesQuery %sQuery SourceRX DTCSRadioRadio did not ack block %iRadio informationRadio sent data after the last awaited block, this happens when the selected model is a non-US but the radio is a US one. Please choose the correct model and try again.RadioReference Canada requires a login before you can queryRefresh requiredRefreshed memory %sReload DriverReload Driver and FileRename bankReporting enabledReporting helps the CHIRP project know which radio models and OS platforms to spend our limited efforts on. We would really appreciate if you left it enabled. Really disable reporting?Restart RequiredRetrieved settingsSaveSave before closing?Save fileSaved settingsSelect BandsSelect ModesSelect a bandplanServiceSettingsShow Raw MemoryShow debug log locationShow extra fieldsSome memories are incompatible with this radioSome memories are not deletableSort by column:Sort memoriesSortingStateState/ProvinceSuccessThe author of this module is not a recognized CHIRP developer. It is recommended that you not load this module as it could pose a security risk. Proceed anyway?The recommended procedure for importing memories is to open the source file and copy/paste memories from it into your target image. If you continue with this import function, CHIRP will replace all memories in your currently-open file with those in %(file)s. Would you like to open this file to copy/paste memories across, or proceed with the import?This MemoryThis is an early stage beta driver This is an early stage beta driver - upload at your own risk This memory and shift all upThis memory and shift block upThis should only be enabled if you are using modified firmware that supports wider frequency coverage. Enabling this will cause CHIRP not to enforce OEM restrictions and may lead to undefined or unregulated behavior. Use at your own risk!This will load a module from a website issueToneTone ModeTone SquelchTuning StepUSB Port FinderUnable to determine port for your cable. Check your drivers and connections.Unable to edit memory before radio is loadedUnable to find stock config %rUnable to open the clipboardUnable to queryUnable to read last block. This often happens when the selected model is US but the radio is a non-US one (or widebanded). Please choose the correct model and try again.Unable to reveal %s on this systemUnable to set %s on this memoryUnited StatesUnplug your cable (if needed) and then click OKUpload instructionsUpload to radioUploaded memory %sUse fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterValuesVendorViewWARNING!WarningWarning: %sWelcomeWould you like CHIRP to install a desktop icon for you?Your cable appears to be on port:bitsbytesbytes eachdisabledenabled{bank} is fullProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2023-07-12 21:21+0200 Last-Translator: szporwolik Language-Team: Polish Language: pl MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); X-Generator: Poedit 3.3.2 %(value)s muszФ… byФ‡ pomiФ™dzy %(min)i oraz %(max)i%s nie zostaХ‚ zapisany. ZapisaФ‡ przed zamkniФ™ciem?(brak)...oraz %i wiФ™cej1. WХ‚Ф…cz radio. 2. PodХ‚Ф…cz kabel do zХ‚Ф…cza mikrofonu/gХ‚oХ›nika. 3. Upewnij siФ™, ХМe zХ‚Ф…cze jest dobrze podХ‚Ф…czone. 4. Kliknij OK, aby przesХ‚aФ‡ obraz do urzФ…dzenia. Obraz moХМe nie dziaХ‚aФ‡, jeХ›li radio zostanie wХ‚Ф…czone z podХ‚Ф…czonym kablem 1. WХ‚Ф…cz radio. 2. PodХ‚Ф…cz kabel do zХ‚Ф…cza mikrofonu/gХ‚oХ›nika. 3. Upewnij siФ™, ХМe zХ‚Ф…cze jest dobrze podХ‚Ф…czone. 4. Kliknij OK, aby przesХ‚aФ‡ obraz do urzФ…dzenia. Obraz moХМe nie dziaХ‚aФ‡, jeХ›li radio zostanie wХ‚Ф…czone z podХ‚Ф…czonym kablemNowa wersja programu CHIRP jest dostФ™pna. OdwiedХК stronФ™ internetowФ… projektu i pobierz jФ…!O programieO programie CHIRPWszystkieWszystkie plikiWszystkie wspierane formaty|AmatorskaWystФ…piХ‚ bХ‚Ф…dStosowanie ustawieХ„DostФ™pne moduХ‚yBandplanPasmaBankiBinPrzeglФ…darkaBudowanie przeglФ…darki radiostacjiKanadaZmiana tego ustawienia wymaga odХ›wieХМenia z obrazu, co zostanie teraz wykonane.KanaХ‚y z takim samym TX oraz RX %s sФ… reprezentowane trybem tonu "%s"Pliki obrazu CHIRPWymagany wybУГrWybierz %s kod DTCS Wybierz %s tonWybierz tryb krzyХМowyWybierz duplexWybierz moduХ‚ do zaimportowania ze zgХ‚oszenia %i:MiastoKlonowane zakoХ„czone, sprawdzanie niewХ‚aХ›ciwych bajtУГwKlonowaniePobieranie z radiostacjiWysyХ‚anie do radiostacjiZamknijZamknij plikKomentarzSkomunikuj siФ™ z radiostacjФ…UkoХ„czonoKopiujKrajNietypowy...WytnijDTCS TXPolaryzacja DTCSPamiФ™Ф‡ DVNiebezpieczeХ„stwoDecUsuХ„Tryb deweloperaTryb developera jest teraz %s. CHIRP musi zostaФ‡ ponowie uruchomiony, aby zmiany przyniosХ‚y efektPorУГwnaj surowe pamiФ™ciKod cyfrowyWyХ‚Ф…cz raportowanieWyХ‚Ф…czonyDystansNie pytaj ponownie dla %sKliknij podwУГjnie w celu zmiany nazwy bankuPobierzPobierz z radiostacjiInstrukcje pobieraniaDupleksZmieХ„ szczegУГХ‚y dla %i pamiФ™ciZmieХ„ szczegУГly dla pamiФ™ci %iZezwУГl na automatycznФ… edycjФ™WХ‚Ф…czonyWprowadХК czФ™stotliwoХ›Ф‡WprowadХК przesuniФ™cie (MHz)WprowadХК czФ™stotliwoХ›Ф‡ nadawania (MHz)WprowadХК nowФ… nazwФ™ dla banku %s:WprowadХК port:Skasowano pamiФ™Ф‡ %sBХ‚Ф…d stosowania ustawieХ„BХ‚Ф…d komunikacji z radiostacjФ…Sterownik eksperymentalnyEksport moХМe tylko zapisywaФ‡ pliki CSVEksportuj do pliku CSVDodatkowaDARMOWA baza przemiennikУГw, ktУГra dostarcza informacji o przemiennikach w Europie. Nie jest wymagane konto uХМytkownika.Nie udaХ‚o siФ™ zaХ‚adowaФ‡ przeglФ…darki radiostacjiParsowanie wyniku nie udaХ‚o siФ™FunkcjePlik nie istnieje: %sPlikiFiltrFiltruj wyniki z lokalizacjФ… pasujФ…co do tej wartoХ›ci tekstowejWyszukajWyszukaj nastФ™pnyZakoХ„czono zadanie radiostacji %sZnaleziono pustФ… wartoХ›Ф‡ listy dla %(name)s: %(value)rCzФ™stotliwoХ›Ф‡GMRSPobieranie ustawieХ„IdХК do pamiФ™ciIdХК do pamiФ™ci:PomocPomocy...HexUkrywaj puste pamiФ™ciJeХ›li ustawiono, sortuje wyniki po odlegХ‚oХ›ci od tych wspУГХ‚rzФ™dnychImportujImportuj nie jest zalecanyIndeksInfoInformacjaUmieХ›Ф‡ wiersz wyХМejUtworzyФ‡ skrУГt pulpitu?Interakcja ze sterownikiemNiewХ‚aХ›ciwe %(value)s (uХМywaj stopni dziesiФ™tnych)NiewХ‚aХ›ciwy wpis: %sNiewХ‚aХ›ciwy kod pocztowyNiewХ‚aХ›ciwa edycja: %sNiewХ‚aХ›ciwy lub niespierany plik moduХ‚uNiewХ‚aХ›ciwa wartoХ›Ф‡: %rNumer zgХ‚oszenia:Na ХМywoSzerokoХ›Ф‡ geograficznaDХ‚ugoХ›Ф‡ musi wynosiФ‡ %iOgranicz pasmaOgranicz trybyOgranicz statusOgranicz wyniki do odlegХ‚oХ›ci (km) od wspУГХ‚rzФ™dnychZaХ‚aduj moduХ‚ ze zgХ‚oszeniaХadowanie moduХ‚УГw moХМe byФ‡ ekstremalnie niebezpiecznie i prowadziФ‡ do uszkodzenia komputera lub/oraz radiostacji. NIGDY nie Х‚aduj moduХ‚u ze ХКrУГdХ‚a, ktУГremu nie ufasz, w szczegУГlnoХ›ci nie pobranego ze strony projektu CHIRP (chirp.danplanet.com). Хadowanie moduХ‚u z innego ХКrУГdХ‚a jest rУГwnoznaczne z udzielaniem dostФ™pu do komputera oraz wszystkiego na nim! KontynuowaФ‡ pomimo ryzyka?Хadowanie ustawieХ„DХ‚ugoХ›Ф‡ geograficznaPamiФ™ciPamiФ™Ф‡ %i jest nieusuwalnaPamiФ™Ф‡ musi byФ‡ w banku, aby moХМna jФ… byХ‚o edytowaФ‡PamiФ™Ф‡ {num} nie jest w banku {bank}TrybModelTrybyModuХ‚ZaХ‚adowano moduХ‚PomyХ›lnie zaХ‚adowano moduХ‚Znaleziono wiФ™cej niХМ jeden port: %sPrzesuХ„ w dУГХ‚PrzesuХ„ w gУГrФ™Nowe oknoNowa wersja jest dostФ™pnaBrak pustych wierszy poniХМej!Nie znaleziono moduХ‚УГwNie znaleziono moduХ‚УГw w zgХ‚oszeniu %iBrak wynikУГwBrak wynikУГw!NumerPrzesuniФ™cieTylko konkretne pasmaTylko konkretne trybyTylko zakХ‚adki pamiФ™ci mogФ… byФ‡ wyeksportowaneTylko czynne przemiennikiOtwУГrzOtwУГrz ostatnio uХМywanyOtwУГrz konfiguracjФ™ wstФ™pnФ…OtwУГrz plikOtwУГrz moduХ‚OtwУГrz log debugowyOtwУГrz w nowym oknieOtwУГrz katalog konfiguracji wstФ™pnychOpcjonalnie: -122.0000Opcjonalnie: 100Opcjonalnie: 45.0000Opcjonalnie: Szpital, Hrabstwo itp.NadpisaФ‡ pamiФ™ci?ParsowanieWklejWklejone pamiФ™ci nadpisze %s istniejФ…cych pamiФ™ciWklejone pamiФ™ci nadpisze pamiФ™ci %sWklejone pamiФ™ci nadpiszФ… pamiФ™Ф‡ %sWklejona pamiФ™Ф‡ nadpisze pamiФ™Ф‡ %sProszФ™ wyjdХК z programu CHIRP przed instalacjФ… nowej wersji!ProszФ™ zauwaХМyФ‡, ХМe tryb dewelopera jest przeznaczony dla deweloperУГw projektu CHIRP lub do uХМycia pod nadzorem dewelopera. WХ‚Ф…cza on zachowania oraz funkcje, ktУГre mogФ… uszkodziФ‡ komputer oraz radiostacjФ™, jeХ›li nie bФ™dФ… wykorzystywane z EKSTREMALNФ„ uwagФ…. ZostaХ‚eХ› ostrzeХМony! KontynuowaФ‡?ProszФ™ czekaФ‡PodХ‚Ф…cz kabel i naciХ›nij przycisk OKPortMocNaciХ›nij przycisk enter, aby ustawiФ‡ to w pamiФ™ciPodglФ…d wydrukuDrukowanieWХ‚aХ›ciwoХ›ciOdpytywanie %sХЙrУГdХ‚o zapytaХ„DTCS RXRadiostacjaRadiostacja nie potwierdziХ‚a (ack) bloku %iInformacje o radiostacjiRadiostacja wysХ‚aХ‚a dane po ostatnim bloku oczekiwania, to dzieje siФ™ jeХ›li jest ona przeznaczona na amerykaХ„ski rynek, a wybrano model na inne regiony. NaleХМy wybraФ‡ wХ‚aХ›ciwy model i sprУГbowaФ‡ ponownie.RadioReference Canada wymaga logowania przed wysХ‚aniem zapytaХ„Wymagane jest odХ›wieХМenieOdХ›wieХМono pamiФ™Ф‡ %sPrzeХ‚aduj sterownikPrzeХ‚aduj sterownik oraz plikZmieХ„ nazwФ™ bankuRaportowanie jest wХ‚Ф…czoneRaportowanie pomaga projektowi CHIRP zrozumieФ‡, ktУГre modele radiostacji oraz systemУГw operacyjnych naleХМy traktowaФ‡ priorytetowo. NaprawdФ™ doceniamy zostawienie tej opcji wХ‚Ф…czonej. NaprawdФ™ wyХ‚Ф…czyФ‡ raportowanie?Wymagany jest restartPobrano ustawieniaZapiszZapisaФ‡ przed zamkniФ™ciem?Zapisz plikZapisano ustawieniaWybierz pasmaWybierz trybyWybierz bandplanUsХ‚ugaUstawieniaPokaХМ surowФ… pamiФ™Ф‡PokaХМ lokalizacjФ™ pliku debugPokazuj dodatkowe polaNiektУГre pamiФ™ci sФ… niekompatybilne z tФ… radiostacjФ…NiektУГre pamiФ™ci sФ… nieusuwalneSortuj wg kolumny:Sortuj pamiФ™ciSortowanieStanStan/ProwincjaSukcesAutor tego moduХ‚u nie jest znany programistom projektu CHIRP. ModuХ‚ moХМe stwarzaФ‡ ryzyko, dlatego rekomendujemy nie Х‚adowanie tego moduХ‚u. KontynuowaФ‡ pomimo tego?RekomendowanФ… procedurФ… do importowania pamiФ™ci jest otworzenie pliku ХКrУГdХ‚owego i kopiowanie/wklejanie z niego do docelowego pliku obrazu. Kontynuacja importu spowoduje, ХМe CHIRP zastФ…pi wszystkie pamiФ™ci w aktualnie otwartym pliku tymi z %(file)s. Czy chcesz otworzyФ‡ ten plik, aby kopiowaФ‡/wklejaФ‡ pamiФ™ci lub kontynuowaФ‡ import?TФ… pamiФ™Ф‡To sterownik we wczesnej wersji beta To sterownik we wczesnej wersji beta - wysyХ‚asz na wХ‚asne ryzyko TФ… pamiФ™Ф‡ i przeusХ„ wszystkie wyХМejTФ… pamiФ™Ф‡ i przesuХ„ blok wyХМejTo powinno zostaФ‡ wХ‚Ф…czone jedynie jeХ›li korzystasz ze zmodyfikowanego firmware z szerszym pokryciem czФ™stotliwoХ›ci. WХ‚Ф…cznie spowoduje, ХМe CHIRP przestanie wymuszaФ‡ ograniczenia producenta radiostacji (OEM) i moХМe doprowadziФ‡ do nieprzewidywalnego lub niezgodnego z przepisami zachowania. WХ‚Ф…czasz na wХ‚asne ryzyko!To zaХ‚aduje moduХ‚ ze strony zgХ‚oszeniaTon TXTryb tonuTon RXKrok strojeniaWykrywacz portУГw USBNie moХМna wykryФ‡ portu kabla. NaleХМy sprawdziФ‡ sterowniki oraz poХ‚Ф…czenie.Przed pobraniem pamiФ™ci, nie moХМna jej edytowaФ‡Nie znaleziono konfiguracji wstФ™pnej %rNie moХМna otworzyФ‡ schowkaNie moХМna wykonaФ‡ zapytaniaNie moХМna odczytaФ‡ ostatniego bloku. To wystФ™puje najczФ™Х›ciej jeХ›li wybrano model na rynek US, ale radiostacja jest przeznaczona na inne regiony (lub szerokopasmowa). NaleХМy wybraФ‡ wХ‚aХ›ciwy model i sprУГbowaФ‡ ponownie.Nie moХМna odkryФ‡ %s na tym systemieNie moХМna ustawiФ‡ %s na tej pamiФ™ciStany ZjednoczoneNaleХМy odpiФ…Ф‡ kabel (jeХ›li to konieczne) i nacisnФ…Ф‡ przycisk OKInstrukcje wysyХ‚aniaWyХ›lij do radiostacjiWysХ‚ano pamiФ™Ф‡ %sUХМywaj czcionki o staХ‚ej szerokoХ›ci znakУГwUХМywaj wiФ™kszej czcionkiWartoХ›Ф‡ nie pasuje do %i bitУГwWartoХ›Ф‡ musi wynosiФ‡ przynajmniej %.4fWartoХ›Ф‡ musi wynosiФ‡ nie wiФ™cej niХМ %.4fWartoХ›Ф‡ musi mieФ‡ dokХ‚adnie %i cyfr dziesiФ™tnychWartoХ›Ф‡ musi wynosiФ‡ zero lub wiФ™cejWartoХ›ciProducentWidokUWAGA!UwagaUwaga: %sWitamyCzy CHIRP ma utworzyФ‡ ikonФ™ na pulpicie?Kabel jest widoczny na porcie:bitУГwbajtУГwbajtУГw kaХМdywyХ‚Ф…czonywХ‚Ф…czony{bank} jest peХ‚nychirp-20240224/chirp/locale/zh_CN/0000755000175000017500000000000014566340177015416 5ustar hibbyhibbychirp-20240224/chirp/locale/zh_CN/LC_MESSAGES/0000755000175000017500000000000014566340177017203 5ustar hibbyhibbychirp-20240224/chirp/locale/zh_CN/LC_MESSAGES/CHIRP.mo0000644000175000017500000002264214566340175020411 0ustar hibbyhibbyо•xмЃœ( +) рU п6 ^ u  …  Ѕ ­ С г л ю џ     $ ) 7 A E L [ m z ˆ ‘ Ќ Р з э є ќ   $2CИI•Ї˜Є@ЃхЃ‰ -7 H Tai ny”Ј ЎК Ыйъќ % , :D LWmty‹šЎ ДРХ!Ы э ћ ! 3AXj ‰’ЂК.Ьћ *<6s x ‚ ›"Ил ћ ,AQX]fLn9Лёѕ№ч@и % , 9FVr Ž›Ћ ЛШ Яйрч ь ј   3 @ MWk{ ‘ ž ЋЕМбъ ЏˆР{I{Х~A{Р< C V c s € ‡ ‘ Њ Б Ч Ю м я ! !&!9!@!G!N!U! \!i!p!w! !!Є!Ћ!О!б!с! ш!ђ!љ!" "#"*":"L" S"`"!y"›"Ў" Ф"б"и"!ы" #!&#H#d# l#v# Š$”$Є$ Д$'С$щ$%'%.%>%T%m%€%‡% Ž% ˜%8XP47 )>HjSK\Q(`%<U !?vs+oFadZ:q^3"JMT@u,=I[cV5 gfR;0YGtx.$#1CL&B* rDhw-k/p _i92bE6Om'WN] lnAe%s has not been saved. Save before closing?1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to download image from device. It will may not work if you turn on the radio with the cable already attached 1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to upload the image to device. It will may not work if you turn on the radio with the cable already attachedA new CHIRP version is available. Please visit the website as soon as possible to download it!About CHIRPAllAll FilesAn error has occurredBrowserChoose %s DTCS CodeChoose Cross ModeCloningCloning from radioCloning to radioClose fileCommentCompleteCopyCutDTCSDTCS PolarityDV MemoryDecDeleteDeveloper ModeDiff Raw MemoriesDigital CodeDigital ModesDisabledDo not prompt again for %sDownload from radioDownload from radio...Download instructionsDuplexEnabledEnter FrequencyError applying settingsExport to CSVExport to CSV...FilesFollow these instructions to upload your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio (unlock it if password protected) 4 - Click OK to start Follow these instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Click OK to start Follow this instructions to download your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to read your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to upload your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Follow this instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data FrequencyGetting settingsGoto MemoryGoto Memory:Goto...HelpHelp Me...Hide empty memoriesImportImport from file...IndexInformationInsert Row AboveInvalid EntryInvalid edit: %sInvalid value: %rLoad Module...MemoriesModeModelModesModuleModule LoadedMove DownMove UpNew WindowNew version availableOffsetOpenOpen Stock ConfigOpen debug logOverwrite memories?PastePlease waitPortPowerPress enter to set this in memoryPrint PreviewPropertiesQuery SourceRX DTCSRadioRadio informationReload DriverReload Driver and FileReporting enabledSave before closing?Save fileSettingsShow Raw MemoryShow debug log locationShow extra fieldsSome memories are incompatible with this radioSome memories are not deletableState/ProvinceThis MemoryThis is an experimental driver for the Quansheng UV-K5. It may harm your radio, or worse. Use at your own risk. Before attempting to do any changes please download the memory image from the radio with chirp and keep it. This can be later used to recover the original settings. some details are not yet implementedToneTone ModeTone SquelchTuning StepUnable to open the clipboardUnable to reveal %s on this systemUnable to set %s on this memoryUnited StatesUpload to radioUpload to radio...Use fixed-width fontUse larger fontVendorViewdisabledenabledProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2024-01-26 13:30+0800 Last-Translator: DuckSoft, BH2UEP Language-Team: Language: zh_CN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; X-Generator: Poedit 3.4.2 %s шϘцВЁцœ‰шЂЋфПх­˜у€‚шІхœЈх…Гщ—­чЈ‹хКх‰фПх­˜х—яМŸ1. ц‰“хМ€ч”ЕхАу€‚ 2. хА†ц•АцЎчКПшПžцŽЅш‡ГщКІх…‹щЃŽх’ŒхН•щŸГцœКцŽЅхЃу€‚ 3. чЁЎфПц•АцЎчКПфИŽч”ЕхАщ—ДшПžцŽЅч‰Ђх›Ку€‚ 4. ч‚Йх‡Л "чЁЎхЎš "фЛŽшЎОхЄ‡фИ‹шННц˜ хƒу€‚ хІ‚цžœхœЈхЗВшПžцŽЅц•АцЎчКПчš„цƒ…х†ЕфИ‹ц‰“хМ€ч”ЕхАяМŒхˆ™хЏшƒНц— цГ•шП›шЁŒ 1. ц‰“хМ€ч”ЕхАу€‚ 2. хА†ц•АцЎчКПшПžцŽЅш‡ГщКІх…‹щЃŽх’ŒхН•щŸГцœКцŽЅхЃу€‚ 3. чЁЎфПц•АцЎчКПфИŽч”ЕхАщ—ДшПžцŽЅч‰Ђх›Ку€‚ 4. ч‚Йх‡Л "чЁЎхЎš "фИŠфМ ц˜ хƒхˆАшЎОхЄ‡у€‚ хІ‚цžœхœЈхЗВшПžцŽЅц•АцЎчКПчš„цƒ…х†ЕфИ‹ц‰“хМ€ч”ЕхАяМŒхˆ™хЏшƒНц— цГ•шП›шЁŒц–Ачš„ CHIRP ч‰ˆцœЌхЗВчЛцŽЈх‡Ку€‚шЏЗхАНхПЋшЎПщ—ЎчН‘чЋ™фИ‹шННяМх…ГфКŽCHIRPх…Јщ€‰х…ЈщƒЈц–‡фЛЖх‘ч”Ÿщ”™шЏЏц•АцЎцЕшЇˆх™Јщ€‰ц‹Љ %s DTCS цŽЅц”ЖфЛЃч ц”Жх‘фНПч”ЈфИхŒфКšщŸГщЂ‘ц­ЃхœЈхЄхˆЖфЛŽч”ЕхАфИ‹шННфИŠфМ хˆАч”ЕхАх…ЈщƒЈц–‡фЛЖхЄ‡цГЈхЗВхЎŒцˆхЄхˆЖх‰Њхˆ‡DTCSDTCS ч­–ч•ЅшЏЅх­˜х‚ЈцŽЂцЕ‹хˆ щ™ЄхМ€х‘ш€…цЈЁхМхЏЙцЏ”хŽŸхЇ‹х­˜х‚Јц•Ах­—фЛЃч ц•Ах­—фЛЃч хЗВчІч”ЈфИх†хЏЙ %s цчЄКфЛŽч”ЕхАфИ‹шННфЛŽч”ЕхАфИ‹шННт€Іт€Іц˜ОчЄКцŒ‡хМ•хЗЎщЂ‘ц–Йх‘хЗВхЏч”ЈщЂ‘чއшЎОчНЎх€Мцœ‰шЏЏяМš%sфЛЅCSVц–‡фЛЖц МхМхЏМх‡КфЛЅCSVц–‡фЛЖц МхМхЏМх‡Кт€Іт€Іц–‡фЛЖшЏЗцŒ‰ч…ЇфЛЅфИ‹шЏДц˜ŽцЅфИŠфМ фПЁцЏхˆАц‚Јчš„ч”ЕхАяМš 1 - х…Гщ—­ч”ЕхА 2 - шПžцŽЅц•АцЎчКП 3 - ц‰“хМ€ч”ЕхАяМˆхІ‚цžœцœ‰хЏ†ч фПцŠЄяМŒшЏЗшЇЃщ”яМ‰ 4 - х•х‡Л "чЁЎхЎš "хМ€хЇ‹ шЏЗцŒ‰ч…ЇфЛЅфИ‹шЏДц˜ŽцЅх†™х…ЅфПЁцЏхˆАц‚Јчš„ч”ЕхАяМš 1 - х…Гщ—­ч”ЕхА 2 - шПžцŽЅц•АцЎчКП 3 - ц‰“хМ€ч”ЕхА 4 - х•х‡Л "чЁЎхЎš "хМ€хЇ‹ шЏЗцŒ‰ч…ЇфЛЅфИ‹шЏДц˜ŽцЅфИ‹шННц‚Јчš„фПЁцЏяМš 1 - х…Гщ—­ч”ЕхА 2 - шПžцŽЅц•АцЎчКП 3 - ц‰“хМ€ч”ЕхА 4 - фИ‹шННч”ЕхАц•АцЎ шЏЗцŒ‰ч…ЇфЛЅфИ‹шЏДц˜ŽцЅцЕшЇˆц‚Јчš„ч”ЕхАяМš 1 - х…Гщ—­ч”ЕхА 2 - шПžцŽЅц•АцЎчКП 3 - ц‰“хМ€ч”ЕхА 4 - фИ‹шННч”ЕхАц•АцЎ шЏЗцŒ‰ч…ЇфЛЅфИ‹шЏДц˜ŽцЅфИŠфМ хˆАц‚Јчš„ч”ЕхАяМš 1 - х…Гщ—­ч”ЕхА 2 - шПžцŽЅц•АцЎчКП 3 - ц‰“хМ€ч”ЕхА 4 - фИŠфМ ч”ЕхАц•АцЎ шЏЗцŒ‰ч…ЇфЛЅфИ‹шЏДц˜ŽцЅх†™х…Ѕц‚Јчš„ч”ЕхАяМš 1 - х…Гщ—­ч”ЕхА 2 - шПžцŽЅц•АцЎчКП 3 - ц‰“хМ€ч”ЕхА 4 - фИŠфМ ч”ЕхАц•АцЎ щЂ‘чއц­ЃхœЈшŽЗх–шЎОчНЎх‰хО€ц•АцЎх‰хО€ц•АцЎяМšх‰хО€т€Іт€ІхИЎхŠЉхИЎхŠЉ...щšш—ц— ц•АцЎчš„х†…хЎЙхЏМх…ЅфЛŽц–‡фЛЖхЏМх…Ѕт€Іт€ІчДЂхМ•{information}фИŠц–Йц’х…ЅфИ€шЁŒшЎОчНЎх€Мц— ц•ˆяМš%sшЎОчНЎх€Мц— ц•ˆяМš%s%r х€Мц— ц•ˆхŠ шННцЈЁх—т€Іт€Іх­˜х‚ЈхˆЖхМхž‹хЗхˆЖхМцЈЁх—цЈЁх—хŠ шННфИ‹чЇЛфИŠчЇЛхˆ›хЛКфИ€фИЊц–Ачš„чЊ—хЃцœ‰ц–Ач‰ˆцœЌщЂ‘хЗЎц‰“хМ€ц‰“хМ€щЂ„ч•™щ…чНЎц‰“хМ€шАƒшЏ•ц—ЅхП—шІшІ†ч›–х—яМŸч˜шДДшЏЗч­‰хО…чЋЏхЃхŠŸчއшЎОчНЎх­˜х‚Јц—Жх‡Кщ”™ц‰“хАщЂ„шЇˆхБžц€ЇцŸЅшЏЂц•АцЎцКDTCS цŽЅц”ЖфЛЃч ч”ЕхАч”ЕхАфПЁцЏщ‡ц–АхŠ шННщЉБхŠЈчЈ‹хКщ‡ц–АхŠ шННщЉБхŠЈчЈ‹хКх’Œц–‡фЛЖхЏч”ЈцŠЅх‘ŠхŠŸшƒНхœЈфПх­˜х‰х…Гщ—­яМŸфПх­˜ц–‡фЛЖшЎОчНЎц˜ОчЄКхŽŸхЇ‹х­˜х‚Јц‰“хМ€шАƒшЏ•ц—ЅхП—ц‰€хœЈц–‡фЛЖхЄЙц˜ОчЄКц›ДхЄšх…ЖфЛ–х†…хЎЙцŸфК›х†…хЎЙфИŽц­Єч”ЕхАфИх…МхЎЙцŸфК›х†…хЎЙфИхЏшЂЋхˆ щ™ЄхЗž/чœшЏЅх†…хЎЙшП™ц˜ЏцГ‰ч›› UV-K5 чš„хЎžщЊŒц€ЇщЉБхŠЈчЈ‹хКу€‚хЎƒхЏшƒНфМšцŸхц‚Јчš„ч”ЕхАяМŒч”šш‡ГфМšц›ДчГŸу€‚фНПч”ЈщЃŽщ™ЉшЏЗш‡ЊшДŸу€‚ хœЈхАшЏ•хŽЛшП›шЁŒфЛЛфН•фПЎц”ЙфЙ‹х‰яМŒшЏЗфЛŽч”ЕхАфИ­фИ‹шННхЙЖфПх­˜х†…х­˜ц˜ хƒу€‚ц‚ЈфЛЅхŽхЏфЛЅч”ЈхЎƒцЂхЄшЎОчНЎу€‚ цŸфК›чЛ†шŠ‚хŠŸшƒНхАšцœЊхЎžчŽАфКšщŸГщЂ‘фКšщŸГщЂ‘хˆЖхМцŽЅц”ЖфКšщŸГщЂ‘шАƒшАщ—Дщš”ц— цГ•ц‰“хМ€ц­Єщ•œхƒяМšхž‹хЗфИц”ЏцŒц— цГ•хœЈц­ЄчГЛчЛŸфИŠц˜ОчЄК %sц— цГ•хœЈц­Єх†…хЎЙфИŠшЎОчНЎ %sчОŽх›НфИŠфМ хˆАч”ЕхАфИŠфМ хˆАч”ЕхАт€Іт€ІфНПч”Јх›КхЎšхЎНхКІх­—фН“фНПч”ЈхЄЇхЗх­—фН“хŽ‚х•†цŸЅчœ‹хЗВчІч”ЈхЗВхЏч”Јchirp-20240224/chirp/locale/tr_TR/0000755000175000017500000000000014566340177015447 5ustar hibbyhibbychirp-20240224/chirp/locale/tr_TR/LC_MESSAGES/0000755000175000017500000000000014566340177017234 5ustar hibbyhibbychirp-20240224/chirp/locale/tr_TR/LC_MESSAGES/CHIRP.mo0000644000175000017500000020377514566340175020452 0ustar hibbyhibbyо•‚, <` a -l!9š!д!;ъ!+&"R"Y"h"˜ƒ#‘$Ў%уL&0'єG(<)љB*ї<+ћ4,я0-  .o,/qœ0л2еъ2pР3e15х—6о}7ж\8я39ь#:ъ;чћ;§у< с=Лы>СЇ?оi@зHAр BнC#пC EMFК]GЖHЬЯHШœIeJmKуqLпUM€5NmЖNо$OщP­эPќ›Qѕ˜RŽSрЁTп‚U^bVСV ЧVгV зVсVјVWW(W:WCWIWOWSW[WrW]yWJзW"X4XDXXXgX yX(‡XАXЕX,дYZ ZZ-Z 3Z%>ZdZlZƒZkŒZ јZ[ [ [ [)[-[ 2[ @[ L[ V[c[g[n[A}[П[ б[ о[ь[ў[\\ +\L\U\i\€\–\CЉ\э\є\],]C]K][]n]‡]Ѕ]И]Щ]с]^^ 4^B^S^Y^ub^и^ѕ^ __-_3_1:_l_ q_{_ƒ_Ъ™_Ыd`У0aєaЈcКЌc”gdТќdХПeН…f8CgЄ|hИ!i•кiЇpjЄkЃНkЃal.m 4m>mCm Tm `mmmum zm…m‰m7mеmмm№mn n nn/nEn'Zn ‚nnЁn"Вnеn чnѕnњno o !o -o4:ooo~o•oyЏo)q:qXq vq€q‰q%ЄqЪqъqяqѕqћq rr+r HrRr Zrer{rrЁr Оr Щrеrмrуrіr s*sAs FsRs ds ps~ss sМs аsоs №st†%tЌtДt3Кt*юt(u&Bu?iuФЉu(nw—x Ћy$Зyмyсy!чy zz z+z 4zAzIzOzjzЈ|z;%{ta{ж{ч{ ћ{ | |W,|„|И–|O}`}}’}—} Ќ}Ж} Х} Я} й}ч} њ} ~~&~.~7~G~_~.q~ ~Р~3р~5J Zhpv…бЌ ~€^ ~‚КŠ‚GEƒ#ƒ=Бƒ<яƒф,…†.†&M†юt‡,cˆˆ •ˆ Ÿˆ ЌˆИˆLШˆ,‰B‰a‰~‰ЉŽ‰"8Š[Š {Š/‰ŠЙŠЭŠнŠ№Š‹‹(‹F‹b‹'}‹Ѕ‹У‹Ъ‹б‹ж‹п‹ ч‹ѓ‹7ћ‹!3ŒUŒZŒ `ŒkŒtŒ|Œe‹Œ&ё4IM—GЋ1ѓ % 0p>НЏ‘m’Ь€”,M• z–є›— ˜œ™єЂšш—›о€œ _pmž[оŸш:Ёб#ЂXѕЂpNЄфПЅыЄІЭЇѓ^ЈпRЉъ2ЊкЋѕјЋюЌХЎЙЦЎы€ЏЯlАэ<Бе*ВdГeД‚nЕЯёЖЖСЗоxИЧWЙ:К8ZЛ“М˜НЅ›О~AПРПжРЬщСЖТњИУГФюЪХьЙЦdІЧ ШШ%Ш ,Ш:ШVШ^ШoШ„Ш •ШЁШЉШВШ ЖШ#СШхШoьШH\ЩЅЩМЩЫЩпЩюЩ Ъ) Ъ7Ъ]>Ъ0œЫ ЭЫкЫёЫЬ Ь#Ь?ЬEЬZЬtbЬзЬщЬёЬїЬЭЭЭ #Э1Э @ЭJЭ[Э_ЭcЭUuЭЫЭ сЭэЭ!ќЭ Ю,Ю3Ю2IЮ|ЮƒЮ“ЮІЮМЮ[аЮ,Я'3Я'[Я$ƒЯЈЯ ЎЯКЯЬЯ!шЯ# а.а"@аcа~а4‘а Цагауаъаѓа!„бІб ТбЮбцбяб6іб-в 1в=вDвЮbвЮ1гедждРцекЇжА‚зЭ3иЭйеЯйGЅкРэллЎмиŠнРcоЙ$пРопКŸр4Zсс—сœс Џс ЙсФсЫсгсцсъсEт GтSтkт„тŠтт–т!ЌтЮт0чту(у=у-Vу„у™уЋуБуЗуЮутуѕу6ф<фMфeфа€фQцeццц ЄцЎц?Тц&ч)ч-ч3ч:чAчRч,oчœчЌч ЛчШчмчјч ш *ш 5шAшHшNшeш0~ш1Џшсшхшўш щ&щ!5щWщ"jщщЉщПщ%йщ%џщš%ъРъ дъIръA*ы=lы7ЊыQтыJ4ьgюZчяBё0Sё„ё‰ё)ёЙёЪё бё нёшёњёђ ђ(ђБ7ђMщђz7ѓВѓЬѓтѓ'ўѓ&є^Aє є ЛєХѕ-сѕіі &іGіWіlі}іŽіžіВі СіЯіціэіѕі+ї4ї)Mїwї#їAГїCѕї9јPј dјnј uј €ј)ŒјчЖјЊžљЈIњ ђћыќћSшќ&<§Lc§€А§ћ1џ$-#R7vIЎ7ј04 =K\km/й% /BЖR (FAcЅЛЪм#№3O m1Ž,Р э ї   #G01xЊБ ЗХр ёL\­/ƒSh‘Я‡<‰-3ьŠ8DpтrT|М yўШB^‚[<fv4r%[Aбg-gs.zр{хJТwj„иРД*aUw&:)ІНlѕM'>7hnKеяЧ5ЏЌcRйiCLŒзGпGнжt(MЦeЉ|xђ $B&)лЗ6›2 H,ЪЬYZfx ˜уАЋqPz,b;/an”7=qюlЁ W€6H\v4k:uЙЖ=F}  OU“Ы…•>ог9а~c–ј3o#"^ЅI.њWuд Pєц™ЛN ЮZ08ќOJ"*ш2_bŸ@†ОК1щъЭ№t‚фЇAK!СRИs!П@ЂћCS$ЄвXmУ?ЃымIžЊёэ—ЩYљQ1š d D’`0mo€ ]j{}~_ŽХчВNFkE+Ј5`pЎФБ?џсѓQdїіe Е§9(VкTi‹'V%]#EГ;ˆXyœ+ 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in [DISP] key while turning on radio ("CLONE" will appear on radio LCD). 4. Press [RECEIVE] screen button ("-WAIT-" will appear on radio LCD). 5. Finally, press OK button below. %(value)s must be between %(min)i and %(max)i%i Memories and shift all up%i Memories and shift all up%i Memory%i Memories%i Memory and shift block up%i Memories and shift block up%s has not been saved. Save before closing?(none)...and %i more1. Ensure your firmware version is 4_10 or higher 2. Turn radio off 3. Connect your interface cable 4. Turn radio on 5. Press and release PTT 3 times while holding MONI key 6. Supported baud rates: 57600 (default) and 19200 (rotate dial while holding MONI to change) 7. Click OK 1. Turn Radio off. 2. Connect data cable. 3. While holding "A/N LOW" button, turn radio on. 4. After clicking OK, press "SET MHz" to send image. 1. Turn Radio off. 2. Connect data cable. 3. While holding "A/N LOW" button, turn radio on. 4. Press "MW D/MR" to receive image. 5. Make sure display says "-WAIT-" (see note below if not) 6. Click OK to dismiss this dialog and start transfer. Note: if you don't see "-WAIT-" at step 5, try cycling power and pressing and holding red "*L" button to unlock radio, then start back at step 1. 1. Turn Radio off. 2. Connect data cable. 3. While holding "TONE" and "REV" buttons, turn radio on. 4. After clicking OK, press "TONE" to send image. 1. Turn Radio off. 2. Connect data cable. 3. While holding "TONE" and "REV" buttons, turn radio on. 4. Press "REV" to receive image. 5. Make sure display says "CLONE RX" and green led is blinking 6. Click OK to start transfer. 1. Turn radio off. 2. Connect cable 3. Press and hold in the MHz, Low, and D/MR keys on the radio while turning it on 4. Radio is in clone mode when TX/RX is flashing 5. After clicking OK, press the MHz key on the radio to send image. ("TX" will appear on the LCD). 1. Turn radio off. 2. Connect cable 3. Press and hold in the MHz, Low, and D/MR keys on the radio while turning it on 4. Radio is in clone mode when TX/RX is flashing 5. Press the Low key on the radio ("RX" will appear on the LCD). 6. Click OK.1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK here, press the [C.S.] key to send image. 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK, press the [A] key to send image. 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Click OK here. ("Receiving" will appear on the LCD). 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Press the [A](RCV) key ("receiving" will appear on the LCD). 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Press the [C] key ("RX" will appear on the LCD). 1. Turn radio off. 2. Connect cable to CAT/LINEAR jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK, press the [C](SEND) key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the "left" [V/M] key while turning the radio on. 4. Rotate the "right" DIAL knob to select "CLONE START". 5. Press the [SET] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. After clicking OK, press the "left" [V/M] key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the "left" [V/M] key while turning the radio on. 4. Rotate the "right" DIAL knob to select "CLONE START". 5. Press the [SET] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. Press the "left" [LOW] key ("CLONE -RX-" will appear on the display). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [FW] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [FW] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MODE] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [MHz(PRI)] key while turning the radio on. 4. Rotate the DIAL job to select "F-7 CLONE". 5. Press and hold in the [BAND(SET)] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. Press the [LOW(ACC)] key ("--RX--" will appear on the display). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [MHz(PRI)] key while turning the radio on. 4. Rotate the DIAL job to select "F-7 CLONE". 5. Press and hold in the [BAND(SET)] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. After clicking OK, press the [V/M(MW)] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold [DISP] key while turning on radio ("CLONE" will appear on the display). 4. After clicking OK here in chirp, press the [Send] screen button. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [F] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [F] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [Dx] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [REV(DW)] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MHz(SETUP)] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC Jack. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [GM(AMS)] key to send image. 1. Turn radio off. 2. Connect cable to MIC Jack. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MHz(SETUP)] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/EAR jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [VFO(DW)SC] key to receive the image from the radio. 1. Turn radio off. 2. Connect cable to MIC/EAR jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MR(SKP)SC] key ("CLONE WAIT" will appear on the LCD). 5. Click OK to send image to radio. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold [PTT] & Knob while turning the radio on. 4. After clicking OK, press the [PTT] switch to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold [PTT] & Knob while turning the radio on. 4. Press the [MONI] switch ("WAIT" will appear on the LCD). 5. Press OK. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [V/M] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MON-F] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MON-F] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [V/M] key ("CLONE WAIT" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MONI] switch while turning the radio on. 4. Rotate the DIAL job to select "F8 CLONE". 5. Press the [F/W] key momentarily. 6. After clicking OK, hold the [PTT] switch for one second to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MONI] switch while turning the radio on. 4. Rotate the DIAL job to select "F8 CLONE". 5. Press the [F/W] key momentarily. 6. Press the [MONI] switch ("--RX--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [moni] key while turning the radio on. 4. Select CLONE in menu, then press F. Radio restarts in clone mode. ("CLONE" will appear on the display). 5. After clicking OK, briefly hold [PTT] key to send image. ("-TX-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [LOW(A/N)] key while turning the radio on. 4. After clicking OK, press the [MHz(SET)] key to send image. 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [LOW(A/N)] key while turning the radio on. 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [MHz], [LOW], and [D/MR] keys while turning the radio on. 4. After clicking OK, press the [MHz(SET)] key to send image. 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [MHz], [LOW], and [D/MR] keys while turning the radio on. 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to download image from device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to upload image to device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on. 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to download image from device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on. 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to upload image to device. 1. Turn radio off. 2. Connect data cable. 3. Prepare radio for clone. 4. After clicking OK, press the key to send image. 1. Turn radio off. 2. Connect data cable. 3. Prepare radio for clone. 4. Press the key to receive the image. 1. Turn radio off. 2. Connect mic and hold [ACC] on mic while powering on. ("CLONE" will appear on the display) 3. Replace mic with PC programming cable. 4. After clicking OK, press the [SET] key to send image. 1. Turn radio off. 2. Connect mic and hold [ACC] on mic while powering on. ("CLONE" will appear on the display) 3. Replace mic with PC programming cable. 4. Press the [DISP/SS] key ("R" will appear on the lower left of LCD). 1. Turn radio off. 2. Remove front head. 3. Connect data cable to radio, use the same connector where head was connected to, not the mic connector. 4. Click OK. 1. Turn radio off. 3. Press and hold in the [moni] key while turning the radio on. 4. Select CLONE in menu, then press F. Radio restarts in clone mode. ("CLONE" will appear on the display). 5. Press the [moni] key ("-RX-" will appear on the LCD). 1. Turn radio on. 2. Connect cable to DATA terminal. 3. Unclip battery. 4. Press and hold in the [AMS] key and power key while clipping in back battery the("ADMS" will appear on the display). 5. After clicking OK, press the [BAND] key. 1. Turn radio on. 2. Connect cable to DATA terminal. 3. Unclip battery. 4. Press and hold in the [AMS] key and power key while clipping in back battery the("ADMS" will appear on the display). 5. Press the [MODE] key ("-WAIT-" will appear on the LCD). OK click Then1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to download image from device. It will may not work if you turn on the radio with the cable already attached 1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to upload the image to device. It will may not work if you turn on the radio with the cable already attachedA new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllAll FilesAll supported formats|AmateurAn error has occurredApplying settingsAvailable modulesBandplanBandsBanksBinBrowserBuilding Radio BrowserCanadaChanging this setting requires refreshing the settings from the image, which will happen now.Channels with equivalent TX and RX %s are represented by tone mode of "%s"Chirp Image FilesChoice RequiredChoose %s DTCS CodeChoose %s ToneChoose Cross ModeChoose duplexChoose the module to load from issue %i:CityClick on the "Special Channels" toggle-button of the memory editor to see/set the EXT channels. P-VFO channels 100-109 are considered Settings. Only a subset of the over 200 available radio settings are supported in this release. Ignore the beeps from the radio on upload and download. Clone completed, checking for spurious bytesCloningCloning from radioCloning to radioCloseClose fileCluster %i memoryCluster %i memoriesCommentCommunicate with radioCompleteConnect your interface cable to the PC Port on the back of the 'TX/RX' unit. NOT the Com Port on the head. Convert to FMCopyCountryCustom PortCustom...CutDTCSDTCS PolarityDTMF decodeDV MemoryDanger AheadDecDeleteDeveloper ModeDeveloper state is now %s. CHIRP must be restarted to take effectDiff Raw MemoriesDigital CodeDigital ModesDisable reportingDisabledDistanceDo not prompt again for %sDouble-click to change bank nameDownloadDownload from radioDownload from radio...Download instructionsDriver informationDual-mode digital repeaters that support analog will be shown as FMDuplexEdit details for %i memoriesEdit details for memory %iEnable Automatic EditsEnabledEnter FrequencyEnter Offset (MHz)Enter TX Frequency (MHz)Enter a new name for bank %s:Enter custom port:Erased memory %sError applying settingsError communicating with radioExperimental driverExport can only write CSV filesExport to CSVExport to CSV...ExtraFM RadioFREE repeater database, which provides most up-to-date information about repeaters in Europe. No account is required.Failed to load radio browserFailed to parse resultFeaturesFile does not exist: %sFilesFilterFilter results with location matching this stringFindFind NextFind...Finished radio job %sFollow these instructions to download the radio memory: 1 - Connect your interface cable 2 - Radio > Download from radio: DO NOT mess with the radio during download! 3 - Disconnect your interface cable Follow these instructions to download the radio memory: 1 - Connect your interface cable 2 - Radio > Download from radio: Don't adjust any settings on the radio head! 3 - Disconnect your interface cable Follow these instructions to download the radio memory: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio, volume @ 50% 4 - CHIRP Menu - Radio - Download from radio Follow these instructions to download your config: 1 - Turn off your radio 2 - Connect your interface cable to the Speaker-2 jack 3 - Turn on your radio 4 - Radio > Download from radio 5 - Disconnect the interface cable! Otherwise there will be no right-side audio! Follow these instructions to download your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow these instructions to download your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio (unlock it if password protected) 4 - Click OK to start Follow these instructions to read your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Click OK to start Follow these instructions to upload the radio memory: 1 - Connect your interface cable 2 - Radio > Upload to radio: DO NOT mess with the radio during upload! 3 - Disconnect your interface cable Follow these instructions to upload the radio memory: 1 - Connect your interface cable 2 - Radio > Upload to radio: Don't adjust any settings on the radio head! 3 - Disconnect your interface cable Follow these instructions to upload the radio memory: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio, volume @ 50% 4 - CHIRP Menu - Radio - Upload to radio Follow these instructions to upload your config: 1 - Turn off your radio 2 - Connect your interface cable to the Speaker-2 jack 3 - Turn on your radio 4 - Radio > Upload to radio 5 - Disconnect the interface cable, otherwise there will be no right-side audio! 6 - Cycle power on the radio to exit clone mode Follow these instructions to upload your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Follow these instructions to upload your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio (unlock it if password protected) 4 - Click OK to start Follow these instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Click OK to start Follow this instructions to download your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to read your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to upload your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Follow this instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Found empty list value for %(name)s: %(value)rFrequencyGMRSGetting settingsGoto MemoryGoto Memory:Goto...HelpHelp Me...HexHide empty memoriesIf set, sort results by distance from these coordinatesImportImport from file...Import not recommendedIndexInfoInformationInsert Row AboveInstall desktop icon?Interact with driverInvalid %(value)s (use decimal degrees)Invalid EntryInvalid ZIP codeInvalid edit: %sInvalid or unsupported module fileInvalid value: %rIssue number:LIVELatitudeLength must be %iLimit BandsLimit ModesLimit StatusLimit results to this distance (km) from coordinatesLoad Module...Load module from issueLoad module from issue...Loading modules can be extremely dangerous, leading to damage to your computer, radio, or both. NEVER load a module from a source you do not trust, and especially not from anywhere other than the main CHIRP website (chirp.danplanet.com). Loading a module from another source is akin to giving them direct access to your computer and everything on it! Proceed despite this risk?Loading settingsLogo string 1 (12 characters)Logo string 2 (12 characters)LongitudeMemoriesMemory %i is not deletableMemory must be in a bank to be editedMemory {num} not in bank {bank}ModeModelModesModuleModule LoadedModule loaded successfullyMore than one port found: %sMove DownMove UpNew WindowNew version availableNo empty rows below!No modules foundNo modules found in issue %iNo resultsNo results!NumberOffsetOnly certain bandsOnly certain modesOnly memory tabs may be exportedOnly working repeatersOpenOpen RecentOpen Stock ConfigOpen a fileOpen a moduleOpen debug logOpen in new windowOpen stock config directoryOptional: -122.0000Optional: 100Optional: 45.0000Optional: County, Hospital, etc.Overwrite memories?P-VFO channels 100-109 are considered Settings. Only a subset of the over 130 available radio settings are supported in this release. ParsingPastePasted memories will overwrite %s existing memoriesPasted memories will overwrite memories %sPasted memories will overwrite memory %sPasted memory will overwrite memory %sPlease be sure to quit CHIRP before installing the new version!Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio 3 - Click the button on this window to start download (you may see another dialog, click ok) 4 - Radio will beep and led will flash 5 - You will get a 10 seconds timeout to press "MON" before data upload start 6 - If all goes right radio will beep at end. After cloning remove the cable and power cycle your radio to get into normal mode. Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio. 3 - Click the button on this window to start download (Radio will beep and led will flash) 4 - Then press the "A" button in your radio to start cloning. (At the end radio will beep) Please note that developer mode is intended for use by developers of the CHIRP project, or under the direction of a developer. It enables behaviors and functions that can damage your computer and your radio if not used with EXTREME care. You have been warned! Proceed anyway?Please waitPlug in your cable and then click OKPortPowerPress enter to set this in memoryPrint PreviewPrintingPropertiesQuery %sQuery SourceRX DTCSRadioRadio did not ack block %iRadio informationRadio sent data after the last awaited block, this happens when the selected model is a non-US but the radio is a US one. Please choose the correct model and try again.RadioReference Canada requires a login before you can queryRadioReference.com is the world's largest radio communications data provider Premium account requiredRefresh requiredRefreshed memory %sReload DriverReload Driver and FileRename bankRepeaterBook is Amateur Radio's most comprehensive, worldwide, FREE repeater directory.Reporting enabledReporting helps the CHIRP project know which radio models and OS platforms to spend our limited efforts on. We would really appreciate if you left it enabled. Really disable reporting?Restart RequiredRestore %i tabRestore %i tabsRetrieved settingsSaveSave before closing?Save fileSaved settingsScanlistsScramblerSecurity RiskSelect Bandplan...Select BandsSelect ModesSelect a bandplanServiceSettingsShow Raw MemoryShow debug log locationShow extra fieldsSome memories are incompatible with this radioSome memories are not deletableSort %i memorySort %i memoriesSort %i memory ascendingSort %i memories ascendingSort %i memory descendingSort %i memories descendingSort by column:Sort memoriesSortingStateState/ProvinceSuccessThe DMR-MARC Worldwide NetworkThe X3Plus driver is currently experimental. There are no known issues but you should proceed with caution. Please save an unedited copy of your first successful download to a CHIRP Radio Images (*.img) file. The author of this module is not a recognized CHIRP developer. It is recommended that you not load this module as it could pose a security risk. Proceed anyway?The recommended procedure for importing memories is to open the source file and copy/paste memories from it into your target image. If you continue with this import function, CHIRP will replace all memories in your currently-open file with those in %(file)s. Would you like to open this file to copy/paste memories across, or proceed with the import?This MemoryThis driver has been tested with v3 of the ID-5100. If your radio is not fully updated please help by opening a bug report with a debug log so we can add support for the other revisions.This driver is in development and should be considered as experimental.This is an early stage beta driver This is an early stage beta driver - upload at your own risk This is an experimental driver for the Quansheng UV-K5. It may harm your radio, or worse. Use at your own risk. Before attempting to do any changes please download the memory image from the radio with chirp and keep it. This can be later used to recover the original settings. some details are not yet implementedThis is experimental support for BJ-9900 which is still under development. Please ensure you have a good backup with OEM software. Also please send in bug and enhancement requests! You have been warned. Proceed at your own risk!This memory and shift all upThis memory and shift block upThis radio has a tricky way of enter into program mode, even the original software has a few tries to get inside. I will try 8 times (most of the time ~3 will doit) and this can take a few seconds, if don't work, try again a few times. If you can get into it, please check the radio and cable. This should only be enabled if you are using modified firmware that supports wider frequency coverage. Enabling this will cause CHIRP not to enforce OEM restrictions and may lead to undefined or unregulated behavior. Use at your own risk!This will load a module from a website issueToneTone ModeTone SquelchTuning StepUSB Port FinderUnable to determine port for your cable. Check your drivers and connections.Unable to edit memory before radio is loadedUnable to find stock config %rUnable to open the clipboardUnable to queryUnable to read last block. This often happens when the selected model is US but the radio is a non-US one (or widebanded). Please choose the correct model and try again.Unable to reveal %s on this systemUnable to set %s on this memoryUnited StatesUnplug your cable (if needed) and then click OKUpload instructionsUpload to radioUpload to radio...Uploaded memory %sUse fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterValuesVendorViewWARNING!WarningWarning: %sWelcomeWould you like CHIRP to install a desktop icon for you?Your cable appears to be on port:bitsbytesbytes eachdisabledenabled{bank} is fullProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2024-01-20 18:51+0300 Last-Translator: Abdullah YILMAZ (TA1AUB) Language-Team: TURKISH Language: tr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 3.4.2 1. Telsizi kapatФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. Telsizi aУЇarken [DISP] tuХŸunu basФБlФБ tutun (telsiz LCD'sinde "CLONE" gУЖrУМnecektir). 4. [RECEIVE] ekran tuХŸuna basФБn (telsiz LCD'sinde "-WAIT-" gУЖrУМnecektir). 5. Son olarak aХŸaФŸФБdaki OK tuХŸuna basФБn. %(value)s, %(min)i ile %(max)i arasФБnda olmalФБdФБr%i KaydФБ ve hepsini yukarФБ kaydФБr%i KaydФБ ve hepsini yukarФБ kaydФБr%i KaydФБ%i KaydФБ%i KaydФБ ve bloФŸu yukarФБ kaydФБr%i KaydФБ ve bloФŸu yukarФБ kaydФБr%s kaydedilmedi. Kapanmadan УЖnce kaydedilsin mi?(hiУЇbiri)...ve %i daha1. DonanФБm yazФБlФБmФБ sУМrУМmУМnУМzУМn 4_10 veya УМzeri olduФŸundan emin olun 2. Telsizi kapatФБn 3. ArayУМz kablonuzu baФŸlayФБn 4. Telsizi aУЇФБn 5. MONI tuХŸunu basФБlФБ tutarken PTT'ye 3 kez basФБn ve bФБrakФБn 6. Desteklenen baud hФБzlarФБ: 57600 (varsayФБlan) ve 19200 (deФŸiХŸtirmek iУЇin MONI'ye basФБlФБ tutarken kadranФБ УЇevirin) 7. TAMAM'a tФБklayФБn 1. Telsizi kapatФБn. 2. Veri kablosunu baФŸlayФБn. 3. "A/N LOW" tuХŸunu basФБlФБ tutarken telsizi aУЇФБn. 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin "SET MHz"e basФБn. 1. Telsizi kapatФБn. 2. Veri kablosunu baФŸlayФБn. 3. "A/N LOW" tuХŸunu basФБlФБ tutarken telsizi aУЇФБn. 4. ФАmajФБ almak iУЇin "MW D/MR" tuХŸuna basФБn. 5. Ekranda "-WAIT-" yazdФБФŸФБndan emin olun (deФŸilse aХŸaФŸФБdaki nota bakФБn) 6. Bu iletiХŸim kutusunu kapatmak ve aktarФБmФБ baХŸlatmak iУЇin TAMAM'a tФБklayФБn. Not: 5. adФБmda "-WAIT-" УЖФŸesini gУЖrmУМyorsanФБz, gУМcУМ kapatФБp aУЇmayФБ ve telsizin kilidini aУЇmak iУЇin kФБrmФБzФБ "*L" tuХŸunu basФБlФБ tutmayФБ deneyin, ardФБndan 1. adФБmdan baХŸlayФБn. 1. Telsizi kapatФБn. 2. Veri kablosunu baФŸlayФБn. 3. "TONE" ve "REV" tuХŸlarФБnФБ basФБlФБ tutarken telsizi aУЇФБn. 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin "TONE" tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Veri kablosunu baФŸlayФБn. 3. "TONE" ve "REV" tuХŸlarФБnФБ basФБlФБ tutarken telsizi aУЇФБn. 4. ФАmajФБ almak iУЇin "REV" tuХŸuna basФБn. 5. Ekranda "CLONE RX" yazdФБФŸФБndan ve yeХŸil ledin yanФБp sУЖndУМФŸУМnden emin olun. 6. AktarФБmФБ baХŸlatmak iУЇin TAMAM'a tФБklayФБn. 1. Telsizi kapatФБn. 2. Kabloyu baФŸlayФБn. 3. Telsizi aУЇarken MHz, LOW ve D/MR tuХŸlarФБnФБ basФБlФБ tutun. 4. TX/RX yanФБp sУЖnerken radyo klon modundadФБr 5. TAMAM'a tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin radyodaki MHz tuХŸuna basФБn. ("TX" LCD'de gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu baФŸlayФБn. 3. Telsizi aУЇarken MHz, LOW ve D/MR tuХŸlarФБnФБ basФБlФБ tutun. 4. TX/RX yanФБp sУЖnerken radyo klon modundadФБr 5. Telsizdeki Low tuХŸuna basФБn ("RX" LCD'de gУЖrУМnecektir). 6. Tamam'a tФБklayФБn.1. Telsizi kapatФБn. 2. Kabloyu ACC jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MODE <] ve [MODE >] tuХŸlarФБnФБ basФБlФБ tutun (ekranda "KLON MODU" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [C.S.] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu ACC jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MODE <] ve [MODE >] tuХŸlarФБnФБ basФБlФБ tutun ("ekranda KLON MODU" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [A] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu ACC jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MODE <] ve [MODE >] tuХŸlarФБnФБ basФБlФБ tutun ("ekranda KLON MODU" gУЖrУМnecektir). 4. Burada TAMAM'ФБ tФБklayФБn. (ekranda "AlФБnФБyor" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu ACC jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MODE <] ve [MODE >] tuХŸlarФБnФБ basФБlФБ tutun (ekranda "KLON MODU" gУЖrУМnecektir). 4. [A](RCV) tuХŸuna basФБn (ekranda "alФБyor" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu ACC jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MODE <] ve [MODE >] tuХŸlarФБnФБ basФБlФБ tutun ("ekranda KLON MODU" gУЖrУМnecektir). 4. [C] tuХŸuna basФБn (ekranda "RX" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu CAT/LINEAR jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MODE <] ve [MODE >] tuХŸlarФБnФБ basФБlФБ tutun (ekranda "KLON MODU" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [C](GУ–NDER) tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu DATA jakФБna baФŸlayФБn. 3. Telsizi aУЇarken "sol" [V/M] tuХŸuna basФБlФБ tutun. 4. "KLONLAMA BAХžLAT"ФБ seУЇmek iУЇin DIAL dУМФŸmesini "saФŸa" УЇevirin. 5. [SET] tuХŸuna basФБn. Ekran bir an kaybolacak, ardФБndan "CLONE" notu gУЖrУМnecektir. 6. Tamam'a tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin "sol" [V/M] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu DATA jakФБna baФŸlayФБn. 3. Telsizi aУЇarken "sol" [V/M] tuХŸuna basФБlФБ tutun. 4. "KLONLAMA BAХžLAT"ФБ seУЇmek iУЇin DIAL dУМФŸmesini "saФŸa" УЇevirin. 5. [SET] tuХŸuna basФБn. Ekran bir an kaybolacak, ardФБndan "CLONE" notu gУЖrУМnecektir. 6. "Sol" [LOW] tuХŸuna basФБn ("CLONE -RX-" ekranda gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu DATA jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [FW] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [BAND] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu DATA jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [FW] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. [MODE] tuХŸuna basФБn (ekranda "CLONE WAIT" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu DATA jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MHz(PRI)] tuХŸunu basФБlФБ tutun. 4. "F-7 CLONE" УЖФŸesini seУЇmek iУЇin KADRANI УЇevirin. 5. [BAND(SET)] tuХŸunu basФБlФБ tutun. Ekran bir an iУЇin kaybolacak, ardФБndan "CLONE" yazФБsФБ belirecektir. 6. [LOW(ACC)] tuХŸuna basФБn (ekranda "--RX--" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu DATA jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MHz(PRI)] tuХŸunu basФБlФБ tutun. 4. "F-7 CLONE" УЖФŸesini seУЇmek iУЇin KADRANI УЇevirin. 5. [BAND(SET)] tuХŸunu basФБlФБ tutun. Ekran bir an iУЇin kaybolacak, ardФБndan "CLONE" yazФБsФБ belirecektir. 6. TAMAM'ФБ tФБkladФБktan sonra, imaj gУЖndermek iУЇin [V/M(MW)] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. Telsizi aУЇarken [DISP] tuХŸunu basФБlФБ tutun ("CLONE" ekranda gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, [GУЖnder] ekran tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. Telsizi aУЇarken [F] tuХŸunu basФБlФБ tutun ("CLONE" ekranda gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [BAND] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. Telsizi aУЇarken [F] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. [Dx] tuХŸuna basФБn (ekranda "-WAIT-" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. Telsizi aУЇarken [MHz(SETUP)] tuХŸunu basФБlФБ tutun ("ekranda CLONE" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [GERФА(DW)] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. Telsizi aУЇarken [MHz(SETUP)] tuХŸunu basФБlФБ tutun ("ekranda CLONE" gУЖrУМnecektir). 4. [MHz(SETUP)] tuХŸuna basФБn (ekranda "-WAIT-" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu MIC JakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MHz(SETUP)] tuХŸunu basФБlФБ tutun ("ekranda CLONE" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imaj gУЖndermek iУЇin [GM(AMS)] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu MIC JakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MHz(SETUP)] tuХŸunu basФБlФБ tutun ("ekranda CLONE" gУЖrУМnecektir). 4. [MHz(SETUP)] tuХŸuna basФБn (ekranda "-WAIT-" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu MIC/EAR jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [F/W] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ telsizden almak iУЇin [VFO(DW)SC] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu MIC/EAR jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [F/W] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. [MR(SKP)SC] tuХŸuna basФБn (ekranda "CLONE WAIT" gУЖrУМnecektir). 5. ФАmajФБ telsize gУЖndermek iУЇin TAMAM'a tФБklayФБn. 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [PTT] & tuХŸuna basФБn. 4. TAMAM'ФБ tФБkladФБktan sonra, imaj gУЖndermek iУЇin [PTT] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [PTT] & tuХŸuna basФБn. 4. [MONI] tuХŸuna basФБn (ekranda "WAIT" gУЖrУМnecektir). 5. TAMAM'a basФБn. 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [F/W] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [BAND] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [F/W] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. [V/M] tuХŸuna basФБn (ekranda "-WAIT-" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MON-F] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [BAND] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MON-F] tuХŸunu basФБlФБ tutun (ekranda "CLONE" gУЖrУМnecektir). 4. [V/M] tuХŸuna basФБn (ekranda "CLONE WAIT" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [PTT] & tuХŸuna basФБn. 3. Telsizi aУЇarken [MONI] tuХŸunu basФБlФБ tutun. 4. "F8 CLONE" УЖФŸesini seУЇmek iУЇin KADRANI УЇevirin. 5. Bir an iУЇin [F/W] tuХŸuna basФБn. 6. TAMAM'ФБ tФБkladФБktan sonra, imaj gУЖndermek iУЇin [PTT] tuХŸunu bir saniye basФБlФБ tutun. 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MONI] tuХŸunu basФБlФБ tutun. 4. "F8 CLONE" УЖФŸesini seУЇmek iУЇin KADRANI УЇevirin. 5. Bir an iУЇin [F/W] tuХŸuna basФБn. 6. [MONI] tuХŸuna basФБn (ekranda "--RX--" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu MIC/SP jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [moni] tuХŸunu basФБlФБ tutun. 4. MenУМden KLON'u seУЇin, ardФБndan F'ye basФБn. Telsiz klon modunda yeniden baХŸlar. (ekranda "CLONE" gУЖrУМnecektir). 5. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [PTT] tuХŸunu kФБsa bir sУМre basФБlФБ tutun. (ekranda "-TX-" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu mikrofon jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [LOW(A/N)] tuХŸunu basФБlФБ tutun. 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [MHz(SET)] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu mikrofon jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [LOW(A/N)] tuХŸunu basФБlФБ tutun. 4. [D/MR(MW)] tuХŸuna basФБn (ekranda "--WAIT--" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu mikrofon jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MHz], [LOW] ve [D/MR] tuХŸlarФБna basФБlФБ tutun 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [MHz(SET)] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Kabloyu mikrofon jakФБna baФŸlayФБn. 3. Telsizi aУЇarken [MHz], [LOW] ve [D/MR] tuХŸlarФБnФБ basФБlФБ tutun. 4. [D/MR(MW)] tuХŸuna basФБn (ekranda "--WAIT--" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. Kabloyu mik/hprlr konektУЖrУМne baФŸlayФБn. 3. KonektУЖrУМn sФБkФБca baФŸlandФБФŸФБndan emin olun. 4. Telsizi aУЇФБn (ses dУМzeyinin %100 olarak ayarlanmasФБ gerekebilir). 5. Telsizin etkin olmayan kanala ayarlandФБФŸФБndan emin olun. 6. ФАmajФБ cihazdan indirmek iУЇin TAMAM'a tФБklayФБn. 1. Telsizi kapatФБn. 2. Kabloyu mic/spkr konektУЖrУМne baФŸlayФБn. 3. KonektУЖrУМn sФБkФБca baФŸlandФБФŸФБndan emin olun. 4. Telsizi aУЇФБn (ses dУМzeyinin %100 olarak ayarlanmasФБ gerekebilir). 5. Telsizin etkin olmayan kanala ayarlandФБФŸФБndan emin olun. 6. ФАmajФБ cihaza yУМklemek iУЇin TAMAM'a tФБklayФБn. 1. Telsizi kapatФБn. 2. Kabloyu mik/hprlr konektУЖrУМne baФŸlayФБn. 3. KonektУЖrУМn sФБkФБca baФŸlandФБФŸФБndan emin olun. 4. Telsizi aУЇФБn. 5. Telsizin etkin olmayan kanala ayarlandФБФŸФБndan emin olun. 6. ФАmajФБ cihazdan indirmek iУЇin TAMAM'a tФБklayФБn. 1. Telsizi kapatФБn. 2. Kabloyu mic/spkr konektУЖrУМne baФŸlayФБn. 3. KonektУЖrУМn sФБkФБca baФŸlandФБФŸФБndan emin olun. 4. Telsizi aУЇФБn. 5. Telsizin etkin olmayan kanala ayarlandФБФŸФБndan emin olun. 6. ФАmajФБ cihaza yУМklemek iУЇin TAMAM'a tФБklayФБn. 1. Telsizi kapatФБn. 2. Veri kablosunu baФŸlayФБn. 3. Telsizi klon iУЇin hazФБrlayФБn. 4. TAMAM'ФБ tФБkladФБktan sonra, imaj gУЖndermek iУЇin tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Veri kablosunu baФŸlayФБn. 3. Telsizi klon iУЇin hazФБrlayФБn. 4. ФАmajФБ almak iУЇin tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Mikrofonu baФŸlayФБn ve aУЇarken mikrofondaki [ACC] tuХŸunu basФБlФБ tutun. ("CLONE" ekranda gУЖrУМnecektir) 3. Mikrofonu PC programlama kablosuyla deФŸiХŸtirin. 4. TAMAM'ФБ tФБkladФБktan sonra, imajФБ gУЖndermek iУЇin [SET] tuХŸuna basФБn. 1. Telsizi kapatФБn. 2. Mikrofonu baФŸlayФБn ve aУЇarken mikrofondaki [ACC] tuХŸunu basФБlФБ tutun. ("CLONE" ekranda gУЖrУМnecektir) 3. Mikrofonu PC programlama kablosuyla deФŸiХŸtirin. 4. [DISP/SS] tuХŸuna basФБn (LCD'nin sol alt kУЖХŸesinde "R" gУЖrУМnecektir). 1. Telsizi kapatФБn. 2. У–n baХŸlФБФŸФБ УЇФБkarФБn. 3. Veri kablosunu telsize baФŸlayФБn, mikrofon konektУЖrУМne deФŸil kafanФБn baФŸlФБ olduФŸu konektУЖrУМ kullanФБn. 4. TAMAM'a tФБklayФБn. 1. Telsizi kapatФБn. 3. Telsizi aУЇarken [moni] tuХŸunu basФБlФБ tutun. 4. MenУМden KLON'u seУЇin, ardФБndan F'ye basФБn. Telsiz klon modunda yeniden baХŸlar. (ekranda "CLONE" gУЖrУМnecektir). 5. [moni] tuХŸuna basФБn (ekranda "-RX-" gУЖrУМnecektir). 1. Radyoyu aУЇФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. BataryayФБ УЇФБkartФБn. 4. BataryayФБ takarken [AMS] tuХŸuna ve gУМУЇ tuХŸuna basФБlФБ tutun ("ADMS" ekranda gУЖrУМnecektir). 5. Tamam'a tФБkladФБktan sonra, [BAND] tuХŸuna basФБn. 1. Radyoyu aУЇФБn. 2. Kabloyu DATA terminaline baФŸlayФБn. 3. BataryayФБ УЇФБkartФБn. 4. BataryayФБ takarken [AMS] tuХŸuna ve gУМУЇ tuХŸuna basФБlФБ tutun ("ADMS" ekranda gУЖrУМnecektir). 5. [MODE] tuХŸuna basФБn (LCD'de "-WAIT-" gУЖrУМnecektir). Sonra TAMAM tФБklayФБn1. Telsizi kapatФБn. 2. Kabloyu mic/spkr konektУЖrУМne baФŸlayФБn. 3. KonektУЖrУМn sФБkФБca baФŸlandФБФŸФБnФБzdan emin olun. 4. ФАmajФБ cihazdan indirmek iУЇin Tamam'a tФБklayФБn. Kablo takФБlФБyken telsizi aУЇarsanФБz УЇalФБХŸmayabilir 1. Telsizi kapatФБn. 2. Kabloyu mic/spkr konektУЖrУМne baФŸlayФБn. 3. KonektУЖrУМn sФБkФБca baФŸlandФБФŸФБnФБzdan emin olun. 4. ФАmajФБ cihaza yУМklemek iУЇin Tamam'a tФБklayФБn. Kablo takФБlФБyken telsizi aУЇarsanФБz УЇalФБХŸmayabilirYeni bir CHIRP sУМrУМmУМ mevcut. ФАndirmek iУЇin lУМtfen en kФБsa zamanda web sitesini ziyaret edin!HakkФБndaCHIRP HakkФБndaTУМmУМTУМm DosyalarDesteklenen tУМm biУЇimler|AmatУЖrBir hata oluХŸtuAyarlar uygulanФБyorMevcut modУМllerBant planФБBantlarBankalarBinTarayФБcФБTelsiz TarayФБcФБsФБ oluХŸturuluyorKanadaBu ayarФБn deФŸiХŸtirilmesi, imajdaki ayarlarФБn yenilenmesini gerektirir, bu iХŸlem ХŸimdi gerУЇekleХŸecektir.EХŸdeФŸer TX ve RX %s'ye sahip kanallar, "%s" ton modu ile temsil edilirChirp ФАmaj DosyalarФБSeУЇim Gerekli%s DTCS Kodunu SeУЇ%s Tonunu SeУЇУ‡apraz Modu SeУЇDubleks seУЇSorun %i'den yУМklenecek modУМlУМ seУЇin:ХžehirEXT kanallarФБnФБ gУЖrmek/ayarlamak iУЇin kayФБt dУМzenleyicisinin "У–zel Kanallar" geУЇiХŸ dУМФŸmesine tФБklayФБn. P-VFO kanallarФБ 100-109 olarak ayarlanabilir. Bu sУМrУМmde 200'den fazla kullanФБlabilir telsiz ayarФБnФБn yalnФБzca bir alt kУМmesi desteklenmektedir. YУМkleme ve indirme sФБrasФБnda telsizden gelen bip seslerini dikkate almayФБn. Klon tamamlandФБ, sahte baytlar kontrol ediliyorKlonlanФБyorTelsizden klonlanФБyorTelsize klonlanФБyorKapatDosyayФБ kapat%i KaydФБ sФБrala%i kaydФБ sФБralaYorumTelsiz ile iletiХŸimTamamlaArayУМz kablonuzu 'TX/RX' УМnitesinin arkasФБndaki PC BaФŸlantФБ NoktasФБna baФŸlayФБn. Kafadaki Com Portu DEФžФАL. FM'e dУЖnУМХŸtУМrKopyalaУœlkeУ–zel BaФŸlantФБ NoktasФБУ–zel...KesDTCSDTCS PolariteDTMF kod УЇУЖzDV KaydФБФАleride TehlikeDecSilGeliХŸtirici ModuGeliХŸtirici durumu artФБk %s. Etkili olmasФБ iУЇin CHIRP yeniden baХŸlatФБlmalФБdФБrFarklФБ Ham KayФБtlarDijital KodDijital ModlarRaporlamayФБ devre dФБХŸФБ bФБrakDevre dФБХŸФБMesafe%s iУЇin tekrar sormaBanka adФБnФБ deФŸiХŸtirmek iУЇin УЇift tФБklayФБnФАndirTelsizden indirTelsizden indir...ФАndirme talimatlarФБSУМrУМcУМ bilgileriAnalogu destekleyen УЇift modlu dijital tekrarlayФБcФБlar(rУЖleler) FM olarak gУЖsterilecekDuplex%i kaydФБ iУЇin ayrФБntФБlarФБ dУМzenle%i kaydФБ iУЇin ayrФБntФБlarФБ dУМzenleOtomatik DУМzenlemeleri EtkinleХŸtirEtkinFrekans GirOfset girin (MHz)TX FrekansФБnФБ girin (MHz)Banka %s iУЇin yeni bir ad girin:У–zel baФŸlantФБ noktasФБnФБ girin:%s kaydФБ silindiAyarlar uygulanФБrken hata oluХŸtuTelsizle iletiХŸim hatasФБDeneysel sУМrУМcУМDФБХŸa aktarma yalnФБzca CSV dosyalarФБnФБ yazabilirCSV'ye aktarCSV'ye aktar...EkstraFM RadyoAvrupa'daki tekrarlayФБcФБlar (rУЖleler) hakkФБnda en gУМncel bilgileri saФŸlayan УœCRETSФАZ tekrarlayФБcФБ (rУЖle) veritabanФБ. Hesap gerekmez.Telsiz tarayФБcФБsФБ yУМklenemediSonuУЇ ayrФБХŸtФБrФБlamadФБУ–zelliklerDosya mevcut deФŸil: %sDosyalarFiltreBu dizeyle eХŸleХŸen konuma sahip sonuУЇlarФБ filtreleBulSonraki BulBul...%s telsiz iХŸleri tamamlandФБTelsiz hafФБzasФБnФБ indirmek iУЇin ХŸu talimatlarФБ izleyin: 1 - ArayУМz kablonuzu baФŸlayФБn 2 - Telsiz > Telsizden ФАndir: ФАndirme sФБrasФБnda telsiz ile uФŸraХŸmayФБn! 3 - ArayУМz kablonuzu УЇФБkarФБn Telsiz hafФБzasФБnФБ indirmek iУЇin ХŸu talimatlarФБ izleyin: 1 - ArayУМz kablonuzu baФŸlayФБn 2 - Telsiz > Telsizden ФАndir: Telsiz kafasФБnda herhangi bir ayar yapmayФБn! 3 - ArayУМz kablonuzu УЇФБkarФБn Telsiz hafФБzasФБnФБ indirmek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn, ses seviyesi @ %50 4 - 4 - CHIRP MenУМsУМ - Telsiz - Telsizden indir YapФБlandФБrmanФБzФБ indirmek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu Speaker-2 jakФБna baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz > Telsizden ФАndir 5 - ArayУМz kablosunu УЇФБkarФБn! Aksi takdirde, saФŸ taraf sesi olmayacaktФБr! Bilgilerinizi indirmek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz verilerinizin indirilmesini gerУЇekleХŸtirin Bilgilerinizi indirmek iУЇin bu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn (ХŸifre korumalФБysa engelini kaldФБrФБn) 4 - BaХŸlatmak iУЇin TAMAM'a tФБklayФБn. Bilgilerinizi indirmek iУЇin bu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - BaХŸlatmak iУЇin TAMAM'a tФБklayФБn. Telsiz hafФБzasФБnФБ yУМklemek iУЇin ХŸu talimatlarФБ izleyin: 1 - ArayУМz kablonuzu baФŸlayФБn 2 - Telsiz > Telsize YУМkle: YУМkleme sФБrasФБnda telsiz ile uФŸraХŸmayФБn! 3 - ArayУМz kablonuzu УЇФБkarФБn Telsiz hafФБzasФБnФБ yУМklemek iУЇin ХŸu talimatlarФБ izleyin: 1 - ArayУМz kablonuzu baФŸlayФБn 2 - Telsiz > Telsize yУМkle: Telsiz kafasФБnda herhangi bir ayar yapmayФБn! 3 - ArayУМz kablonuzu УЇФБkarФБn Telsiz hafФБzasФБnФБ yУМklemek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn, ses seviyesi @ %50 4 - 4 - CHIRP MenУМsУМ - Telsiz - Telsize yУМkle YapФБlandФБrmanФБzФБ yУМklemek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu Speaker-2 jakФБna baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz > Telsize yУМkle 5 - ArayУМz kablosunu УЇФБkarФБn, aksi takdirde saФŸ tarafta ses olmayacaktФБr! 6 - Klon modundan УЇФБkmak iУЇin telsizi kapatФБp aУЇФБn Bilgilerinizi yУМklemek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz verilerinizin yУМklemesini gerУЇekleХŸtirin Bilgilerinizi yУМklemek iУЇin bu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn (ХŸifre korumalФБysa engelini kaldФБrФБn) 4 - BaХŸlatmak iУЇin TAMAM'a tФБklayФБn. Bilgilerinizi yazmak iУЇin bu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn (ХŸifre korumalФБysa engelini kaldФБrФБn) 4 - BaХŸlatmak iУЇin TAMAM'a tФБklayФБn. Bilgilerinizi indirmek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz verilerinizin indirilmesini gerУЇekleХŸtirin Telsizinizi okumak iУЇin bu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz verilerinizin indirmesini gerУЇekleХŸtirin Bilgilerinizi yУМklemek iУЇin ХŸu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz verilerinizin yУМklemesini gerУЇekleХŸtirin Telsizinizi yazmak iУЇin bu talimatlarФБ izleyin: 1 - Telsizinizi kapatФБn 2 - ArayУМz kablonuzu baФŸlayФБn 3 - Telsizinizi aУЇФБn 4 - Telsiz verilerinizin yУМklemesini gerУЇekleХŸtirin %(name)s iУЇin boХŸ liste deФŸeri bulundu: %(value)rFrekansGMRSAyarlar alФБnФБyorKayda GitKayda Git:Git...YardФБmBana YardФБm Et...HexBoХŸ kayФБtlarФБ gizleAyarlanФБrsa, sonuУЇlarФБ bu koordinatlardan uzaklФБФŸa gУЖre sФБralaФАУЇe AktarDosyadan ФАУЇe Aktar...ФАУЇe aktarma УЖnerilmezDizinBilgiBilgiYukarФБya SatФБr EkleMasaУМstУМ simgesi yУМklensin mi?SУМrУМcУМ ile etkileХŸimGeУЇersiz %(value)s (ondalФБk basamak kullanФБn)GeУЇersiz GirdiGeУЇersiz Posta koduGeУЇersiz dУМzenleme: %sGeУЇersiz veya desteklenmeyen modУМl dosyasФБGeУЇersiz deФŸer: %rKayФБt numarasФБ:CANLIEnlemUzunluk %i olmalФБdФБrBantlarФБ SФБnФБrlaModlarФБ SФБnФБrlaDurum SФБnФБrlaSonuУЇlarФБ koordinatlardan bu mesafeye (km) sФБnФБrlaModУМl YУМkle...KayФБttan modУМl yУМkleKayФБttan modУМl yУМkle...ModУМlleri yУМklemek son derece tehlikeli olabilir ve bilgisayarФБnФБza, telsizinize veya her ikisine birden zarar verebilir. ASLA gУМvenmediФŸiniz bir kaynaktan ve УЖzellikle ana CHIRP web sitesi (chirp.danplanet.com) dФБХŸФБnda herhangi bir yerden modУМl yУМklemeyin. BaХŸka bir kaynaktan bir modУМl yУМklemek, kaynak sahiplerinin bilgisayarФБnФБza ve УМzerindeki her ХŸeye doФŸrudan eriХŸim saФŸlamasФБna olanak saФŸlayabilir! Bu riske raФŸmen devam edilsin mi?Ayarlar yУМkleniyorLogo dizesi 1 (12 karakter)Logo dizesi 2 (12 karakter)BoylamKayФБtlarKayФБt %i silinemezHafФБzanФБn dУМzenlenebilmesi iУЇin bir bankada olmasФБ gerekir{num} kaydФБ {bank} bankasФБnda deФŸilModModelModlarModУМlModУМl YУМklendiModУМl baХŸarФБyla yУМklendiBirden fazla baФŸlantФБ noktasФБ bulundu: %sAХŸaФŸФБ TaХŸФБYukarФБ TaХŸФБYeni PencereYeni sУМrУМm mevcutAХŸaФŸФБda boХŸ satФБr yok!ModУМl bulunamadФБ%i kadФБnda modУМl bulunamadФБSonuУЇ yokSonuУЇ yok!NumaraOfsetSadece belirli gruplarYalnФБzca belirli modlarYalnФБzca kayФБt sekmeleri dФБХŸa aktarФБlabilirYalnФБzca УЇalФБХŸan tekrarlayФБcФБlar (rУЖleler)AУЇSon KullanФБlanlarФБ AУЇHazФБr YapФБlandФБrma AУЇBir dosya aУЇBir modУМl aУЇHata ayФБklama gУМnlУМФŸУМnУМ aУЇYeni pencerede aУЇHazФБr yapФБlandФБrma dizinini aУЇФАsteФŸe baФŸlФБ: -122.0000ФАsteФŸe baФŸlФБ: 100ФАsteФŸe baФŸlФБ: 45.0000ФАsteФŸe baФŸlФБ: bУЖlge, Hastane vb.KayФБtlarФБn УМzerine yazФБlsФБn mФБ?P-VFO kanallarФБ 100-109 olarak ayarlanabilir. Bu sУМrУМmde 130'dan fazla kullanФБlabilir telsiz ayarФБnФБn yalnФБzca bir alt kУМmesi desteklenmektedir. AyrФБХŸtФБrФБlФБyorYapФБХŸtФБrYapФБХŸtФБrФБlan kayФБtlar, mevcut %s kayФБtlarФБnФБn УМzerine yazФБlacakYapФБХŸtФБrФБlan kayФБtlar %s kayФБtlarФБnФБn УМzerine yazФБlacakYapФБХŸtФБrФБlan kayФБtlar, %s kaydФБnФБn УМzerine yazФБlacakYapФБХŸtФБrФБlan kayФБt, %s kaydФБnФБn УМzerine yazacakLУМtfen yeni sУМrУМmУМ yУМklemeden УЖnce CHIRP'den УЇФБktФБФŸФБnФБzdan emin olun!LУМtfen bu adФБmlarФБ dikkatlice izleyin: 1 - Telsizinizi aУЇФБn 2 - ArayУМz kablosunu telsizinize baФŸlayФБn 3 - ФАndirmeyi baХŸlatmak iУЇin bu penceredeki tuХŸa tФБklayФБn (baХŸka bir iletiХŸim kutusu gУЖrebilirsiniz, tamam'a tФБklayФБn) 4 - Telsiz bip sesi УЇФБkaracak ve led yanФБp sУЖnecektir 5 - Veri yУМkleme baХŸlamadan УЖnce "MON" tuХŸuna basmanФБz iУЇin 10 saniyelik bir zaman aХŸФБmФБ sУМresi alacaksФБnФБz. 6 - Her ХŸey yolunda giderse sonunda telsiz bip sesi УЇФБkaracaktФБr. KlonladФБktan sonra kabloyu УЇФБkarФБn ve normal moda geУЇmek iУЇin telsizinizi kapatФБp aУЇФБn. LУМtfen bu adФБmlarФБ dikkatlice izleyin: 1 - Telsizinizi aУЇФБn 2 - ArayУМz kablosunu telsizinize baФŸlayФБn. 3 - ФАndirmeyi baХŸlatmak iУЇin bu penceredeki tuХŸa tФБklayФБn (Telsiz bip sesi УЇФБkaracak ve led yanФБp sУЖnecektir) 4 - ArdФБndan klonlamaya baХŸlamak iУЇin telsizinizdeki "A" tuХŸuna basФБn. (Sonunda telsiz bip sesi УЇФБkaracaktФБr) LУМtfen geliХŸtirici modunun CHIRP projesinin geliХŸtiricileri tarafФБndan veya bir geliХŸtiricinin yУЖnetimi altФБnda kullanФБlmasФБ iУЇin tasarlandФБФŸФБnФБ unutmayФБn. У‡OK DФАKKATLФА kullanФБlmadФБФŸФБ takdirde bilgisayarФБnФБza ve telsizinize zarar verebilecek davranФБХŸ ve iХŸlevleri mУМmkУМn kФБlar. UyarФБldФБn! Yine de devam edilsin mi?LУМtfen bekleyinKablonuzu takФБn ve ardФБndan Tamam'a tФБklayФБnPortGУМУЇBu kayda almak iУЇin enter tuХŸuna basФБnBaskФБ У–nizlemeBaskФБУ–zellikler%s sorgusuKaynaktan SorgulaRX DTCSTelsizTelsiz %i bloФŸunu onaylamadФБTelsiz bilgisiTelsiz, beklenen son bloktan sonra veri gУЖnderdi, bu, seУЇilen model ABD dФБХŸФБndaysa gerУЇekleХŸir ama telsiz bir ABD telsizi. LУМtfen doФŸru modeli seУЇin ve tekrar deneyin.RadioReference Kanada, sorgulayabilmeniz iУЇin УЖnce oturum aУЇmanФБz gerekirRadioReference.com dУМnyanФБn en bУМyУМk telsiz iletiХŸim veri saФŸlayФБcФБsФБdФБr Premium hesap gereklidirYeniden BaХŸlatma GerekliYenilenmiХŸ %s kaydФБSУМrУМcУМyУМ Yeniden YУМkleSУМrУМcУМyУМ ve DosyayФБ Yeniden YУМkleBankayФБ yeniden adlandФБrRepeaterBook, AmatУЖr Telsiz iУЇin dУМnya УЇapФБnda en kapsamlФБ УœCRETSФАZ rУЖle rehberidir.Raporlama etkinleХŸtirildiRaporlama, CHIRP projesinin sФБnФБrlФБ УЇabalarФБmФБzФБ hangi telsiz modellerine ve iХŸletim sistemi platformlarФБna harcayacaФŸФБnФБ bilmesine yardФБmcФБ olur. Etkin bФБrakФБrsanФБz gerУЇekten minnettar oluruz. Raporlama gerУЇekten devre dФБХŸФБ bФБrakФБlsФБn mФБ?Yeniden BaХŸlatma Gerekiyor%i sekmeyi geri yУМkle%i sekmeyi geri yУМkleAlФБnan ayarlarKaydetKapanmadan УЖnce kaydedilsin mi?DosyayФБ kaydetKaydedilmiХŸ ayarlarTarama listeleriKarФБХŸtФБrФБcФБGУМvenlik RiskiBant PlanФБ SeУЇ...BantlarФБ SeУЇModlarФБ SeУЇBir bant planФБ seУЇinServisAyarlarHam KaydФБ GУЖsterHata ayФБklama gУМnlУМФŸУМ konumunu gУЖsterEkstra alanlarФБ gУЖsterBazФБ kayФБtlar bu telsizle uyumlu deФŸilBazФБ anФБlar silinemez%i kaydФБ sФБrala%i kaydФБ sФБrala%i kaydФБ artan ХŸekilde sФБrala%i kaydФБ artan ХŸekilde sФБrala%i kaydФБ azalan ХŸekilde sФБrala%i kaydФБ azalan ХŸekilde sФБralaSУМtuna gУЖre sФБrala:KayФБtlarФБ sФБralaSФБralamaDevletEyalet/ФАlBaХŸarФБlФБDMR-MARC DУМnya У‡apФБnda iletiХŸim AФŸФБX3Plus sУМrУМcУМsУМ ХŸu anda deneyseldir. Bilinen bir sorun yok, ancak dikkatli bir ХŸekilde ilerlemelisiniz. LУМtfen ilk baХŸarФБlФБ indirmenizin dУМzenlenmemiХŸ bir kopyasФБnФБ bir CHIRP Radio Images (*.img) dosyasФБna kaydedin. Bu modУМlУМn yazarФБ tanФБnmФБХŸ bir CHIRP geliХŸtiricisi deФŸildir. GУМvenlik riski oluХŸturabileceФŸinden bu modУМlУМ yУМklememeniz УЖnerilir. Yine de devam edilsin mi?KayФБtlarФБ iУЇe aktarmak iУЇin УЖnerilen prosedУМr, kaynak dosyayФБ aУЇmak ve kayФБtlarФБ bu dosyadan hedef gУЖrУМntУМnУМze kopyalamak/yapФБХŸtФБrmaktФБr. Bu iУЇe aktarma iХŸlevine devam ederseniz CHIRP, ХŸu anda aУЇФБk olan dosyanФБzdaki tУМm kayФБtlarФБ %(file)s iУЇindekilerle deФŸiХŸtirecektir. KayФБtlarФБ kopyalamak/yapФБХŸtФБrmak iУЇin bu dosyayФБ aУЇmak mФБ yoksa iУЇe aktarma iХŸlemine devam etmek mi istiyorsunuz?Bu kaydФБBu sУМrУМcУМ, ID-5100'УМn v3'УМ ile test edilmiХŸtir. Telsiziniz tam olarak gУМncellenmemiХŸse, lУМtfen hata ayФБklama gУМnlУМФŸУМ iУЇeren bir hata raporu aУЇarak bize yardФБm edin, bУЖylece diФŸer revizyonlar iУЇin destek verebilelim.Bu sУМrУМcУМ geliХŸtirme aХŸamasФБndadФБr ve deneysel olarak deФŸerlendirilmelidir.Bu erken aХŸama beta sУМrУМcУМsУМdУМr Bu, erken aХŸamadaki bir beta sУМrУМcУМsУМdУМr - yУМkleme riski size aittir Bu Quansheng UV-K5 iУЇin deneysel bir sУМrУМcУМdУМr. Telsizinize zarar verebilir veya daha kУЖtУМsУМ olabilir. Riski size ait olmak УМzere kullanФБn. Herhangi bir deФŸiХŸiklik yapmadan УЖnce lУМtfen hafФБza imajФБnФБ telsizden chirp ile indirin ve saklayФБn. (Yedekleme yapФБn) Bu daha sonra orijinal ayarlarФБ kurtarmak iУЇin kullanФБlabilir. bazФБ ayrФБntФБlar henУМz uygulanmadФБBu, halen geliХŸtirilmekte olan BJ-9900 iУЇin deneysel destektir. LУМtfen OEM yazФБlФБmФБyla iyi bir yedeklemeniz olduФŸundan emin olun. AyrФБca lУМtfen hata raporu ve geliХŸtirme istekleri gУЖnderin! UyarФБldФБnФБz. Kendi sorumluluФŸunuzda ilerleyin!Bu kaydФБ ve hepsini yukarФБ kaydФБrBu kaydФБ ve bloФŸu yukarФБ kaydФБrBu telsizde program moduna girmenin zor bir yolu var, orijinal yazФБlФБm ile bile girmek iУЇin birkaУЇ deneme yapmak gerekir. 8 kez deneyeceФŸim (УЇoФŸu zaman ~3 de iХŸe yarar) ve bu birkaУЇ saniye sУМrebilir, iХŸe yaramazsa birkaУЇ kez tekrar deneyin. ФАХŸe yaramazsa, lУМtfen telsizi ve kabloyu kontrol edin. Bu yalnФБzca daha geniХŸ frekans kapsamФБnФБ destekleyen deФŸiХŸtirilmiХŸ УМrУМn yazФБlФБmФБ kullanФБyorsanФБz etkinleХŸtirilmelidir. Bunun etkinleХŸtirilmesi, CHIRP'in OEM kФБsФБtlamalarФБnФБ uygulamamasФБna neden olur ve tanФБmlanmamФБХŸ veya dУМzenlenmemiХŸ davranФБХŸlara yol aУЇabilir. Riski size ait olmak УМzere kullanФБn!Bu, bir web sitesi kaydФБndan bir modУМl yУМkleyecektirTonTon ModuTon SusturucuAyarlama AdФБmФБUSB Portu BulucuKablonuz iУЇin baФŸlantФБ noktasФБ belirlenemiyor. SУМrУМcУМlerinizi ve baФŸlantФБlarФБnФБzФБ kontrol edin.Radyo yУМklenmeden УЖnce kayФБt dУМzenlenemiyor%r stok yapФБlandФБrmasФБ bulunamadФБPano aУЇФБlamФБyorSorgulanamФБyorSon blok okunamФБyor. Bu genellikle seУЇilen model ABD olduФŸunda olur ama telsiz ABD dФБХŸФБ bir telsizdir (veya geniХŸ bantlФБdФБr). LУМtfen doФŸru modeli seУЇin ve tekrar deneyin.%s bu sistemde gУЖsterilemiyorBu kayФБtta %s ayarlanamФБyorAmerika BirleХŸik Devletleri(gerekirse) Kablonuzu УЇФБkarФБn ve ardФБndan Tamam'ФБ tФБklayФБnYУМkleme talimatlarФБTelsize yУМkleTelsize yУМkle...YУМklenen kayФБt %sSabit geniХŸlikte yazФБ tipi kullanDaha bУМyУМk yazФБ tipi kullanDeФŸer %i bit'e sФБФŸmФБyorDeФŸer en az %.4f olmalФБdФБrDeФŸer en fazla %.4f olmalФБdФБrDeФŸer tam olarak %i ondalФБk basamak olmalФБdФБrDeФŸer sФБfФБr veya daha bУМyУМk olmalФБdФБrDeФŸerlerTedarikУЇiGУЖsterUYARI!UyarФБUyarФБ: %sHoХŸgeldinizCHIRP'in sizin iУЇin bir masaУМstУМ simgesi yУМklemesini ister misiniz?Kablonuz ХŸu baФŸlantФБ noktasФБnda gУЖrУМnУМyor:bitlerbytesher biri baytdevre dФБХŸФБ bФБrakФБldФБetkinleХŸtirildi{bank} doluchirp-20240224/chirp/locale/pt_BR/0000755000175000017500000000000014566340177015423 5ustar hibbyhibbychirp-20240224/chirp/locale/pt_BR/LC_MESSAGES/0000755000175000017500000000000014566340177017210 5ustar hibbyhibbychirp-20240224/chirp/locale/pt_BR/LC_MESSAGES/CHIRP.mo0000644000175000017500000000252414566340175020413 0ustar hibbyhibbyо•є%Ь`ae{‰‘–šЁ ГР Чбжнуьђљџ   %/46kp€‡ ›ЂЉАТб иущђљ "(<@ I     AllAn error has occurredBanksCloningCommentCopyCutDeleteDiff Raw MemoriesDigital CodeDuplexFrequencyHelpImportIndexMemoriesModelOffsetPastePortPowerRadioShow Raw MemoryToneTone ModeVendorProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2013-03-30 22:04-0300 Last-Translator: Crezivando Language-Team: Language pt-BR Language: pt-BR MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-15 Content-Transfer-Encoding: 8bit X-Generator: Poedit 1.5.5 TudoOcorreu um erroBancosClonandoComentсrioCopiarCortarApagarDiff Memѓrias RawCѓdigo DigitalDuplexFrequъnciaAjudaImportarЭndiceMemѓriasModeloOffsetColarPortaPowerRсdioMostrar Memѓria RawTomModo TomFornecedorchirp-20240224/chirp/locale/el/0000755000175000017500000000000014566340177015015 5ustar hibbyhibbychirp-20240224/chirp/locale/el/LC_MESSAGES/0000755000175000017500000000000014566340177016602 5ustar hibbyhibbychirp-20240224/chirp/locale/el/LC_MESSAGES/CHIRP.mo0000644000175000017500000003417014566340175020007 0ustar hibbyhibbyо•ЋtхЬ `a^hЧ Эй нчў.7=CGOfmЃВЗПву щєќ $. 3 AKOVen ‰ЊГЧнњ%>\o€˜ЗЫ ыљџ%=C1J| ‹ ЁЋА С Э кхщ юњ -?H Zf wŠ%ЅЫыёј+ @LS f‡ Œ˜ Њ ЖФг чѕ? [$gŒ‘!— ЙЧ ал фёљџ, @N eq‚•š ЏЙ Шечяј.?_eфtY ^ h u‘ Ў/Мь#8Hf‚'Хуъя ї! -2 8CІR љфыњ"(;d.ƒ#В!жј!%>:y!ˆ#Њ%Ює$-*R}Ž Ў0Ль  , 1 K Y ] 1n   -Б ]п =!$F!k!F…!IЬ!#"::"Su"5Щ"!џ"2!#FT#%›#HС#2 $=$KT$ $+З$ у$ №$z§$ x%…%%Ѓ%Щ%м%с% §%!&@&R&V&m&*„&Џ&Ш&ч&!'/('%X'!~' ' Р'<Э'p (U{(б(р(Fч(&.)/U)"…)Ј)*З)Pт)3*!B*>d*Ѓ*#С*Oх*!5+W+s+(“+™М+%V,D|,С, Ъ,Bе,--F-W-j-|-–-І-JН-+.%4.%Z.;€.0М.-э.)/E/4Z/#/-Г/с/,џ/,0=0fP0jЗ0V"1y1!Š1.Ќ1 л3ц3ќ3464?R4#’4oЖ4!&5*H5!s5G•5>н5,6DI6<Ž6VЫ6K"7n7…7–7Б7а7Lч74898?8 W8 „< sЊ|J`):ЁUE’Ÿ~› ”cˆ‘•.v>"M,f‹]Є&N4' KL*ЇЉ™…@˜D+€Ym!i 8(“ЂCtbWŠp\1%7BFIwS5r AuzexV$^ƒy?6š-3o/‚Ѕ{kЃ#2 [jŽH=R‰9œ;–ZnGЈqOQŒ—ЋaXghlTž†P}dІ_0‡(none)A new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllAll FilesAll supported formats|AmateurAn error has occurredApplying settingsBandplanBandsBanksBinBrowserBuilding Radio BrowserCanadaChirp Image FilesChoice RequiredChoose %s DTCS CodeChoose %s ToneCityCloningCloning from radioCloning to radioCloseClose fileCommentCommunicate with radioCompleteCountryCustom...DTCSDTCS PolarityDV MemoryDecDeleteDeveloper ModeDistanceDo not prompt again for %sDouble-click to change bank nameDownloadDownload from radioDownload instructionsEdit details for %i memoriesEdit details for memory %iEnter FrequencyEnter TX Frequency (MHz)Enter a new name for bank %s:Enter custom port:Erased memory %sError applying settingsError communicating with radioExperimental driverExport can only write CSV filesExport to CSVExtraFailed to load radio browserFeaturesFile does not exist: %sFilesFilterFilter results with location matching this stringFindFind NextFinished radio job %sFrequencyGMRSGetting settingsGoto MemoryGoto Memory:Help Me...HexInfoInformationInsert Row AboveInvalid ZIP codeInvalid edit: %sInvalid value: %rLatitudeLength must be %iLimit BandsLoading settingsLongitudeMemoriesMemory %i is not deletableMemory must be in a bank to be editedMemory {num} not in bank {bank}ModelModuleMore than one port found: %sNew version availableNo empty rows below!No results!NumberOnly certain bandsOnly memory tabs may be exportedOpenOpen RecentOpen Stock ConfigOpen a fileOpen a moduleOpen debug logOptional: -122.0000Optional: 100Optional: 45.0000Overwrite memories?Please be sure to quit CHIRP before installing the new version!Please waitPlug in your cable and then click OKPortPowerPress enter to set this in memoryPrint PreviewPrintingPropertiesQuery %sQuery SourceRX DTCSRadioRadio did not ack block %iRadio informationRefreshed memory %sReload DriverReload Driver and FileRename bankRestart RequiredRetrieved settingsSaveSave before closing?Save fileSaved settingsSelect BandsSelect a bandplanServiceSettingsShow debug log locationSome memories are incompatible with this radioSome memories are not deletableStateState/ProvinceThis is experimental support for BJ-9900 which is still under development. Please ensure you have a good backup with OEM software. Also please send in bug and enhancement requests! You have been warned. Proceed at your own risk!ToneTone ModeTone SquelchTuning StepUSB Port FinderUnable to open the clipboardUnited StatesUnplug your cable (if needed) and then click OKUpload instructionsUpload to radioUploaded memory %sUse fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterVendorViewWarningWarning: %sWelcomeYour cable appears to be on port:bitsbytesbytes each{bank} is fullProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2023-02-11 15:12+0200 Last-Translator: Sokratis Alichanidis Language-Team: Greek Language: el MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 3.2.2 X-Poedit-SourceCharset: ISO-8859-15 X-Poedit-Basepath: . X-Poedit-SearchPath-0: . (ЮКЮБЮМЮЏЮБ)ЮœЮЏЮБ ЮНЮ­ЮБ Ю­ЮКЮДЮПЯƒЮЗ Я„ЮПЯ… CHIRP ЮЕЮЏЮНЮБЮЙ ЮДЮЙЮБЮИЮ­ЯƒЮЙЮМЮЗ. Ю ЮБЯЮБЮКЮБЮЛЮПЯЮМЮЕ ЮЕЯ€ЮЙЯƒЮКЮЕЯ†ЮИЮЕЮЏЯ„ЮЕ Я„ЮЗЮН ЮЙЯƒЯ„ЮПЯƒЮЕЮЛЮЏЮДЮБ Я„ЮП ЯƒЯ…ЮНЯ„ЮПЮМЯŒЯ„ЮЕЯЮП ЮДЯ…ЮНЮБЯ„ЯŒ ЮГЮЙЮБ ЮНЮБ Я„ЮЗЮН ЮКЮБЯ„ЮЕЮВЮЌЯƒЮЕЯ„ЮЕ!ЮЃЯ‡ЮЕЯ„ЮЙЮКЮЌЮЃЯ‡ЮЕЯ„ЮЙЮКЮЌ ЮМЮЕ Я„ЮП CHIRPЮŒЮЛЮЕЯ‚ЮŒЮЛЮБ Я„ЮБ ЮБЯЯ‡ЮЕЮЏЮБЮŒЮЛЮПЮЙ ЮПЮЙ Я„ЯЯ€ЮПЮЙ ЮБЯЯ‡ЮЕЮЏЯ‰ЮН|ЮЁЮБЮДЮЙЮПЮЕЯЮБЯƒЮЙЯ„Ю­Я‡ЮНЮЗЮ ЮБЯЮПЯ…ЯƒЮЙЮЌЯƒЯ„ЮЗЮКЮЕ Ю­ЮНЮБ ЯƒЯ†ЮЌЮЛЮМЮБЮ•Я†ЮБЯЮМЮПЮГЮЎ ЯЯ…ЮИЮМЮЏЯƒЮЕЯ‰ЮНЮЇЮЌЯЯ„ЮЗЯ‚ ЯƒЯ…Я‡ЮНЮПЯ„ЮЎЯ„Я‰ЮНЮœЯ€ЮЌЮНЯ„ЮЕЯ‚ЮŸЮМЮЌЮДЮЕЯ‚ ЮМЮНЮЗЮМЯŽЮНBinЮ ЮЕЯЮЙЮЗЮГЮЗЯ„ЮЎЯ‚Ю”ЮЗЮМЮЙЮПЯ…ЯЮГЮЏЮБ Ю ЮЕЯЮЙЮЗЮГЮЗЯ„ЮЎ Ю ЮПЮМЯ€ЮПЮДЮЕЮКЯ„ЯŽЮНЮšЮБЮНЮБЮДЮЌЯ‚Ю‘ЯЯ‡ЮЕЮЏЮБ ЮЕЮЙЮДЯŽЮЛЮПЯ… CHIRPЮ‘Я€ЮБЮЙЯ„ЮЕЮЏЯ„ЮБЮЙ ЮЕЯ€ЮЙЮЛЮПЮГЮЎЮ•Я€ЮЙЮЛЮ­ЮОЯ„ЮЕ ЮКЯ‰ЮДЮЙЮКЯŒ DTCS %sЮ•Я€ЮЙЮЛЮ­ЮОЯ„ЮЕ Я„ЯŒЮНЮП %sЮ ЯŒЮЛЮЗЮ‘ЮНЯ„ЮЙЮГЯЮБЯ†ЮЎЮ›ЮЎЯˆЮЗ ЮБЯ€ЯŒ Я€ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮ‘Я€ЮПЯƒЯ„ЮПЮЛЮЎ ЯƒЮЕ Я€ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮšЮЛЮЕЮЏЯƒЮЙЮМЮПЮšЮЛЮЕЮЏЯƒЮЙЮМЮП ЮБЯЯ‡ЮЕЮЏЮПЯ…ЮЃЯ‡ЯŒЮЛЮЙЮПЮ•Я€ЮЙЮКЮПЮЙЮНЯ‰ЮНЮЏЮБ ЮМЮЕ Я€ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮŸЮЛЮПЮКЮЛЮЗЯЯ‰ЮМЮ­ЮНЮЗЮЇЯŽЯЮБЮ ЯЮПЯƒЮБЯЮМЮПЯƒЮМЮ­ЮНЮЗ...DTCSЮ ЮПЮЛЮЙЮКЯŒЯ„ЮЗЯ„ЮБ DTCSЮœЮНЮЎЮМЮЗ DVDecЮ”ЮЙЮБЮГЯЮБЯ†ЮЎЮ›ЮЕЮЙЯ„ЮПЯ…ЯЮГЮЏЮБ Я€ЯЮПЮГЯЮБЮМЮМЮБЯ„ЮЙЯƒЯ„ЮЎЮ‘Я€ЯŒЯƒЯ„ЮБЯƒЮЗЮЮБ ЮМЮЗЮН ЮЕЯЯ‰Я„ЮЗЮИЯŽ ЮОЮБЮНЮЌ ЮГЮЙЮБ %sЮšЮЌЮНЯ„ЮЕ ЮДЮЙЯ€ЮЛЯŒ ЮКЮЛЮЙЮК ЮГЮЙЮБ ЮМЮЕЯ„ЮПЮНЮПЮМЮБЯƒЮЏЮБ Я„ЮЗЯ‚ ЮПЮМЮЌЮДЮБЯ‚ ЮМЮНЮЗЮМЯŽЮНЮ›ЮЎЯˆЮЗЮ›ЮЎЯˆЮЗ Ю‘Я€ЯŒ Ю ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮŸЮДЮЗЮГЮЏЮЕЯ‚ ЮЛЮЎЯˆЮЗЯ‚Ю•Я€ЮЕЮОЮЕЯЮГЮБЯƒЮЏЮБ ЮЛЮЕЯ€Я„ЮПЮМЮЕЯЮЕЮЙЯŽЮН ЮГЮЙЮБ %i ЮМЮНЮЎЮМЮЕЯ‚Ю•Я€ЮЕЮОЮЕЯЮГЮБЯƒЮЏЮБ ЮЛЮЕЯ€Я„ЮПЮМЮЕЯЮЕЮЙЯŽЮН ЮГЮЙЮБ Я„ЮЗ ЮМЮНЮЎЮМЮЗ %iЮ•ЮЙЯƒЮЌЮГЮЕЯ„ЮЕ ЯƒЯ…Я‡ЮНЯŒЯ„ЮЗЯ„ЮБЮ•ЮЙЯƒЮЌЮГЮЕЯ„ЮЕ ЯƒЯ…Я‡ЮНЯŒЯ„ЮЗЯ„ЮБ ЮЕЮКЯ€ЮПЮМЯ€ЮЎЯ‚ (MHz)Ю•ЮЙЯƒЮЌЮГЮЕЯ„ЮЕ Ю­ЮНЮБ ЮНЮ­ЮП ЯŒЮНЮПЮМЮБ ЮГЮЙЮБ Я„ЮЗЮН ЮПЮМЮЌЮДЮБ ЮМЮНЮЗЮМЯŽЮН %s:Ю•ЮЙЯƒЮЌЮГЮЕЯ„ЮЕ Я€ЯЮПЯƒЮБЯЮМЮПЯƒЮМЮ­ЮНЮЗ ЮИЯЯЮБ:Ю”ЮЙЮЕЮГЯЮЌЯ†ЮЗ ЮЗ ЮМЮНЮЎЮМЮЗ %sЮЃЯ†ЮЌЮЛЮМЮБ ЮЕЯ†ЮБЯЮМЮПЮГЮЎЯ‚ ЯЯ…ЮИЮМЮЏЯƒЮЕЯ‰ЮНЮЃЯ†ЮЌЮЛЮМЮБ ЮЕЯ€ЮЙЮКЮПЮЙЮНЯ‰ЮНЮЏЮБЯ‚ ЮМЮЕ Я„ЮПЮН Я€ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮ ЮЕЮЙЯЮБЮМЮБЯ„ЮЙЮКЯŒЯ‚ ЮПЮДЮЗЮГЯŒЯ‚Ю— ЮЕЮОЮБЮГЯ‰ЮГЮЎ ЮЕЮЏЮНЮБЮЙ ЮДЯ…ЮНЮБЯ„ЮЎ ЮМЯŒЮНЮП ЯƒЮЕ ЮБЯЯ‡ЮЕЮЏЮБ CSVЮ•ЮОЮБЮГЯ‰ЮГЮЎ ЯƒЮЕ ЮБЯЯ‡ЮЕЮЏЮП ЮМЮПЯЯ†ЮЎЯ‚ .CSVЮ ЮЕЯЮЙЯƒЯƒЯŒЯ„ЮЕЯЮБЮ‘ЮДЯ…ЮНЮБЮМЮЏЮБ Я†ЯŒЯЯ„Я‰ЯƒЮЗЯ‚ Я€ЮЕЯЮЙЮЗЮГЮЗЯ„ЮЎ Я€ЮПЮМЯ€ЮПЮДЮЕЮКЯ„ЯŽЮНЮ”Я…ЮНЮБЯ„ЯŒЯ„ЮЗЯ„ЮЕЯ‚ЮЄЮП ЮБЯЯ‡ЮЕЮЏЮП ЮДЮЕЮН Я…Я€ЮЌЯЯ‡ЮЕЮЙ: %sЮ‘ЯЯ‡ЮЕЮЏЮБЮІЮЏЮЛЯ„ЯЮПЮІЮЙЮЛЯ„ЯЮЌЯЮЙЯƒЮМЮБ ЮБЯ€ЮПЯ„ЮЕЮЛЮЕЯƒЮМЮЌЯ„Я‰ЮН ЮМЮЕ Я„ЮПЯ€ЮПЮИЮЕЯƒЮЏЮБ ЯƒЯЮМЯ†Я‰ЮНЮЗ ЮМЮЕ ЮБЯ…Я„ЯŒ Я„ЮП ЮЛЮЕЮКЯ„ЮЙЮКЯŒЮ•ЯЯЮЕЯƒЮЗЮ•ЯЯЮЕЯƒЮЗ ЮЕЯ€ЯŒЮМЮЕЮНЮПЯ…ЮЄЮЕЮЛЮЕЮЏЯ‰ЯƒЮЕ ЮЗ ЮЕЯЮГЮБЯƒЮЏЮБ %sЮЃЯ…Я‡ЮНЯŒЯ„ЮЗЯ„ЮБGMRSЮ›ЮЎЯˆЮЗ ЯЯ…ЮИЮМЮЏЯƒЮЕЯ‰ЮНЮœЮЕЯ„ЮЌЮВЮБЯƒЮЗ ЯƒЮЕ ЮœЮНЮЎЮМЮЗЮœЮЕЯ„ЮЌЮВЮБЯƒЮЗ ЯƒЮЕ ЮœЮНЮЎЮМЮЗ:Ю’ЮПЮЎЮИЮЕЮЙЮБ...HexЮ ЮЛЮЗЯЮПЯ†ЮПЯЮЏЮЕЯ‚Ю ЮЛЮЗЯЮПЯ†ЮПЯЮЏЮЕЯ‚Ю•ЮЙЯƒЮБЮГЯ‰ЮГЮЎ ЮГЯЮБЮМЮМЮЎЯ‚ ЮЕЯ€ЮЌЮНЯ‰ЮœЮЗ Ю­ЮГЮКЯ…ЯЮПЯ‚ ЮЄЮšЮœЮЗ Ю­ЮГЮКЯ…ЯЮЗ Я„ЮЙЮМЮЎ: %sЮœЮЗ Ю­ЮГЮКЯ…ЯЮЗ Я„ЮЙЮМЮЎ: %rЮ“ЮЕЯ‰ЮГЯЮБЯ†ЮЙЮКЯŒ Я€ЮЛЮЌЯ„ЮПЯ‚ЮЄЮП ЮМЮЎЮКЮПЯ‚ Я€ЯЮ­Я€ЮЕЮЙ ЮНЮБ ЮЕЮЏЮНЮБЮЙ %iЮ ЮЕЯЮЙЮПЯЮЙЯƒЮМЯŒЯ‚ ЮœЯ€ЮБЮНЯ„ЯŽЮНЮІЯŒЯЯ„Я‰ЯƒЮЗ ЯЯ…ЮИЮМЮЏЯƒЮЕЯ‰ЮНЮ“ЮЕЯ‰ЮГЯЮБЯ†ЮЙЮКЯŒ ЮМЮЎЮКЮПЯ‚ЮœЮНЮЎЮМЮЕЯ‚Ю— ЮМЮНЮЎЮМЮЗ %i ЮДЮЕЮН ЮМЯ€ЮПЯЮЕЮЏ ЮНЮБ ЮДЮЙЮБЮГЯЮБЯ†ЮЕЮЏЮ— ЮМЮНЮЎЮМЮЗ Я€ЯЮ­Я€ЮЕЮЙ ЮНЮБ ЮВЯЮЏЯƒЮКЮЕЯ„ЮБЮЙ ЯƒЮЕ ЮПЮМЮЌЮДЮБ ЮГЮЙЮБ ЮНЮБ ЮГЮЏЮНЮЕЮЙ ЮЕЯ€ЮЕЮОЮЕЯЮГЮБЯƒЮЏЮБЮ— ЮМЮНЮЎЮМЮЗ {num} ЮДЮЕЮН ЮВЯЮЏЯƒЮКЮЕЯ„ЮБЮЙ ЯƒЯ„ЮЗЮН ЮПЮМЮЌЮДЮБ ЮМЮНЮЗЮМЯŽЮН {bank}ЮœЮПЮНЯ„Ю­ЮЛЮПModuleЮ’ЯЮ­ЮИЮЗЮКЮБЮН Я€ЮЕЯЮЙЯƒЯƒЯŒЯ„ЮЕЯЮЕЯ‚ ЮБЯ€ЯŒ ЮМЮЏЮБ ЮИЯЯЮЕЯ‚: %sЮ”ЮЙЮБЮИЮ­ЯƒЮЙЮМЮЗ ЮНЮ­ЮБ Ю­ЮКЮДЮПЯƒЮЗЮšЮБЮМЮЏЮБ ЮКЮЕЮНЮЎ ЯƒЮЕЮЙЯЮЌ ЮБЯ€ЯŒ ЮКЮЌЯ„Я‰!ЮšЮБЮНЮ­ЮНЮБ ЮБЯ€ЮПЯ„Ю­ЮЛЮЕЯƒЮМЮБ!Ю‘ЯЮЙЮИЮМЯŒЯ‚ЮœЯŒЮНЮП ЮПЯЮЙЯƒЮМЮ­ЮНЮЕЯ‚ ЮМЯ€ЮЌЮНЯ„ЮЕЯ‚ЮœЯŒЮНЮП ЮПЮЙ ЮКЮБЯЯ„Ю­ЮЛЮЕЯ‚ ЮМЮНЮЗЮМЯŽЮН ЮМЯ€ЮПЯЮПЯЮН ЮНЮБ ЮЕЮОЮБЯ‡ЮИЮПЯЮНЮ†ЮНЮПЮЙЮГЮМЮБЮ†ЮНЮПЮЙЮГЮМЮБ Я€ЯЯŒЯƒЯ†ЮБЯ„ЮПЯ…Ю†ЮНЮПЮЙЮГЮМЮБ Я€ЯЮПЮЕЯ€ЮЙЮЛЮЕЮГЮМЮ­ЮНЯ‰ЮН ЯЯ…ЮИЮМЮЏЯƒЮЕЯ‰ЮНЮ†ЮНЮПЮЙЮГЮМЮБ ЮБЯЯ‡ЮЕЮЏЮПЯ…Ю†ЮНЮПЮЙЮГЮМЮБ ЮБЯЮИЯЯŽЮМЮБЯ„ЮПЯ‚Ю†ЮНЮПЮЙЮГЮМЮБ ЮБЯЯ‡ЮЕЮЏЮПЯ… ЮКЮБЯ„ЮБЮГЯЮБЯ†ЮЎЯ‚ ЮБЯ€ЮПЯƒЯ†ЮБЮЛЮМЮЌЯ„Я‰ЯƒЮЗЯ‚Ю ЯЮПЮБЮЙЯЮЕЯ„ЮЙЮКЯŒ: -122.0000Ю ЯЮПЮБЮЙЯЮЕЯ„ЮЙЮКЯŒ: 100Ю ЯЮПЮБЮЙЯЮЕЯ„ЮЙЮКЯŒ: 45.0000Ю‘ЮНЯ„ЮЙЮКЮБЯ„ЮЌЯƒЯ„ЮБЯƒЮЗ ЮМЮНЮЗЮМЯŽЮН;Ю ЮБЯЮБЮКЮБЮЛЮПЯЮМЮЕ ЮВЮЕЮВЮБЮЙЯ‰ЮИЮЕЮЏЯ„ЮЕ ЯŒЯ„ЮЙ Ю­Я‡ЮЕЯ„ЮЕ ЮКЮЛЮЕЮЏЯƒЮЕЮЙ Я„ЮП CHIRP Я€ЯЮЙЮН ЮЕЮГЮКЮБЯ„ЮБЯƒЯ„ЮЎЯƒЮЕЯ„ЮЕ Я„ЮЗЮН ЮНЮ­ЮБ Ю­ЮКЮДЮПЯƒЮЗ!Ю ЮБЯЮБЮКЮБЮЛЯŽ Я€ЮЕЯЮЙЮМЮ­ЮНЮЕЯ„ЮЕЮЃЯ…ЮНЮДЮ­ЯƒЯ„ЮЕ Я„ЮП ЮКЮБЮЛЯŽЮДЮЙЮП ЯƒЮБЯ‚ ЮКЮБЮЙ Я€ЮБЯ„ЮЎЯƒЯ„ЮЕ OKЮ˜ЯЯЮБЮ™ЯƒЯ‡ЯЯ‚Ю ЮБЯ„ЮЎЯƒЯ„ЮЕ enter ЮГЮЙЮБ ЮКЮБЯ„ЮБЯ‡ЯŽЯЮЗЯƒЮЗ ЯƒЯ„ЮЗ ЮМЮНЮЎЮМЮЗЮ ЯЮПЮЕЯ€ЮЙЯƒЮКЯŒЯ€ЮЗЯƒЮЗ ЮЕЮКЯ„ЯЯ€Я‰ЯƒЮЗЯ‚Ю•ЮКЯ„ЯЯ€Я‰ЯƒЮЗЮ™ЮДЮЙЯŒЯ„ЮЗЯ„ЮЕЯ‚Ю•ЯЯŽЯ„ЮЗЮМЮБ %sЮ•ЯЯŽЯ„ЮЗЮМЮБ Ю ЮЗЮГЮЎЯ‚DTCS Ю›ЮЎЯˆЮЗЯ‚Ю ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЯ‚ЮŸ Я€ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЯ‚ ЮДЮЕЮН ЮЕЯ€ЮЙЮВЮЕЮВЮБЮЏЯ‰ЯƒЮЕ Я„ЮП ЮМЯ€ЮЛЮПЮК %iЮ ЮЛЮЗЯЮПЯ†ЮПЯЮЏЮЕЯ‚ Я€ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮ‘ЮНЮБЮНЮЕЯŽЮИЮЗЮКЮЕ ЮЗ ЮМЮНЮЎЮМЮЗ %sЮ•Я€ЮБЮНЮБЯ†ЯŒЯЯ„Я‰ЯƒЮЗ ЮŸЮДЮЗЮГЮПЯЮ•Я€ЮБЮНЮБЯ†ЯŒЯЯ„Я‰ЯƒЮЗ ЮŸЮДЮЗЮГЮПЯ ЮКЮБЮЙ Ю‘ЯЯ‡ЮЕЮЏЮПЯ…ЮœЮЕЯ„ЮПЮНЮПЮМЮБЯƒЮЏЮБ ЮПЮМЮЌЮДЮБЯ‚ ЮМЮНЮЗЮМЯŽЮНЮ‘Я€ЮБЮЙЯ„ЮЕЮЏЯ„ЮБЮЙ ЮЕЯ€ЮБЮНЮЕЮКЮКЮЏЮНЮЗЯƒЮЗЮЁЯ…ЮИЮМЮЏЯƒЮЕЮЙЯ‚ ЮБЮНЮБЮКЯ„ЮЎЮИЮЗЮКЮБЮНЮ‘Я€ЮПЮИЮЎЮКЮЕЯ…ЯƒЮЗЮ‘Я€ЮПЮИЮЎЮКЮЕЯ…ЯƒЮЗ Я€ЯЮЙЮН Я„ЮП ЮКЮЛЮЕЮЏЯƒЮЙЮМЮП;Ю‘Я€ЮПЮИЮЎЮКЮЕЯ…ЯƒЮЗ ЮБЯЯ‡ЮЕЮЏЮПЯ…ЮЁЯ…ЮИЮМЮЏЯƒЮЕЮЙЯ‚ ЮБЯ€ЮПЮИЮЗЮКЮЕЯЮИЮЗЮКЮБЮНЮ•Я€ЮЙЮЛЮПЮГЮЎ ЮœЯ€ЮБЮНЯ„ЯŽЮНЮ•Я€ЮЙЮЛЮПЮГЮЎ Я‡ЮЌЯЯ„ЮЗ ЯƒЯ…ЮНЮПЯ„ЮЎЯ„Я‰ЮНЮЅЯ€ЮЗЯЮЕЯƒЮЏЮБЮЁЯ…ЮИЮМЮЏЯƒЮЕЮЙЯ‚Ю•ЮМЯ†ЮЌЮНЮЙЯƒЮЗ Я„ЮПЯ€ЮПЮИЮЕЯƒЮЏЮБЯ‚ ЮБЯЯ‡ЮЕЮЏЮПЯ… ЮКЮБЯ„ЮБЮГЯЮБЯ†ЮЎЯ‚ ЮБЯ€ЮПЯƒЯ†ЮБЮЛЮМЮЌЯ„Я‰ЯƒЮЗЯ‚ЮšЮЌЯ€ЮПЮЙЮЕЯ‚ ЮМЮНЮЎЮМЮЕЯ‚ ЮДЮЕЮН ЮЕЮЏЮНЮБЮЙ ЯƒЯ…ЮМЮВЮБЯ„Ю­Я‚ ЮМЮЕ ЮБЯ…Я„ЯŒЮН Я„ЮПЮН Я€ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮšЮЌЯ€ЮПЮЙЮЕЯ‚ ЮМЮНЮЎЮМЮЕЯ‚ ЮДЮЕЮН ЮЕЮЏЮНЮБЮЙ ЮДЯ…ЮНЮБЯ„ЯŒЮН ЮНЮБ ЮДЮЙЮБЮГЯЮБЯ†ЮПЯЮНЮ ЮПЮЛЮЙЯ„ЮЕЮЏЮБЮ ЮПЮЛЮЙЯ„ЮЕЮЏЮБ / Ю•Я€ЮБЯЯ‡ЮЏЮБЮ‘Я…Я„ЮЎ ЮЕЮЏЮНЮБЮЙ Я€ЮЕЮЙЯЮБЮМЮБЯ„ЮЙЮКЮЎ Я…Я€ЮПЯƒЯ„ЮЎЯЮЙЮОЮЗ ЮГЮЙЮБ Я„ЮП BJ-9900 ЮЗ ЮПЯ€ЮПЮЏЮБ ЮЕЮЏЮНЮБЮЙ Я…Я€ЯŒ ЮБЮНЮЌЯ€Я„Я…ЮОЮЗ. Ю ЮБЯЮБЮКЮБЮЛЮПЯЮМЮЕ ЮВЮЕЮВЮБЮЙЯ‰ЮИЮЕЮЏЯ„ЮЕ Я€Я‰Я‚ ЮДЮЙЮБЮИЮ­Я„ЮЕЯ„ЮЕ ЯƒЯ‰ЯƒЯ„ЯŒ ЮБЮНЯ„ЮЏЮГЯЮБЯ†ЮП ЮБЯƒЯ†ЮБЮЛЮЕЮЏЮБЯ‚ Я„ЮПЯ… ЮЕЯЮГЮПЯƒЯ„ЮБЯƒЮЙЮБЮКЮПЯ Я€ЯЮПЮГЯЮБЮМЮМЮБЯ„ЮЙЯƒЮМЮПЯ. Ю•Я€ЮЏЯƒЮЗЯ‚ Я€ЮБЯЮБЮКЮБЮЛЮПЯЮМЮЕ ЮНЮБ ЮМЮБЯ‚ ЯƒЯ„ЮЕЮЏЮЛЮЕЯ„ЮЕ ЮБЮЙЯ„ЮЎЯƒЮЗЯ‚ ЮБЯ€ЮПЯƒЯ†ЮБЮЛЮМЮЌЯ„Я‰ЯƒЮЗЯ‚ ЮЎ ЮНЮ­Я‰ЮН ЮДЯ…ЮНЮБЯ„ЮПЯ„ЮЎЯ„Я‰ЮН! ЮЃЮБЯ‚ Я€ЯЮПЮЕЮЙЮДЮПЯ€ЮПЮЙЮЎЯƒЮБЮМЮЕ. Ю ЯЮПЯ‡Я‰ЯЮЌЯ„ЮЕ ЮМЮЕ ЮДЮЙЮКЮЎ ЯƒЮБЯ‚ ЮЕЯ…ЮИЯЮНЮЗ!ЮЄЯŒЮНЮПЯ‚ЮЄЯЯ€ЮПЯ‚ Я„ЯŒЮНЮПЯ…ЮЄЯŒЮНЮПЯ‚ ЮІЮЏЮМЯ‰ЯƒЮЗЯ‚Ю’ЮЎЮМЮБ ЯƒЯ…ЮНЯ„ЮПЮНЮЙЯƒЮМЮПЯЮˆЯ…ЯЮЕЯƒЮЗ ЮИЯ…ЯЯŽЮН USBЮ‘ЮДЯ…ЮНЮБЮМЮЏЮБ ЮБЮНЮПЮЏЮГЮМЮБЯ„ЮПЯ‚ Я„ЮПЯ… Я€ЯЯŒЯ‡ЮЕЮЙЯЮПЯ…Ю—ЮНЯ‰ЮМЮ­ЮНЮЕЯ‚ Ю ЮПЮЛЮЙЯ„ЮЕЮЏЮЕЯ‚Ю‘Я€ЮПЯƒЯ…ЮНЮДЮ­ЯƒЯ„ЮЕ Я„ЮП ЮКЮБЮЛЯŽЮДЮЙЮП ЯƒЮБЯ‚ (ЮБЮН Я‡ЯЮЕЮЙЮЌЮЖЮЕЯ„ЮБЮЙ) ЮКЮБЮЙ ЮМЮЕЯ„ЮЌ Я€ЮБЯ„ЮЎЯƒЯ„ЮЕ OKЮŸЮДЮЗЮГЮЏЮЕЯ‚ ЮБЯ€ЮПЯƒЯ„ЮПЮЛЮЎЯ‚Ю‘Я€ЮПЯƒЯ„ЮПЮЛЮЎ ЮЃЮЕ Ю ЮПЮМЯ€ЮПЮДЮ­ЮКЯ„ЮЗЮ‘Я€ЮЕЯƒЯ„ЮЌЮЛЮЗ ЮЗ ЮМЮНЮЎЮМЮЗ %sЮЇЯЮЎЯƒЮЗ ЮГЯЮБЮМЮМЮБЯ„ЮПЯƒЮЕЮЙЯЮЌЯ‚ ЯƒЯ„ЮБЮИЮЕЯЮПЯ Я€ЮЛЮЌЯ„ЮПЯ…Я‚ЮЇЯЮЎЯƒЮЗ ЮМЮЕЮГЮБЮЛЯЯ„ЮЕЯЮЗЯ‚ ЮГЯЮБЮМЮМЮБЯ„ЮПЯƒЮЕЮЙЯЮЌЯ‚Ю— Я„ЮЙЮМЮЎ ЮДЮЕЮН Я‡Я‰ЯЮЌЮЕЮЙ ЯƒЮЕ %i bitsЮ— Я„ЮЙЮМЮЎ Я€ЯЮ­Я€ЮЕЮЙ ЮНЮБ ЮЕЮЏЮНЮБЮЙ Я„ЮПЯ…ЮЛЮЌЯ‡ЮЙЯƒЯ„ЮПЮН %.4fЮ— Я„ЮЙЮМЮЎ Я€ЯЮ­Я€ЮЕЮЙ ЮНЮБ ЮЕЮЏЮНЮБЮЙ Я„ЮП Я€ЮПЮЛЯ %.4fЮ— Я„ЮЙЮМЮЎ Я€ЯЮ­Я€ЮЕЮЙ ЮНЮБ Ю­ЮЙЮНЮБЮЙ ЮБЮКЯЮЙЮВЯŽЯ‚ %i ЮДЮЕЮКЮБЮДЮЙЮКЮЌ ЯˆЮЗЯ†ЮЏЮБЮ— Я„ЮЙЮМЮЎ Я€ЯЮ­Я€ЮЕЮЙ ЮНЮБ ЮЕЮЏЮНЮБЮЙ ЮМЮЗЮДЮ­ЮН ЮЎ ЮМЮЕЮГЮБЮЛЯЯ„ЮЕЯЮЗЮ ЯЮПЮМЮЗЮИЮЕЯ…Я„ЮЎЯ‚Ю•ЮМЯ†ЮЌЮНЮЙЯƒЮЗЮ ЯЮПЮЕЮЙЮДЮПЯ€ЮПЮЏЮЗЯƒЮЗЮ ЯЮПЮЕЮЙЮДЮПЯ€ЮПЮЏЮЗЯƒЮЗ: %sЮšЮБЮЛЯ‰ЯƒЮЎЯЮИЮБЯ„ЮЕЮЄЮП ЮКЮБЮЛЯŽЮДЮЙЮП ЯƒЮБЯ‚ Я†ЮБЮЏЮНЮЕЯ„ЮБЮЙ ЮНЮБ ЮЕЮЏЮБЮНЮЙ ЯƒЯ„ЮЗ ЮИЯЯЮБ:bitsbytesbytes Я„ЮП ЮКЮБЮИЮ­ЮНЮБH {bank} ЮЕЮЏЮНЮБЮЙ ЮГЮЕЮМЮЌЯ„ЮЗchirp-20240224/chirp/locale/hu/0000755000175000017500000000000014566340177015031 5ustar hibbyhibbychirp-20240224/chirp/locale/hu/LC_MESSAGES/0000755000175000017500000000000014566340177016616 5ustar hibbyhibbychirp-20240224/chirp/locale/hu/LC_MESSAGES/CHIRP.mo0000644000175000017500000000274614566340175020027 0ustar hibbyhibbyо•ќ%мpqu‹“›ЃЈЌГ Хв йушяѕў "+; @JZQЌБ Р Ь з у эї!"2 9D KXajq y†‹š ЂЏХЫн     AllAn error has occurredBrowserCloningCommentCopyCutDeleteDiff Raw MemoriesDigital CodeDuplexFrequencyHelpImportIndexMemoriesModelOffsetPastePortPowerRadioSettingsShow Raw MemoryToneTone ModeVendorProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2015-01-28 13:47+0100 Last-Translator: Attila Joubert Language-Team: English Language: hu_HU MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 1.7.4 MindHiba tУЖrtУЉntBУЖngУЉszХ‘KlУГnozУЁsMegjegyzУЉsMУЁsolУЁsKivУЁgУЁsTУЖrlУЉsMemУГriasorok УЖsszehasonlУ­tУЁsaDigitУЁlis kУГdDuplexFrekvenciaSУКgУГImportУЁlУЁsSorszУЁmMemУГriaModellOffszetBeillesztУЉsPortTeljesУ­tmУЉnyRУЁdiУГBeУЁllУ­tУЁsMemУГriasor mutatУЁsaCTCSSHang (CTCSS) mУГdGyУЁrtУГchirp-20240224/chirp/locale/de/0000755000175000017500000000000014566340177015005 5ustar hibbyhibbychirp-20240224/chirp/locale/de/LC_MESSAGES/0000755000175000017500000000000014566340177016572 5ustar hibbyhibbychirp-20240224/chirp/locale/de/LC_MESSAGES/CHIRP.mo0000644000175000017500000000271614566340175020000 0ustar hibbyhibbyо•ќ%мpqu‹‘™ЁІЊБ Уа зсцэѓќ  )9 >HmOНТнт щѓ ќ  )6=F LX^gm t~ƒŒ “ЁД Й У     AllAn error has occurredBanksCloningCommentCopyCutDeleteDiff Raw MemoriesDigital CodeDuplexFrequencyHelpImportIndexMemoriesModelOffsetPastePortPowerRadioSettingsShow Raw MemoryToneTone ModeVendorProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2012-10-02 22:11+0100 Last-Translator: Benjamin, HB9EUK Language-Team: German Language: de MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 1.5.3 X-Poedit-SourceCharset: UTF-8 AlleEin Fehler ist aufgetretenBankKlonenKommentarKopierenAusschneidenLУЖschenVergleiche RohspeicherDigital CodeDuplexFrequenzHilfeImportierenIndexSpeicherModelOffsetEinfУМgenPortLeistungGerУЄtEinstellungenZeige RAW SpeicherToneTone ModeHerstellerchirp-20240224/chirp/locale/it/0000755000175000017500000000000014566340177015031 5ustar hibbyhibbychirp-20240224/chirp/locale/it/LC_MESSAGES/0000755000175000017500000000000014566340177016616 5ustar hibbyhibbychirp-20240224/chirp/locale/it/LC_MESSAGES/CHIRP.mo0000644000175000017500000003614314566340175020025 0ustar hibbyhibbyо•ыt9ЬА-Б9п;/+k—ž^­   ",CKasyƒ‹’ЄДШз щїќ( .%9_g~ ‡•š Ђ ЎИМ С Яйнфѓ %@I]tŠCсш 7?Ob{ŽŸОв ђuЈЎ1Еч ьі ў  &. 3>B7VŽ•ЉРЦ Ызш'ў &4EW` r ~ Š4—Ьл ьіџ%+ 2@[ x‚ Š•Ћ М Чгксє #/ A M[j}™ ­Л Эю3*<(g&?З ї$(-!3 Uc lw €•› ­WЙ # 4 S i |  –   Џ Н а н ъ ќ ! !!5!.G!v!–!3Ж!5ъ! " 0">"F"L"T" s""œ"Л" Р" Ъ" з"Lу",0#]#|#"™#М# м#/ъ#$.$>$Q$f$v$”$А$'Ы$ѓ$%%%$%7,%!d%†%‹% ‘%Gœ%+ф&9'J'A`'4Ђ' з' с'`я' P(](s( y(†( Ђ(Џ(Ъ(н(у(ъ(ю(і(§()%)A)V)n)‚)‰)˜)Џ)Щ)а))п) **-*6*E*K*S*h*x**„* “*ž*Ђ*Њ*С* е* у*№*љ*++/+F+e+S}+б+ и+#љ+, ;,E,[,s,!’,Д,,Ъ,ї,* -6-E-W-…`-ц-§-.B .L.R.c. l.v.{.Œ.ž.Ѕ. Ћ.Ж.К.Gб./!/4/R/ Y/ f/s/"ˆ/2Ћ/о/№/0 0)0 E0 R0 ^0:k0І0З0 ж0т0 ъ0 1111$141Q1 o1 {1…1”1Џ1Х1ж1ш1я1і12232 82E2 b2 l2x22&І2Э2т2ё2!3&3@3:H33ƒ33З30ы3E4 b4l4‹4‘4'™4С4е4 х4 №4§4 55545ZC5ž5В5)Ф5ю5 6"6(6 C6N6c6x6Ž6Ѓ6Ж6Ю6 з6ф6њ672,7$_7#„7AЈ7Aъ7,8G8 V8b8h8q8‹8%š8)Р8ъ8я8 ў8 9T9Fn91Е9ч9):*0: [:3g:›:Й:Ь:т:;;!:;%\;6‚;.Й;ш; я; њ; < <0<L<P< U<JaЋЗo Ьа›m…ЊЇЈ^’ЌЄi—0Np5ŒОŸ”B*фx,шСЁfyX'œMuП21ЦБYм‘|-нЧr{Aзт •T\=k~МЂj@Хдe‡вl˜9иHDIцгеƒ€Р&к] $Q6U)?RЖ/šnхА ­ЩCvZ;„WуН}Ъc‰жOыДщ<‚ЛЉ3b“–УGV>"(ІК[LъЙ†h8пFžсzP_‹!оФg+ГЕй%`ВЯdˆ4 .ЫSw7Žрчt ™ЃбЎKsЅqŠЏл:EИЭЮ#ТШ%(value)s must be between %(min)i and %(max)i%i Memories and shift all up%i Memories and shift all up%i Memory%i Memories%i Memory and shift block up%i Memories and shift block up%s has not been saved. Save before closing?(none)...and %i moreA new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllAll FilesAll supported formats|AmateurAn error has occurredAvailable modulesBandsBanksBinBrowserCanadaChirp Image FilesChoice RequiredChoose %s DTCS CodeChoose %s ToneChoose Cross ModeChoose duplexCityCloningCloning from radioCloning to radioCloseClose fileCluster %i memoryCluster %i memoriesCommentCommunicate with radioCompleteConvert to FMCopyCountryCustom PortCustom...CutDTCSDTCS PolarityDV MemoryDecDeleteDeveloper ModeDiff Raw MemoriesDigital ModesDisabledDistanceDo not prompt again for %sDownloadDownload from radioDownload from radio...Download instructionsDriver informationDual-mode digital repeaters that support analog will be shown as FMDuplexEdit details for %i memoriesEdit details for memory %iEnable Automatic EditsEnabledEnter FrequencyEnter Offset (MHz)Enter TX Frequency (MHz)Enter custom port:Erased memory %sError communicating with radioExperimental driverExport can only write CSV filesExport to CSVExport to CSV...FM RadioFREE repeater database, which provides most up-to-date information about repeaters in Europe. No account is required.File does not exist: %sFilesFilterFilter results with location matching this stringFindFind NextFind...FrequencyGMRSGoto MemoryGoto Memory:Goto...HelpHelp Me...HexHide empty memoriesIf set, sort results by distance from these coordinatesImportImport from file...Import not recommendedIndexInfoInformationInsert Row AboveInstall desktop icon?Invalid %(value)s (use decimal degrees)Invalid EntryInvalid edit: %sInvalid value: %rLatitudeLength must be %iLimit BandsLimit ModesLimit StatusLimit results to this distance (km) from coordinatesLoad Module...Loading settingsLongitudeMemoriesMemory %i is not deletableModeModelModesModuleModule LoadedModule loaded successfullyMore than one port found: %sMove DownMove UpNew WindowNew version availableNo modules foundNo resultsNo results!NumberOffsetOnly certain bandsOnly certain modesOnly working repeatersOpenOpen RecentOpen Stock ConfigOpen a fileOpen a moduleOpen debug logOpen in new windowOpen stock config directoryOptional: -122.0000Optional: 100Optional: 45.0000Optional: County, Hospital, etc.Overwrite memories?PastePasted memories will overwrite %s existing memoriesPasted memories will overwrite memories %sPasted memories will overwrite memory %sPasted memory will overwrite memory %sPlease be sure to quit CHIRP before installing the new version!Please waitPlug in your cable and then click OKPortPowerPress enter to set this in memoryPrint PreviewPrintingPropertiesQuery %sQuery SourceRX DTCSRadioRadio informationRename bankRepeaterBook is Amateur Radio's most comprehensive, worldwide, FREE repeater directory.Reporting enabledRestart RequiredRestore %i tabRestore %i tabsRestore tabs on startRetrieved settingsSaveSave before closing?Save fileSaved settingsSecurity RiskSelect Bandplan...Select BandsSelect ModesSelect a bandplanServiceSettingsShow Raw MemoryShow debug log locationShow extra fieldsSome memories are incompatible with this radioSome memories are not deletableSort %i memorySort %i memoriesSort %i memory ascendingSort %i memories ascendingSort %i memory descendingSort %i memories descendingSort by column:Sort memoriesSortingStateSuccessThe DMR-MARC Worldwide NetworkThis MemoryThis memory and shift all upThis memory and shift block upToneTone ModeTone SquelchTuning StepUnable to determine port for your cable. Check your drivers and connections.Unable to edit memory before radio is loadedUnable to find stock config %rUnable to open the clipboardUnable to reveal %s on this systemUnable to set %s on this memoryUnited StatesUnplug your cable (if needed) and then click OKUpload instructionsUpload to radioUpload to radio...Use fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterValuesVendorViewWelcomeWould you like CHIRP to install a desktop icon for you?Your cable appears to be on port:bitsbytesbytes eachProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2024-01-20 12:24+0100 Last-Translator: Daniele Forsi Language-Team: Language: it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 3.4.2 %(value)s deve essere tra %(min)i e %(max)i%i memoria e sposta tutto su%i memorie e sposta tutto su%i memoria%i memorie%i memoria e sposta il blocco su%i memoria e sposta il blocco su%s non УЈ stato salvato. Salvarlo prima di chiudere?(nessuno)...e altri %iУˆ disponibile una nuova versione di CHIRP. Visitare il sito web prima possibile per scaricarla!InformazioniInformazioni su CHIRPTuttoTutti i fileTutti i formati supportati|RadioamatoreSi УЈ verificato un erroreModuli disponibiliBandeBanchiBinBrowserCanadaFile immagine di ChirpScelta richiestaScegliere il codice DTCS %sScegliere il Tono %sScegliere il modo CrossScegliere il duplexCittУ ProgrammazioneClonazione dalla radioClonazione verso la radioChiudiChiude il fileRaggruppa %i memoriaRaggruppa %i memorieCommentoComunicazione con la radioCompletoConverti in FMCopiaNazionePorta personalizzataPersonalizza...TagliaDTCSPolaritУ  DTCSMemoria DVDecEliminaModalitУ  sviluppatoreDiff memorie grezzeModi digitaliDisabilitataDistanzaNon mostrarlo piУЙ per %sScaricaScarica dalla radioScarica dalla radio...Istruzioni per lo scaricamentoInformazioni sul driverI ripetitori digitali dual-mode che supportano l'analogico saranno mostrati come FMDuplexModifica dettagli per %i memorieModifica dettagli per la memoria %iAbilita modifiche automaticheAbilitataInserire la frequenzaInserire l'offset (MHz)Inserire la frequenza TX (MHz)Inserire la porta personalizzata:Memoria %s cancellataErrore durante la comunicazione con la radioDriver sperimentaleL'esportazione puУВ scrivere solo file CSVEsporta in CSVEsporta in CSV...Radio FMDatabase GRATUITO di ripetitori, che fornisce le informazioni piУЙ aggiornate sui ripetitori in Europa. Non УЈ necessario un account.Il file non esiste: %sFileFiltroFiltra i risultati con i luoghi che corrispondono a questa stringaTrovaTrova successivoTrova...FrequenzaGMRSVai alla memoriaVai alla memoria:Vai...AiutoAiutami...HexNascondi memorie vuoteSe impostata, ordina i risultati secondo la distanza da tali coordinateImportaImporta da file...Importazione non raccomandataIndiceInformazioniInformazioniInserisci riga sopraInstallare l'icona per il desktop?Valore %(value)s non valido (usare gradi decimali)Valore non validoModifica non valida: %sValore non valido: %rLatitudineLa lunghezza deve essere %iLimita bandeLimita modiLimita statoLimita i risultati a questa distanza (km) dalle coordinateCarica modulo...Caricamento delle impostazioniLongitudineMemorieLa memoria %i non УЈ eliminabileModoModelloModiModuloModulo caricatoModulo caricato con successoTrovata piУЙ di una porta: %sSposta giУЙSposta suNuova finestraNuova versione disponibileNessun modulo trovatoNessun risultatoNessun risultato!NumeroOffsetSolo certe bandeSolo certi modiSolo ripetitori funzionantiApriApri recenteApri configurazione standardApri fileApri moduloApri registro di debugApri in nuova finestraApri directory configurazioni standardOpzionale: -122.0000Opzionale: 100Opzionale: 45.0000Opzionale: contea, ospedale, ecc.Sovrascrivere le memorie?IncollaLe memorie incollate sovrascriveranno %s memorie esistentiLe memorie incollate sovrascriveranno le memorie %sLe memorie incollate sovrascriveranno la memoria %sLa memoria incollata sovrascrivera la memoria %sAssicurarsi di uscire da CHIRP prima di installare la nuova versione!AttendereCollegare il cavo e premere OKPortaPotenzaPremere Invio per impostarlo in memoriaAnteprima di stampaStampa in corsoProprietУ Interroga %sInterroga fonteDTCS RXRadioInformazioni sulla radioRinomina bancoRepeaterBook УЈ l'elenco mondiale e GRATUITO piУЙ completo di ripetitori per radioamatori.Reporting abilitatoRiavvio richiestoRipristina %i schedaRipristina %i schedeRipristina schede all'avvioImpostazioni recuperateSalvaSalvare prima di chiudere?Salva fileImpostazioni salvateRischio di sicurezzaSeleziona bandplan...Selezionare le bandeSelezionare i modiSelezionare un bandplanServizioImpostazioniMostra memoria grezzaMostra posizione di debugMostra campi aggiuntiviAlcune memorie sono incompatibili con questa radioAlcune memorie non sono cancellabiliOrdina %i memoriaOrdina %i memorie%i memoria in ordine decrescente%i memorie in ordine decrescente%i memoria in ordine decrescente%i memorie in ordine decrescenteColonna per l'ordinamento:Ordina memorieOrdinamentoStatoSuccessoLa rete mondiale DMR-MARCQuesta memoriaQuesta memoria e sposta tutto in altoQuesta memoria e sposta il blocco in altoTonoModalitУ  tonoTone squelchStep sintoniaImpossibile determinare la porta per il cavo. Controllare i driver e i collegamenti.Impossibile modificare la memoria prima di averla caricata dalla radioImpossibile trovare la configurazione standard %rImpossibile aprire gli appuntiImpossibile rivelare %s su questo sistemaImpossibile impostare %s su questa memoriaStati UnitiScollegare il cavo (se necessario) e poi premere OKIstruzioni per il caricamentoCarica sulla radioCarica sulla radio...Usa carattere a larghezza fissaUsa carattere piУЙ grandeIl valore non entra in %i bitIl valore deve essere almeno %.4fIl valore deve essere al massimo %.4fIl valore deve essere di esattamente %i cifre decimaliIl valore deve essere maggiore o uguale a zeroValoriProduttoreVisualizzaBenvenutoInstallare un'icona sul desktop?Il cavo sembra sulla porta:bitbytebyte ciascunochirp-20240224/chirp/locale/es/0000755000175000017500000000000014566340177015024 5ustar hibbyhibbychirp-20240224/chirp/locale/es/LC_MESSAGES/0000755000175000017500000000000014566340177016611 5ustar hibbyhibbychirp-20240224/chirp/locale/es/LC_MESSAGES/CHIRP.mo0000644000175000017500000022137014566340175020016 0ustar hibbyhibbyо•Ё$ -,р" с"-ь#9$T$;j$+І$в$й$ш$˜&‘œ&.(уЬ(А)єЧ*М+љТ,їМ-ћД.яА/  0oЌ1q3лŽ4еj5p@6eБ7х9о§9жм:яГ;ьЃ<ъ=ч{>§c? a@ЛkAС'BощBзШCр DнE#_F ƒGMHКнIƘJЬOKШLхLэMуёNпеO€ЕPm6QоЄQщƒR­mSќTѕUVр!WпX^тXAY GYSY WYaYxY€Y–YЈYКYУYЩYЯYгYлYђY]љYJWZЂZДZФZиZчZ љZ([0[5[,T\\‰\œ\­\ Г\%О\ф\ь\]Q ]k^] Ъ]и]н] х] №] ќ]^ ^ ^ ^ )^ 3^@^D^K^AZ^œ^ Ў^ Л^Щ^л^ф^э^_ _A_J_^_u_‹_’_Ѕ_CЕ_љ_``8`O`W`g`z`“`Б`Ф`е`э` a a @aNa_aeaunaфabb!b9b?b1Fbxb }b‡bbЪЅbЫpcУй ]йhй}йй ЄйВйЙйРй Шйвйђй]љйNWкІкПкгкъкљк л/лLлESл2™мЬмемъмћмн&н 8нCн \нegнpЭн>оMоTо Zоgо|оо”о™оЈо НоШойосошоVћоRпpп€пп Іп ДпОпмп'ёп р#р9рRр jрvр“рRЌрџр с(с Hс iсtсˆсІс)Усэс тт!7тYт)rтœтЋтНтУтЬт"\ууžуЎуЧуау:иуфф +ф5фйUфп/хЭцнцЎћчбЊш™|щЬъеуъУЙыN}ьЈЬэЮuюDяЎтяЂ‘№Ѕ4ёЃкё9~ђ Иђ!Уђхђъђ §ђ ѓѓ ѓ &ѓ 2ѓ>ѓ;WѓM“ѓсѓъѓєє2є :є GєTєiє‰єЅє*Уєюєѕѕ+0ѕ\ѕpѕ…ѕѕ•ѕЇѕ ЖѕФѕ:гѕ іі-і Kі‹lіјї% ј%/јUј^јgј,„ј2Бј)фјљљљ љ'љ7љ Tљ uљ љ ŽљœљЖљељ)№љњ,њAњHњWњkњ0~њЏњЭњгњтњћћ!ћ?ћ+Vћ‚ћ –ћЄћ!Жћићœёћ Žќ™ќ;Ÿќ0лќ2 §.?§Mn§М§\вџB/r,ƒАЗ.Нь   $0AI#OsЪ‰RTЇ)D]vЂСcб5ЩJ,'Ts‡ЊК5Ь  4Qdv™PЁђ. : 7U 1 !П &с N PW Ј Н  Ю и п № )ї ! Q9 ъ‹ЛvŒ2 ПыЬNИџ•л.yMЈhі_*d,7Мhє];uБ ЖУзѓL YXnKЧ*VB=™0з!*Ь@& )4 ^ ~ D в щ ў  !!2!L!d!}! š!0Л!ь! """ " /";" K">V" •"Ж"Л" С" Ь" к"х"3•ОZ‘^гw(ЬPќЋВЯq„.Б]T‹%7|/€B™ЙыHв-t”1™<'бй;т–2Ю.\rІj}жЗ8AmD§'uДœ ие5Y2 Х~\rFb,fƒPO>XB„љ‰dS"_Т‰Ы7ЄGъЛRx6zR*ЌЦФ? ƒЖ ŸšњHЕfŠ8 ju+x0‡пžyЅe#oўлщ†a#№Kg=l=1дŒ…ЎV+o)ŽАLі”$I:МрOїє d†cIšУРVЧЪ—СЇp˜ЁНD[K-Щ&Г]l0яŠwф›n?N5кК_tѕ’)•z`qG‹"kˆ€х “Jh`A“kЊebMЉ{y˜;Ђ›{gёsn^шiZ:4mс WEEЭИџуS@p |YT–Ѓ@юF$П!(ŒC9аscQ  ‚U/‚XC ­чŽ[LQ4a6N‡—&WMћЁ* ђ}ˆнцѓ~ЏŸЈiv!мU,ь<hœјž’Ш…‘3Jэv>оз%9 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in [DISP] key while turning on radio ("CLONE" will appear on radio LCD). 4. Press [RECEIVE] screen button ("-WAIT-" will appear on radio LCD). 5. Finally, press OK button below. %(value)s must be between %(min)i and %(max)i%i Memories and shift all up%i Memories and shift all up%i Memory%i Memories%i Memory and shift block up%i Memories and shift block up%s has not been saved. Save before closing?(none)...and %i more1. Ensure your firmware version is 4_10 or higher 2. Turn radio off 3. Connect your interface cable 4. Turn radio on 5. Press and release PTT 3 times while holding MONI key 6. Supported baud rates: 57600 (default) and 19200 (rotate dial while holding MONI to change) 7. Click OK 1. Turn Radio off. 2. Connect data cable. 3. While holding "A/N LOW" button, turn radio on. 4. After clicking OK, press "SET MHz" to send image. 1. Turn Radio off. 2. Connect data cable. 3. While holding "A/N LOW" button, turn radio on. 4. Press "MW D/MR" to receive image. 5. Make sure display says "-WAIT-" (see note below if not) 6. Click OK to dismiss this dialog and start transfer. Note: if you don't see "-WAIT-" at step 5, try cycling power and pressing and holding red "*L" button to unlock radio, then start back at step 1. 1. Turn Radio off. 2. Connect data cable. 3. While holding "TONE" and "REV" buttons, turn radio on. 4. After clicking OK, press "TONE" to send image. 1. Turn Radio off. 2. Connect data cable. 3. While holding "TONE" and "REV" buttons, turn radio on. 4. Press "REV" to receive image. 5. Make sure display says "CLONE RX" and green led is blinking 6. Click OK to start transfer. 1. Turn radio off. 2. Connect cable 3. Press and hold in the MHz, Low, and D/MR keys on the radio while turning it on 4. Radio is in clone mode when TX/RX is flashing 5. After clicking OK, press the MHz key on the radio to send image. ("TX" will appear on the LCD). 1. Turn radio off. 2. Connect cable 3. Press and hold in the MHz, Low, and D/MR keys on the radio while turning it on 4. Radio is in clone mode when TX/RX is flashing 5. Press the Low key on the radio ("RX" will appear on the LCD). 6. Click OK.1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK here, press the [C.S.] key to send image. 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK, press the [A] key to send image. 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Click OK here. ("Receiving" will appear on the LCD). 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Press the [A](RCV) key ("receiving" will appear on the LCD). 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Press the [C] key ("RX" will appear on the LCD). 1. Turn radio off. 2. Connect cable to CAT/LINEAR jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK, press the [C](SEND) key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the "left" [V/M] key while turning the radio on. 4. Rotate the "right" DIAL knob to select "CLONE START". 5. Press the [SET] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. After clicking OK, press the "left" [V/M] key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the "left" [V/M] key while turning the radio on. 4. Rotate the "right" DIAL knob to select "CLONE START". 5. Press the [SET] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. Press the "left" [LOW] key ("CLONE -RX-" will appear on the display). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [FW] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [FW] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MODE] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [MHz(PRI)] key while turning the radio on. 4. Rotate the DIAL job to select "F-7 CLONE". 5. Press and hold in the [BAND(SET)] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. Press the [LOW(ACC)] key ("--RX--" will appear on the display). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [MHz(PRI)] key while turning the radio on. 4. Rotate the DIAL job to select "F-7 CLONE". 5. Press and hold in the [BAND(SET)] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. After clicking OK, press the [V/M(MW)] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold [DISP] key while turning on radio ("CLONE" will appear on the display). 4. After clicking OK here in chirp, press the [Send] screen button. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [F] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [F] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [Dx] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [REV(DW)] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MHz(SETUP)] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC Jack. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [GM(AMS)] key to send image. 1. Turn radio off. 2. Connect cable to MIC Jack. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MHz(SETUP)] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/EAR jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [VFO(DW)SC] key to receive the image from the radio. 1. Turn radio off. 2. Connect cable to MIC/EAR jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MR(SKP)SC] key ("CLONE WAIT" will appear on the LCD). 5. Click OK to send image to radio. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold [PTT] & Knob while turning the radio on. 4. After clicking OK, press the [PTT] switch to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold [PTT] & Knob while turning the radio on. 4. Press the [MONI] switch ("WAIT" will appear on the LCD). 5. Press OK. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [V/M] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MON-F] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MON-F] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [V/M] key ("CLONE WAIT" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MONI] switch while turning the radio on. 4. Rotate the DIAL job to select "F8 CLONE". 5. Press the [F/W] key momentarily. 6. After clicking OK, hold the [PTT] switch for one second to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MONI] switch while turning the radio on. 4. Rotate the DIAL job to select "F8 CLONE". 5. Press the [F/W] key momentarily. 6. Press the [MONI] switch ("--RX--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [moni] key while turning the radio on. 4. Select CLONE in menu, then press F. Radio restarts in clone mode. ("CLONE" will appear on the display). 5. After clicking OK, briefly hold [PTT] key to send image. ("-TX-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [LOW(A/N)] key while turning the radio on. 4. After clicking OK, press the [MHz(SET)] key to send image. 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [LOW(A/N)] key while turning the radio on. 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [MHz], [LOW], and [D/MR] keys while turning the radio on. 4. After clicking OK, press the [MHz(SET)] key to send image. 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [MHz], [LOW], and [D/MR] keys while turning the radio on. 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to download image from device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to upload image to device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on. 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to download image from device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on. 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to upload image to device. 1. Turn radio off. 2. Connect data cable. 3. Prepare radio for clone. 4. After clicking OK, press the key to send image. 1. Turn radio off. 2. Connect data cable. 3. Prepare radio for clone. 4. Press the key to receive the image. 1. Turn radio off. 2. Connect mic and hold [ACC] on mic while powering on. ("CLONE" will appear on the display) 3. Replace mic with PC programming cable. 4. After clicking OK, press the [SET] key to send image. 1. Turn radio off. 2. Connect mic and hold [ACC] on mic while powering on. ("CLONE" will appear on the display) 3. Replace mic with PC programming cable. 4. Press the [DISP/SS] key ("R" will appear on the lower left of LCD). 1. Turn radio off. 2. Remove front head. 3. Connect data cable to radio, use the same connector where head was connected to, not the mic connector. 4. Click OK. 1. Turn radio off. 3. Press and hold in the [moni] key while turning the radio on. 4. Select CLONE in menu, then press F. Radio restarts in clone mode. ("CLONE" will appear on the display). 5. Press the [moni] key ("-RX-" will appear on the LCD). 1. Turn radio on. 2. Connect cable to DATA terminal. 3. Unclip battery. 4. Press and hold in the [AMS] key and power key while clipping in back battery the("ADMS" will appear on the display). 5. After clicking OK, press the [BAND] key. 1. Turn radio on. 2. Connect cable to DATA terminal. 3. Unclip battery. 4. Press and hold in the [AMS] key and power key while clipping in back battery the("ADMS" will appear on the display). 5. Press the [MODE] key ("-WAIT-" will appear on the LCD). OK click Then1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to download image from device. It will may not work if you turn on the radio with the cable already attached 1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to upload the image to device. It will may not work if you turn on the radio with the cable already attachedA new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllAll FilesAll supported formats|AmateurAn error has occurredApplying settingsAvailable modulesBandplanBandsBanksBinBrowserBuilding Radio BrowserCanadaChanging this setting requires refreshing the settings from the image, which will happen now.Channels with equivalent TX and RX %s are represented by tone mode of "%s"Chirp Image FilesChoice RequiredChoose %s DTCS CodeChoose %s ToneChoose Cross ModeChoose duplexChoose the module to load from issue %i:CityClick on the "Special Channels" toggle-button of the memory editor to see/set the EXT channels. P-VFO channels 100-109 are considered Settings. Only a subset of the over 200 available radio settings are supported in this release. Ignore the beeps from the radio on upload and download. Clone completed, checking for spurious bytesCloningCloning from radioCloning to radioCloseClose fileCluster %i memoryCluster %i memoriesCommentCommunicate with radioCompleteComplex or non-standard tone squelch mode (starts the tone mode selection wizard)Connect your interface cable to the PC Port on the back of the 'TX/RX' unit. NOT the Com Port on the head. Convert to FMCopyCountryCross ModeCustom PortCustom...CutDTCSDTCS PolarityDTMF decodeDV MemoryDanger AheadDecDeleteDeveloper ModeDeveloper state is now %s. CHIRP must be restarted to take effectDiff Raw MemoriesDigital CodeDigital ModesDisable reportingDisabledDistanceDo not prompt again for %sDo you accept the risk?Double-click to change bank nameDownloadDownload from radioDownload from radio...Download instructionsDriverDriver informationDriver messagesDual-mode digital repeaters that support analog will be shown as FMDuplexEdit details for %i memoriesEdit details for memory %iEnable Automatic EditsEnabledEnter FrequencyEnter Offset (MHz)Enter TX Frequency (MHz)Enter a new name for bank %s:Enter custom port:Erased memory %sError applying settingsError communicating with radioExperimental driverExport can only write CSV filesExport to CSVExport to CSV...ExtraFM RadioFREE repeater database, which provides most up-to-date information about repeaters in Europe. No account is required.Failed to load radio browserFailed to parse resultFeaturesFile does not exist: %sFilesFilterFilter results with location matching this stringFindFind NextFind...Finished radio job %sFollow these instructions to download the radio memory: 1 - Connect your interface cable 2 - Radio > Download from radio: DO NOT mess with the radio during download! 3 - Disconnect your interface cable Follow these instructions to download the radio memory: 1 - Connect your interface cable 2 - Radio > Download from radio: Don't adjust any settings on the radio head! 3 - Disconnect your interface cable Follow these instructions to download the radio memory: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio, volume @ 50% 4 - CHIRP Menu - Radio - Download from radio Follow these instructions to download your config: 1 - Turn off your radio 2 - Connect your interface cable to the Speaker-2 jack 3 - Turn on your radio 4 - Radio > Download from radio 5 - Disconnect the interface cable! Otherwise there will be no right-side audio! Follow these instructions to download your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow these instructions to download your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio (unlock it if password protected) 4 - Click OK to start Follow these instructions to read your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Click OK to start Follow these instructions to upload the radio memory: 1 - Connect your interface cable 2 - Radio > Upload to radio: DO NOT mess with the radio during upload! 3 - Disconnect your interface cable Follow these instructions to upload the radio memory: 1 - Connect your interface cable 2 - Radio > Upload to radio: Don't adjust any settings on the radio head! 3 - Disconnect your interface cable Follow these instructions to upload the radio memory: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio, volume @ 50% 4 - CHIRP Menu - Radio - Upload to radio Follow these instructions to upload your config: 1 - Turn off your radio 2 - Connect your interface cable to the Speaker-2 jack 3 - Turn on your radio 4 - Radio > Upload to radio 5 - Disconnect the interface cable, otherwise there will be no right-side audio! 6 - Cycle power on the radio to exit clone mode Follow these instructions to upload your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Follow these instructions to upload your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio (unlock it if password protected) 4 - Click OK to start Follow these instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Click OK to start Follow this instructions to download your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to read your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to upload your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Follow this instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Found empty list value for %(name)s: %(value)rFrequencyFrequency granularity in kHzGMRSGetting settingsGoto MemoryGoto Memory:Goto...HelpHelp Me...HexHide empty memoriesHuman-readable comment (not stored in radio)If set, sort results by distance from these coordinatesImportImport from file...Import messagesImport not recommendedIndexInfoInformationInsert Row AboveInstall desktop icon?Interact with driverInternal driver errorInvalid %(value)s (use decimal degrees)Invalid EntryInvalid ZIP codeInvalid edit: %sInvalid or unsupported module fileInvalid value: %rIssue number:LIVELatitudeLength must be %iLimit BandsLimit ModesLimit StatusLimit results to this distance (km) from coordinatesLive RadioLoad Module...Load module from issueLoad module from issue...Loading modules can be extremely dangerous, leading to damage to your computer, radio, or both. NEVER load a module from a source you do not trust, and especially not from anywhere other than the main CHIRP website (chirp.danplanet.com). Loading a module from another source is akin to giving them direct access to your computer and everything on it! Proceed despite this risk?Loading settingsLogo string 1 (12 characters)Logo string 2 (12 characters)LongitudeMemoriesMemory %i is not deletableMemory label (stored in radio)Memory must be in a bank to be editedMemory {num} not in bank {bank}ModeModelModesModuleModule LoadedModule loaded successfullyMore than one port found: %sMove DownMove UpNew WindowNew version availableNo empty rows below!No modules foundNo modules found in issue %iNo resultsNo results!NumberOffsetOnly certain bandsOnly certain modesOnly memory tabs may be exportedOnly working repeatersOpenOpen RecentOpen Stock ConfigOpen a fileOpen a moduleOpen debug logOpen in new windowOpen stock config directoryOptional: -122.0000Optional: 100Optional: 45.0000Optional: County, Hospital, etc.Overwrite memories?P-VFO channels 100-109 are considered Settings. Only a subset of the over 130 available radio settings are supported in this release. ParsingPastePasted memories will overwrite %s existing memoriesPasted memories will overwrite memories %sPasted memories will overwrite memory %sPasted memory will overwrite memory %sPlease be sure to quit CHIRP before installing the new version!Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio 3 - Click the button on this window to start download (you may see another dialog, click ok) 4 - Radio will beep and led will flash 5 - You will get a 10 seconds timeout to press "MON" before data upload start 6 - If all goes right radio will beep at end. After cloning remove the cable and power cycle your radio to get into normal mode. Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio. 3 - Click the button on this window to start download (Radio will beep and led will flash) 4 - Then press the "A" button in your radio to start cloning. (At the end radio will beep) Please note that developer mode is intended for use by developers of the CHIRP project, or under the direction of a developer. It enables behaviors and functions that can damage your computer and your radio if not used with EXTREME care. You have been warned! Proceed anyway?Please waitPlug in your cable and then click OKPortPowerPress enter to set this in memoryPrint PreviewPrintingPropertiesQuery %sQuery SourceRX DTCSRadioRadio did not ack block %iRadio informationRadio sent data after the last awaited block, this happens when the selected model is a non-US but the radio is a US one. Please choose the correct model and try again.RadioReference Canada requires a login before you can queryRadioReference.com is the world's largest radio communications data provider Premium account requiredReceive DTCS codeReceive frequencyRefresh requiredRefreshed memory %sReload DriverReload Driver and FileRename bankRepeaterBook is Amateur Radio's most comprehensive, worldwide, FREE repeater directory.Reporting enabledReporting helps the CHIRP project know which radio models and OS platforms to spend our limited efforts on. We would really appreciate if you left it enabled. Really disable reporting?Restart RequiredRestore %i tabRestore %i tabsRestore tabs on startRetrieved settingsSaveSave before closing?Save fileSaved settingsScan control (skip, include, priority, etc)ScanlistsScramblerSecurity RiskSelect Bandplan...Select BandsSelect ModesSelect a bandplanServiceSettingsShift amount (or transmit frequency) controlled by duplexShow Raw MemoryShow debug log locationShow extra fieldsShow image backup locationSome memories are incompatible with this radioSome memories are not deletableSort %i memorySort %i memoriesSort %i memory ascendingSort %i memories ascendingSort %i memory descendingSort %i memories descendingSort by column:Sort memoriesSortingStateState/ProvinceSuccessTX-RX DTCS polarity (normal or reversed)The DMR-MARC Worldwide NetworkThe FT-450D radio driver loads the 'Special Channels' tab with the PMS scanning range memories (group 11), 60meter channels (group 12), the QMB (STO/RCL) memory, the HF and 50m HOME memories and all the A and B VFO memories. There are VFO memories for the last frequency dialed in each band. The last mem-tune config is also stored. These Special Channels allow limited field editing. This driver also populates the 'Other' tab in the channel memory Properties window. This tab contains values for those channel memory settings that don't fall under the standard Chirp display columns. With FT450 support, the gui now uses the mode 'DIG' to represent data modes and a new column 'DATA MODE' to select USER-U, USER-L and RTTY The X3Plus driver is currently experimental. There are no known issues but you should proceed with caution. Please save an unedited copy of your first successful download to a CHIRP Radio Images (*.img) file. The author of this module is not a recognized CHIRP developer. It is recommended that you not load this module as it could pose a security risk. Proceed anyway?The recommended procedure for importing memories is to open the source file and copy/paste memories from it into your target image. If you continue with this import function, CHIRP will replace all memories in your currently-open file with those in %(file)s. Would you like to open this file to copy/paste memories across, or proceed with the import?This MemoryThis driver has been tested with v3 of the ID-5100. If your radio is not fully updated please help by opening a bug report with a debug log so we can add support for the other revisions.This driver is in development and should be considered as experimental.This image is missing firmware information. It may have been generated with an old or modified version of CHIRP. It is advised that you download a fresh image from your radio and use that going forward for the best safety and compatibility.This is a live-mode radio, which means changes are sent to the radio in real-time as you make them. Upload is not necessary!This is a radio-independent file and cannot be uploaded directly to a radio. Open a radio image (or download one from a radio) an then copy/paste items from this tab into that one in order to uploadThis is an early stage beta driver This is an early stage beta driver - upload at your own risk This is an experimental driver for the Quansheng UV-K5. It may harm your radio, or worse. Use at your own risk. Before attempting to do any changes please download the memory image from the radio with chirp and keep it. This can be later used to recover the original settings. some details are not yet implementedThis is experimental support for BJ-9900 which is still under development. Please ensure you have a good backup with OEM software. Also please send in bug and enhancement requests! You have been warned. Proceed at your own risk!This memory and shift all upThis memory and shift block upThis option may break your radio! Each radio has a unique set of calibration data and uploading the data from the image will cause physical harm to the radio if it is from a different piece of hardware. Do not use this unless you know what you are doing and accept the risk of destroying your radio!This radio has a tricky way of enter into program mode, even the original software has a few tries to get inside. I will try 8 times (most of the time ~3 will doit) and this can take a few seconds, if don't work, try again a few times. If you can get into it, please check the radio and cable. This should only be enabled if you are using modified firmware that supports wider frequency coverage. Enabling this will cause CHIRP not to enforce OEM restrictions and may lead to undefined or unregulated behavior. Use at your own risk!This will load a module from a website issueToneTone ModeTone SquelchTone squelch modeTransmit PowerTransmit shift, split mode, or transmit inhibitTransmit toneTransmit/receive DTCS code for DTCS mode, else transmit codeTransmit/receive tone for TSQL mode, else receive toneTuning StepUSB Port FinderUnable to determine port for your cable. Check your drivers and connections.Unable to edit memory before radio is loadedUnable to find stock config %rUnable to open the clipboardUnable to queryUnable to read last block. This often happens when the selected model is US but the radio is a non-US one (or widebanded). Please choose the correct model and try again.Unable to reveal %s on this systemUnable to set %s on this memoryUnable to upload this fileUnited StatesUnplug your cable (if needed) and then click OKUnsupported model %rUpload instructionsUpload to radioUpload to radio...Uploaded memory %sUse fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterValuesVendorViewWARNING!WarningWarning: %sWelcomeWould you like CHIRP to install a desktop icon for you?Your cable appears to be on port:bitsbytesbytes eachdisabledenabled{bank} is fullProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2024-02-23 21:47-0300 Last-Translator: MELERIX Language-Team: Language: es MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 3.4.2 X-Poedit-SourceCharset: UTF-8 X-Poedit-Basepath: .. X-Poedit-SearchPath-0: . 1. Apaga la radio. 2. Conecta el cable al terminal DATA. 3. Presiona y mantУЉn la tecla [DISP] mientras enciendes la radio ("CLONE" aparecerУЁ en la LCD de la radio). 4. Presiona el botУГn de pantalla [RECEIVE] ("-WAIT-" aparecerУЁ en la LCD de la radio). 5. Finalmente, presiona el botУГn Aceptar abajo. %(value)s debe estar entre %(min)i y %(max)i%i Memoria y desplazar todo hacia arriba%i Memorias y desplazar todo hacia arriba%i Memoria%i Memorias%i Memoria y desplazar bloque hacia arriba%i Memorias y desplazar bloque hacia arriba%s no ha sido guardado. ТПGuardar antes de cerrar?(nada)...y %i mУЁs1. AsegУКrate de que tu versiУГn de firmware es 4_10 o superior 2. Apaga la radio 3. Conecta tu cable de interfaz 4. Enciende la radio 5. Presiona y suelta PTT 3 veces mientras mantienes presionada la tecla MONI 6. Tasas de baudios admitidas: 57600 (predeterminado) y 19200 (gira el dial mientras mantienes presionado MONI para cambiar) 7. Cliquea Aceptar 1. Apaga la radio. 2. Conecta el cable de datos. 3. Mientras mantienes presionado el botУГn "A/N LOW", enciende la radio. 4. DespuУЉs de cliquear Aceptar, presiona "SET MHz" para enviar imagen. 1. Apaga la radio. 2. Conecta el cable de datos. 3. Mientras mantienes presionado el botУГn "A/N LOW", enciende la radio. 4. Presiona "MW D/MR" para recibir la imagen. 5. AsegУКrate de que la pantalla dice "-WAIT-" (mira la nota abajo si no) 6. Cliquea Aceptar para descartar este dialogo e iniciar la transferencia. Nota: si no ves "-WAIT-" en el paso 5, intenta apagar y encender y manteniendo presionado el botУГn rojo "*L" para desbloquear la radio, entonces vuelve a iniciar en el paso 1. 1. Apaga la radio. 2. Conecta el cable de datos. 3. Mientras mantienes presionados los botones "TONE" y "REV", enciende la radio. 4. DespuУЉs de cliquear Aceptar, presiona "TONE" para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable de datos. 3. Mientras mantienes presionados los botones "TONE" y "REV", enciende la radio. 4. Presiona "REV" para recibir la imagen. 5. AsegУКrate de que la pantalla diga "CLONE RX" y el led verde estУЉ parpadeando 6. Cliquea Aceptar para iniciar la transferencia. 1. Apaga la radio. 2. Conecta el cable 3. Presiona y mantУЉn las teclas MHz, Low, y D/MR en la radio mientras la enciendes 4. La radio estarУЁ en modo clonaciУГn cuando TX/RX estУЉ parpadeando 5. DespuУЉs de cliquear Aceptar, presiona la tecla MHz en la radio para enviar la imagen. ("TX" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable 3. Presiona y mantУЉn las teclas MHz, Low, y D/MR en la radio mientras la enciendes 4. La radio estarУЁ en modo clonaciУГn cuando TX/RX estУЉ parpadeando 5. Presiona la tecla Low en la radio ("RX" aparecerУЁ en la LCD). 6. Cliquea Aceptar.1. Apaga la radio. 2. Conecta el cable al conector ACC. 3. Presiona y mantУЉn las teclas [MODE <] y [MODE >] mientras enciendes la radio ("CLONE MODE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar aquУ­, presiona la tecla [C.S.] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector ACC. 3. Presiona y mantУЉn las teclas [MODE <] y [MODE >] mientras enciendes la radio ("CLONE MODE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar aquУ­, presiona la tecla [A] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector ACC. 3. Presiona y mantУЉn las teclas [MODE <] y [MODE >] mientras enciendes la radio ("CLONE MODE" aparecerУЁ en la pantalla). 4. Cliquea Aceptar aquУ­. ("Receiving" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector ACC. 3. Presiona y mantУЉn las teclas [MODE <] y [MODE >] mientras enciendes la radio ("CLONE MODE" aparecerУЁ en la pantalla). 4. Presiona la tecla [A](RCV) ("receiving" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector ACC. 3. Presiona y mantУЉn las teclas [MODE <] y [MODE >] mientras enciendes la radio ("CLONE MODE" aparecerУЁ en la pantalla). 4. Presiona la tecla [C] ("RX" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector CAT/LINEAR. 3. Presiona y mantУЉn las teclas [MODE <] y [MODE >] mientras enciendes la radio ("CLONE MODE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [C](SEND) para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector DATA. 3. Presiona y mantУЉn la tecla "izquierda" [V/M] mientras enciendes la radio. 4. Gira la perilla "derecha" DIAL para seleccionar "CLONE START". 5. Presiona la tecla [SET]. La pantalla desaparecerУЁ por un momento, entonces la notaciУГn "CLONE" aparecerУЁ. 6. DespuУЉs de cliquear Aceptar, presiona la tecla "izquierda" [V/M] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector DATA. 3. Presiona y mantУЉn la tecla "izquierda" [V/M] mientras enciendes la radio. 4. Gira la perilla "derecha" DIAL para seleccionar "CLONE START". 5. Presiona la tecla [SET]. La pantalla desaparecerУЁ por un momento, entonces la notaciУГn "CLONE" aparecerУЁ. 6. Presiona la tecla "izquierda" [LOW] ("CLONE -RX-" aparecerУЁ en la pantalla). 1. Apaga la radio. 2. Conecta el cable al terminal DATA. 3. Presiona y mantУЉn la tecla [FW] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [BAND] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector DATA. 3. Presiona y mantУЉn la tecla [FW] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. Presiona la tecla [MODE] ("-WAIT-" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector DATA. 3. Presiona y mantУЉn la tecla [MHz(PRI)] mientras enciendes la radio. 4. Gira la perilla DIAL para seleccionar "F-7 CLONE". 5. Presiona y mantУЉn la tecla [BAND(SET)]. La pantalla desaparecerУЁ por un momento, entonces la notaciУГn "CLONE" aparecerУЁ. 6. Presiona la tecla [LOW(ACC)] ("--RX--" aparecerУЁ en la pantalla). 1. Apaga la radio. 2. Conecta el cable al conector DATA. 3. Presiona y mantУЉn la tecla [MHz(PRI)] mientras enciendes la radio. 4. Gira la perilla DIAL para seleccionar "F-7 CLONE". 5. Presiona y mantУЉn la tecla [BAND(SET)]. La pantalla desaparecerУЁ por un momento, entonces la notaciУГn "CLONE" aparecerУЁ. 6. DespuУЉs de cliquear Aceptar, presiona la tecla [V/M(MW)] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al terminal DATA. 3. Presiona y mantУЉn la tecla [DISP] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar aquУ­ en chirp, presiona el botУГn de pantalla [Send]. 1. Apaga la radio. 2. Conecta el cable al terminal DATA. 3. Presiona y mantУЉn la tecla [F] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [BAND] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al terminal DATA. 3. Presiona y mantУЉn la tecla [F] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. Presiona la tecla [Dx] ("-WAIT-" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al terminal DATA. 3. Presiona y mantУЉn la tecla [MHz(SETUP)] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [REV(DW)] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al terminal DATA. 3. Presiona y mantУЉn la tecla [MHz(SETUP)] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. Presiona la tecla [MHz(SETUP)] ("-WAIT-" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector MIC. 3. Presiona y mantУЉn la tecla [MHz(SETUP)] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [GM(AMS)] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable la conector MIC. 3. Presiona y mantУЉn la tecla [MHz(SETUP)] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. Presiona la tecla [MHz(SETUP)] ("-WAIT-" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector MIC/EAR. 3. Presiona y mantУЉn la tecla [F/W] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [VFO(DW)SC] para recibir la imagen desde la radio. 1. Apaga la radio. 2. Conecta el cable al conector MIC/EAR. 3. Presiona y mantУЉn la tecla [F/W] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. Presiona la tecla [MR(SKP)SC] ("CLONE WAIT" aparecerУЁ en la LCD). 5. Cliquea Aceptar para enviar la imagen a la radio. 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn la perilla [PTT] mientras enciendes la radio. 4. DespuУЉs de cliquear Aceptar, presiona el interruptor [PTT] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn la perilla [PTT] mientras enciendes la radio. 4. Presiona el interruptor [MONI] ("WAIT" aparecerУЁ en la LCD). 5. Presiona Aceptar. 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn la tecla [F/W] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [BAND] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn la tecla [F/W] mientras enciendes la radio ("CLONE" aparecerУЁ en pantalla). 4. Presiona la tecla [V/M] ("-WAIT-" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn la tecla [MON-F] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. DespuУЉs de cliquear Aceptar, presiona la tecla [BAND] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn la tecla [MON-F] mientras enciendes la radio ("CLONE" aparecerУЁ en la pantalla). 4. Presiona la tecla [V/M] ("CLONE WAIT" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn el interruptor [MONI] mientras enciendes la radio. 4. Gira el DIAL para seleccionar "F8 CLONE". 5. Presiona la tecla [F/W] momentУЁneamente. 6. DespuУЉs de cliquear Aceptar, mantУЉn presionado el interruptor [PTT] por un segundo para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn el interruptor [MONI] mientras enciendes la radio. 4. Gira el DIAL para seleccionar "F8 CLONE". 5. Presiona la tecla [F/W] momentУЁneamente. 6. Presiona el interruptor [MONI] ("--RX--" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector MIC/SP. 3. Presiona y mantУЉn la tecla [moni] mientras enciendes la radio. 4. Selecciona CLONE en el menУК, entonces presiona F. La radio se reinicia en modo clonaciУГn. ("CLONE" aparecerУЁ en la pantalla). 5. DespuУЉs de cliquear Aceptar, mantУЉn presionada brevemente la tecla [PTT] para enviar la imagen. ("-TX-" aparecerУЁ en la pantalla). 1. Apaga la radio. 2. Conecta el cable al conector de micrУГfono. 3. Presiona y mantУЉn la tecla [LOW(A/N)] mientras enciendes la radio. 4. DespuУЉs de cliquear Aceptar, presiona la tecla [MHz(SET)] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector de micrУГfono. 3. Presiona y mantУЉn la tecla [LOW(A/N)] mientras enciendes la radio. 4. Presiona la tecla [D/MR(MW)] ("--WAIT--" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector de micrУГfono. 3. Presiona y mantУЉn las teclas [MHz], [LOW] y [D/MR] mientras enciendes la radio. 4. DespuУЉs de cliquear Aceptar, presiona la tecla [MHz(SET)] para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable al conector de micrУГfono. 3. Presiona y mantУЉn las teclas [MHz], [LOW] y [D/MR] mientras enciendes la radio. 4. Presiona la tecla [D/MR(MW)] ("--WAIT--" aparecerУЁ en la LCD). 1. Apaga la radio. 2. Conecta el cable al conector mic/spkr. 3. AsegУКrate de que el conector estУЉ firmemente conectado. 4. Enciende la radio (es posible que el volumen necesite establecerse al 100%). 5. AsegУКrate de que la radio estУЉ sintonizada a un canal sin actividad. 6. Cliquea Aceptar para descargar la imagen desde el dispositivo. 1. Apaga la radio. 2. Conecta el cable al conector mic/spkr. 3. AsegУКrate de que el conector estУЉ firmemente conectado. 4. Enciende la radio (es posible que el volumen necesite establecerse al 100%). 5. AsegУКrate de que la radio estУЉ sintonizada a un canal sin actividad. 6. Cliquea Aceptar para cargar la imagen al dispositivo. 1. Apaga la radio. 2. Conecta el cable al conector mic/spkr. 3. AsegУКrate de que el conector estУЉ firmemente conectado. 4. Enciende la radio. 5. AsegУКrate de que la radio estУЉ sintonizada a un canal sin actividad. 6. Cliquea Aceptar para descargar la imagen desde dispositivo. 1. Apaga la radio. 2. Conecta el cable al conector mic/spkr. 3. AsegУКrate de que el conector estУЉ firmemente conectado. 4. Enciende la radio. 5. AsegУКrate de que la radio estУЉ sintonizada a un canal sin actividad. 6. Cliquea Aceptar para cargar la imagen al dispositivo. 1. Apaga la radio. 2. Conecta el cable de datos. 3. Prepara la radio para clonar. 4. DespuУЉs de cliquear Aceptar, presiona la tecla para enviar la imagen. 1. Apaga la radio. 2. Conecta el cable de datos. 3. Prepara la radio para clonar. 4. Presiona la tecla para recibir la imagen. 1. Apaga la radio. 2. Conecta el micrУГfono y mantУЉn presionado [ACC] en el micrУГfono mientras lo enciendes. ("CLONE" aparecerУЁ en la pantalla) 3. Remplaza el micrУГfono con el cable de programaciУГn de PC. 4. DespuУЉs de cliquear Aceptar, presiona la tecla [SET] para enviar la imagen. 1. Apaga la radio. 2. Conecta micrУГfono y mantУЉn presionado [ACC] en micrУГfono mientras enciendes. ("CLONE" aparecerУЁ en la pantalla) 3. Remplaza micrУГfono con el cable de programaciУГn de PC. 4. Presiona la tecla [DISP/SS] ("R" aparecerУЁ en la parte inferior izquierda de la LCD). 1. Apaga la radio. 2. Remueve la cabeza frontal. 3. Conecta el cable de datos a la radio, usa el mismo conector en donde la cabeza estaba conectada, no el conector de micrУГfono. 4. Cliquea Aceptar. 1. Apaga la radio. 3. Presiona y mantУЉn la tecla [moni] mientras enciendes la radio. 4. Selecciona CLONE en el menУК, entonces presiona F. La radio se reiniciara en modo clonaciУГn. ("CLONE" aparecerУЁ en la pantalla). 5. Presiona la tecla [moni] ("-RX-" aparecerУЁ en la LCD). 1. Enciende la radio. 2. Conecta el cable al terminal DATA. 3. Desengancha la baterУ­a. 4. Presiona y mantУЉn la tecla [AMS] y la tecla de encendido mientras enganchas de vuelta la baterУ­a ("ADMS" aparecerУЁ en la pantalla). 5. DespuУЉs de cliquear Aceptar, presiona la tecla [BAND]. 1. Enciende la radio. 2. Conecta el cable al terminal DATA. 3. Desengancha la baterУ­a. 4. Presiona y mantУЉn la tecla [AMS] y la tecla de encendido mientras enganchas de vuelta la baterУ­a ("ADMS" aparecerУЁ en la pantalla). 5. Presiona la tecla [MODE] ("-WAIT-" aparecerУЁ en la LCD). Entonces cliquea Aceptar 1. Enciende la radio. 2. Conecta el cable al conector mic/spkr. 3. AsegУКrate de que el conector estУЉ firmemente conectado. 4. Cliquea Aceptar para descargar la imagen desde el dispositivo. Esto podrУ­a no funcionar si enciendes la radio con el cable ya conectado 1. Enciende la radio. 2. Conecta el cable al conector mic/spkr. 3. AsegУКrate de que el conector estУЉ firmemente conectado. 4. Cliquea Aceptar para cargar la imagen al dispositivo. Esto podrУ­a no funcionar si enciendes la radio con el cable ya conectadoUna nueva versiУГn de CHIRP estУЁ disponible, ТЁPor favor visita el sitio web tan pronto como sea posible para descargarla!Acerca deAcerca de CHIRPTodoTodos los archivosTodos los formatos soportados|AficionadoHa ocurrido un errorAplicando ajustesMУГdulos disponiblesPlan de bandaBandasBancosBinarioNavegadorConstruyendo navegador de radioCanadaCambiar este ajuste requiere actualizar los ajustes desde la imagen, lo cual ocurrirУЁ ahora.Canales con TX y RX equivalentes %s son representados por modo de tono de "%s"Archivos de imagen ChirpElecciУГn requeridaElegir %s cУГdigo DTCSElegir %s tonoElegir modo cruzadoElegir DУКplexElige el mУГdulo para cargar desde problema %i:CiudadCliquea en el botУГn para alternar "Canales Especiales" del editor de memoria para ver/establecer los canales EXT. Los canales P-VFO 100-109 se consideran Ajustes. Solo un subconjunto de las mУЁs de 200 ajustes de radio disponibles estУЁn soportados en este lanzamiento. Ignora los pitidos de la radio al cargar y descargar. Clonado completado, comprobando por bytes espuriosClonandoClonando desde radioClonando a radioCerrarCerrar archivoAgrupar %i memoriaAgrupar %i memoriasComentarioComunicarse con la radioCompletadoModo silenciador de tono complejo o no estУЁndar (inicia el asistente de selecciУГn del modo de tono)Conecta tu cable de interfaz al Puerto de PC en la espalda de la unidad 'TX/RX'. NO el Puerto Com en la cabeza. Convertir a FMCopiarPaУ­sModo cruzadoPuerto personalizadoPersonalizado...CortarDTCSPolaridad DTCSDecodificaciУГn DTMFMemoria DVPeligro adelanteDecimalBorrarModo desarrolladorEstado de desarrollador ahora estУЁ %s. CHIRP debe ser reiniciado para que tome efectoDiferenciar memorias en brutoCУГdigo digitalModos digitalesDeshabilitar reportesDesahbilitadoDistanciaNo preguntar de nuevo para %sТПAceptas el riesgo?Doble clic para cambiar nombre de bancoDescargarDescargar desde radioDescargar desde radio...Descargar instruccionesControladorInformaciУГn del controladorMensajes del controladorLos repetidores digitales de modo dual que soportan anУЁlogo se mostrarУЁn como FMDУКplexEditar detalles para %i memoriasEditar detalles para memoria %iHabilitar ediciones automУЁticasHabilitadoIngresar frecuenciaIngresar desplazamiento (MHz)Ingresar frecuencia TX (MHz)Ingresa un nuevo nombre para el banco %s:Ingresar puerto personalizado:Memoria borrada %sError aplicando ajustesError comunicУЁndose con la radioControlador experimentalExportar solo puede escribir archivos CSVExportar a CSVExportar a CSV...ExtraRadio FMBase de datos de repetidores GRATUITA, la cual proporciona la informaciУГn mУЁs actualizada sobre de repetidores en Europa. No requiere cuenta.Fallo al cargar navegador de radioFallo al analizar el resultadoCaracteristicasEl archivo no existe: %sArchivosFiltrarFiltrar resultados con ubicaciУГn coincidiendo esta cadenaBuscarBuscar siguienteBuscar...Trabajos de radio terminados %sSigue estas instrucciones para descargar la memoria de la radio: 1 - Conecta tu cable de interfaz 2 - Radio > Descargar desde radio: ТЁNO te metas con la radio durante la descarga! 3 - Desconecta tu cable de interfaz Sigue estas instrucciones para descargar la memoria de la radio: 1 - Conecta tu cable de interfaz 2 - Radio > Descargar desde radio: ТЁNo ajustes ningУКn ajuste en la cabeza de la radio! 3 - Desconecta tu cable de interfaz Sigue estas instrucciones para descargar la memoria de la radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio, volumen @ 50% 4 - MenУК de CHIRP - Radio > Descargar desde radio Sigue estas instrucciones para descargar tu configuraciУГn: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz al conector Speaker-2 3 - Enciende tu radio 4 - Radio > Descargar desde radio 5 - ТЁDesconecta el cable de interfaz! ТЁDe lo contrario no habrУЁ audio del lado derecho! Sigue estas instrucciones para descargar tu informaciУГn: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio 4 - Haz la descarga de tus datos de radio Sigue estas instrucciones para descargar tu radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio (desbloquУЉala si estУЁ protegida por contraseУБa) 4 - Cliquea Aceptar para iniciar Sigue estas instrucciones para leer tu radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio 4 - Cliquea Aceptar para iniciar Sigue estas instrucciones para cargar la memoria de la radio: 1 - Conecta tu cable de interfaz 2 - Radio > Cargar a radio: ТЁNO te metas con la radio durante la carga! 3 - Desconecta tu cable de interfaz Sigue estas instrucciones para cargar la memoria de la radio: 1 - Conecta tu cable de interfaz 2 - Radio > Cargar a radio: ТЁNo ajustes ningУКn ajuste en la cabeza de la radio! 3 - Desconecta tu cable de interfaz Sigue estas instrucciones para cargar la memoria de la radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio, volumen @ 50% 4 - MenУК de CHIRP - Radio > Cargar a radio Sigue estas instrucciones para cargar tu configuraciУГn: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz al conector Speaker-2 3 - Enciende tu radio 4 - Radio > Cargar a radio 5 - ТЁDesconecta el cable de interfaz, de otro modo no habrУЁ audio del lado derecho! 6 - Apaga y enciende la radio para salir del modo de clonaciУГn Sigue estas instrucciones para cargar tu informaciУГn: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio 4 - Haz la carga de tus datos de radio Sigue estas instrucciones para cargar tu radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio (desbloquУЉala si estУЁ protegida por contraseУБa) 4 - Cliquea Aceptar para iniciar Sigue estas instrucciones para escribir tu radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio 4 - Cliquea Aceptar para iniciar Sigue estas instrucciones para descargar tu informaciУГn: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio 4 - Haz la descarga de tus datos de radio Sigue estas instrucciones para leer tu radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio 4 - Haz la descarga de tus datos de radio Sigue estas instrucciones para cargar tu informaciУГn: 1 - Apaga tu radio 2 - Conecta cable de interfaz 3 - Enciende tu radio 4 - Haz la carga de tus datos de radio Sigue estas instrucciones para escribir tu radio: 1 - Apaga tu radio 2 - Conecta tu cable de interfaz 3 - Enciende tu radio 4 - Haz la carga de tus datos de radio Encontrado valor de lista vacУ­a para %(name)s: %(value)rFrecuenciaGranularidad de frecuencia en kHzGMRSObteniendo ajustesIr a memoriaIr a memoria:Ir a...AyudaAyУКdame...HexadecimalOcultar memorias vacУ­asComentario legible para humanos (no almacenado en la radio)Si se establece, ordenar los resultados por distancia desde estas coordenadasImportarImportar desde archivo...Importar mensajesImportaciУГn no recomendadaУndiceInformaciУГnInformaciУГnInsertar fila arribaТПInstalar icono de escritorio?Interactuar con controladorError interno del controlador%(value)s invУЁlido (usa grados decimales)Entrada invУЁlidaCУГdigo postal invУЁlidoEdiciУГn invУЁlida: %sArchivo de mУГdulo invУЁlido o no soportadoValor invУЁlido: %rNУКmero de problema:EN VIVOLatitudLargo debe ser %iBandas lУ­miteModos lУ­miteEstado lУ­miteLimitar resultados a esta distancia (km) desde coordenadasRadio en vivoCargar modulo...Cargar mУГdulo desde problemaCargar mУГdulo desde problema...Cargar mУГdulos puede ser extremadamente peligroso, pudiendo daУБar tu computador, radio o ambos. NUNCA cargues un mУГdulo desde una fuente que no confУ­es, y especialmente desde ningУКn sitio que no sea el sitio web principal de CHIRP (chirp.danplanet.com). ТЁCargar un mУГdulo desde otra fuente es como darles acceso directo a tu computador y a todo en este! ТПProceder a pesar de este riesgo?Cargando ajustesCadena del logotipo 1 (12 caracteres)Cadena del logotipo 2 (12 caracteres)LongitudMemoriasLa memoria %i no es borrableEtiqueta de memoria (almacenada en la radio)La memoria debe estar en un banco para ser editadaLa memoria {num} no estУЁ en banco {bank}ModoModeloModosModuloMУГdulo cargadoMУГdulo cargado exitosamenteMУЁs de un puerto encontrado: %sMover abajoMover arribaNueva ventanaNueva versiУГn disponibleТЁNo hay filas vacУ­as debajo!No se encontraron mУГdulosNo se encontraron mУГdulos en problema %iNo hay resultadosТЁNo hay resultados!NumeroDesplazamientoSolo ciertas bandasSolo ciertos modosSolo pestaУБas de memorias pueden ser exportadasSУГlo repetidores funcionandoAbrirAbrir recienteAbrir configuraciУГn originalAbrir un archivoAbrir un moduloAbrir registro de depuraciУГnAbrir en nueva ventanaAbrir directorio de configuraciУГn originalOpcional: -122.0000Opcional: 100Opcional: 45.0000Opcional: Condado, Hospital, etc.ТПSobrescribir memorias?Los canales P-VFO 100-109 se consideran Ajustes. Solo un subconjunto de las mУЁs de 130 ajustes de radio disponibles estУЁn soportados en este lanzamiento. AnalizandoPegarLas memorias pegadas sobrescribirУЁn %s memorias existentesLas memorias pegadas sobrescribirУЁn memorias %sLas memorias pegadas sobrescribirУЁn la memoria %sLa memoria pegada sobrescribirУЁ la memoria %sТЁPor favor asegУКrate de salir de CHIRP antes de instalar la nueva versiУГn!Por favor sigue estos pasos cuidadosamente: 1 - Enciende tu radio 2 - Conecta el cable de interfaz a tu radio 3 - Cliquea el botУГn en esta ventana para iniciar la descarga (puedes ver otro dialogo, cliquea aceptar) 4 - La radio emitirУЁ un pitido y el led parpadeara 5 - TendrУЁs un tiempo de espera de 10 segundos para presionar "MON" antes de que la carga de datos inicie 6 - Si todo va bien la radio emitirУЁ un pitido al final. DespuУЉs de clonar remueve el cable y apaga y enciende tu radio para entrar en modo normal. Por favor sigue estos pasos cuidadosamente: 1 - Enciende tu radio 2 - Conecta el cable de interfaz a tu radio. 3 - Cliquea el botУГn en esta ventana para iniciar la descarga (La radio emitirУЁ un pitido y el led parpadearУЁ) 4 - Entonces presiona el botУГn "A" en tu radio para iniciar la clonaciУГn. (Al final la radio emitirУЁ un pitido) Por favor te en cuenta que el modo desarrollador estУЁ pensado para uso por desarrolladores del proyecto CHIRP, o bajo la direcciУГn de un desarrollador. Esto habilita comportamientos y funciones que pueden daУБar tu computador y tu radio si no se usan con EXTREMO cuidado. ТЁhas sido advertido! ТПProceder de todos modos?Por favor esperaConecta tu cable y luego haz clic en ACEPTARPuertoPoderPresiona enter para configurar esto en memoriaPrevisualizaciУГn de impresiУГnImprimiendoPropiedadesConsulta %sConsultar fuenteRX DTCSRadioLa radio no reconociУГ el bloque %iInformaciУГn de radioLa radio enviУГ datos despuУЉs del УКltimo bloque esperado, esto sucede cuando el modelo seleccionado no es de EE.UU pero la radio es una de EE.UU. Por favor elije el modelo correcto e intenta de nuevo.RadioReference CanadУЁ requiere un inicio de sesiУГn antes de que puedas consultarRadioReference.com es el proveedor de datos de comunicaciones de radio mas largo del mundo Requiere cuenta premiumCУГdigo DTCS de recepciУГnFrecuencia de recepciУГnActualizaciУГn requeridaMemoria actualizada %sRecargar controladorRecargar controlador y archivoRenombrar bancoRepeaterBook es el directorio GRATUITO de repetidores, mundial, de Radio Aficionados mУЁs completo.Reportes habilitadosReportes ayudan al proyecto CHIRP a saber en cuales modelos de radio y plataformas de SO gastar nuestros limitados esfuerzos. Apreciamos mucho si lo dejas habilitado. ТПRealmente deshabilitar reportes?Reinicio requeridoRestaurar %i pestaУБaRestaurar %i pestaУБasRestaurar pestaУБas al iniciarAjustes recuperadosGuardarТПGuardar antes de cerrar?Guardar archivoAjustes guardadosControl de escУЁner (omitir, incluir, prioridad, etc)Listas de escaneoCodificadorRiesgo de seguridadSeleccionar plan de banda...Seleccionar bandasSeleccionar modosSeleccionar plan de bandaServicioAjustesCantidad de desplazamiento (o frecuencia de transmisiУГn) controlada por dУКplexMostrar memoria en brutoMostrar ubicaciУГn del registro de depuraciУГnMostrar campos adicionalesMostrar ubicaciУГn de la copia de respaldo de la imagenAlgunas memorias son incompatibles con esta radioAlgunas memorias no son borrablesOrdenar %i memoriaOrdenar %i memoriasOrdenar %i memoria de forma ascendenteOrdenar %i memorias de forma ascendenteOrdenar %i memoria de forma descendenteOrdenar %i memorias de forma descendenteOrdenar por columna:Ordenar memoriasOrdenandoEstadoEstado/ProvinciaУ‰xitoPolaridad TX-RX CTCS (normal o invertida)La red mundial DMR-MARCEl controlador de la radio FT-450D carga la pestaУБa 'Canales Especiales' con las memorias de rango de escaneo PMS (grupo 11), canales de 60 metros (grupo 12), la memoria QMB (STO/RCL), las HF y memorias 50m HOME y todas las memorias VFO A y B. Hay memorias de VFO para la УКltima frecuencia marcada en cada banda. La УКltima configuraciУГn de mem-tune tambiУЉn se almacena. Estos Canales Especiales permiten una ediciУГn de campo limitada. Este controlador tambiУЉn llena la pestaУБa 'Otro' en la ventana de Propiedades de la memoria del canal. Esta pestaУБa contiene valores para esos ajustes de memoria de canal que no caen bajo el estУЁndar de columnas de visualizaciУГn Chirp. Con el soporte de la FT450, la gui ahora usa el modo 'DIG' para representar los modos de datos y una nueva columna 'DATA MODE' para seleccionar USER-U, USER-L y RTTY El controlador X3Plus es actualmente experimental. No hay problemas conocidos pero debes proceder con precauciУГn. Por favor guarda una copia sin editar de tu primera descarga exitosa a un archivo de imagen de Radio de CHIRP (*.img). El autor de este modulo no estУЁ reconocido por el desarrollador de CHIRP. Se recomienda que no cargues este modulo ya que podrУ­a poner un riesgo de seguridad. ТПProceder de todos modos?El procedimiento recomendado para importar memorias es para abrir el archivo de origen y copiar/pegar memorias desde este en tu imagen objetivo. Si continУКas con esta funciУГn de importaciУГn, CHIRP remplazara todas las memorias de tu archivo actualmente abierto por las de %(file)s. ТПTe gustarУ­a abrir este archivo para copiar/pegar memorias a travУЉs de este, o proceder con la importaciУГn?Esta memoriaEste controlador ha sido probado con v3 del ID-5100. Si tu radio no estУЁ completamente actualizada por favor ayuda abriendo un reporte de error con un registro de depuraciУГn para que podamos agregar soporte para las otras revisiones.Este controlador estУЁ en desarrollo y debe ser considerado como experimental.A esta imagen le falta la informaciУГn de firmware. Esta puede haber sido generada con una versiУГn antigua o modificada de CHIRP. Se recomienda que descargues una imagen nueva de tu radio y utilizarla en adelante para la mejor seguridad y compatibilidad.Este es un modo de radio en vivo, lo que significa que los cambios son enviados a la radio en tiempo real cuando los haces. ТЁCargar no es necesario!Este es un archivo de radio independiente y no puede ser cargado directamente a una radio. Abre una imagen de radio (o descarga una de una radio) y entonces copia/pega los elementos desde esta pestaУБa a esa para cargarEste es un controlador beta de etapa temprana Este es un controlador beta de etapa temprana - cargar bajo tu propio riesgo Este es un controlador experimental para la Quansheng UV-K5. Este podrУ­a daУБar tu radio, o algo peor. Уšsalo bajo tu propio riesgo. Antes de intentar hacer algУКn cambio por favor descarga la imagen de memoria de la radio con chirp y guУЁrdala. Esta se puede usar despuУЉs para recuperar los ajustes originales. algunos detalles aun no estУЁn implementadosEste es un soporte experimental para BJ-9900 que aУКn estУЁ en desarrollo. Por favor asegУКrate de tener un buen respaldo con el software OEM. ТЁTambiУЉn por favor envУ­a en solicitudes de errores y mejoras! Has sido advertido. ТЁProcede bajo tu propio riesgo!Esta memoria y desplazar todo hacia arribaEsta memoria y desplazar bloque hacia arribaТЁEsta opciУГn podrУ­a romper tu radio! Cara radio tiene un conjunto УКnico de datos de calibraciУГn y cargar los datos de la imagen causarУЁ daУБo fУ­sico a la radio si esta es de una pieza de hardware diferente. ТЁNo uses esto a menos que sepas lo que estУЁs haciendo y aceptas el riesgo de destruir tu radio!Esta radio tiene una forma engorrosa de entrar en el modo de programaciУГn, incluso el software original tiene algunos cuantos intentos de entrar. Lo intentarУЉ 8 veces (la mayorУ­a de las veces ~3 lo harУЁn) y esto puede tardar unos segundos, si no funciona, intУЉntelo de nuevo unas cuantas veces. Si puede ingresar, por favor comprueba la radio y el cable. Esto sУГlo debe habilitarse si utilizas un firmware modificado que soporte una cobertura de frecuencias mУЁs amplia. Habilitar esto harУЁ que CHIRP no aplique las restricciones del OEM y puede conducir a un comportamiento indefinido o no regulado. ТЁУšsalo bajo tu propio riesgo!Esto va a cargar un mУГdulo desde un problema del sitio webTonoModo de tonoSilenciador de tonoModo de silenciador de tonoPotencia de transmisiУГnDesplazamiento de transmisiУГn, modo dividido, o inhibiciУГn de transmisiУГnTono de transmisiУГnCУГdigo DTCS de transmisiУГn/recepciУГn para el modo DTCS, sino, cУГdigo de transmisiУГnTono de transmisiУГn/recepciУГn para el modo TSQL, sino, tono de recepciУГnPaso de sintonizaciУГnBuscador de puertos USBNo se puede determinar puerto para tu cable. Comprueba tus controladores y conexiones.No se puede editar memoria antes de que la radio este cargadaNo se puede buscar la configuraciУГn original %rNo se puede abrir el portapapelesNo se puede consultarNo se puede leer el УКltimo bloque. Esto suele suceder cuando el modelo seleccionado es de EE.UU pero la radio no es una de EE.UU (o de banda ancha). Por favor elije el modelo correcto e intenta de nuevo.No se puede revelar %s en este sistemaNo se puede establecer %s en esta memoriaNo se puede cargar este archivoEstados UnidosDesconecta tu cable (si es necesario) y entonces haz clic en ACEPTARModelo no soportado %rCargar instruccionesCargar a radioCargar a radio...Memoria cargada %sUsar fuente de ancho fijoUsar fuente mУЁs grandeValor no cabe en %i bitsValor debe ser al menos %.4fValor debe ser como mУЁximo %.4fValor debe ser exactamente %i dУ­gitos decimalesValor debe ser cero o superiorValoresVendedorVerТЁADVERTENCIA!AdvertenciaAdvertencia: %sBienvenidoТПQuieres que CHIRP instale un icono en el escritorio para ti?Tu cable parece estar en puerto:bitsbytesbytes cadadeshabilitadohabilitado{bank} estУЁ llenochirp-20240224/chirp/locale/fr/0000755000175000017500000000000014566340177015024 5ustar hibbyhibbychirp-20240224/chirp/locale/fr/LC_MESSAGES/0000755000175000017500000000000014566340177016611 5ustar hibbyhibbychirp-20240224/chirp/locale/fr/LC_MESSAGES/CHIRP.mo0000644000175000017500000007351314566340175020022 0ustar hibbyhibbyо•&L |А Б-М+ъ^,‹ ‘ ЁЋТЪрђ %<]CJЁьў"1 C(Qz,žЫгцї §'k0 œЊЏ З УЭб ж ф юћџAW i v„–ŸЈ Уфэ  C. r y – Б Ш а р ѓ  !*!=!N!f!…!™! Й!Ч!и!uо!T"q"ˆ"‘"Љ"Џ"1Ж"ш" э"ї"џ".# D#N#S# d# p#}#…# Š#•#™#7­#х#ь#$$$ "$.$?$U$'j$ ’$ $Б$"Т$х$ ї$% %% %% 1% =%4J%%Ž%Ѕ%yП%9' J'T']'%x'ž'О'У'Щ'Я' ж'ф'џ' (&( .(9(O(d(u( ’( (Љ(А(З(Ъ( н(ў() )&) 8) D)R)a)t)) Є)В) Ф)х)†љ)€*ˆ*3Ž**Т*(э*&+?=+Ф}+(B-k. /$‹/А/Е/!Л/ н/ы/ є/џ/ 000#0>0ЈP0;љ051F1 Z1h1 1‹1И1V2g2z22 ”2ž2 ­2Л2 Ю2 л2ш2њ23 3333.E3t3”3 Є3В3К3Р3Я3жз3бЎ6 €7^!8 €9КŒ9GG:#:=Г:фё:ж;ѓ;&<ю9=(> -> 7> D>P>L`>,­>к>љ>?Љ&?"а?ѓ? @/!@Q@e@u@ˆ@›@А@Р@о@њ@'A=A[AbAiAnAwA A‹A7“A!ЫAэAђA јAB BBT#B;xC,ДD7сDE El.E›EЄEЖE ЛEЩEтEъEF F4FGFNF VF `FkFŠFq‘FXG\GqG‚G—GЇGКG2ЩGќGXH2[IŽI%–I%МIтIщI јIJJx%JžJЎJЕJКJгJчJюJ ѓJ K KK K(K]9K—K ГKРK#бK ѕKџKL0$L UL"aL%„LЊLRЩLM##M%GMmMŠM‘MЅM$ОM(уM N)N,?N%lN’N1ІNиNѕNOŒO-ЈOжOєOPP%PQ-P PŠP  PЎP6ЦP §PQ Q(Q;QOQXQ ]QjQnQLˆQеQоQќQRR R)R"ARdR-R­RНRвR'чRS#S4S9SBS[SmS~SASвS$чS' TД4TщU VV#V6;V'rVšVŸVІVЌV ГVСVлV ѕVџVWW3WNW'bWŠW™WЉWАWЙWдW4эW*"XMX TXbXyX‹XœX КX'лXYY'Y!:Y\YЄrYZZ8&Z1_Z/‘Z*СZEьZ@2[Rs]^Ц^%`&?`f` k`0u`І` О` Щ` д`т`є`ќ`,a/aИHa?bAb]bvb‡bЃbГbаbтcљc dd9dMdfd ydšdЋdЛdйd сd'эd,e"Be0ee%–eМeЭeоeтe чeѕeyќeчviЖ^jyk lнlL{m*ШmOѓm&Cn!jo$ŒopБo1"qTr Yr crprrT•r@ъr1+s$]s‚sМšs(Wt*€t Ћt8Жtяt u'uDu![u}u%u#Уu#чu0 v) У ŠŽWŒЄ/ЋwФёу  %№<fb"mЛх Ё‰;’{Т”ьПH3#,ЖДџN%‹ЕhЧg$rIЃ\&~зЩ‘эр9ї_joГыKGјѕD‚§ЙUгВюЗdХм­СLчP™q@5Cъkеў&aFђ:!ЉЫyѓЭЇ'-ЈЎ†ая 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in [DISP] key while turning on radio ("CLONE" will appear on radio LCD). 4. Press [RECEIVE] screen button ("-WAIT-" will appear on radio LCD). 5. Finally, press OK button below. %(value)s must be between %(min)i and %(max)i%s has not been saved. Save before closing?(none)...and %i moreA new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllAll FilesAll supported formats|AmateurAn error has occurredApplying settingsAvailable modulesBandplanBandsBanksBinBrowserBuilding Radio BrowserCanadaChanging this setting requires refreshing the settings from the image, which will happen now.Channels with equivalent TX and RX %s are represented by tone mode of "%s"Chirp Image FilesChoice RequiredChoose %s DTCS CodeChoose %s ToneChoose Cross ModeChoose duplexChoose the module to load from issue %i:CityClick on the "Special Channels" toggle-button of the memory editor to see/set the EXT channels. P-VFO channels 100-109 are considered Settings. Only a subset of the over 200 available radio settings are supported in this release. Ignore the beeps from the radio on upload and download. Clone completed, checking for spurious bytesCloningCloning from radioCloning to radioCloseClose fileCommentCommunicate with radioCompleteConnect your interface cable to the PC Port on the back of the 'TX/RX' unit. NOT the Com Port on the head. Convert to FMCopyCountryCustom PortCustom...CutDTCSDTCS PolarityDV MemoryDanger AheadDecDeleteDeveloper ModeDeveloper state is now %s. CHIRP must be restarted to take effectDiff Raw MemoriesDigital CodeDigital ModesDisable reportingDisabledDistanceDo not prompt again for %sDouble-click to change bank nameDownloadDownload from radioDownload from radio...Download instructionsDual-mode digital repeaters that support analog will be shown as FMDuplexEdit details for %i memoriesEdit details for memory %iEnable Automatic EditsEnabledEnter FrequencyEnter Offset (MHz)Enter TX Frequency (MHz)Enter a new name for bank %s:Enter custom port:Erased memory %sError applying settingsError communicating with radioExperimental driverExport can only write CSV filesExport to CSVExport to CSV...ExtraFREE repeater database, which provides most up-to-date information about repeaters in Europe. No account is required.Failed to load radio browserFailed to parse resultFeaturesFile does not exist: %sFilesFilterFilter results with location matching this stringFindFind NextFind...Finished radio job %sFound empty list value for %(name)s: %(value)rFrequencyGMRSGetting settingsGoto MemoryGoto Memory:Goto...HelpHelp Me...HexHide empty memoriesIf set, sort results by distance from these coordinatesImportImport from file...Import not recommendedIndexInfoInformationInsert Row AboveInstall desktop icon?Interact with driverInvalid %(value)s (use decimal degrees)Invalid EntryInvalid ZIP codeInvalid edit: %sInvalid or unsupported module fileInvalid value: %rIssue number:LIVELatitudeLength must be %iLimit BandsLimit ModesLimit StatusLimit results to this distance (km) from coordinatesLoad Module...Load module from issueLoad module from issue...Loading modules can be extremely dangerous, leading to damage to your computer, radio, or both. NEVER load a module from a source you do not trust, and especially not from anywhere other than the main CHIRP website (chirp.danplanet.com). Loading a module from another source is akin to giving them direct access to your computer and everything on it! Proceed despite this risk?Loading settingsLongitudeMemoriesMemory %i is not deletableMemory must be in a bank to be editedMemory {num} not in bank {bank}ModeModelModesModuleModule LoadedModule loaded successfullyMore than one port found: %sMove DownMove UpNew WindowNew version availableNo empty rows below!No modules foundNo modules found in issue %iNo resultsNo results!NumberOffsetOnly certain bandsOnly certain modesOnly memory tabs may be exportedOnly working repeatersOpenOpen RecentOpen Stock ConfigOpen a fileOpen a moduleOpen debug logOpen in new windowOpen stock config directoryOptional: -122.0000Optional: 100Optional: 45.0000Optional: County, Hospital, etc.Overwrite memories?P-VFO channels 100-109 are considered Settings. Only a subset of the over 130 available radio settings are supported in this release. ParsingPastePasted memories will overwrite %s existing memoriesPasted memories will overwrite memories %sPasted memories will overwrite memory %sPasted memory will overwrite memory %sPlease be sure to quit CHIRP before installing the new version!Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio 3 - Click the button on this window to start download (you may see another dialog, click ok) 4 - Radio will beep and led will flash 5 - You will get a 10 seconds timeout to press "MON" before data upload start 6 - If all goes right radio will beep at end. After cloning remove the cable and power cycle your radio to get into normal mode. Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio. 3 - Click the button on this window to start download (Radio will beep and led will flash) 4 - Then press the "A" button in your radio to start cloning. (At the end radio will beep) Please note that developer mode is intended for use by developers of the CHIRP project, or under the direction of a developer. It enables behaviors and functions that can damage your computer and your radio if not used with EXTREME care. You have been warned! Proceed anyway?Please waitPlug in your cable and then click OKPortPowerPress enter to set this in memoryPrint PreviewPrintingPropertiesQuery %sQuery SourceRX DTCSRadioRadio did not ack block %iRadio informationRadio sent data after the last awaited block, this happens when the selected model is a non-US but the radio is a US one. Please choose the correct model and try again.RadioReference Canada requires a login before you can queryRefresh requiredRefreshed memory %sReload DriverReload Driver and FileRename bankReporting enabledReporting helps the CHIRP project know which radio models and OS platforms to spend our limited efforts on. We would really appreciate if you left it enabled. Really disable reporting?Restart RequiredRetrieved settingsSaveSave before closing?Save fileSaved settingsSecurity RiskSelect Bandplan...Select BandsSelect ModesSelect a bandplanServiceSettingsShow Raw MemoryShow debug log locationShow extra fieldsSome memories are incompatible with this radioSome memories are not deletableSort by column:Sort memoriesSortingStateState/ProvinceSuccessThe FT-450D radio driver loads the 'Special Channels' tab with the PMS scanning range memories (group 11), 60meter channels (group 12), the QMB (STO/RCL) memory, the HF and 50m HOME memories and all the A and B VFO memories. There are VFO memories for the last frequency dialed in each band. The last mem-tune config is also stored. These Special Channels allow limited field editing. This driver also populates the 'Other' tab in the channel memory Properties window. This tab contains values for those channel memory settings that don't fall under the standard Chirp display columns. With FT450 support, the gui now uses the mode 'DIG' to represent data modes and a new column 'DATA MODE' to select USER-U, USER-L and RTTY The X3Plus driver is currently experimental. There are no known issues but you should proceed with caution. Please save an unedited copy of your first successful download to a CHIRP Radio Images (*.img) file. The author of this module is not a recognized CHIRP developer. It is recommended that you not load this module as it could pose a security risk. Proceed anyway?The recommended procedure for importing memories is to open the source file and copy/paste memories from it into your target image. If you continue with this import function, CHIRP will replace all memories in your currently-open file with those in %(file)s. Would you like to open this file to copy/paste memories across, or proceed with the import?This MemoryThis driver has been tested with v3 of the ID-5100. If your radio is not fully updated please help by opening a bug report with a debug log so we can add support for the other revisions.This driver is in development and should be considered as experimental.This is an early stage beta driver This is an early stage beta driver - upload at your own risk This is experimental support for BJ-9900 which is still under development. Please ensure you have a good backup with OEM software. Also please send in bug and enhancement requests! You have been warned. Proceed at your own risk!This memory and shift all upThis memory and shift block upThis radio has a tricky way of enter into program mode, even the original software has a few tries to get inside. I will try 8 times (most of the time ~3 will doit) and this can take a few seconds, if don't work, try again a few times. If you can get into it, please check the radio and cable. This should only be enabled if you are using modified firmware that supports wider frequency coverage. Enabling this will cause CHIRP not to enforce OEM restrictions and may lead to undefined or unregulated behavior. Use at your own risk!ToneTone ModeTone SquelchTuning StepUSB Port FinderUnable to determine port for your cable. Check your drivers and connections.Unable to edit memory before radio is loadedUnable to find stock config %rUnable to open the clipboardUnable to queryUnable to read last block. This often happens when the selected model is US but the radio is a non-US one (or widebanded). Please choose the correct model and try again.Unable to reveal %s on this systemUnable to set %s on this memoryUnited StatesUnplug your cable (if needed) and then click OKUpload instructionsUpload to radioUpload to radio...Uploaded memory %sUse fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterValuesVendorViewWARNING!WarningWarning: %sWelcomeWould you like CHIRP to install a desktop icon for you?Your cable appears to be on port:bitsbytesbytes eachdisabledenabled{bank} is fullProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2023-12-13 00:03+0100 Last-Translator: Matthieu Lapadu-Hargues Language-Team: French Language: fr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n > 1); X-Generator: Poedit 3.2.2 1. Eteignez la radio. 2. Connectez le cable a la prise DATA. 3. Appuyez et maintenez la touche [DISP] en allumant la radio ("CLONE" va apparaitre sur l'ecran LCD). 4. Appuyez sur le bouton [RECEIVE] du logiciel ("-WAIT-" va apparaitre sur l'ecran LCD). 5. A la fin, pressez le bouton OK en-dessous. %(value)s doit etre entre %(min)i et %(max)i%s n'a pas ete enregistre. Enregistrer avant de fermer?(vide)...et %i plusUne nouvelle version de CHIRP est disponible. Visitez le site internet des que possible pour la telecharger!A proposA propos de CHIRPToutTous fichiersTours formats supportes|AmateurUne erreur s'est produiteApplication des preferencesModules disponiblesPlan de frequencesBandesBanquesCorbeilleNavigateurEtablissement navigateur radioCanadaModifier ce parametre necessite de refraichir tous les parametres depuis l'image, ce qui va etre fait maintenant.Les canaux avec TX et RX equivalents %s sont representes par le mode de tonalite de "%s"Fichiers image ChirpChoix necessaireChoisir %s DTCS CodeChoisir %s ToneChoisir cross modeChoisir duplexChoisir le module a charger depuis le probleme %i:VilleCliquez sur le commutateur "Special Channels" de l'editeur de memoire pour voir ou modifier les canaux EXT. Les canaux P-VFO 100-109 sont consideres comme parametres. Seul un sous-ensemble des 200 premiers parametres radio disponibles sont suppportes dans cette publication. Ne tenez pas compter des bips de la radio durant le telechargement. Clonage termine, verification des octets parasitesClonageTelechargement depuis la radio - LireTelechargement vers la radio - EcrireFermerFermer fichierCommentaireCommunique avec la radioTermineConnectez votre cable d'interface au port PC a l'arriere de l'unite 'TX/RX'. PAS au port de communication de la facade. Convertir en FMCopierPaysPersonnalisation du portPersonnalisation...CouperDTCSDTCS PolarityMemoire DVDanger devantDecSupprimerMode developpeurLe mode developpement est maintenant %s. CHIRP doit etre redemarre pour que ceci prenne effetComparaison memoires brutesDigital CodeModes numeriquesDesactiver le rapport d'utilisationDescativeDistanceNe plus demander pendant %sDouble-cliquer pour modifier le nom de la banqueTelechargerTelecharger depuis la radio - LireTelecharger depuis la radio - Lire...Instructions de telechargementLes repeteurs numeriques bimodes supportant l'analogique seront presentes comme FMDuplexEditer les details pour %i memoiresEditer les details pour la memoire %iAciter l'edition automatiqueActiveEntrer la frequenceSaisir le decalage (MHz)Saisir la frequence d'emission (MHz)Saisir un nouveau nom pour la banque %s:Saisir un port personnalise:Effacer la memoire %sErreur lors de l'application des preferencesErreur de communication avec la radioPilote experimentalL'exportation ne peut ecrire que des fichiers CSVExporter vers un fichier CSVExporter vers un fichier CSV...ExtraBase de donnees LIBRE de relais proposant les informations les plus a jour sur les relais Europeens. Un compte utiliseteur n'est pas requis.Echec du chargement du navigateur de la radioEchec d'analyse des resultatsCaracteristiquesFichier inexistant: %sFichiersFiltrerFiltrer les resultats avec emplacement correspondant a cette chaine de caracteresRechercherRechercher le suivantRechercher...Tache radio terminee %sListe de valeurs vide trouvee pour %(name)s: %(value)rFrequenceGMRSAcquisition des preferencesAller a la memoireAller a la memoire:Aller...AideAidez moi...HexCacher les memoires videsSi selectionne, trier les resultats selon la distance depuis ces coordonneesImporterImporter depuis un fichier...Import non recommandeIndexInfoInformationInserer une ligne avantInstaller une icone sur le bureau?Interaction avec le piloteInvalide %(value)s (utiliser degres decimaux)Entree invalideCode postal invalideEdition invalide: %sFichier module invalide ou pas supporteValeur invalide: %rProbleme numero:LIVELatitudeLa longueur doit etre %iLimite les bandesLimite les modesLimites les etatsLimite les resultats a cette distance (km) depuis les coordonneesChargement module...Chargement module depuis un problemeChargement module depuis un probleme...Charger des modules peut etre extremement dangereux, causant des dommages a votre ordinateur, radio ou les deux. NE JAMAIS charger un module issu d'une source dont vous n'avez pas confiance, et plus specialement d'ailleurs que du site internet principal de CHIRP (chirp.danplanet.com). Charger un module depuis une autre source revient a donner un acces direct a votre ordinateur et a tout ce qu'il contient! Continuez malgre le risque?Chargement des preferencesLongitudeMemoiresLa memoire %i n'est pas supprimableLa memoire doit entre dans une banque pour etre editeeMemoire {num} pas dans la banque {bank}ModeModeleModesModuleModule chargeModule charge avec succesPlus d'un port trouve: %sDescendreMonterNouvelle fenetreNouvelle version disponiblePas de ligne vide dessous!Aucun module trouveAucun module trouve pour le probleme %iAucun resultatAucun resultat!NombreDecalageSeulement certaines bandesSeulement certains modesSeuls les onglets des memoires peuvent etre exportesUniquement les repeteurs en fonctionnementOuvrirOuvrir recentOuvrir base de donneesOuvrir un fichierOuvrir un moduleOuvrir le fichier de debogageOuvrir dans une nouvelle fenetreOuvrir le repertoire de base de donneesOptionnel: -122.0000Optionnel: 100Optionnel: 45.0000Optionnel: County, Hospital, etc.Ecraser les memoires?Les canaux P-VFO 100-109 sont considere comme parametres. Seul un sous-ensemble des plus de 130 parametres radio disponibles est pris en charge dans cette version. AnalyseCollerLes memoires collees vont ecraser %s memoires existantesLes memoires collees vont ecraser les memoires %sLes memoires collees vont ecraser la memoire %sLa memoire collee va ecraser la memoire %sSoyez certain de quitter CHIRP avant d'installer la nouvelle version!Suiez ces etapes avec attention: 1 - Allumez votre radio 2 - Connectez le cable d'interface a votre radio 3 - Cliquez sur le bouton de cette fenetre pour demarrer le telechargement (vous devriez voir une autre boite de dialogue, cliquez sur ok) 4 - La radio va sonner et la LED clignoter 5 - Vous disposez de 10 secondes pour appuyer sur "MON" avant que le telechargement vers la radio ne demarre 6 - Si tout se deroule bien la radio va sonner a la fin. Apres le clonage debranchez le cable puis eteignez et rallumez votre radio pour revenir au fonctionnement normal. Suiez ces etapes avec attention: 1 - Allumez votre radio 2 - Connectez le cable d'interface a votre radio 3 - Cliquez sur le bouton de cette fenetre pour demarrer le telechargement (La radio va sonner et la LED clignoter) 4 - Ensuite appuyez sur le bouton "A" de votre radio pour demarrer le clonage (A la fin la radio va sonner) Veuillez noter que le mode developpeur est destinУЉ a n'etre utilise que par les dУЉveloppeurs du projet CHIRP, ou en suivant les directives d'un developpeur. Il active des comportements et des fonctions qui peuvent endommager votre ordinateur et votre radio s'ils ne sont pas utilises avec un EXTREME soin. Vous etes prevenu! Continuer malgrУЉ tout?Patientez s'il vous plaitBranchez votre cable et cliquez sur OKPortPuissanceAppuyez sur entree pour inscrire ceci en memoireApercu avant impressionImpressionProprietesInterroger %sInterroger SourceRX DTCSRadioLa radio n'a pas accuse reception du bloc %iInformations de la radioLa radio a envoye des donnees apres le dernier bloc attendu, ceci se produit quand le modele selectionne n'est pas US mais que la radio est US. Selectionnez le bon modele et reessayez.RadioReference Canada necessite une connexion avant une requeteRafraichissement necessaireRafraichir la memoire %sRecharger piloteRecharger pilote et fichierRenommer banqueRapport d'utilisation activeLe rapport d'utilisation aide le projet CHIRP a savoir quelles radios et systemes d'exploitation sont utilises pour concentrer les efforts sur ceux-la. Nous apprecierions vraiment que vous le laissiez actif. Etes-vous certain de vouloir desactiver le rapport d'utilisation?Redemarrage necessairePreferences recupereesEnregistrerEnregistrer avant de fermer?Enregistrer fichierPreferences enregistreesRisque de securiteChoix d'un plan de frequences...Choix des bandesChoix des modesChoix d'un plan de frequencesServicePreferencesAfficher les donnees de memoires brutesMontrer l'emplacement du fichier de debogageMontrer les champs supplementairesDes memoires sont incompatibles avec cette radioDes memoires ne sont pas supprimablesTri par colonne:Tri des memoiresTriEtatEtat/ProvinceReussiLe pilote du FT-450D charge l'onglet des "Special Channels' avec les memoires de plage de balayage PMS (groupe 11), les canaux 60 metres (groupe 12), la memoire QMB (STO/RCL), les memoires HOME HF et 50 m et toutes les memoires VFO A et B. Il y a des memoires VFO pour les derniУЈres frУЉquences regles sur chaque bande. La derniere configuration de reglage de memoire est egalement stockee. Ces canaux spУЉciaux permettent une edition reduite des champs. Ce pilote remplit egalement l'onglet "Other" de la fenetre PropriУЉtУЉs du canal mУЉmoire. Cet onglet contient des valeurs pour les parametres de canal memoire qui ne correspondent pas aux colonnes d'affichage Chirp standard. Avec la prise en charge du FT450, l'interface graphique utilise desormais le mode 'DIG' pour reprУЉsenter les modes de donnУЉes et une nouvelle colonne 'DATA MODE' pour sУЉlectionner USER-U, USER-L et RTTY Le pilote X3Plus est actuellement experimental. Il n'y a pas de probleme connu mais vous devriez proceder avec precaution. Sauvegardez une copie non editee de votre premier telechargement dans un fichier image radio CHIRP (*.img). Lт€™auteur de ce module n'est pas un developpeur de CHIRP connu. Comme il peut comporter un risque de securite, il est recommande de ne pas importer ce module. Importer tout de meme?La procedure d'importation des memoires preconisee consiste a ouvrir le fichier source et copier/coller les memoires depuis celui-ci vers l'image cible. Si vous continuez avec cette fonction d'importation, CHIRP va remplacer toutes les memoires du fichier actuellement ouvert avec celles de %(file)s. Souhaitez-vous ouvrir ce fichier pour copier/coller entre eux ou l'importer?Cette memoireCe pilote a ete teste avec la v3 de l'ID-5100. Si votre radio n'est pas a jour merci d'aider en ouvrant un rapport de bogue avec un journal de debogage pour que nous puissions ajouter du support pour les autres revisions.Ce pilote est en developpement et devrait etre considere comme experimental.Ceci est un pilote recent en version beta Ceci est un pilote recent en version beta - chargement a vos risques et perils Ceci est un support experimental pour le BJ-9900 encore en cours de developpement. SVP assurez-vous de disposer d'une sauvegarde correcte avec le logiciel d'origine (OEM). Envoyez aussi vos demandes d'ameliorations ou rapports de bogues! Vous avez ete prevenu. Procedez a vos risques et perils!Remonter ces memoires et decalageBloquer cette memoire et le decalageCette radio rentre en mode programmation avec une methode particuliere, meme le logiciel d'origine fait plusieurs tentative pour y parvenir. Je vais essayer 8 fois (la plupart du temps ~3 fois suffisent) et cela pourra prendre quelques secondes, si cela ne fonctionne pas, essayez encore quelques fois. Si vous ne parvenez pas a entrer, verifiez la radio et le cable. Ceci ne devrait etre active que si vous utilisez un micrologiciel modifie supportant une plus large couverture en frequences. L'activation de cette option empechera CHIRP d'appliquer les restrictions OEM et peut conduire a un comportement indefini ou non reglementaire. A utiliser a vos risques et perils!ToneTone ModeTone SquelchPas de reglageRecherche de port USBImpossible de determiner le port de votre cable. Verifiez les pilotes et connexions.Impossible d'editer une memoire avant telechargement de la radioImpossible de trouver la configuration de base %rImpossible d'ouvrir le presse-papierImpossible d'interrogerImpossible de lire le dernier bloc. Ceci se produit frequemment quand le modele selectionne est US mais que la radio n'est pas US (ou large-bande). Selectionnez le bon modele et reessayez.Impossible de montrer %s dans ce systemeImpossible de regler %s dans cette memoireEtats-UnisDebranchez votre cable (si necessaire) et cliquez sur OKInstruction de telechargementTelecharger vers la radioTelecharger vers la radio...Memoire telechargee %sUtiliser une police a chasse fixeUtiliser une plus grande policeLa valeur ne correspond pas a %i bitsLa valeur doit etre d'au moins %.4fLa valeur ne doit pas depasser %.4fLa valeur doit comporter exactement %i decimalesLes valeur doivent etre zero ou positivesValeursFabricantVoirATTENTION!AttentionAttention: %sBienvenueSouhaitez-vous que CHIRP installe une icone pour vous sur le bureau?Votre cable apparai t sur le port:bitsoctetsoctets chacundesactiveactive{bank} pleinechirp-20240224/chirp/locale/nl/0000755000175000017500000000000014566340177015026 5ustar hibbyhibbychirp-20240224/chirp/locale/nl/LC_MESSAGES/0000755000175000017500000000000014566340177016613 5ustar hibbyhibbychirp-20240224/chirp/locale/nl/LC_MESSAGES/CHIRP.mo0000644000175000017500000000254614566340175020022 0ustar hibbyhibbyо•є%Ь`ae{‰‘–šЁ ГР Чбжнуьђљџ   %/46kq‹’ ™ Ѓ­ ЕС кш яњ џ %-3<BR Wa     AllAn error has occurredBanksCloningCommentCopyCutDeleteDiff Raw MemoriesDigital CodeDuplexFrequencyHelpImportIndexMemoriesModelOffsetPastePortPowerRadioShow Raw MemoryToneTone ModeVendorProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2012-03-18 12:01+0100 Last-Translator: Michael Tel Language-Team: Dutch Language: nl MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); AllesEr is een fout opgetredenBankenKlonenOpmerkingKopiУЋrenKnippenVerwijderenVerschillen ruwe kanalenDigitale codeDuplexFrequentieHelpImporterenIndexKanalenModelOffsetPlakkenPoortVermogenRadioToon ruw kanaalToonToonmodusMerkchirp-20240224/chirp/locale/ru/0000755000175000017500000000000014566340177015043 5ustar hibbyhibbychirp-20240224/chirp/locale/ru/LC_MESSAGES/0000755000175000017500000000000014566340177016630 5ustar hibbyhibbychirp-20240224/chirp/locale/ru/LC_MESSAGES/CHIRP.mo0000644000175000017500000024661014566340175020041 0ustar hibbyhibbyо•id чЌH I-T+‚ЎЕФ˜п ‘x! #уЈ#Œ$єЃ%˜&љž'ї˜(ћ)яŒ* |+oˆ,qј-лj/еF0p1e2хѓ3ой4жИ5я6ь7ъl8чW9§?: =;ЛG<С=оХ=зЄ>р|?н]@#;A _BMkCКЙDЖtEЬ+FШјFСGЩHуЭIпБJ€‘KmLо€Lщ_M­INќїNѕєOъPр§QпоR^ОST #T/T 3T=TTT\TrT„T–TŸTЅTЋTЏTЗTЮT]еTJ3U~UU UДUУU еU(уU VV,0W]WeWxW‰W WšWЂWЙWkТW.X3X ;X GXQXUX ZX hX rXXƒXŠXA™XлX эXњX YYY 9YZYcYwYŽYЄYЋYШYуYњYZZ%Z>Z\ZoZ€Z˜ZЗZЫZ ыZљZ [u[†[Ѓ[К[У[л[с[1ш[\ \)\1\ЪG\Ы]о]Јэ^К–_”Q`Тц`ХЉa8obЄЈcИMd•eЇœeЄDfЃщfЃg.1h `hjhoh €h Œh™hЁh ІhБhЕh7Щhiii3i9i >iJi[iqi'†i ЎiМiЭi"оij j!j&j/j Aj Mj Yj4fj›jЊjСjyлjUl flplyl%”lКlкlпlхlыl ђlmm 8mBm JmUmkm€m‘m Ўm ЙmХmЬmгmцm љmn1n 6nBn Tn `nnn}nnЌn РnЮn рno†oœoЄo3Њo*оo( p&2p?YpФ™p(^r‡s ›t$ЇtЬtбt!зt љtu uu $u1u9u?uZuЈlu;vQvbv vv„v ›vЇvИЙvrwƒw–w›w АwКw Щwзw ъw їwxxx'x7xOx.axxАx РxЮxжxмxыxбѓx Хy^fz Х{Кб{#Œ|=А|фю|г}№}&~ю6,%€R€ W€ a€ n€z€LŠ€,з€#@ЉP"њ‚ =‚/K‚{‚‚Ÿ‚В‚Х‚к‚ъ‚ƒ$ƒ'?ƒgƒ…ƒŒƒ“ƒ˜ƒЁƒ ЉƒЕƒ7Нƒ!ѕƒ„„ "„-„6„>„НM„ж †[т‡k>ˆЊˆГˆAУˆ)‹~/Œ.ЎЧн Ѕ’вГ”Д†–œ;˜‡и™`›uтœЉXžh MkЂ…ЙЄb?ІHЂЇbыЉNЌˆп­chЏ”ЬАtaВжГofЕІжЖШ}И[FКWЂЛƒњМe~О…фПkjС*жТеХjзЦnBЩNБЪzЬX{Э дЮ оаЏъвБšд%Lж§rзЦpиЧ7к{џлР{нЖ<ппѓрМгтНф“Nцтцјцчч3-ч-aч ч)œчЦчцчш ш'ш8шGш eшЗrшs*щžщ.Ощэщ ъ&(ъOъKoъ ЛъЦъfпьFэ,_э,ŒэЙэШэрэ/їэ'юИ:юѓю я)я#?яcяtяyя“я!ЃяХякя#щя™ №GЇ№я№2ё:ёMё0bё[“ёяё&ђ))ђ*Sђ~ђOђMнђJ+ѓvѓ‡ѓ(Ѕѓ)Юѓ/јѓ9(є)bє6Œє>Ує1ѕa4ѕ–ѕЌѕХѕорѕDПіGїLї&[ї ‚ї їšї ј%ј ;ј3Iј{}јlљљѕfћ[\§žИўMW{Ѕl!Ž[ zM [i dХ [*b†Vщ@O'T+|,Јечі"3)‡] хђ, ?La&v;/йY %c.‰/ИVш%?e ~ Œ/™.Щ%ј)hH"Б1д4Ъ;%,;8UyŽK T _ l y†,Є5б!'I(](† Џ3а" AL9],—PФ2HWJwТк*і%!YG!ЁУп>џ3> чr  Z!g!x!fј!d_"dФ"|)#дІ#]{'\й)6,<I,†,,G ,ш, ---/-O-W-4f-&›-dТ-f'/'Ž//Ж/)ц/50#F00j0Е›0'Q2'y2Ё21Д2ц2)3%,3-R3"€3Ѓ3*Н3 ш3ѕ3G4GP46˜4bЯ4H25+{50Ї5и5э5ќ56R'6z7c‹8 я:‚;;“<{Я<ХK=F?HX??Ё?IсAd+D DD ГDРDкD’іDz‰E]F:bF3FnбFG@HVˆH!пHXI%ZI$€I'ЅI1ЭI<џI=ЂQ§Џ"ЛK$yуtЬlЗ;…* 2+oJЈ‚ё„C.а?XтœgйС9]rckp 5”G‹шAШ’aіЯjqn|ŽŸ7Ѓл—*юфс[De\O[~mыV€ šW(e`zЖWh_ъ8MOбI4­fT}Юрs@Ћ1MKП™E\0КUP"оu“aГZC{‘1ƒ@•БGH#iЪbSи А˜dУХUЌžP†Й'JѕЕ&LЊОчЦ3R И)ѓЭ$wTL.вRfЅ<яг‰ '`ZЄЉ:д)ŒЇ>-ењ]YЁїQxТРЧ6-Нэ+: 7жD_9!цђМ–  !Hˆ›? % d(v№SЫљ4N =FY,,6ДзI0н;bј Щхьм‡8%2ІџЎщFiŠ/cB^єA5<#hX&^/NкBќVEФпў 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in [DISP] key while turning on radio ("CLONE" will appear on radio LCD). 4. Press [RECEIVE] screen button ("-WAIT-" will appear on radio LCD). 5. Finally, press OK button below. %(value)s must be between %(min)i and %(max)i%s has not been saved. Save before closing?(none)...and %i more1. Ensure your firmware version is 4_10 or higher 2. Turn radio off 3. Connect your interface cable 4. Turn radio on 5. Press and release PTT 3 times while holding MONI key 6. Supported baud rates: 57600 (default) and 19200 (rotate dial while holding MONI to change) 7. Click OK 1. Turn Radio off. 2. Connect data cable. 3. While holding "A/N LOW" button, turn radio on. 4. After clicking OK, press "SET MHz" to send image. 1. Turn Radio off. 2. Connect data cable. 3. While holding "A/N LOW" button, turn radio on. 4. Press "MW D/MR" to receive image. 5. Make sure display says "-WAIT-" (see note below if not) 6. Click OK to dismiss this dialog and start transfer. Note: if you don't see "-WAIT-" at step 5, try cycling power and pressing and holding red "*L" button to unlock radio, then start back at step 1. 1. Turn Radio off. 2. Connect data cable. 3. While holding "TONE" and "REV" buttons, turn radio on. 4. After clicking OK, press "TONE" to send image. 1. Turn Radio off. 2. Connect data cable. 3. While holding "TONE" and "REV" buttons, turn radio on. 4. Press "REV" to receive image. 5. Make sure display says "CLONE RX" and green led is blinking 6. Click OK to start transfer. 1. Turn radio off. 2. Connect cable 3. Press and hold in the MHz, Low, and D/MR keys on the radio while turning it on 4. Radio is in clone mode when TX/RX is flashing 5. After clicking OK, press the MHz key on the radio to send image. ("TX" will appear on the LCD). 1. Turn radio off. 2. Connect cable 3. Press and hold in the MHz, Low, and D/MR keys on the radio while turning it on 4. Radio is in clone mode when TX/RX is flashing 5. Press the Low key on the radio ("RX" will appear on the LCD). 6. Click OK.1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK here, press the [C.S.] key to send image. 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK, press the [A] key to send image. 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Click OK here. ("Receiving" will appear on the LCD). 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Press the [A](RCV) key ("receiving" will appear on the LCD). 1. Turn radio off. 2. Connect cable to ACC jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. Press the [C] key ("RX" will appear on the LCD). 1. Turn radio off. 2. Connect cable to CAT/LINEAR jack. 3. Press and hold in the [MODE <] and [MODE >] keys while turning the radio on ("CLONE MODE" will appear on the display). 4. After clicking OK, press the [C](SEND) key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the "left" [V/M] key while turning the radio on. 4. Rotate the "right" DIAL knob to select "CLONE START". 5. Press the [SET] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. After clicking OK, press the "left" [V/M] key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the "left" [V/M] key while turning the radio on. 4. Rotate the "right" DIAL knob to select "CLONE START". 5. Press the [SET] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. Press the "left" [LOW] key ("CLONE -RX-" will appear on the display). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [FW] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [FW] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MODE] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [MHz(PRI)] key while turning the radio on. 4. Rotate the DIAL job to select "F-7 CLONE". 5. Press and hold in the [BAND(SET)] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. Press the [LOW(ACC)] key ("--RX--" will appear on the display). 1. Turn radio off. 2. Connect cable to DATA jack. 3. Press and hold in the [MHz(PRI)] key while turning the radio on. 4. Rotate the DIAL job to select "F-7 CLONE". 5. Press and hold in the [BAND(SET)] key. The display will disappear for a moment, then the "CLONE" notation will appear. 6. After clicking OK, press the [V/M(MW)] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold [DISP] key while turning on radio ("CLONE" will appear on the display). 4. After clicking OK here in chirp, press the [Send] screen button. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [F] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [F] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [Dx] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [REV(DW)] key to send image. 1. Turn radio off. 2. Connect cable to DATA terminal. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MHz(SETUP)] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC Jack. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [GM(AMS)] key to send image. 1. Turn radio off. 2. Connect cable to MIC Jack. 3. Press and hold in the [MHz(SETUP)] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MHz(SETUP)] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/EAR jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [VFO(DW)SC] key to receive the image from the radio. 1. Turn radio off. 2. Connect cable to MIC/EAR jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [MR(SKP)SC] key ("CLONE WAIT" will appear on the LCD). 5. Click OK to send image to radio. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold [PTT] & Knob while turning the radio on. 4. After clicking OK, press the [PTT] switch to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold [PTT] & Knob while turning the radio on. 4. Press the [MONI] switch ("WAIT" will appear on the LCD). 5. Press OK. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [F/W] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [V/M] key ("-WAIT-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MON-F] key while turning the radio on ("CLONE" will appear on the display). 4. After clicking OK, press the [BAND] key to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MON-F] key while turning the radio on ("CLONE" will appear on the display). 4. Press the [V/M] key ("CLONE WAIT" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MONI] switch while turning the radio on. 4. Rotate the DIAL job to select "F8 CLONE". 5. Press the [F/W] key momentarily. 6. After clicking OK, hold the [PTT] switch for one second to send image. 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [MONI] switch while turning the radio on. 4. Rotate the DIAL job to select "F8 CLONE". 5. Press the [F/W] key momentarily. 6. Press the [MONI] switch ("--RX--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to MIC/SP jack. 3. Press and hold in the [moni] key while turning the radio on. 4. Select CLONE in menu, then press F. Radio restarts in clone mode. ("CLONE" will appear on the display). 5. After clicking OK, briefly hold [PTT] key to send image. ("-TX-" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [LOW(A/N)] key while turning the radio on. 4. After clicking OK, press the [MHz(SET)] key to send image. 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [LOW(A/N)] key while turning the radio on. 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [MHz], [LOW], and [D/MR] keys while turning the radio on. 4. After clicking OK, press the [MHz(SET)] key to send image. 1. Turn radio off. 2. Connect cable to mic jack. 3. Press and hold in the [MHz], [LOW], and [D/MR] keys while turning the radio on. 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to download image from device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to upload image to device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on. 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to download image from device. 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on. 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to upload image to device. 1. Turn radio off. 2. Connect data cable. 3. Prepare radio for clone. 4. After clicking OK, press the key to send image. 1. Turn radio off. 2. Connect data cable. 3. Prepare radio for clone. 4. Press the key to receive the image. 1. Turn radio off. 2. Connect mic and hold [ACC] on mic while powering on. ("CLONE" will appear on the display) 3. Replace mic with PC programming cable. 4. After clicking OK, press the [SET] key to send image. 1. Turn radio off. 2. Connect mic and hold [ACC] on mic while powering on. ("CLONE" will appear on the display) 3. Replace mic with PC programming cable. 4. Press the [DISP/SS] key ("R" will appear on the lower left of LCD). 1. Turn radio off. 2. Remove front head. 3. Connect data cable to radio, use the same connector where head was connected to, not the mic connector. 4. Click OK. 1. Turn radio off. 3. Press and hold in the [moni] key while turning the radio on. 4. Select CLONE in menu, then press F. Radio restarts in clone mode. ("CLONE" will appear on the display). 5. Press the [moni] key ("-RX-" will appear on the LCD). 1. Turn radio on. 2. Connect cable to DATA terminal. 3. Unclip battery. 4. Press and hold in the [AMS] key and power key while clipping in back battery the("ADMS" will appear on the display). 5. After clicking OK, press the [BAND] key. 1. Turn radio on. 2. Connect cable to DATA terminal. 3. Unclip battery. 4. Press and hold in the [AMS] key and power key while clipping in back battery the("ADMS" will appear on the display). 5. Press the [MODE] key ("-WAIT-" will appear on the LCD). OK click Then1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to download image from device. It will may not work if you turn on the radio with the cable already attached 1. Turn radio on. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Click OK to upload the image to device. It will may not work if you turn on the radio with the cable already attachedA new CHIRP version is available. Please visit the website as soon as possible to download it!AboutAbout CHIRPAllAll FilesAll supported formats|AmateurAn error has occurredApplying settingsAvailable modulesBandplanBandsBanksBinBrowserBuilding Radio BrowserCanadaChanging this setting requires refreshing the settings from the image, which will happen now.Channels with equivalent TX and RX %s are represented by tone mode of "%s"Chirp Image FilesChoice RequiredChoose %s DTCS CodeChoose %s ToneChoose Cross ModeChoose duplexChoose the module to load from issue %i:CityClick on the "Special Channels" toggle-button of the memory editor to see/set the EXT channels. P-VFO channels 100-109 are considered Settings. Only a subset of the over 200 available radio settings are supported in this release. Ignore the beeps from the radio on upload and download. Clone completed, checking for spurious bytesCloningCloning from radioCloning to radioCloseClose fileCommentCommunicate with radioCompleteConnect your interface cable to the PC Port on the back of the 'TX/RX' unit. NOT the Com Port on the head. CopyCountryCustom PortCustom...CutDTCSDTCS PolarityDV MemoryDanger AheadDecDeleteDeveloper ModeDeveloper state is now %s. CHIRP must be restarted to take effectDiff Raw MemoriesDigital CodeDisable reportingDisabledDistanceDo not prompt again for %sDouble-click to change bank nameDownloadDownload from radioDownload from radio...Download instructionsDuplexEdit details for %i memoriesEdit details for memory %iEnable Automatic EditsEnabledEnter FrequencyEnter Offset (MHz)Enter TX Frequency (MHz)Enter a new name for bank %s:Enter custom port:Erased memory %sError applying settingsError communicating with radioExperimental driverExport can only write CSV filesExport to CSVExport to CSV...ExtraFREE repeater database, which provides most up-to-date information about repeaters in Europe. No account is required.Failed to load radio browserFailed to parse resultFeaturesFile does not exist: %sFilesFilterFilter results with location matching this stringFindFind NextFind...Finished radio job %sFollow these instructions to download the radio memory: 1 - Connect your interface cable 2 - Radio > Download from radio: DO NOT mess with the radio during download! 3 - Disconnect your interface cable Follow these instructions to download the radio memory: 1 - Connect your interface cable 2 - Radio > Download from radio: Don't adjust any settings on the radio head! 3 - Disconnect your interface cable Follow these instructions to download your config: 1 - Turn off your radio 2 - Connect your interface cable to the Speaker-2 jack 3 - Turn on your radio 4 - Radio > Download from radio 5 - Disconnect the interface cable! Otherwise there will be no right-side audio! Follow these instructions to download your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow these instructions to download your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio (unlock it if password protected) 4 - Click OK to start Follow these instructions to read your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Click OK to start Follow these instructions to upload the radio memory: 1 - Connect your interface cable 2 - Radio > Upload to radio: DO NOT mess with the radio during upload! 3 - Disconnect your interface cable Follow these instructions to upload the radio memory: 1 - Connect your interface cable 2 - Radio > Upload to radio: Don't adjust any settings on the radio head! 3 - Disconnect your interface cable Follow these instructions to upload your config: 1 - Turn off your radio 2 - Connect your interface cable to the Speaker-2 jack 3 - Turn on your radio 4 - Radio > Upload to radio 5 - Disconnect the interface cable, otherwise there will be no right-side audio! 6 - Cycle power on the radio to exit clone mode Follow these instructions to upload your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Follow these instructions to upload your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio (unlock it if password protected) 4 - Click OK to start Follow these instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Click OK to start Follow this instructions to download your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to read your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the download of your radio data Follow this instructions to upload your info: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Follow this instructions to write your radio: 1 - Turn off your radio 2 - Connect your interface cable 3 - Turn on your radio 4 - Do the upload of your radio data Found empty list value for %(name)s: %(value)rFrequencyGMRSGetting settingsGoto MemoryGoto Memory:Goto...HelpHelp Me...HexHide empty memoriesIf set, sort results by distance from these coordinatesImportImport from file...Import not recommendedIndexInfoInformationInsert Row AboveInstall desktop icon?Interact with driverInvalid %(value)s (use decimal degrees)Invalid EntryInvalid ZIP codeInvalid edit: %sInvalid or unsupported module fileInvalid value: %rIssue number:LIVELatitudeLength must be %iLimit BandsLimit ModesLimit StatusLimit results to this distance (km) from coordinatesLoad Module...Load module from issueLoad module from issue...Loading modules can be extremely dangerous, leading to damage to your computer, radio, or both. NEVER load a module from a source you do not trust, and especially not from anywhere other than the main CHIRP website (chirp.danplanet.com). Loading a module from another source is akin to giving them direct access to your computer and everything on it! Proceed despite this risk?Loading settingsLongitudeMemoriesMemory %i is not deletableMemory must be in a bank to be editedMemory {num} not in bank {bank}ModeModelModesModuleModule LoadedModule loaded successfullyMore than one port found: %sMove DownMove UpNew WindowNew version availableNo empty rows below!No modules foundNo modules found in issue %iNo resultsNo results!NumberOffsetOnly certain bandsOnly certain modesOnly memory tabs may be exportedOnly working repeatersOpenOpen RecentOpen Stock ConfigOpen a fileOpen a moduleOpen debug logOpen in new windowOpen stock config directoryOptional: -122.0000Optional: 100Optional: 45.0000Optional: County, Hospital, etc.Overwrite memories?P-VFO channels 100-109 are considered Settings. Only a subset of the over 130 available radio settings are supported in this release. ParsingPastePasted memories will overwrite %s existing memoriesPasted memories will overwrite memories %sPasted memories will overwrite memory %sPasted memory will overwrite memory %sPlease be sure to quit CHIRP before installing the new version!Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio 3 - Click the button on this window to start download (you may see another dialog, click ok) 4 - Radio will beep and led will flash 5 - You will get a 10 seconds timeout to press "MON" before data upload start 6 - If all goes right radio will beep at end. After cloning remove the cable and power cycle your radio to get into normal mode. Please follow this steps carefully: 1 - Turn on your radio 2 - Connect the interface cable to your radio. 3 - Click the button on this window to start download (Radio will beep and led will flash) 4 - Then press the "A" button in your radio to start cloning. (At the end radio will beep) Please note that developer mode is intended for use by developers of the CHIRP project, or under the direction of a developer. It enables behaviors and functions that can damage your computer and your radio if not used with EXTREME care. You have been warned! Proceed anyway?Please waitPlug in your cable and then click OKPortPowerPress enter to set this in memoryPrint PreviewPrintingPropertiesQuery %sQuery SourceRX DTCSRadioRadio did not ack block %iRadio informationRadio sent data after the last awaited block, this happens when the selected model is a non-US but the radio is a US one. Please choose the correct model and try again.RadioReference Canada requires a login before you can queryRefresh requiredRefreshed memory %sReload DriverReload Driver and FileRename bankReporting enabledReporting helps the CHIRP project know which radio models and OS platforms to spend our limited efforts on. We would really appreciate if you left it enabled. Really disable reporting?Restart RequiredRetrieved settingsSaveSave before closing?Save fileSaved settingsSecurity RiskSelect Bandplan...Select BandsSelect ModesSelect a bandplanServiceSettingsShow Raw MemoryShow debug log locationShow extra fieldsSome memories are incompatible with this radioSome memories are not deletableSort by column:Sort memoriesSortingStateState/ProvinceSuccessThe X3Plus driver is currently experimental. There are no known issues but you should proceed with caution. Please save an unedited copy of your first successful download to a CHIRP Radio Images (*.img) file. The author of this module is not a recognized CHIRP developer. It is recommended that you not load this module as it could pose a security risk. Proceed anyway?The recommended procedure for importing memories is to open the source file and copy/paste memories from it into your target image. If you continue with this import function, CHIRP will replace all memories in your currently-open file with those in %(file)s. Would you like to open this file to copy/paste memories across, or proceed with the import?This MemoryThis driver has been tested with v3 of the ID-5100. If your radio is not fully updated please help by opening a bug report with a debug log so we can add support for the other revisions.This is an early stage beta driver This is an early stage beta driver - upload at your own risk This is experimental support for BJ-9900 which is still under development. Please ensure you have a good backup with OEM software. Also please send in bug and enhancement requests! You have been warned. Proceed at your own risk!This memory and shift all upThis memory and shift block upThis radio has a tricky way of enter into program mode, even the original software has a few tries to get inside. I will try 8 times (most of the time ~3 will doit) and this can take a few seconds, if don't work, try again a few times. If you can get into it, please check the radio and cable. This should only be enabled if you are using modified firmware that supports wider frequency coverage. Enabling this will cause CHIRP not to enforce OEM restrictions and may lead to undefined or unregulated behavior. Use at your own risk!This will load a module from a website issueToneTone ModeTone SquelchTuning StepUSB Port FinderUnable to determine port for your cable. Check your drivers and connections.Unable to edit memory before radio is loadedUnable to find stock config %rUnable to open the clipboardUnable to queryUnable to read last block. This often happens when the selected model is US but the radio is a non-US one (or widebanded). Please choose the correct model and try again.Unable to reveal %s on this systemUnable to set %s on this memoryUnited StatesUnplug your cable (if needed) and then click OKUpload instructionsUpload to radioUpload to radio...Uploaded memory %sUse fixed-width fontUse larger fontValue does not fit in %i bitsValue must be at least %.4fValue must be at most %.4fValue must be exactly %i decimal digitsValue must be zero or greaterValuesVendorViewWARNING!WarningWarning: %sWelcomeWould you like CHIRP to install a desktop icon for you?Your cable appears to be on port:bitsbytesbytes eachdisabledenabled{bank} is fullProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2023-10-11 16:47+0300 Last-Translator: Olesya Gerasimenko Language-Team: Basealt Translation Team Language: ru MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Generator: Lokalize 23.04.3 Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [DISP] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ бб‚аАаНб†аИаИ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ баКб€аАаНаНбƒбŽ аКаНаОаПаКбƒ [RECEIVE] (аНаА баКб€аАаНаЕ бб‚аАаНб†аИаИ аПаОбаВаИб‚бб ТЋ-WAIT-ТЛ). 5. ааАаЖаМаИб‚аЕ аКаНаОаПаКбƒ ТЋаžаšТЛ аНаИаЖаЕ. %(value)s аДаОаЛаЖаНаО аНаАб…аОаДаИб‚бŒбб аВ аДаИаАаПаАаЗаОаНаЕ аОб‚ %(min)i аДаО %(max)iаЁаОб…б€аАаНаЕаНаИаЕ %s аНаЕ аБб‹аЛаО аВб‹аПаОаЛаНаЕаНаО. аЁаОб…б€аАаНаИб‚бŒ аПаЕб€аЕаД аЗаАаКб€б‹б‚аИаЕаМ?(аНаЕб‚)...аИ аЕб‰б‘ %i1. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО бƒ аВаАб аМаИаКб€аОаПб€аОаГб€аАаМаМаА аВаЕб€баИаИ 4_10 аИаЛаИ аВб‹бˆаЕ 2. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ 3. аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 4. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ 5. ааАаЖаМаИб‚аЕ аИ аОб‚аПбƒбб‚аИб‚аЕ PTT 3 б€аАаЗаА, бƒаДаЕб€аЖаИаВаАб аКаЛаАаВаИбˆбƒ MONI 6. аŸаОаДаДаЕб€аЖаИаВаАаЕаМаАб баКаОб€аОбб‚бŒ аВ аБаОаДаАб…: 57600 (аПаО бƒаМаОаЛб‡аАаНаИбŽ) аИ 19200 (б‡б‚аОаБб‹ аИаЗаМаЕаНаИб‚бŒ, аПаОаВаЕб€аНаИб‚аЕ б€бƒб‡аКбƒ аНаАбб‚б€аОаЙаКаИ, бƒаДаЕб€аЖаИаВаАб MONI) 7. ааАаЖаМаИб‚аЕ ТЋOKТЛ 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аПаЕб€аЕаДаАб‡аИ аДаАаНаНб‹б…. 3. аЃаДаЕб€аЖаИаВаАб аКаНаОаПаКбƒ ТЋA/N LOWТЛ, аВаКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ ТЋSET MHzТЛ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аПаЕб€аЕаДаАб‡аИ аДаАаНаНб‹б…. 3. аЃаДаЕб€аЖаИаВаАб аКаНаОаПаКбƒ ТЋA/N LOWТЛ, аВаКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 4. ааАаЖаМаИб‚аЕ ТЋMW D/MRТЛ аДаЛб аПаОаЛбƒб‡аЕаНаИб аОаБб€аАаЗаА. 5. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аНаА баКб€аАаНаЕ аНаАаПаИбаАаНаО ТЋ-WAIT-ТЛ (баМ. аПб€аИаМаЕб‡аАаНаИаЕ аНаИаЖаЕ, аЕбаЛаИ бб‚аО аНаЕ б‚аАаК) 6. ааАаЖаМаИб‚аЕ ТЋOKТЛ аДаЛб аЗаАаКб€б‹б‚аИб бб‚аОаГаО аДаИаАаЛаОаГаА аИ аНаАб‡аАаЛаА аПаЕб€аЕаДаАб‡аИ. аŸб€аИаМаЕб‡аАаНаИаЕ: аЕбаЛаИ аНаА бˆаАаГаЕ 5 аНаА баКб€аАаНаЕ аНаЕб‚ б‚аЕаКбб‚аА ТЋ-WAIT-ТЛ, аПаОаПб€аОаБбƒаЙб‚аЕ аВб‹аКаЛбŽб‡аИб‚бŒ аИ баНаОаВаА аВаКаЛбŽб‡аИб‚бŒ аПаИб‚аАаНаИаЕ, аПаОб‚аОаМ аНаАаЖаАб‚бŒ аИ бƒаДаЕб€аЖаИаВаАб‚бŒ аКб€аАбаНбƒбŽ аКаНаОаПаКбƒ ТЋ*LТЛ аДаЛб б€аАаЗаБаЛаОаКаИб€аОаВаКаИ бб‚аАаНб†аИаИ, аА аЗаАб‚аЕаМ аНаАб‡аНаИб‚аЕ баНаОаВаА б бˆаАаГаА 1. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аПаЕб€аЕаДаАб‡аИ аДаАаНаНб‹б…. 3. аЃаДаЕб€аЖаИаВаАб аКаНаОаПаКаИ ТЋTONEТЛ аИ ТЋREVТЛ, аВаКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ ТЋTONEТЛ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аПаЕб€аЕаДаАб‡аИ аДаАаНаНб‹б…. 3. аЃаДаЕб€аЖаИаВаАб аКаНаОаПаКаИ ТЋTONEТЛ аИ ТЋREVТЛ, аВаКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 4. ааАаЖаМаИб‚аЕ ТЋREVТЛ аДаЛб аПаОаЛбƒб‡аЕаНаИб аОаБб€аАаЗаА. 5. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аНаА баКб€аАаНаЕ аНаАаПаИбаАаНаО ТЋCLONE RXТЛ аИ аМаИаГаАаЕб‚ аЗаЕаЛб‘аНб‹аЙ баВаЕб‚аОаДаИаОаД. 6. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аНаАб‡аАаЛаА аПаЕб€аЕаДаАб‡аИ. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аНаА бб‚аАаНб†аИаИ аКаЛаАаВаИбˆаИ ТЋMHzТЛ, ТЋLowТЛ аИ ТЋD/MRТЛ аВаО аВб€аЕаМб аЕб‘ аВаКаЛбŽб‡аЕаНаИб. 4. аЁб‚аАаНб†аИб аНаАб…аОаДаИб‚бб аВ б€аЕаЖаИаМаЕ аКаЛаОаНаИб€аОаВаАаНаИб, аКаОаГаДаА аМаИаГаАаЕб‚ TX/RX. 5. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аНаА бб‚аАаНб†аИаИ аКаЛаАаВаИбˆбƒ ТЋMHzТЛ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋTXТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аНаА бб‚аАаНб†аИаИ аКаЛаАаВаИбˆаИ ТЋMHzТЛ, ТЋLowТЛ аИ ТЋD/MRТЛ аВаО аВб€аЕаМб аЕб‘ аВаКаЛбŽб‡аЕаНаИб. 4. аЁб‚аАаНб†аИб аНаАб…аОаДаИб‚бб аВ б€аЕаЖаИаМаЕ аКаЛаОаНаИб€аОаВаАаНаИб, аКаОаГаДаА аМаИаГаАаЕб‚ TX/RX. 5. ааАаЖаМаИб‚аЕ аНаА бб‚аАаНб†аИаИ аКаЛаАаВаИбˆбƒ ТЋLowТЛ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋRXТЛ). 6. ааАаЖаМаИб‚аЕ ТЋOKТЛ.1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ ACC. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MODE <] аИ [MODE >] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE MODEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аВ бб‚аОаМ аОаКаНаЕ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [C.S.] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ ACC. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MODE <] аИ [MODE >] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE MODEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [A] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ ACC. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MODE <] аИ [MODE >] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE MODEТЛ). 4. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аВ бб‚аОаМ аОаКаНаЕ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋReceivingТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ ACC. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MODE <] аИ [MODE >] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE MODEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [A](RCV) (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋreceivingТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ ACC. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MODE <] аИ [MODE >] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE MODEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [C] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋRXТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ CAT/LINEAR. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MODE <] аИ [MODE >] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE MODEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [C](SEND) аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ ТЋаЛаЕаВбƒбŽТЛ аКаЛаАаВаИбˆбƒ [V/M] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОаВаЕб€аНаИб‚аЕ ТЋаПб€аАаВбƒбŽТЛ б€бƒб‡аКбƒ DIAL аДаЛб аВб‹аБаОб€аА ТЋCLONE STARTТЛ. 5. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [SET]. а­аКб€аАаН аНаА аВб€аЕаМб бб‚аАаНаЕб‚ аПбƒбб‚б‹аМ, аЗаАб‚аЕаМ аПаОбаВаИб‚бб аНаАаДаПаИббŒ ТЋCLONEТЛ. 6. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ ТЋаЛаЕаВбƒбŽТЛ аКаЛаАаВаИбˆбƒ [V/M] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ ТЋаЛаЕаВбƒбŽТЛ аКаЛаАаВаИбˆбƒ [V/M] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОаВаЕб€аНаИб‚аЕ ТЋаПб€аАаВбƒбŽТЛ б€бƒб‡аКбƒ DIAL аДаЛб аВб‹аБаОб€аА ТЋCLONE STARTТЛ. 5. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [SET]. а­аКб€аАаН аНаА аВб€аЕаМб бб‚аАаНаЕб‚ аПбƒбб‚б‹аМ, аЗаАб‚аЕаМ аПаОбаВаИб‚бб аНаАаДаПаИббŒ ТЋCLONEТЛ. 6. ааАаЖаМаИб‚аЕ ТЋаЛаЕаВбƒбŽТЛ аКаЛаАаВаИбˆбƒ [LOW] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE -RX-ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [FW] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [BAND] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [FW] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [MODE] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-WAIT-ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(PRI)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОаВаЕб€аНаИб‚аЕ б€аЕаГбƒаЛбб‚аОб€ DIAL аДаЛб аВб‹аБаОб€аА ТЋF-7 CLONEТЛ. 5. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [BAND(SET)]. а­аКб€аАаН аНаА аВб€аЕаМб бб‚аАаНаЕб‚ аПбƒбб‚б‹аМ, аЗаАб‚аЕаМ аПаОбаВаИб‚бб аНаАаДаПаИббŒ ТЋCLONEТЛ. 6. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [LOW(ACC)] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ--RX--ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(PRI)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОаВаЕб€аНаИб‚аЕ б€аЕаГбƒаЛбб‚аОб€ DIAL аДаЛб аВб‹аБаОб€аА ТЋF-7 CLONEТЛ. 5. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [BAND(SET)]. а­аКб€аАаН аНаА аВб€аЕаМб бб‚аАаНаЕб‚ аПбƒбб‚б‹аМ, аЗаАб‚аЕаМ аПаОбаВаИб‚бб аНаАаДаПаИббŒ ТЋCLONEТЛ. 6. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [V/M(MW)] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [DISP] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аВ бб‚аОаМ аОаКаНаЕ chirp аНаАаЖаМаИб‚аЕ баКб€аАаНаНбƒбŽ аКаНаОаПаКбƒ [Send]. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [F] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [BAND] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [F] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [Dx] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-WAIT-ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SETUP)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [REV(DW)] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SETUP)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SETUP)] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-WAIT-ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SETUP)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [GM(AMS)] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SETUP)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SETUP)] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-WAIT-ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/EAR. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [F/W] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [VFO(DW)SC] аДаЛб аПаОаЛбƒб‡аЕаНаИб аОаБб€аАаЗаА аОб‚ бб‚аАаНб†аИаИ. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/EAR. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [F/W] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [MR(SKP)SC] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE WAITТЛ). 5. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА аНаА бб‚аАаНб†аИбŽ. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ б€бƒб‡аКбƒ [PTT] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋOKТЛ аНаАаЖаМаИб‚аЕ аПаЕб€аЕаКаЛбŽб‡аАб‚аЕаЛбŒ [PTT] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ б€бƒб‡аКбƒ [PTT] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. ааАаЖаМаИб‚аЕ аПаЕб€аЕаКаЛбŽб‡аАб‚аЕаЛбŒ [MONI] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋWAITТЛ). 5. ааАаЖаМаИб‚аЕ ТЋOKТЛ. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [F/W] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋOKТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [BAND] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [F/W] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [V/M] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-WAIT-ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MON-F] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋOKТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [BAND] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [MON-F] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [V/M] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONE WAITТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аПаЕб€аЕаКаЛбŽб‡аАб‚аЕаЛбŒ [MONI] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОаВаЕб€аНаИб‚аЕ б€аЕаГбƒаЛбб‚аОб€ DIAL аДаЛб аВб‹аБаОб€аА ТЋF8 CLONEТЛ. 5. аšб€аАб‚аКаО аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [F/W]. 6. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋOKТЛ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аПаЕб€аЕаКаЛбŽб‡аАб‚аЕаЛбŒ [PTT] аВ б‚аЕб‡аЕаНаИаЕ аОаДаНаОаЙ баЕаКбƒаНаДб‹ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аПаЕб€аЕаКаЛбŽб‡аАб‚аЕаЛбŒ [MONI] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОаВаЕб€аНаИб‚аЕ б€аЕаГбƒаЛбб‚аОб€ DIAL аДаЛб аВб‹аБаОб€аА ТЋF8 CLONEТЛ. 5. аšб€аАб‚аКаО аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [F/W]. 6. ааАаЖаМаИб‚аЕ аПаЕб€аЕаКаЛбŽб‡аАб‚аЕаЛбŒ [MONI] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ--RX--ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ MIC/SP. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [moni] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. а’б‹аБаЕб€аИб‚аЕ аВ аМаЕаНбŽ CLONE, аЗаАб‚аЕаМ аНаАаЖаМаИб‚аЕ F. аЁб‚аАаНб†аИб аПаЕб€аЕаЗаАаГб€бƒаЗаИб‚бб аВ б€аЕаЖаИаМаЕ аКаЛаОаНаИб€аОаВаАаНаИб (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 5. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋOKТЛ аКб€аАб‚аКаО бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [PTT] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-TX-ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ аМаИаКб€аОб„аОаНаА. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [LOW(A/N)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋOKТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SET)] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ аМаИаКб€аОб„аОаНаА. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [LOW(A/N)] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [D/MR(MW)] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ--WAIT--ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ аМаИаКб€аОб„аОаНаА. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MHz], [LOW] аИ [D/MR] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋOKТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [MHz(SET)] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б€аАаЗбŠб‘аМбƒ аМаИаКб€аОб„аОаНаА. 3. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆаИ [MHz], [LOW] аИ [D/MR] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [D/MR(MW)] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ--WAIT--ТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК аКаОаНаНаЕаКб‚аОб€бƒ аМаИаКб€аОб„аОаНаА/spkr. 3. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аКаОаНаНаЕаКб‚аОб€ аПаЛаОб‚аНаО баОаЕаДаИаНб‘аН. 4. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ (аМаОаЖаЕб‚ аПаОб‚б€аЕаБаОаВаАб‚бŒбб бƒбб‚аАаНаОаВаИб‚бŒ аГб€аОаМаКаОбб‚бŒ аНаА 100%). 5. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО бб‚аАаНб†аИб аНаАбб‚б€аОаЕаНаА аНаА аНаЕаАаКб‚аИаВаНб‹аЙ аКаАаНаАаЛ. 6. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аЗаАаГб€бƒаЗаКаИ аОаБб€аАаЗаА б бƒбб‚б€аОаЙбб‚аВаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК аКаОаНаНаЕаКб‚аОб€бƒ аМаИаКб€аОб„аОаНаА/spkr. 3. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аКаОаНаНаЕаКб‚аОб€ аПаЛаОб‚аНаО баОаЕаДаИаНб‘аН. 4. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ (аМаОаЖаЕб‚ аПаОб‚б€аЕаБаОаВаАб‚бŒбб бƒбб‚аАаНаОаВаИб‚бŒ аГб€аОаМаКаОбб‚бŒ аНаА 100%). 5. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО бб‚аАаНб†аИб аНаАбб‚б€аОаЕаНаА аНаА аНаЕаАаКб‚аИаВаНб‹аЙ аКаАаНаАаЛ. 6. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА аНаА бƒбб‚б€аОаЙбб‚аВаО. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК аКаОаНаНаЕаКб‚аОб€бƒ аМаИаКб€аОб„аОаНаА/spkr. 3. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аКаОаНаНаЕаКб‚аОб€ аПаЛаОб‚аНаО баОаЕаДаИаНб‘аН. 4. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 5. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО бб‚аАаНб†аИб аНаАбб‚б€аОаЕаНаА аНаА аНаЕаАаКб‚аИаВаНб‹аЙ аКаАаНаАаЛ. 6. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аЗаАаГб€бƒаЗаКаИ аОаБб€аАаЗаА б бƒбб‚б€аОаЙбб‚аВаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК аКаОаНаНаЕаКб‚аОб€бƒ аМаИаКб€аОб„аОаНаА/spkr. 3. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аКаОаНаНаЕаКб‚аОб€ аПаЛаОб‚аНаО баОаЕаДаИаНб‘аН. 4. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 5. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО бб‚аАаНб†аИб аНаАбб‚б€аОаЕаНаА аНаА аНаЕаАаКб‚аИаВаНб‹аЙ аКаАаНаАаЛ. 6. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА аНаА бƒбб‚б€аОаЙбб‚аВаО. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аПаЕб€аЕаДаАб‡аИ аДаАаНаНб‹б…. 3. аŸаОаДаГаОб‚аОаВбŒб‚аЕ бб‚аАаНб†аИбŽ аДаЛб аКаЛаОаНаИб€аОаВаАаНаИб. 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аПаЕб€аЕаДаАб‡аИ аДаАаНаНб‹б…. 3. аŸаОаДаГаОб‚аОаВбŒб‚аЕ бб‚аАаНб†аИбŽ аДаЛб аКаЛаОаНаИб€аОаВаАаНаИб. 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ аДаЛб аПаОаЛбƒб‡аЕаНаИб аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аМаИаКб€аОб„аОаН аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аНаА аМаИаКб€аОб„аОаНаЕ [ACC] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 3. а—аАаМаЕаНаИб‚аЕ аМаИаКб€аОб„аОаН аНаА аКаАаБаЕаЛбŒ аПб€аОаГб€аАаМаМаИб€аОаВаАаНаИб PC. 4. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [SET] аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аМаИаКб€аОб„аОаН аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аНаА аМаИаКб€аОб„аОаНаЕ [ACC] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 3. а—аАаМаЕаНаИб‚аЕ аМаИаКб€аОб„аОаН аНаА аКаАаБаЕаЛбŒ аПб€аОаГб€аАаМаМаИб€аОаВаАаНаИб PC. 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [DISP/SS] (аВ аЛаЕаВаОаЙ аНаИаЖаНаЕаЙ б‡аАбб‚аИ баКб€аАаНаА аПаОбаВаИб‚бб ТЋRТЛ). 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аЃаБаЕб€аИб‚аЕ аПаЕб€аЕаДаНбŽбŽ аГаОаЛаОаВаКбƒ. 3. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аПаЕб€аЕаДаАб‡аИ аДаАаНаНб‹б… аК бб‚аАаНб†аИаИ, аИбаПаОаЛбŒаЗбƒб б‚аОб‚ аЖаЕ аКаОаНаНаЕаКб‚аОб€, аК аКаОб‚аОб€аОаМбƒ аБб‹аЛаА аПаОаДаКаЛбŽб‡аЕаНаА аГаОаЛаОаВаКаА, аА аНаА аКаОаНаНаЕаКб‚аОб€ аМаИаКб€аОб„аОаНаА. 4. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ. 1. а’б‹аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [moni] аВаО аВб€аЕаМб аВаКаЛбŽб‡аЕаНаИб бб‚аАаНб†аИаИ. 3. а’б‹аБаЕб€аИб‚аЕ CLONE аВ аМаЕаНбŽ, аЗаАб‚аЕаМ аНаАаЖаМаИб‚аЕ F. аЁб‚аАаНб†аИб аПаЕб€аЕаЗаАаГб€бƒаЗаИб‚бб аВ б€аЕаЖаИаМаЕ аКаЛаОаНаИб€аОаВаАаНаИб (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋCLONEТЛ). 4. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [moni] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-RX-ТЛ). 1. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. аžб‚баОаЕаДаИаНаИб‚аЕ аБаАб‚аАб€аЕбŽ. 4. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [AMS] аИ аКаЛаАаВаИбˆбƒ аПаИб‚аАаНаИб аВаО аВб€аЕаМб бƒбб‚аАаНаОаВаКаИ аБаАб‚аАб€аЕаИ аОаБб€аАб‚аНаО (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋADMSТЛ). 5. аŸаОбаЛаЕ аНаАаЖаАб‚аИб ТЋаžаšТЛ аНаАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [BAND]. 1. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК б‚аЕб€аМаИаНаАаЛбƒ DATA. 3. аžб‚баОаЕаДаИаНаИб‚аЕ аБаАб‚аАб€аЕбŽ. 4. ааАаЖаМаИб‚аЕ аИ бƒаДаЕб€аЖаИаВаАаЙб‚аЕ аКаЛаАаВаИбˆбƒ [AMS] аИ аКаЛаАаВаИбˆбƒ аПаИб‚аАаНаИб аВаО аВб€аЕаМб бƒбб‚аАаНаОаВаКаИ аБаАб‚аАб€аЕаИ аОаБб€аАб‚аНаО (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋADMSТЛ). 5. ааАаЖаМаИб‚аЕ аКаЛаАаВаИбˆбƒ [MODE] (аНаА баКб€аАаНаЕ аПаОбаВаИб‚бб ТЋ-WAIT-ТЛ). а—аАб‚аЕаМ аНаАаЖаМаИб‚аЕ ТЋаžаšТЛ.1. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК аКаОаНаНаЕаКб‚аОб€бƒ аМаИаКб€аОб„аОаНаА/spkr. 3. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аКаОаНаНаЕаКб‚аОб€ аПаЛаОб‚аНаО баОаЕаДаИаНб‘аН. 4. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аЗаАаГб€бƒаЗаКаИ аОаБб€аАаЗаА б бƒбб‚б€аОаЙбб‚аВаА. а—аАаГб€бƒаЗаКаА аМаОаЖаЕб‚ аНаЕ аПаОаЛбƒб‡аИб‚бŒбб, аЕбаЛаИ аВб‹ аВаКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ, аКаОаГаДаА аКаАаБаЕаЛбŒ бƒаЖаЕ аПаОаДаКаЛбŽб‡б‘аН 1. а’аКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ. 2. аŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аК аКаОаНаНаЕаКб‚аОб€бƒ аМаИаКб€аОб„аОаНаА/spkr. 3. аЃаБаЕаДаИб‚аЕббŒ, б‡б‚аО аКаОаНаНаЕаКб‚аОб€ аПаЛаОб‚аНаО баОаЕаДаИаНб‘аН. 4. ааАаЖаМаИб‚аЕ ТЋаžаšТЛ аДаЛб аОб‚аПб€аАаВаКаИ аОаБб€аАаЗаА аНаА бƒбб‚б€аОаЙбб‚аВаО. аžб‚аПб€аАаВаКаА аМаОаЖаЕб‚ аНаЕ аПаОаЛбƒб‡аИб‚бŒбб, аЕбаЛаИ аВб‹ аВаКаЛбŽб‡аИб‚аЕ бб‚аАаНб†аИбŽ, аКаОаГаДаА аКаАаБаЕаЛбŒ бƒаЖаЕ аПаОаДаКаЛбŽб‡б‘аНа”аОбб‚бƒаПаНаАб аНаОаВаАб аВаЕб€баИб аПб€аОаГб€аАаМаМб‹ CHIRP. аšаАаК аМаОаЖаНаО баКаОб€аЕаЕ аЗаАаГб€бƒаЗаИб‚аЕ аЕб‘ аНаА аВаЕаБ-баАаЙб‚аЕ!аž аПб€аОаГб€аАаМаМаЕаž аПб€аОаГб€аАаМаМаЕ CHIRPа’баЕа’баЕ б„аАаЙаЛб‹а’баЕ аПаОаДаДаЕб€аЖаИаВаАаЕаМб‹аЕ б„аОб€аМаАб‚б‹|а›бŽаБаИб‚аЕаЛбŒбаКаАб б€аАаДаИаОбаВбаЗбŒаžбˆаИаБаКаАаŸб€аИаМаЕаНаЕаНаИаЕ аПаАб€аАаМаЕб‚б€аОаВа”аОбб‚бƒаПаНб‹аЕ аМаОаДбƒаЛаИаЇаАбб‚аОб‚аНб‹аЙ аПаЛаАаНаŸаОаЛаОбб‹ б‡аАбб‚аОб‚а‘аАаНаКаИа‘аИаНаАб€аНб‹аЙа‘б€аАбƒаЗаЕб€а‘б€аАбƒаЗаЕб€ бб‚аАаНб†аИаЙаšаАаНаАаДаАа”аЛб аИаЗаМаЕаНаЕаНаИб бб‚аОаГаО аПаАб€аАаМаЕб‚б€аА б‚б€аЕаБбƒаЕб‚бб аОаБаНаОаВаИб‚бŒ аПаАб€аАаМаЕб‚б€б‹ аИаЗ аОаБб€аАаЗаА, б‡б‚аО аИ аБбƒаДаЕб‚ баЕаЙб‡аАб аВб‹аПаОаЛаНаЕаНаО.аšаАаНаАаЛб‹ б баКаВаИаВаАаЛаЕаНб‚аНб‹аМаИ TX аИ RX %s аПб€аЕаДбб‚аАаВаЛаЕаНб‹ аВаИаДаОаМ ббƒаБб‚аОаНаА ТЋ%sТЛ.аЄаАаЙаЛб‹ аОаБб€аАаЗаОаВ ChirpааЕаОаБб…аОаДаИаМаО баДаЕаЛаАб‚бŒ аВб‹аБаОб€а’б‹аБаЕб€аИб‚аЕ аКаОаД DTCS %sа’б‹аБаЕб€аИб‚аЕ б‚аОаН %sа’б‹аБаЕб€аИб‚аЕ аКб€аОбб-б€аЕаЖаИаМа’б‹аБаЕб€аИб‚аЕ аДбƒаПаЛаЕаКба’б‹аБаЕб€аИб‚аЕ аМаОаДбƒаЛбŒ аДаЛб аЗаАаГб€бƒаЗаКаИ аИаЗ аЗаАаДаАб‡аИ %i:а“аОб€аОаДааАаЖаМаИб‚аЕ аКаНаОаПаКбƒ-аПаЕб€аЕаКаЛбŽб‡аАб‚аЕаЛбŒ ТЋSpecial ChannelsТЛ б€аЕаДаАаКб‚аОб€аА бб‡аЕаЕаК аПаАаМбб‚аИ, б‡б‚аОаБб‹ аПб€аОбаМаОб‚б€аЕб‚бŒ/аЗаАаДаАб‚бŒ аКаАаНаАаЛб‹ EXT. аšаАаНаАаЛб‹ P-VFO 100-109 бб‡аИб‚аАбŽб‚бб аПаАб€аАаМаЕб‚б€аАаМаИ. а’ бб‚аОаЙ аВаЕб€баИаИ аПаОаДаДаЕб€аЖаИаВаАаЕб‚бб б‚аОаЛбŒаКаО б‡аАбб‚бŒ аИаЗ аБаОаЛаЕаЕ б‡аЕаМ 200 аДаОбб‚бƒаПаНб‹б… аПаАб€аАаМаЕб‚б€аОаВ бб‚аАаНб†аИаИ. а˜аГаНаОб€аИб€бƒаЙб‚аЕ аЗаВбƒаКаОаВб‹аЕ баИаГаНаАаЛб‹ аОб‚ бб‚аАаНб†аИаИ аПб€аИ аОб‚аПб€аАаВаКаЕ аИ аЗаАаГб€бƒаЗаКаЕ. аšаЛаОаНаИб€аОаВаАаНаИаЕ аЗаАаВаЕб€бˆаЕаНаО, аПб€аОаВаЕб€аКаА аНаАаЛаИб‡аИб аЛаОаЖаНб‹б… аБаАаЙб‚аОаВаšаЛаОаНаИб€аОаВаАаНаИаЕаšаЛаОаНаИб€аОаВаАаНаИаЕ аИаЗ бб‚аАаНб†аИаИаšаЛаОаНаИб€аОаВаАаНаИаЕ аНаА бб‚аАаНб†аИбŽа—аАаКб€б‹б‚бŒа—аАаКб€б‹б‚бŒ б„аАаЙаЛаšаОаМаМаЕаНб‚аАб€аИаЙаžаБаМаЕаН аДаАаНаНб‹аМаИ баО бб‚аАаНб†аИаЕаЙа—аАаВаЕб€бˆаЕаНаОаŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аК PC-аПаОб€б‚бƒ аНаА аЗаАаДаНаЕаЙ бб‚аОб€аОаНаЕ аМаОаДбƒаЛб ТЋTX/RXТЛ. аа• аК COM-аПаОб€б‚бƒ аНаА аГаОаЛаОаВаКаЕ. аšаОаПаИб€аОаВаАб‚бŒаЁб‚б€аАаНаАаŸаОаЛбŒаЗаОаВаАб‚аЕаЛбŒбаКаИаЙ аПаОб€б‚аŸаОаЛбŒаЗаОаВаАб‚аЕаЛбŒбаКаИаЙ...а’б‹б€аЕаЗаАб‚бŒDTCSаŸаОаЛбб€аНаОбб‚бŒ DTCSDV-аПаАаМбб‚бŒа’аПаЕб€аЕаДаИ аОаПаАбаНаОбб‚бŒа”аЕббб‚аИб‡аНб‹аЙаЃаДаАаЛаИб‚бŒа аЕаЖаИаМ б€аАаЗб€аАаБаОб‚б‡аИаКаАа аЕаЖаИаМ б€аАаЗб€аАаБаОб‚б‡аИаКаА б‚аЕаПаЕб€бŒ %s. а”аЛб аПб€аИаМаЕаНаЕаНаИб аИаЗаМаЕаНаЕаНаИаЙ аНаЕаОаБб…аОаДаИаМаО аПаЕб€аЕаЗаАаПбƒбб‚аИб‚бŒ CHIRPаЁб€аАаВаНаИб‚бŒ аНаЕаОаБб€аАаБаОб‚аАаНаНб‹аЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИаІаИб„б€аОаВаОаЙ аКаОаДаžб‚аКаЛбŽб‡аИб‚бŒ аОб‚аПб€аАаВаКбƒ аОб‚б‡б‘б‚аОаВаžб‚аКаЛбŽб‡аЕаНаОа аАббб‚аОбаНаИаЕааЕ аЗаАаПб€аАбˆаИаВаАб‚бŒ баНаОаВаА аДаЛб %sаЁаДаЕаЛаАаЙб‚аЕ аДаВаОаЙаНаОаЙ б‰аЕаЛб‡аОаК, б‡б‚аОаБб‹ аИаЗаМаЕаНаИб‚бŒ аИаМб аБаАаНаКаАа—аАаГб€бƒаЗаИб‚бŒа—аАаГб€бƒаЗаИб‚бŒ аИаЗ бб‚аАаНб†аИаИа—аАаГб€бƒаЗаИб‚бŒ аИаЗ бб‚аАаНб†аИаИ...а˜аНбб‚б€бƒаКб†аИаИ аПаО аЗаАаГб€бƒаЗаКаЕа”бƒаПаЛаЕаКба аЕаДаАаКб‚аИб€аОаВаАб‚бŒ баВаЕаДаЕаНаИб аО бб‡аЕаЙаКаАб… аПаАаМбб‚аИ (%i)а аЕаДаАаКб‚аИб€аОаВаАб‚бŒ баВаЕаДаЕаНаИб аО бб‡аЕаЙаКаЕ аПаАаМбб‚аИ (%i)а’аКаЛбŽб‡аИб‚бŒ аАаВб‚аОаМаАб‚аИб‡аЕбаКаОаЕ б€аЕаДаАаКб‚аИб€аОаВаАаНаИаЕа’аКаЛбŽб‡аЕаНаОа’аВаЕаДаИб‚аЕ б‡аАбб‚аОб‚бƒа’аВаЕаДаИб‚аЕ баМаЕб‰аЕаНаИаЕ (аœа“б†)а’аВаЕаДаИб‚аЕ б‡аАбб‚аОб‚бƒ TX (аœа“б†)а’аВаЕаДаИб‚аЕ аНаОаВаОаЕ аИаМб аБаАаНаКаА %s:а’аВаЕаДаИб‚аЕ аПаОаЛбŒаЗаОаВаАб‚аЕаЛбŒбаКаИаЙ аПаОб€б‚:аЁб‚б‘б€б‚аА бб‡аЕаЙаКаА аПаАаМбб‚аИ %sаžбˆаИаБаКаА аПб€аИаМаЕаНаЕаНаИб аПаАб€аАаМаЕб‚б€аОаВаžбˆаИаБаКаА аОаБаМаЕаНаА аДаАаНаНб‹аМаИ баО бб‚аАаНб†аИаЕаЙа­аКбаПаЕб€аИаМаЕаНб‚аАаЛбŒаНб‹аЙ аДб€аАаЙаВаЕб€аŸб€аИ баКбаПаОб€б‚аЕ аМаОаЖаНаО аВб‹аПаОаЛаНбб‚бŒ аЗаАаПаИббŒ б‚аОаЛбŒаКаО аВ б„аАаЙаЛб‹ CSVа­аКбаПаОб€б‚ аВ CSVа­аКбаПаОб€б‚ аВ CSV...а”аОаПаОаЛаНаИб‚аЕаЛбŒаНаОаЁа’аžа‘аžа”аааЏ аБаАаЗаА аДаАаНаНб‹б… б€аЕаПаИб‚аЕб€аОаВ, баОаДаЕб€аЖаАб‰аАб баАаМб‹аЕ аАаКб‚бƒаАаЛбŒаНб‹аЕ баВаЕаДаЕаНаИб аО б€аЕаПаИб‚аЕб€аАб… аВ а•аВб€аОаПаЕ. аЃб‡б‘б‚аНаАб аЗаАаПаИббŒ аНаЕ б‚б€аЕаБбƒаЕб‚бб.ааЕ бƒаДаАаЛаОббŒ аЗаАаГб€бƒаЗаИб‚бŒ аБб€аАбƒаЗаЕб€ бб‚аАаНб†аИаЙааЕ бƒаДаАаЛаОббŒ аПб€аОаАаНаАаЛаИаЗаИб€аОаВаАб‚бŒ б€аЕаЗбƒаЛбŒб‚аАб‚аЄбƒаНаКб†аИаИаЄаАаЙаЛ аНаЕ ббƒб‰аЕбб‚аВбƒаЕб‚: %sаЄаАаЙаЛб‹аЄаИаЛбŒб‚б€аЄаИаЛбŒб‚б€аОаВаАб‚бŒ б€аЕаЗбƒаЛбŒб‚аАб‚б‹ б б€аАбаПаОаЛаОаЖаЕаНаИаЕаМ, баОаОб‚аВаЕб‚бб‚аВбƒбŽб‰аИаМ бб‚аОаЙ бб‚б€аОаКаЕааАаЙб‚аИааАаЙб‚аИ аДаАаЛаЕаЕааАаЙб‚аИ...а—аАаВаЕб€бˆаЕаНаО аЗаАаДаАаНаИаЕ бб‚аАаНб†аИаИ %sаЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаГб€бƒаЗаИб‚бŒ аПаАаМбб‚бŒ бб‚аАаНб†аИаИ: 1 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 2 - аЁб‚аАаНб†аИб > а—аАаГб€бƒаЗаИб‚бŒ аИаЗ бб‚аАаНб†аИаИ: аа• б‚б€аОаГаАаЙб‚аЕ бб‚аАаНб†аИбŽ аВаО аВб€аЕаМб аЗаАаГб€бƒаЗаКаИ! 3 - аžб‚аКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаГб€бƒаЗаИб‚бŒ аПаАаМбб‚бŒ бб‚аАаНб†аИаИ: 1 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 2 - аЁб‚аАаНб†аИб > а—аАаГб€бƒаЗаИб‚бŒ аИаЗ бб‚аАаНб†аИаИ: аНаЕ аНаАбб‚б€аАаИаВаАаЙб‚аЕ б€аАаДаИаОаГаОаЛаОаВаКбƒ! 3 - аžб‚аКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаГб€бƒаЗаИб‚бŒ аВаАбˆбƒ аКаОаНб„аИаГбƒб€аАб†аИбŽ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аК б€аАаЗбŠаЕаМбƒ Speaker-2 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - аЁб‚аАаНб†аИб > а—аАаГб€бƒаЗаИб‚бŒ аИаЗ бб‚аАаНб†аИаИ 5 - аžб‚аКаЛбŽб‡аИб‚аЕ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ! а˜аНаАб‡аЕ б аПб€аАаВаОаЙ бб‚аОб€аОаНб‹ аНаЕ аБбƒаДаЕб‚ аЗаВбƒаКаА! аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаГб€бƒаЗаИб‚бŒ аВаАбˆбƒ аИаНб„аОб€аМаАб†аИбŽ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - а’б‹аПаОаЛаНаИб‚аЕ аЗаАаГб€бƒаЗаКбƒ аВаАбˆаИб… б€аАаДаИаОаДаАаНаНб‹б… аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаГб€бƒаЗаИб‚бŒ аДаАаНаНб‹аЕ аВаАбˆаЕаЙ бб‚аАаНб†аИаИ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ (б€аАаЗаБаЛаОаКаИб€бƒаЙб‚аЕ аЕб‘, аЕбаЛаИ аЕбб‚бŒ аЗаАб‰аИб‚аА аПаАб€аОаЛаЕаМ) 4 - аЇб‚аОаБб‹ аНаАб‡аАб‚бŒ, аНаАаЖаМаИб‚аЕ ТЋOKТЛ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аПб€аОб‡аИб‚аАб‚бŒ аДаАаНаНб‹аЕ аВаАбˆаЕаЙ бб‚аАаНб†аИаИ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - аЇб‚аОаБб‹ аНаАб‡аАб‚бŒ, аНаАаЖаМаИб‚аЕ ТЋOKТЛ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аОб‚аПб€аАаВаИб‚бŒ аПаАаМбб‚бŒ бб‚аАаНб†аИаИ: 1 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 2 - аЁб‚аАаНб†аИб > аžб‚аПб€аАаВаИб‚бŒ аНаА бб‚аАаНб†аИбŽ: аНаЕ б‚б€аОаГаАаЙб‚аЕ бб‚аАаНб†аИбŽ аВаО аВб€аЕаМб аОб‚аПб€аАаВаКаИ! 3 - аžб‚аКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аОб‚аПб€аАаВаИб‚бŒ аПаАаМбб‚бŒ бб‚аАаНб†аИаИ: 1 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 2 - аЁб‚аАаНб†аИб > аžб‚аПб€аАаВаИб‚бŒ аНаА бб‚аАаНб†аИбŽ: аНаЕ аНаАбб‚б€аАаИаВаАаЙб‚аЕ б€аАаДаИаОаГаОаЛаОаВаКбƒ! 3 - аžб‚аКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аОб‚аПб€аАаВаИб‚бŒ аВаАбˆбƒ аКаОаНб„аИаГбƒб€аАб†аИбŽ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аК б€аАаЗбŠаЕаМбƒ Speaker-2 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - аЁб‚аАаНб†аИб > аžб‚аПб€аАаВаИб‚бŒ аНаА бб‚аАаНб†аИбŽ 5 - аžб‚аКаЛбŽб‡аИб‚аЕ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ, аИаНаАб‡аЕ б аПб€аАаВаОаЙ бб‚аОб€аОаНб‹ аНаЕ аБбƒаДаЕб‚ аЗаВбƒаКаА! 6 - а’б‹аКаЛбŽб‡аИб‚аЕ аИ баНаОаВаА аВаКаЛбŽб‡аИб‚аЕ аПаИб‚аАаНаИаЕ бб‚аАаНб†аИаИ, б‡б‚аОаБб‹ аВб‹аЙб‚аИ аИаЗ б€аЕаЖаИаМаА аКаЛаОаНаИб€аОаВаАаНаИб аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аОб‚аПб€аАаВаИб‚бŒ аВаАбˆбƒ аИаНб„аОб€аМаАб†аИбŽ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - а’б‹аПаОаЛаНаИб‚аЕ аОб‚аПб€аАаВаКбƒ аВаАбˆаИб… б€аАаДаИаОаДаАаНаНб‹б… аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аОб‚аПб€аАаВаИб‚бŒ аДаАаНаНб‹аЕ аВаАбˆаЕаЙ бб‚аАаНб†аИаИ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ (б€аАаЗаБаЛаОаКаИб€бƒаЙб‚аЕ аЕб‘, аЕбаЛаИ аЕбб‚бŒ аЗаАб‰аИб‚аА аПаАб€аОаЛаЕаМ) 4 - аЇб‚аОаБб‹ аНаАб‡аАб‚бŒ, аНаАаЖаМаИб‚аЕ ТЋаžаšТЛ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаПаИбаАб‚бŒ аДаАаНаНб‹аЕ аВаАбˆаЕаЙ бб‚аАаНб†аИаИ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - аЇб‚аОаБб‹ аНаАб‡аАб‚бŒ, аНаАаЖаМаИб‚аЕ ТЋаžаšТЛ аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаГб€бƒаЗаИб‚бŒ аВаАбˆбƒ аИаНб„аОб€аМаАб†аИбŽ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - а’б‹аПаОаЛаНаИб‚аЕ аЗаАаГб€бƒаЗаКбƒ аВаАбˆаИб… б€аАаДаИаОаДаАаНаНб‹б… аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аПб€аОб‡аИб‚аАб‚бŒ аДаАаНаНб‹аЕ аВаАбˆаЕаЙ бб‚аАаНб†аИаИ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - а’б‹аПаОаЛаНаИб‚аЕ аЗаАаГб€бƒаЗаКбƒ аВаАбˆаИб… б€аАаДаИаОаДаАаНаНб‹б… аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аОб‚аПб€аАаВаИб‚бŒ аВаАбˆбƒ аИаНб„аОб€аМаАб†аИбŽ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - а’б‹аПаОаЛаНаИб‚аЕ аОб‚аПб€аАаВаКбƒ аВаАбˆаИб… б€аАаДаИаОаДаАаНаНб‹б… аЁаЛаЕаДбƒаЙб‚аЕ бб‚аИаМ аИаНбб‚б€бƒаКб†аИбаМ, б‡б‚аОаБб‹ аЗаАаПаИбаАб‚бŒ аДаАаНаНб‹аЕ аВаАбˆаЕаЙ бб‚аАаНб†аИаИ: 1 - а’б‹аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аВаАбˆ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ 3 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ 4 - а’б‹аПаОаЛаНаИб‚аЕ аОб‚аПб€аАаВаКбƒ аВаАбˆаИб… б€аАаДаИаОаДаАаНаНб‹б… ааАаЙаДаЕаНаО аЗаНаАб‡аЕаНаИаЕ аПбƒбб‚аОаГаО баПаИбаКаА аДаЛб %(name)s: %(value)rаЇаАбб‚аОб‚аАGMRSаŸаОаЛбƒб‡аЕаНаИаЕ аПаАб€аАаМаЕб‚б€аОаВаŸаЕб€аЕаЙб‚аИ аК бб‡аЕаЙаКаЕ аПаАаМбб‚аИаŸаЕб€аЕб…аОаД аК бб‡аЕаЙаКаЕ аПаАаМбб‚аИ:аŸаЕб€аЕб…аОаД...аЁаПб€аАаВаКаАаŸаОаМаОб‰бŒ...аЈаЕбб‚аНаАаДб†аАб‚аЕб€аИб‡аНб‹аЙаЁаКб€б‹б‚бŒ аПбƒбб‚б‹аЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИа•баЛаИ бƒбб‚аАаНаОаВаЛаЕаНаО, бƒаПаОб€баДаОб‡аИб‚бŒ б€аЕаЗбƒаЛбŒб‚аАб‚б‹ аПаО б€аАббб‚аОбаНаИбŽ аОб‚ бб‚аИб… аКаОаОб€аДаИаНаАб‚а˜аМаПаОб€б‚а˜аМаПаОб€б‚ аИаЗ б„аАаЙаЛаА...а˜аМаПаОб€б‚ аНаЕ б€аЕаКаОаМаЕаНаДбƒаЕб‚бба˜аНаДаЕаКба˜аНб„аОб€аМаАб†аИба˜аНб„аОб€аМаАб†аИба’бб‚аАаВаИб‚бŒ бб‚б€аОаКбƒ аВб‹бˆаЕаЁаОаЗаДаАб‚бŒ аЗаНаАб‡аОаК аНаА б€аАаБаОб‡аЕаМ бб‚аОаЛаЕ?аžаБаМаЕаН аДаАаНаНб‹аМаИ б аДб€аАаЙаВаЕб€аОаМ%(value)s т€” аНаЕаВаЕб€аНаО (аИбаПаОаЛбŒаЗбƒаЙб‚аЕ аДаЕббб‚аИб‡аНб‹аЕ аГб€аАаДбƒбб‹)ааЕаКаОб€б€аЕаКб‚аНаАб аЗаАаПаИббŒааЕаВаЕб€аНб‹аЙ аПаОб‡б‚аОаВб‹аЙ аИаНаДаЕаКбааЕаКаОб€б€аЕаКб‚аНаОаЕ аИаЗаМаЕаНаЕаНаИаЕ: %sааЕаКаОб€б€аЕаКб‚аНб‹аЙ аИаЛаИ аНаЕаПаОаДаДаЕб€аЖаИаВаАаЕаМб‹аЙ б„аАаЙаЛ аМаОаДбƒаЛбааЕаВаЕб€аНаОаЕ аЗаНаАб‡аЕаНаИаЕ: %rааОаМаЕб€ аЗаАаДаАб‡аИ:а’ а­аЄа˜а а•аЈаИб€аОб‚аАа”аЛаИаНаА аДаОаЛаЖаНаА баОбб‚аАаВаЛбб‚бŒ %iаžаГб€аАаНаИб‡аЕаНаИаЕ аПаОаЛаОб б‡аАбб‚аОб‚аžаГб€аАаНаИб‡аЕаНаИаЕ б€аЕаЖаИаМаОаВаžаГб€аАаНаИб‡аЕаНаИаЕ баОбб‚аОбаНаИбаžаГб€аАаНаИб‡аИб‚бŒ б€аЕаЗбƒаЛбŒб‚аАб‚б‹ бб‚аИаМ б€аАббб‚аОбаНаИаЕаМ (аКаМ) аОб‚ аКаОаОб€аДаИаНаАб‚а—аАаГб€бƒаЗаИб‚бŒ аМаОаДбƒаЛбŒ...а—аАаГб€бƒаЗаИб‚бŒ аМаОаДбƒаЛбŒ аИаЗ аЗаАаДаАб‡аИа—аАаГб€бƒаЗаИб‚бŒ аМаОаДбƒаЛбŒ аИаЗ аЗаАаДаАб‡аИ...а—аАаГб€бƒаЗаКаА аМаОаДбƒаЛаЕаЙ аМаОаЖаЕб‚ аПб€аЕаДбб‚аАаВаЛбб‚бŒ аОаПаАбаНаОбб‚бŒ аДаЛб аВаАбˆаЕаГаО аКаОаМаПбŒбŽб‚аЕб€аА аИ/аИаЛаИ бб‚аАаНб†аИаИ. аа˜аšаžа“а”а аНаЕ аЗаАаГб€бƒаЖаАаЙб‚аЕ аМаОаДбƒаЛбŒ аИаЗ аИбб‚аОб‡аНаИаКаА, аКаОб‚аОб€аОаМбƒ аВб‹ аНаЕ аДаОаВаЕб€баЕб‚аЕ, аВ аОбаОаБаЕаНаНаОбб‚аИ т€” аИаЗ аЛбŽаБаОаГаО аИбб‚аОб‡аНаИаКаА, аОб‚аЛаИб‡аНаОаГаО аОб‚ аОбаНаОаВаНаОаГаО аВаЕаБ-баАаЙб‚аА CHIRP (chirp.danplanet.com). а—аАаГб€бƒаЗаИб‚бŒ аМаОаДбƒаЛбŒ аИаЗ аДб€бƒаГаОаГаО аИбб‚аОб‡аНаИаКаА т€” аВбб‘ б€аАаВаНаО б‡б‚аО аПб€аЕаДаОбб‚аАаВаИб‚бŒ аПб€баМаОаЙ аДаОбб‚бƒаП аК баВаОаЕаМбƒ аКаОаМаПбŒбŽб‚аЕб€бƒ аИ аВбаЕаМбƒ аНаА аНб‘аМ! аŸб€аОаДаОаЛаЖаИб‚бŒ аНаЕбаМаОб‚б€б аНаА бб‚аОб‚ б€аИбаК?а—аАаГб€бƒаЗаКаА аПаАб€аАаМаЕб‚б€аОаВа”аОаЛаГаОб‚аАаЏб‡аЕаЙаКаИ аПаАаМбб‚аИаЏб‡аЕаЙаКбƒ аПаАаМбб‚аИ %i аНаЕаЛбŒаЗб бƒаДаАаЛаИб‚бŒаЇб‚аОаБб‹ б€аЕаДаАаКб‚аИб€аОаВаАб‚бŒ бб‡аЕаЙаКбƒ аПаАаМбб‚аИ, аНаЕаОаБб…аОаДаИаМаО аПаОаМаЕбб‚аИб‚бŒ аЕб‘ аВ аБаАаНаКаЏб‡аЕаЙаКаА аПаАаМбб‚аИ {num} аОб‚ббƒб‚бб‚аВбƒаЕб‚ аВ аБаАаНаКаЕ {bank}а аЕаЖаИаМаœаОаДаЕаЛбŒа аЕаЖаИаМб‹аœаОаДбƒаЛбŒаœаОаДбƒаЛбŒ аЗаАаГб€бƒаЖаЕаНаœаОаДбƒаЛбŒ бƒбаПаЕбˆаНаО аЗаАаГб€бƒаЖаЕаНааАаЙаДаЕаНаО аБаОаЛаЕаЕ аОаДаНаОаГаО аПаОб€б‚аА: %sаŸаЕб€аЕаМаЕбб‚аИб‚бŒ аВаНаИаЗаŸаЕб€аЕаМаЕбб‚аИб‚бŒ аВаВаЕб€б…ааОаВаОаЕ аОаКаНаОа”аОбб‚бƒаПаНаА аНаОаВаАб аВаЕб€баИбааИаЖаЕ аНаЕб‚ аПбƒбб‚б‹б… бб‚б€аОаК!аœаОаДбƒаЛаИ аНаЕ аНаАаЙаДаЕаНб‹а’ аЗаАаДаАб‡аЕ %i аНаЕ аНаАаЙаДаЕаНб‹ аМаОаДбƒаЛаИааЕб‚ б€аЕаЗбƒаЛбŒб‚аАб‚аОаВааЕб‚ б€аЕаЗбƒаЛбŒб‚аАб‚аОаВ!аЇаИбаЛаОаЁаМаЕб‰аЕаНаИаЕаЂаОаЛбŒаКаО аНаЕаКаОб‚аОб€б‹аЕ аПаОаЛаОбб‹ б‡аАбб‚аОб‚аЂаОаЛбŒаКаО аНаЕаКаОб‚аОб€б‹аЕ б€аЕаЖаИаМб‹аœаОаЖаНаО баКбаПаОб€б‚аИб€аОаВаАб‚бŒ б‚аОаЛбŒаКаО аВаКаЛаАаДаКаИ аПаАаМбб‚аИаЂаОаЛбŒаКаО б€аАаБаОб‚аАбŽб‰аИаЕ б€аЕаПаИб‚аЕб€б‹аžб‚аКб€б‹б‚бŒаžб‚аКб€б‹б‚бŒ аНаЕаДаАаВаНаИаЕаžб‚аКб€б‹б‚бŒ аПб€аЕаДбƒбб‚аАаНаОаВаЛаЕаНаНбƒбŽ аКаОаНб„аИаГбƒб€аАб†аИбŽаžб‚аКб€б‹б‚бŒ б„аАаЙаЛаžб‚аКб€б‹б‚бŒ аМаОаДбƒаЛбŒаžб‚аКб€б‹б‚бŒ аЖбƒб€аНаАаЛ аОб‚аЛаАаДаКаИаžб‚аКб€б‹б‚бŒ аВ аНаОаВаОаМ аОаКаНаЕаžб‚аКб€б‹б‚бŒ аКаАб‚аАаЛаОаГ аПб€аЕаДбƒбб‚аАаНаОаВаЛаЕаНаНаОаЙ аКаОаНб„аИаГбƒб€аАб†аИаИаžаПб†аИаОаНаАаЛбŒаНаО: -122.0000аžаПб†аИаОаНаАаЛбŒаНаО: 100аžаПб†аИаОаНаАаЛбŒаНаО: 45.0000аžаПб†аИаОаНаАаЛбŒаНаО: аОаКб€бƒаГ, аБаОаЛбŒаНаИб†аА аИ б‚.аД.аŸаЕб€аЕаЗаАаПаИбаАб‚бŒ бб‡аЕаЙаКаИ аПаАаМбб‚аИ?аšаАаНаАаЛб‹ P-VFO 100-109 бб‡аИб‚аАбŽб‚бб аПаАб€аАаМаЕб‚б€аАаМаИ. а’ бб‚аОаЙ аВаЕб€баИаИ аПаОаДаДаЕб€аЖаИаВаАаЕб‚бб б‚аОаЛбŒаКаО б‡аАбб‚бŒ аИаЗ аБаОаЛаЕаЕ б‡аЕаМ 130 аДаОбб‚бƒаПаНб‹б… аПаАб€аАаМаЕб‚б€аОаВ бб‚аАаНб†аИаИ. ааНаАаЛаИаЗа’бб‚аАаВаИб‚бŒа’бб‚аАаВаЛаЕаНаНб‹аЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аПаЕб€аЕаЗаАаПаИбˆбƒб‚ ббƒб‰аЕбб‚аВбƒбŽб‰аИаЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИ (%s)а’бб‚аАаВаЛаЕаНаНб‹аЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аПаЕб€аЕаЗаАаПаИбˆбƒб‚ бб‡аЕаЙаКаИ аПаАаМбб‚аИ (%s)а’бб‚аАаВаЛаЕаНаНб‹аЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аПаЕб€аЕаЗаАаПаИбˆбƒб‚ бб‡аЕаЙаКбƒ аПаАаМбб‚аИ %sа’бб‚аАаВаЛаЕаНаНаАб бб‡аЕаЙаКаА аПаАаМбб‚аИ аПаЕб€аЕаЗаАаПаИбˆаЕб‚ бб‡аЕаЙаКбƒ аПаАаМбб‚аИ %sаžаБбаЗаАб‚аЕаЛбŒаНаО аВб‹аЙаДаИб‚аЕ аИаЗ аПб€аОаГб€аАаМаМб‹ CHIRP аПаЕб€аЕаД бƒбб‚аАаНаОаВаКаОаЙ аНаОаВаОаЙ аВаЕб€баИаИ!а’б‹аПаОаЛаНаИб‚аЕ баЛаЕаДбƒбŽб‰аИаЕ аДаЕаЙбб‚аВаИб: 1 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ. 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аК аВаАбˆаЕаЙ бб‚аАаНб†аИаИ. 3 - ааАаЖаМаИб‚аЕ аКаНаОаПаКбƒ аВ бб‚аОаМ аОаКаНаЕ аДаЛб аНаАб‡аАаЛаА аЗаАаГб€бƒаЗаКаИ. (аМаОаЖаЕб‚ аПаОбаВаИб‚бб аДб€бƒаГаОаЙ аДаИаАаЛаОаГ, аНаАаЖаМаИб‚аЕ ТЋаžаšТЛ). 4 - аЁб‚аАаНб†аИб аПаОаДаАбб‚ аЗаВбƒаКаОаВаОаЙ баИаГаНаАаЛ, баВаЕб‚аОаДаИаОаД аЗаАаМаИаГаАаЕб‚. 5 - аЃ аВаАб аБбƒаДаЕб‚ 10 баЕаКбƒаНаД аДаЛб б‚аОаГаО, б‡б‚аОаБб‹ аНаАаЖаАб‚бŒ ТЋMONТЛ аПаЕб€аЕаД аНаАб‡аАаЛаОаМ аОб‚аПб€аАаВаКаИ аДаАаНаНб‹б…. 6 - а•баЛаИ аВбб‘ аПб€аОаЙаДб‘б‚ б…аОб€аОбˆаО, аПаО аЗаАаВаЕб€бˆаЕаНаИаИ бб‚аАаНб†аИб аПаОаДаАбб‚ аЗаВбƒаКаОаВаОаЙ баИаГаНаАаЛ. аŸаОбаЛаЕ аВб‹аПаОаЛаНаЕаНаИб аКаЛаОаНаИб€аОаВаАаНаИб бƒаБаЕб€аИб‚аЕ аКаАаБаЕаЛбŒ аИ аВб‹аКаЛбŽб‡аИб‚аЕ аИ баНаОаВаА аВаКаЛбŽб‡аИб‚аЕ аПаИб‚аАаНаИаЕ бб‚аАаНб†аИаИ аДаЛб аПаЕб€аЕб…аОаДаА аВ аОаБб‹б‡аНб‹аЙ б€аЕаЖаИаМ. а’б‹аПаОаЛаНаИб‚аЕ баЛаЕаДбƒбŽб‰аИаЕ аДаЕаЙбб‚аВаИб: 1 - а’аКаЛбŽб‡аИб‚аЕ аВаАбˆбƒ бб‚аАаНб†аИбŽ. 2 - аŸаОаДаКаЛбŽб‡аИб‚аЕ аИаНб‚аЕб€б„аЕаЙбаНб‹аЙ аКаАаБаЕаЛбŒ аК аВаАбˆаЕаЙ бб‚аАаНб†аИаИ. 3 - ааАаЖаМаИб‚аЕ аКаНаОаПаКбƒ аВ бб‚аОаМ аОаКаНаЕ аДаЛб аНаАб‡аАаЛаА аЗаАаГб€бƒаЗаКаИ. (аЁб‚аАаНб†аИб аПаОаДаАбб‚ аЗаВбƒаКаОаВаОаЙ баИаГаНаАаЛ, баВаЕб‚аОаДаИаОаД аЗаАаМаИаГаАаЕб‚.) 4 - а—аАб‚аЕаМ аНаАаЖаМаИб‚аЕ аКаНаОаПаКбƒ ТЋAТЛ аНаА аВаАбˆаЕаЙ бб‚аАаНб†аИаИ аДаЛб аНаАб‡аАаЛаА аКаЛаОаНаИб€аОаВаАаНаИб. (аŸаО аЗаАаВаЕб€бˆаЕаНаИаИ бб‚аАаНб†аИб аПаОаДаАбб‚ аЗаВбƒаКаОаВаОаЙ баИаГаНаАаЛ.) аžаБб€аАб‚аИб‚аЕ аВаНаИаМаАаНаИаЕ, б‡б‚аО б€аЕаЖаИаМ б€аАаЗб€аАаБаОб‚б‡аИаКаА аПб€аЕаДаНаАаЗаНаАб‡аЕаН аДаЛб аИбаПаОаЛбŒаЗаОаВаАаНаИб б€аАаЗб€аАаБаОб‚б‡аИаКаАаМаИ аПб€аОаЕаКб‚аА CHIRP аИаЛаИ аПаОаД б€бƒаКаОаВаОаДбб‚аВаОаМ б€аАаЗб€аАаБаОб‚б‡аИаКаА. а’ бб‚аОаМ б€аЕаЖаИаМаЕ аВаКаЛбŽб‡аАбŽб‚бб аПаОаВаЕаДаЕаНаИаЕ аИ б„бƒаНаКб†аИаИ, аКаОб‚аОб€б‹аЕ баЛаЕаДбƒаЕб‚ аИбаПаОаЛбŒаЗаОаВаАб‚бŒ аšа аа™аа• аОбб‚аОб€аОаЖаНаО, б‡б‚аОаБб‹ аНаЕ аНаАаВб€аЕаДаИб‚бŒ аВаАбˆаЕаМбƒ аКаОаМаПбŒбŽб‚аЕб€бƒ аИ аВаАбˆаЕаЙ бб‚аАаНб†аИаИ. а’б‹ аБб‹аЛаИ аПб€аЕаДбƒаПб€аЕаЖаДаЕаНб‹. а’бб‘ б€аАаВаНаО аПб€аОаДаОаЛаЖаИб‚бŒ?аŸаОаДаОаЖаДаИб‚аЕаŸаОаДаКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ аИ аНаАаЖаМаИб‚аЕ ТЋаžаšТЛаŸаОб€б‚аœаОб‰аНаОбб‚бŒааАаЖаМаИб‚аЕ ТЋа’аВаОаДТЛ аДаЛб аДаОаБаАаВаЛаЕаНаИб аВ аПаАаМбб‚бŒаŸб€аЕаДаПб€аОбаМаОб‚б€аŸаЕб‡аАб‚бŒаЁаВаОаЙбб‚аВаАа—аАаПб€аОб %sа—аАаПб€аОб аИбб‚аОб‡аНаИаКаАDTCS RXаЁб‚аАаНб†аИбаЁб‚аАаНб†аИб аНаЕ б€аАбаПаОаЗаНаАаЛаА аБаЛаОаК %iа˜аНб„аОб€аМаАб†аИб аО бб‚аАаНб†аИаИаЁб‚аАаНб†аИб аОб‚аПб€аАаВаИаЛаА аДаАаНаНб‹аЕ аПаОбаЛаЕ аПаОбаЛаЕаДаНаЕаГаО аОаЖаИаДаАаЕаМаОаГаО аБаЛаОаКаА; бб‚аО аПб€аОаИбб…аОаДаИб‚, аКаОаГаДаА аВб‹аБб€аАаНаНаАб аМаОаДаЕаЛбŒ аНаЕ баВаЛбаЕб‚бб аАаМаЕб€аИаКаАаНбаКаОаЙ, аА бб‚аАаНб†аИб баВаЛбаЕб‚бб. а’б‹аБаЕб€аИб‚аЕ аПб€аАаВаИаЛбŒаНбƒбŽ аМаОаДаЕаЛбŒ аИ аПаОаВб‚аОб€аИб‚аЕ аПаОаПб‹б‚аКбƒ.RadioReference Canada аЗаАаПб€аАбˆаИаВаАаЕб‚ аВб…аОаД аПаЕб€аЕаД аВб‹аПаОаЛаНаЕаНаИаЕаМ аЗаАаПб€аОбаАаЂб€аЕаБбƒаЕб‚бб аОаБаНаОаВаЛаЕаНаИаЕаžаБаНаОаВаЛаЕаНаА бб‡аЕаЙаКаИ аПаАаМбб‚аИ %sаŸаЕб€аЕаЗаАаГб€бƒаЗаИб‚бŒ аДб€аАаЙаВаЕб€аŸаЕб€аЕаЗаАаГб€бƒаЗаИб‚бŒ аДб€аАаЙаВаЕб€ аИ б„аАаЙаЛаŸаЕб€аЕаИаМаЕаНаОаВаАб‚бŒ аБаАаНаКаžб‚аПб€аАаВаКаА аОб‚б‡б‘б‚аОаВ аВаКаЛбŽб‡аЕаНаАаžб‚аПб€аАаВаКаА аОб‚б‡б‘б‚аОаВ аПаОаМаОаГаАаЕб‚ аПб€аОаЕаКб‚бƒ CHIRP аПаОаЛбƒб‡аАб‚бŒ аИаНб„аОб€аМаАб†аИбŽ аО б‚аОаМ, аКаАаКаИаЕ аМаОаДаЕаЛаИ бб‚аАаНб†аИаЙ аИ аПаЛаАб‚б„аОб€аМб‹ аžаЁ б‚б€аЕаБбƒбŽб‚ аНаАбˆаЕаГаО аВаНаИаМаАаНаИб. аœб‹ аБбƒаДаЕаМ аОб‡аЕаНбŒ аПб€аИаЗаНаАб‚аЕаЛбŒаНб‹, аЕбаЛаИ аВб‹ аОбб‚аАаВаИб‚аЕ бб‚бƒ б„бƒаНаКб†аИбŽ аВаКаЛбŽб‡б‘аНаНаОаЙ. а”аЕаЙбб‚аВаИб‚аЕаЛбŒаНаО аОб‚аКаЛбŽб‡аИб‚бŒ аОб‚аПб€аАаВаКбƒ аОб‚б‡б‘б‚аОаВ?аЂб€аЕаБбƒаЕб‚бб аПаЕб€аЕаЗаАаПбƒбаКаŸаОаЛбƒб‡аЕаНаНб‹аЕ аПаАб€аАаМаЕб‚б€б‹аЁаОб…б€аАаНаИб‚бŒаЁаОб…б€аАаНаИб‚бŒ аПаЕб€аЕаД аЗаАаКб€б‹б‚аИаЕаМ?аЁаОб…б€аАаНаИб‚бŒ б„аАаЙаЛаЁаОб…б€аАаНб‘аНаНб‹аЕ аПаАб€аАаМаЕб‚б€б‹аЃаГб€аОаЗаА аБаЕаЗаОаПаАбаНаОбб‚аИа’б‹аБб€аАб‚бŒ б‡аАбб‚аОб‚аНб‹аЙ аПаЛаАаН...а’б‹аБаОб€ аПаОаЛаОб б‡аАбб‚аОб‚а’б‹аБаОб€ б€аЕаЖаИаМаОаВа’б‹аБаОб€ б‡аАбб‚аОб‚аНаОаГаО аПаЛаАаНаАаЁаЛбƒаЖаБаАаŸаАб€аАаМаЕб‚б€б‹аŸаОаКаАаЗаАб‚бŒ аНаЕаОаБб€аАаБаОб‚аАаНаНбƒбŽ бб‡аЕаЙаКбƒ аПаАаМбб‚аИаŸаОаКаАаЗаАб‚бŒ б€аАбаПаОаЛаОаЖаЕаНаИаЕ аЖбƒб€аНаАаЛаА аОб‚аЛаАаДаКаИаŸаОаКаАаЗаАб‚бŒ аДаОаПаОаЛаНаИб‚аЕаЛбŒаНб‹аЕ аПаОаЛбааЕаКаОб‚аОб€б‹аЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аНаЕбаОаВаМаЕбб‚аИаМб‹ б бб‚аОаЙ бб‚аАаНб†аИаЕаЙааЕаКаОб‚аОб€б‹аЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аНаЕаЛбŒаЗб бƒаДаАаЛаИб‚бŒаЁаОб€б‚аИб€аОаВаАб‚бŒ аПаО бб‚аОаЛаБб†бƒ:аЃаПаОб€баДаОб‡аИб‚бŒ бб‡аЕаЙаКаИ аПаАаМбб‚аИаЁаОб€б‚аИб€аОаВаКаАаžаБаЛаАбб‚бŒаžаБаЛаАбб‚бŒ/б€аЕаГаИаОаНаЃбаПаЕбˆаНаОа”б€аАаЙаВаЕб€ X3Plus баВаЛбаЕб‚бб баКбаПаЕб€аИаМаЕаНб‚аАаЛбŒаНб‹аМ. а˜аЗаВаЕбб‚аНб‹б… аОбˆаИаБаОаК аНаЕб‚, аНаО баЛаЕаДбƒаЕб‚ аДаЕаЙбб‚аВаОаВаАб‚бŒ аОбаМаОб‚б€аИб‚аЕаЛбŒаНаО. аЁаОб…б€аАаНаИб‚аЕ аНаЕб€аЕаДаАаКб‚аИб€аОаВаАаНаНбƒбŽ аКаОаПаИбŽ аПаЕб€аВаОаЙ бƒбаПаЕбˆаНаОаЙ аЗаАаГб€бƒаЗаКаИ аВ б„аАаЙаЛ CHIRP Radio Images (*.img). ааВб‚аОб€аА бб‚аОаГаО аМаОаДбƒаЛб аНаЕб‚ бб€аЕаДаИ б€аАаЗб€аАаБаОб‚б‡аИаКаОаВ CHIRP. а аЕаКаОаМаЕаНаДбƒаЕб‚бб аНаЕ аЗаАаГб€бƒаЖаАб‚бŒ бб‚аОб‚ аМаОаДбƒаЛбŒ, б‚аАаК аКаАаК аВаОаЗаМаОаЖаНаА бƒаГб€аОаЗаА аБаЕаЗаОаПаАбаНаОбб‚аИ. а’бб‘ б€аАаВаНаО аПб€аОаДаОаЛаЖаИб‚бŒ?а аЕаКаОаМаЕаНаДбƒаЕаМаАб аПб€аОб†аЕаДбƒб€аА аИаМаПаОб€б‚аА бб‡аЕаЕаК аПаАаМбб‚аИ: аОб‚аКб€б‹б‚бŒ аИбб…аОаДаНб‹аЙ б„аАаЙаЛ аИ баКаОаПаИб€аОаВаАб‚бŒ/аВбб‚аАаВаИб‚бŒ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аИаЗ аНаЕаГаО аВ аВаАбˆ б†аЕаЛаЕаВаОаЙ аОаБб€аАаЗ. а•баЛаИ аПб€аОаДаОаЛаЖаИб‚бŒ б€аАаБаОб‚бƒ б бб‚аОаЙ б„бƒаНаКб†аИаЕаЙ аИаМаПаОб€б‚аА, CHIRP аЗаАаМаЕаНаИб‚ аВбаЕ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аВ б‚аЕаКбƒб‰аЕаМ аОб‚аКб€б‹б‚аОаМ б„аАаЙаЛаЕ аНаА бб‡аЕаЙаКаИ аИаЗ %(file)s. аžб‚аКб€б‹б‚бŒ бб‚аОб‚ б„аАаЙаЛ аДаЛб аКаОаПаИб€аОаВаАаНаИб/аВбб‚аАаВаКаИ бб‡аЕаЕаК аПаАаМбб‚аИ аИаЛаИ аПб€аОаДаОаЛаЖаИб‚бŒ аИаМаПаОб€б‚?а­б‚аА бб‡аЕаЙаКаА аПаАаМбб‚аИа­б‚аОб‚ аДб€аАаЙаВаЕб€ аБб‹аЛ аПб€аОб‚аЕбб‚аИб€аОаВаАаН б ID-5100 v3. а•баЛаИ аВаАбˆаА бб‚аАаНб†аИб аОаБаНаОаВаЛаЕаНаА аНаЕ аПаОаЛаНаОбб‚бŒбŽ, баОаЗаДаАаЙб‚аЕ аОб‚б‡б‘б‚ аОаБ аОбˆаИаБаКаЕ аИ аПб€аИаЛаОаЖаИб‚аЕ аК аНаЕаМбƒ аЖбƒб€аНаАаЛ аОб‚аЛаАаДаКаИ, б‡б‚аОаБб‹ аМб‹ аМаОаГаЛаИ аДаОаБаАаВаИб‚бŒ баОаОб‚аВаЕб‚бб‚аВбƒбŽб‰бƒбŽ аПаОаДаДаЕб€аЖаКбƒ аДаЛб аДб€бƒаГаИб… аВаЕб€баИаЙ.а­б‚аО б€аАаНаНбб аБаЕб‚аА-аВаЕб€баИб аДб€аАаЙаВаЕб€аА а­б‚аО б€аАаНаНбб аБаЕб‚аА-аВаЕб€баИб аДб€аАаЙаВаЕб€аА т€” аОб‚аПб€аАаВаЛбаЙб‚аЕ аНаА баВаОаЙ бб‚б€аАб… аИ б€аИбаК а­б‚аО баКбаПаЕб€аИаМаЕаНб‚аАаЛбŒаНаАб аПаОаДаДаЕб€аЖаКаА аДаЛб BJ-9900, аОаНаА аВбб‘ аЕб‰б‘ аВ б€аАаЗб€аАаБаОб‚аКаЕ. аžаБбаЗаАб‚аЕаЛбŒаНаО баДаЕаЛаАаЙб‚аЕ б€аЕаЗаЕб€аВаНбƒбŽ аКаОаПаИбŽ б аПаОаМаОб‰бŒбŽ OEM-аПб€аОаГб€аАаМаМб‹. аЂаАаКаЖаЕ аПб€аИбб‹аЛаАаЙб‚аЕ аОб‚б‡б‘б‚б‹ аОаБ аОбˆаИаБаКаАб… аИ аПб€аЕаДаЛаОаЖаЕаНаИб аПаО бƒаЛбƒб‡бˆаЕаНаИбŽ. а’б‹ аБб‹аЛаИ аПб€аЕаДбƒаПб€аЕаЖаДаЕаНб‹; аПб€аОаДаОаЛаЖаАаЙб‚аЕ аНаА баВаОаЙ бб‚б€аАб… аИ б€аИбаК!а­б‚аА бб‡аЕаЙаКаА аПаАаМбб‚аИ аИ баДаВаИаНбƒб‚бŒ аВбаЕ аВаВаЕб€б…а­б‚аА бб‡аЕаЙаКаА аПаАаМбб‚аИ аИ баДаВаИаНбƒб‚бŒ аБаЛаОаК аВаВаЕб€б…ааА бб‚аОаЙ бб‚аАаНб†аИаИ баЛаОаЖаНаО аВаОаЙб‚аИ аВ б€аЕаЖаИаМ аПб€аОаГб€аАаМаМаИб€аОаВаАаНаИб, аНбƒаЖаНаО аНаЕбаКаОаЛбŒаКаО аПаОаПб‹б‚аОаК аДаАаЖаЕ аПб€аИ аИбаПаОаЛбŒаЗаОаВаАаНаИаИ аОб€аИаГаИаНаАаЛбŒаНаОаГаО аŸаž. аŸаОаПб€аОаБбƒаЙб‚аЕ 8 б€аАаЗ (аВ аБаОаЛбŒбˆаИаНбб‚аВаЕ баЛбƒб‡аАаЕаВ аДаОбб‚аАб‚аОб‡аНаО ~3 б€аАаЗ). а’б…аОаД аМаОаЖаЕб‚ аЗаАаНбб‚бŒ аНаЕбаКаОаЛбŒаКаО баЕаКбƒаНаД. а•баЛаИ аНаЕ аПаОаЛбƒб‡аАаЕб‚бб, баДаЕаЛаАаЙб‚аЕ аЕб‰б‘ аНаЕбаКаОаЛбŒаКаО аПаОаПб‹б‚аОаК. а•баЛаИ бƒаДаАаЛаОббŒ аВаОаЙб‚аИ, аПб€аОаВаЕб€бŒб‚аЕ бб‚аАаНб†аИбŽ аИ аКаАаБаЕаЛбŒ. а­б‚бƒ аОаПб†аИбŽ баЛаЕаДбƒаЕб‚ аВаКаЛбŽб‡аАб‚бŒ б‚аОаЛбŒаКаО аВ б‚аОаМ баЛбƒб‡аАаЕ, аЕбаЛаИ аВб‹ аИбаПаОаЛбŒаЗбƒаЕб‚аЕ аМаОаДаИб„аИб†аИб€аОаВаАаНаНбƒбŽ аМаИаКб€аОаПб€аОаГб€аАаМаМбƒ, аКаОб‚аОб€аАб аПаОаДаДаЕб€аЖаИаВаАаЕб‚ аБаОаЛаЕаЕ бˆаИб€аОаКаИаЙ аДаИаАаПаАаЗаОаН б‡аАбб‚аОб‚. а•баЛаИ аВаКаЛбŽб‡аИб‚бŒ бб‚бƒ аОаПб†аИбŽ, CHIRP аНаЕ аБбƒаДаЕб‚ аПб€аИаМаЕаНбб‚бŒ OEM-аОаГб€аАаНаИб‡аЕаНаИб, б‡б‚аО аМаОаЖаЕб‚ аПб€аИаВаЕбб‚аИ аК аНаЕаОаПб€аЕаДаЕаЛб‘аНаНаОаМбƒ аИаЛаИ аНаЕб€аЕаГбƒаЛаИб€бƒаЕаМаОаМбƒ аПаОаВаЕаДаЕаНаИбŽ. а˜баПаОаЛбŒаЗбƒаЙб‚аЕ аНаА баВаОаЙ бб‚б€аАб… аИ б€аИбаК!а‘бƒаДаЕб‚ аВб‹аПаОаЛаНаЕаНаА аЗаАаГб€бƒаЗаКаА аМаОаДбƒаЛб аИаЗ аЗаАаДаАб‡аИ аНаА аВаЕаБ-баАаЙб‚аЕаЂаОаНаŸа а”а’аИаД ббƒаБб‚аОаНаАаЂаОаНаЈаŸа”аЈаАаГ аНаАбб‚б€аОаЙаКаИаŸаОаИбаК USB-аПаОб€б‚аОаВааЕ бƒаДаАаЛаОббŒ аОаПб€аЕаДаЕаЛаИб‚бŒ аПаОб€б‚ аДаЛб аВаАбˆаЕаГаО аКаАаБаЕаЛб. аŸб€аОаВаЕб€бŒб‚аЕ аДб€аАаЙаВаЕб€б‹ аИ аПаОаДаКаЛбŽб‡аЕаНаИб.аŸаЕб€аЕаД б€аЕаДаАаКб‚аИб€аОаВаАаНаИаЕаМ бб‡аЕаЙаКаИ аПаАаМбб‚аИ аНаЕаОаБб…аОаДаИаМаО аЗаАаГб€бƒаЗаИб‚бŒ бб‚аАаНб†аИбŽааЕ бƒаДаАаЛаОббŒ аНаАаЙб‚аИ аПб€аЕаДбƒбб‚аАаНаОаВаЛаЕаНаНбƒбŽ аКаОаНб„аИаГбƒб€аАб†аИбŽ %rааЕ бƒаДаАаЛаОббŒ аОб‚аКб€б‹б‚бŒ аБбƒб„аЕб€ аОаБаМаЕаНаАааЕ бƒаДаАаЛаОббŒ аВб‹аПаОаЛаНаИб‚бŒ аЗаАаПб€аОбааЕаВаОаЗаМаОаЖаНаО аПб€аОб‡аИб‚аАб‚бŒ аПаОбаЛаЕаДаНаИаЙ аБаЛаОаК. а­б‚аО б‡аАбб‚аО баЛбƒб‡аАаЕб‚бб, аКаОаГаДаА аВб‹аБб€аАаНаА аАаМаЕб€аИаКаАаНбаКаАб аМаОаДаЕаЛбŒ, аНаО бб‚аАаНб†аИб аНаЕ баВаЛбаЕб‚бб аАаМаЕб€аИаКаАаНбаКаОаЙ (аИаЛаИ бˆаИб€аОаКаОаПаОаЛаОбаНаОаЙ). а’б‹аБаЕб€аИб‚аЕ аПб€аАаВаИаЛбŒаНбƒбŽ аМаОаДаЕаЛбŒ аИ аПаОаВб‚аОб€аИб‚аЕ аПаОаПб‹б‚аКбƒ.ааЕаВаОаЗаМаОаЖаНаО аОаБаНаАб€бƒаЖаИб‚бŒ %s аВ бб‚аОаЙ баИбб‚аЕаМаЕааЕаВаОаЗаМаОаЖаНаО бƒбб‚аАаНаОаВаИб‚бŒ %s аДаЛб бб‚аОаЙ бб‡аЕаЙаКаИ аПаАаМбб‚аИаЁаОаЕаДаИаНб‘аНаНб‹аЕ аЈб‚аАб‚б‹аžб‚аКаЛбŽб‡аИб‚аЕ аКаАаБаЕаЛбŒ (аЕбаЛаИ б‚б€аЕаБбƒаЕб‚бб) аИ аНаАаЖаМаИб‚аЕ ТЋаžаšТЛаžб‚аПб€аАаВаКаА аИаНбб‚б€бƒаКб†аИаЙаžб‚аПб€аАаВаКаА аНаА бб‚аАаНб†аИбŽаžб‚аПб€аАаВаКаА аНаА бб‚аАаНб†аИбŽ...аžб‚аПб€аАаВаЛаЕаНаА бб‡аЕаЙаКаА аПаАаМбб‚аИ %sа˜баПаОаЛбŒаЗаОаВаАб‚бŒ аМаОаНаОбˆаИб€аИаНаНб‹аЙ бˆб€аИб„б‚а˜баПаОаЛбŒаЗаОаВаАб‚бŒ аБаОаЛаЕаЕ аКб€бƒаПаНб‹аЙ бˆб€аИб„б‚а—аНаАб‡аЕаНаИаЕ аНаЕ аПаОаМаЕб‰аАаЕб‚бб аВ %i аБаИб‚а—аНаАб‡аЕаНаИаЕ аНаЕ аДаОаЛаЖаНаО аБб‹б‚бŒ аМаЕаНбŒбˆаЕ %.4fа—аНаАб‡аЕаНаИаЕ аНаЕ аДаОаЛаЖаНаО аПб€аЕаВб‹бˆаАб‚бŒ %.4fа—аНаАб‡аЕаНаИаЕ аДаОаЛаЖаНаО баОаДаЕб€аЖаАб‚бŒ аДаЕббб‚аИб‡аНб‹аЕ б†аИб„б€б‹, б€аОаВаНаО %iа—аНаАб‡аЕаНаИаЕ аДаОаЛаЖаНаО аБб‹б‚бŒ аБаОаЛбŒбˆаЕ аИаЛаИ б€аАаВаНаО аНбƒаЛбŽа—аНаАб‡аЕаНаИба˜аЗаГаОб‚аОаВаИб‚аЕаЛбŒа’аИаДаŸа а•а”аЃаŸа а•а–а”а•аа˜а•!аŸб€аЕаДбƒаПб€аЕаЖаДаЕаНаИаЕаŸб€аЕаДбƒаПб€аЕаЖаДаЕаНаИаЕ: %sа”аОаБб€аО аПаОаЖаАаЛаОаВаАб‚бŒаЁаЛаЕаДбƒаЕб‚ аЛаИ аПб€аОаГб€аАаМаМаЕ CHIRP баОаЗаДаАб‚бŒ аЗаНаАб‡аОаК аНаА б€аАаБаОб‡аЕаМ бб‚аОаЛаЕ?аŸаОб…аОаЖаЕ, аВаАбˆ аКаАаБаЕаЛбŒ аВбб‚аАаВаЛаЕаН аВ аПаОб€б‚:аБаИб‚аБаАаЙб‚аБаАаЙб‚ аКаАаЖаДб‹аЙаОб‚аКаЛбŽб‡б‘аНаВаКаЛбŽб‡б‘аН{bank} аПаОаЛаОаНchirp-20240224/chirp/locale/uk_UA/0000755000175000017500000000000014566340177015421 5ustar hibbyhibbychirp-20240224/chirp/locale/uk_UA/LC_MESSAGES/0000755000175000017500000000000014566340177017206 5ustar hibbyhibbychirp-20240224/chirp/locale/uk_UA/LC_MESSAGES/CHIRP.mo0000644000175000017500000000226714566340175020415 0ustar hibbyhibbyо•ДLРСХлсщ ёў !'.39 >HNOžЅ УЮує * 9 F Q^gp…ŒІ   AllAn error has occurredBanksCloningCommentDigital CodeDuplexFrequencyHelpImportIndexModelOffsetPortPowerToneTone ModeVendorProject-Id-Version: CHIRP Report-Msgid-Bugs-To: PO-Revision-Date: 2015-11-30 10:36+0200 Last-Translator: laser Language-Team: laser Language: uk_UA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); а’баЕаЁб‚аАаЛаАбб аПаОаМаИаЛаКаАа‘аАаНаКаИаšаЛаОаНбƒаВаАаНаНбаšаОаМаЕаНб‚аАб€аІаИб„б€аОаВаИаЙ аКаОаДа”бƒаПаЛаЕаКбаЇаАбб‚аОб‚аАа”аОаВб–аДаКаАа†аМаПаОб€б‚а—аМб–бб‚аœаОаДаЕаЛбŒа—ббƒаВаŸаОб€б‚аŸаОб‚бƒаЖаНб–бб‚бŒаЂаОаНаЂаОаНаОаВаИаЙ б€аЕаЖаИаМа’аИб€аОаБаНаИаКchirp-20240224/chirp/directory.py0000644000175000017500000001665714563632215015545 0ustar hibbyhibby# Copyright 2010 Dan Smith # Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import glob import os import logging import sys from chirp import chirp_common, errors LOG = logging.getLogger(__name__) def radio_class_id(cls): """Return a unique identification string for @cls""" ident = "%s_%s" % (cls.VENDOR, cls.MODEL) if cls.VARIANT: ident += "_%s" % cls.VARIANT ident = ident.replace("/", "_") ident = ident.replace(" ", "_") ident = ident.replace("(", "") ident = ident.replace(")", "") return ident ALLOW_DUPS = False def enable_reregistrations(): """Set the global flag ALLOW_DUPS=True, which will enable a driver to re-register for a slot in the directory without triggering an exception""" global ALLOW_DUPS if not ALLOW_DUPS: LOG.info("driver re-registration enabled") ALLOW_DUPS = True def register(cls): """Register radio @cls with the directory""" global DRV_TO_RADIO ident = radio_class_id(cls) if ident in list(DRV_TO_RADIO.keys()): if ALLOW_DUPS: LOG.warn("Replacing existing driver id `%s'" % ident) else: raise Exception("Duplicate radio driver id `%s'" % ident) elif ALLOW_DUPS: LOG.info("Registered %s = %s" % (ident, cls.__name__)) DRV_TO_RADIO[ident] = cls RADIO_TO_DRV[cls] = ident if not hasattr(cls, '_DETECTED_MODEL'): cls._DETECTED_MODEL = False return cls def detected_by(manager_class): """Mark a class as detected by another class This means it may not be offered directly as a choice and instead is added to @manager_class's DETECTED_MODELS list and should be returned from detect_from_serial() when appropriate. """ assert issubclass(manager_class, chirp_common.CloneModeRadio) def wrapper(cls): assert issubclass(cls, chirp_common.CloneModeRadio) cls._DETECTED_MODEL = True if manager_class.DETECTED_MODELS is None: manager_class.DETECTED_MODELS = [] manager_class.DETECTED_MODELS.append(cls) return cls return wrapper DRV_TO_RADIO = {} RADIO_TO_DRV = {} AUX_FORMATS = set() def register_format(name, pattern, readonly=False): """Register a named format and file pattern. The name and pattern must not exist in the directory already (except together). The name should be something like "CSV" or "Icom ICF" and the pattern should be a glob like "*.icf". Returns a unique name to go in Radio.FORMATS so the UI knows what additional formats a driver can read (and write unless readonly is set). """ if (name, pattern) not in [(n, p) for n, p, r in AUX_FORMATS]: if name in [x[0] for x in AUX_FORMATS]: raise Exception('Duplicate format name %r' % name) AUX_FORMATS.add((name, pattern, readonly)) return name def get_radio(driver): """Get radio driver class by identification string""" if driver in DRV_TO_RADIO: return DRV_TO_RADIO[driver] else: raise Exception("Unknown radio type `%s'" % driver) def get_driver(rclass): """Get the identification string for a given class""" if rclass in RADIO_TO_DRV: return RADIO_TO_DRV[rclass] elif rclass.__bases__[0] in RADIO_TO_DRV: return RADIO_TO_DRV[rclass.__bases__[0]] else: raise Exception("Unknown radio type `%s'" % rclass) # This is a mapping table of radio models that have changed in the past. # ideally we would never do this, but in the case where a radio was added # as the wrong model name, or a model has to be split, we need to be able # to open older files and do something intelligent with them. MODEL_COMPAT = { ('Retevis', 'RT-5R'): ('Retevis', 'RT5R'), ('Retevis', 'RT-5RV'): ('Retevis', 'RT5RV'), ('Signus', 'XTR-5'): ('Cignus', 'XTR-5'), } def get_radio_by_image(image_file): """Attempt to get the radio class that owns @image_file""" if os.path.exists(image_file): with open(image_file, "rb") as f: filedata = f.read() else: filedata = b"" data, metadata = chirp_common.CloneModeRadio._strip_metadata(filedata) for rclass in list(DRV_TO_RADIO.values()): if not issubclass(rclass, chirp_common.FileBackedRadio): continue if not metadata: # If no metadata, we do the old thing try: if rclass.match_model(filedata, image_file): return rclass(image_file) except Exception as e: LOG.error('Radio class %s failed during detection: %s' % ( rclass.__name__, e)) pass meta_vendor = metadata.get('vendor') meta_model = metadata.get('model') meta_variant = metadata.get('variant') meta_vendor, meta_model = MODEL_COMPAT.get((meta_vendor, meta_model), (meta_vendor, meta_model)) # If metadata, then it has to match one of the aliases or the parent for alias in rclass.ALIASES + [rclass]: if (alias.VENDOR == meta_vendor and alias.MODEL == meta_model and (meta_variant is None or alias.VARIANT == meta_variant)): class DynamicRadioAlias(rclass): _orig_rclass = rclass VENDOR = meta_vendor MODEL = meta_model VARIANT = metadata.get('variant') return DynamicRadioAlias(image_file) if metadata: ex = errors.ImageMetadataInvalidModel("Unsupported model %s %s" % ( metadata.get("vendor"), metadata.get("model"))) ex.metadata = metadata raise ex else: raise errors.ImageDetectFailed("Unknown file format") def import_drivers(limit=None): frozen = getattr(sys, 'frozen', False) if sys.platform == 'win32' and frozen: # We are in a frozen win32 build, so we can not glob # the driver files, but we do not need to anyway import chirp.drivers for module in chirp.drivers.__all__: try: __import__('chirp.drivers.%s' % module) except Exception as e: print('Failed to import %s: %s' % (module, e)) return # Safe import of everything in chirp/drivers. We need to import them # to get them to register, but should not abort if one import fails chirp_module_base = os.path.dirname(os.path.abspath(__file__)) driver_files = glob.glob(os.path.join(chirp_module_base, 'drivers', '*.py')) for driver_file in driver_files: module, ext = os.path.splitext(driver_file) driver_module = os.path.basename(module) if limit and driver_module not in limit: continue __import__('chirp.drivers.%s' % driver_module) chirp-20240224/chirp/bandplan_au.py0000644000175000017500000001116414563632215015771 0ustar hibbyhibby# Copyright 2013 Sean Burford # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import bandplan, bandplan_iaru_r3 SHORTNAME = "australia" DESC = { "name": "Australian Amateur Band Plan", "updated": "April 2010", "url": "http://www.wia.org.au/members/bandplans/data" "/documents/Australian%20Band%20Plans%20100404.pdf", } BANDS_10M = ( # bandplan.Band((28000000, 29700000), "10 Meter Band"), bandplan.Band((29520000, 29680000), "FM Simplex and Repeaters", mode="FM", step_khz=20), bandplan.Band((29620000, 29680000), "FM Repeaters", input_offset=-100000), ) BANDS_6M = ( # bandplan.Band((50000000, 54000000), "6 Meter Band"), bandplan.Band((52525000, 53975000), "FM Simplex and Repeaters", mode="FM", step_khz=25), bandplan.Band((53550000, 53975000), "FM Repeaters", input_offset=-1000000), ) BANDS_2M = ( bandplan.Band((144000000, 148000000), "2 Meter Band", tones=(91.5, 123.0, 141.3, 146.2, 85.4)), bandplan.Band((144400000, 144600000), "Beacons", step_khz=1), bandplan.Band((146025000, 147975000), "FM Simplex and Repeaters", mode="FM", step_khz=25), bandplan.Band((146625000, 147000000), "FM Repeaters Group A", input_offset=-600000), bandplan.Band((147025000, 147375000), "FM Repeaters Group B", input_offset=600000), ) BANDS_70CM = ( bandplan.Band((420000000, 450000000), "70cm Band", tones=(91.5, 123.0, 141.3, 146.2, 85.4)), bandplan.Band((432400000, 432600000), "Beacons", step_khz=1), bandplan.Band((438025000, 439975000), "FM Simplex and Repeaters", mode="FM", step_khz=25), bandplan.Band((438025000, 438725000), "FM Repeaters Group A", input_offset=-5000000), bandplan.Band((439275000, 439975000), "FM Repeaters Group B", input_offset=-5000000), ) BANDS_23CM = ( # bandplan.Band((1240000000, 1300000000), "23cm Band"), bandplan.Band((1273025000, 1273975000), "FM Repeaters", mode="FM", step_khz=25, input_offset=20000000), bandplan.Band((1296400000, 1296600000), "Beacons", step_khz=1), bandplan.Band((1297025000, 1300400000), "General FM Simplex Data", mode="FM", step_khz=25), ) BANDS_13CM = ( bandplan.Band((2300000000, 2450000000), "13cm Band"), bandplan.Band((2403400000, 2403600000), "Beacons", step_khz=1), bandplan.Band((2425000000, 2428000000), "FM Simplex", mode="FM", step_khz=25), bandplan.Band((2428025000, 2429000000), "FM Duplex (Voice)", mode="FM", step_khz=25, input_offset=20000000), bandplan.Band((2429000000, 2429975000), "FM Duplex (Data)", mode="FM", step_khz=100, input_offset=20000000), ) BANDS_9CM = ( bandplan.Band((3300000000, 3600000000), "9cm Band"), bandplan.Band((3320000000, 3340000000), "WB Channel 2: Voice/Data", step_khz=100), bandplan.Band((3400400000, 3400600000), "Beacons", step_khz=1), bandplan.Band((3402000000, 3403000000), "FM Simplex (Voice)", mode="FM", step_khz=100), bandplan.Band((3403000000, 3405000000), "FM Simplex (Data)", mode="FM", step_khz=100), ) BANDS_6CM = ( bandplan.Band((5650000000, 5850000000), "6cm Band"), bandplan.Band((5760400000, 5760600000), "Beacons", step_khz=1), bandplan.Band((5700000000, 5720000000), "WB Channel 2: Data", step_khz=100, input_offset=70000000), bandplan.Band((5720000000, 5740000000), "WB Channel 3: Voice", step_khz=100, input_offset=70000000), bandplan.Band((5762000000, 5763000000), "FM Simplex (Voice)", mode="FM", step_khz=100), bandplan.Band((5763000000, 5765000000), "FM Simplex (Data)", mode="FM", step_khz=100), ) BANDS = bandplan_iaru_r3.BANDS_20M + bandplan_iaru_r3.BANDS_17M + \ bandplan_iaru_r3.BANDS_15M + bandplan_iaru_r3.BANDS_12M + \ bandplan_iaru_r3.BANDS_10M + bandplan_iaru_r3.BANDS_6M + \ BANDS_10M + BANDS_6M + BANDS_2M + BANDS_70CM + BANDS_23CM + \ BANDS_13CM + BANDS_9CM + BANDS_6CM chirp-20240224/chirp/bandplan_iaru_r1.py0000644000175000017500000001544214563632215016731 0ustar hibbyhibby# Copyright 2013 Sean Burford # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import bandplan SHORTNAME = "iaru_r1" DESC = { "name": "IARU Region 1 (Europe, Africa, Middle East and Northern Asia)", "url": "http://iaru-r1.org/index.php?option=com_content" "&view=article&id=175&Itemid=127", "updated": "General Conference Sun City 2011", } # Bands are broken up like this so that other plans can import bits. BANDS_2100M = ( bandplan.Band((135700, 137800), "137 kHz Band", mode="CW"), ) BANDS_160M = ( bandplan.Band((1810000, 2000000), "160 Meter Band"), bandplan.Band((1810000, 1838000), "CW", mode="CW"), bandplan.Band((1838000, 1840000), "All narrow band modes"), bandplan.Band((1840000, 1843000), "All modes, digimodes", mode="RTTY"), ) BANDS_80M = ( bandplan.Band((3500000, 3800000), "80 Meter Band"), bandplan.Band((3500000, 3510000), "CW, priority for DX", mode="CW"), bandplan.Band((3510000, 3560000), "CW, contest preferred", mode="CW"), bandplan.Band((3560000, 3580000), "CW", mode="CW"), bandplan.Band((3580000, 3600000), "All narrow band modes, digimodes"), bandplan.Band((3590000, 3600000), "All narrow band, digimodes, unattended"), bandplan.Band((3600000, 3650000), "All modes, SSB contest preferred", mode="LSB"), bandplan.Band((3600000, 3700000), "All modes, SSB QRP", mode="LSB"), bandplan.Band((3700000, 3800000), "All modes, SSB contest preferred", mode="LSB"), bandplan.Band((3775000, 3800000), "All modes, SSB DX preferred", mode="LSB"), ) BANDS_40M = ( bandplan.Band((7000000, 7200000), "40 Meter Band"), bandplan.Band((7000000, 7040000), "CW", mode="CW"), bandplan.Band((7040000, 7047000), "All narrow band modes, digimodes"), bandplan.Band((7047000, 7050000), "All narrow band, digimodes, unattended"), bandplan.Band((7050000, 7053000), "All modes, digimodes, unattended"), bandplan.Band((7053000, 7060000), "All modes, digimodes"), bandplan.Band((7060000, 7100000), "All modes, SSB contest preferred", mode="LSB"), bandplan.Band((7100000, 7130000), "All modes, R1 Emergency Center Of Activity", mode="LSB"), bandplan.Band((7130000, 7200000), "All modes, SSB contest preferred", mode="LSB"), bandplan.Band((7175000, 7200000), "All modes, SSB DX preferred", mode="LSB"), ) BANDS_30M = ( bandplan.Band((10100000, 10150000), "30 Meter Band"), bandplan.Band((10100000, 10140000), "CW", mode="CW"), bandplan.Band((10140000, 10150000), "All narrow band digimodes"), ) BANDS_20M = ( bandplan.Band((14000000, 14350000), "20 Meter Band"), bandplan.Band((14000000, 14070000), "CW", mode="CW"), bandplan.Band((14070000, 14099000), "All narrow band modes, digimodes"), bandplan.Band((14099000, 14101000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((14101000, 14112000), "All narrow band modes, digimodes"), bandplan.Band((14125000, 14350000), "All modes, SSB contest preferred", mode="USB"), bandplan.Band((14300000, 14350000), "All modes, Global Emergency center of activity", mode="USB"), ) BANDS_17M = ( bandplan.Band((18068000, 18168000), "17 Meter Band"), bandplan.Band((18068000, 18095000), "CW", mode="CW"), bandplan.Band((18095000, 18109000), "All narrow band modes, digimodes"), bandplan.Band((18109000, 18111000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((18111000, 18168000), "All modes, digimodes"), ) BANDS_15M = ( bandplan.Band((21000000, 21450000), "15 Meter Band"), bandplan.Band((21000000, 21070000), "CW", mode="CW"), bandplan.Band((21070000, 21090000), "All narrow band modes, digimodes"), bandplan.Band((21090000, 21110000), "All narrow band, digimodes, unattended"), bandplan.Band((21110000, 21120000), "All modes, digimodes, unattended"), bandplan.Band((21120000, 21149000), "All narrow band modes"), bandplan.Band((21149000, 21151000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((21151000, 21450000), "All modes", mode="USB"), ) BANDS_12M = ( bandplan.Band((24890000, 24990000), "12 Meter Band"), bandplan.Band((24890000, 24915000), "CW", mode="CW"), bandplan.Band((24915000, 24929000), "All narrow band modes, digimodes"), bandplan.Band((24929000, 24931000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((24931000, 24990000), "All modes, digimodes", mode="USB"), ) BANDS_10M = ( bandplan.Band((28000000, 29700000), "10 Meter Band"), bandplan.Band((28000000, 28070000), "CW", mode="CW"), bandplan.Band((28070000, 28120000), "All narrow band modes, digimodes"), bandplan.Band((28120000, 28150000), "All narrow band, digimodes, unattended"), bandplan.Band((28150000, 28190000), "All narrow band modes"), bandplan.Band((28190000, 28199000), "Beacons", mode="CW"), bandplan.Band((28199000, 28201000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((28201000, 28300000), "Beacons", mode="CW"), bandplan.Band((28300000, 28320000), "All modes, digimodes, unattended"), bandplan.Band((28320000, 29100000), "All modes"), bandplan.Band((29100000, 29200000), "FM simplex", mode="NFM", step_khz=10), bandplan.Band((29200000, 29300000), "All modes, digimodes, unattended"), bandplan.Band((29300000, 29510000), "Satellite downlink"), bandplan.Band((29510000, 29520000), "Guard band, no transmission allowed"), bandplan.Band((29520000, 29590000), "All modes, FM repeater inputs", step_khz=10, mode="NFM"), bandplan.Band((29600000, 29610000), "FM simplex", step_khz=10, mode="NFM"), bandplan.Band((29620000, 29700000), "All modes, FM repeater outputs", step_khz=10, mode="NFM", input_offset=-100000), bandplan.Band((29520000, 29700000), "Wide band", step_khz=10, mode="NFM"), ) BANDS = BANDS_2100M + BANDS_160M + BANDS_80M + BANDS_40M + BANDS_30M + \ BANDS_20M + BANDS_17M + BANDS_15M + BANDS_12M + BANDS_10M # EU Analogue/DMR PMR446 Frequencies PMR446_FREQS = [446006250, 446018750, 446031250, 446043750, 446056250, 446068750, 446081250, 446093750, 446106250, 446118750, 446131250, 446143750, 446156250, 446168750, 446181250, 446193750] chirp-20240224/chirp/sources/0000755000175000017500000000000014566340177014641 5ustar hibbyhibbychirp-20240224/chirp/sources/dmrmarc.py0000644000175000017500000000753414430171343016634 0ustar hibbyhibby# Copyright 2016 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import requests from chirp import chirp_common from chirp.sources import base from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList LOG = logging.getLogger(__name__) def list_filter(haystack, attr, needles): if not needles or not needles[0]: return haystack return [x for x in haystack if x[attr] in needles] class DMRMARCRadio(base.NetworkResultRadio): """DMR-MARC data source""" VENDOR = "DMR-MARC" def get_label(self): return 'DMR-MARC' def do_fetch(self, status, params): status.send_status('Querying', 10) try: r = requests.get('https://radioid.net/api/dmr/repeater/', headers=base.HEADERS, params={'city': params['city'], 'state': params['state'], 'country': params['country']}) r.raise_for_status() except requests.exceptions.RequestException as e: LOG.error('Failed to query DMR-MARC: %s' % e) status.send_fail('Unable to query DMR-MARC') return status.send_status('Parsing', 20) self._repeaters = r.json()['results'] self._memories = [self.make_memory(i) for i in range(0, len(self._repeaters))] status.send_end() def get_raw_memory(self, number): return repr(self._repeaters[number]) def make_memory(self, number): repeater = self._repeaters[number] mem = chirp_common.Memory() mem.number = number mem.name = repeater.get('city') mem.freq = chirp_common.parse_freq(repeater.get('frequency')) offset = chirp_common.parse_freq(repeater.get('offset', '0')) if offset > 0: mem.duplex = "+" elif offset < 0: mem.duplex = "-" else: mem.duplex = "" mem.offset = abs(offset) mem.mode = 'DMR' mem.comment = repeater.get('details') mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting( "color_code", "Color Code", RadioSettingValueList( range(16), int(repeater.get('color_code', 0)))) mem.extra.append(rs) return mem def main(): import argparse from pprint import PrettyPrinter parser = argparse.ArgumentParser( description=("Fetch DMR-MARC repeater " "database and filter by city, state, and/or country. " "Multiple items combined with a , will be filtered with " "logical OR.")) parser.add_argument( "-c", "--city", help="Comma-separated list of cities to include in output.") parser.add_argument( "-s", "--state", help="Comma-separated list of states to include in output.") parser.add_argument( "--country", help="Comma-separated list of countries to include in output.") args = parser.parse_args() dmrmarc = DMRMARCRadio(None) dmrmarc.set_params(**vars(args)) dmrmarc.do_fetch() pp = PrettyPrinter(indent=2) pp.pprint(dmrmarc._repeaters) if __name__ == "__main__": main() chirp-20240224/chirp/sources/repeaterbook.py0000644000175000017500000002711214531336265017673 0ustar hibbyhibbyimport datetime import json import logging import math import os import requests from chirp import chirp_common from chirp import errors from chirp import platform as chirp_platform from chirp.sources import base from chirp.wxui import fips LOG = logging.getLogger(__name__) NA_COUNTRIES = [ 'United States', 'Canada', 'Mexico', ] MEXICO_STATES = [ "Aguascalientes", "Baja California Sur", "Baja California", "Campeche", "Chiapas", "Chihuahua", "Coahuila", "Colima", "Durango", "Guanajuato", "Guerrero", "Hidalgo", "Jalisco", "Mexico City", "Mexico", "MichoacУЁn", "Morelos", "Nayarit", "Nuevo Leon", "Puebla", "Queretaro", "Quintana Roo", "San Luis Potosi", "Sinaloa", "Sonora", "Tabasco", "Tamaulipas", "Tlaxcala", "Veracruz", "Yucatan", "Zacatecas", ] STATES = { 'United States': [s for s, i in fips.FIPS_STATES.items() if isinstance(i, int)], 'Canada': [s for s, i in fips.FIPS_STATES.items() if isinstance(i, str)], 'Mexico': MEXICO_STATES, } MODES = ['FM', 'DV', 'DMR', 'DN'] def parse_tone(val): if val.startswith('D'): mode = 'DTCS' val = int(val[1:]) elif '.' in val: mode = 'Tone' val = float(val) elif val in ('CSQ', 'Restricted'): val = mode = None elif val: LOG.warning('Unsupported PL format: %r' % val) val = mode = None else: val = mode = None return mode, val def distance(lat_a, lon_a, lat_b, lon_b): lat_a = math.radians(lat_a) lon_a = math.radians(lon_a) lat_b = math.radians(lat_b) lon_b = math.radians(lon_b) earth_radius_km = 6371 dlon = lon_b - lon_a dlat = lat_b - lat_a a = math.sin(dlat / 2)**2 + math.cos(lat_a) * \ math.cos(lat_b) * math.sin(dlon / 2)**2 c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) return earth_radius_km * c class RepeaterBook(base.NetworkResultRadio): VENDOR = 'RepeaterBook' def get_label(self): return 'RepeaterBook' def get_data(self, status, country, state, service): # Ideally we would be able to pull the whole database, but right # now this is limited to 3500 results, so we need to filter and # cache by state to stay under that limit. fn = 'rb%s-%s-%s.json' % (service, country.lower().replace(' ', '_'), state.lower().replace(' ', '_')) db_dir = chirp_platform.get_platform().config_file('repeaterbook') try: os.mkdir(db_dir) except FileExistsError: pass except Exception as e: LOG.exception('Failed to create %s: %s' % (db_dir, e)) status.set_fail('Internal error - check log') return data_file = os.path.join(db_dir, fn) try: modified = os.path.getmtime(data_file) except FileNotFoundError: modified = 0 modified_dt = datetime.datetime.fromtimestamp(modified) interval = datetime.timedelta(days=30) if datetime.datetime.now() - modified_dt < interval: return data_file if modified == 0: LOG.debug('RepeaterBook database %s not cached' % fn) else: LOG.debug('RepeaterBook database %s too old: %s', fn, modified_dt) params = {'country': country, 'stype': service} if country in NA_COUNTRIES: export = 'export.php' else: export = 'exportROW.php' if country in STATES: params['state'] = state r = requests.get('https://www.repeaterbook.com/api/%s' % export, headers=base.HEADERS, params=params, stream=True) if r.status_code != 200: if modified: status.send_status('Using cached data', 50) status.send_fail('Got error code %i from server' % r.status_code) return tmp = data_file + '.tmp' chunk_size = 8192 probable_end = 3 << 20 counter = 0 data = b'' with open(tmp, 'wb') as f: for chunk in r.iter_content(chunk_size=chunk_size): f.write(chunk) data += chunk counter += len(chunk) status.send_status('Downloading', counter / probable_end * 50) try: results = json.loads(data) except Exception as e: LOG.exception('Invalid JSON in response: %s' % e) status.send_fail('RepeaterBook returned invalid response') return if results['count']: try: os.rename(tmp, data_file) except FileExistsError: # Windows can't do atomic rename os.remove(data_file) os.rename(tmp, data_file) else: os.remove(tmp) status.send_fail('No results!') return status.send_status('Download complete', 50) return data_file def item_to_memory(self, item, number): if item.get('D-Star') == 'Yes': m = chirp_common.DVMemory() m.dv_urcall = 'CQCQCQ'.ljust(8) m.dv_rpt1call = item.get('Callsign')[:8].ljust(8) m.dv_rpt2call = item.get('Callsign')[:8].ljust(8) else: m = chirp_common.Memory() m.number = number m.freq = chirp_common.parse_freq(item['Frequency']) try: m.tuning_step = chirp_common.required_step(m.freq) except errors.InvalidDataError as e: LOG.debug(e) txf = chirp_common.parse_freq(item['Input Freq']) if txf == 0: m.duplex = 'off' else: chirp_common.split_to_offset(m, m.freq, txf) txm, tx = parse_tone(item['PL']) rxm, rx = parse_tone(item['TSQ']) chirp_common.split_tone_decode(m, (txm, tx, 'N'), (rxm, rx, 'N')) if item['DMR'] == 'Yes': m.mode = 'DMR' elif item['D-Star'] == 'Yes': m.mode = 'DV' elif item['System Fusion'] == 'Yes': m.mode = 'DN' elif item['FM Analog'] == 'Yes': m.mode = 'FM' else: LOG.warning('Unable to determine mode for repeater %s' % ( item['Rptr ID'])) return None if 'State' in item and 'County' in item: m.comment = ( '%(Callsign)s near %(Nearest City)s, %(County)s County, ' '%(State)s %(Use)s') % item else: m.comment = ( '%(Callsign)s near %(Nearest City)s, %(Region)s ' '%(Use)s') % item m.comment += ' ' + item.get('Notes', '') m.comment = m.comment.strip() m.name = item['Landmark'] or item['Callsign'] return m def do_fetch(self, status, params): lat = float(params.pop('lat') or 0) lon = float(params.pop('lon') or 0) dist = int(params.pop('dist') or 0) search_filter = params.pop('filter', '') bands = params.pop('bands', []) modes = params.pop('modes', []) fmconv = params.pop('fmconv', False) data_file = self.get_data(status, params.get('country'), params.pop('state'), params.get('service', '')) if not data_file: return status.send_status('Parsing', 50) def sorter(item): if lat == 0 and lon == 0: # No sort if not provided return 0 return distance(lat, lon, float(item.get('Lat', 0)), float(item.get('Long', 0))) def match(item): search_fields = ('County', 'State', 'Landmark', 'Nearest City', 'Callsign', 'Region', 'Notes') content = ' '.join(item.get(k) or '' for k in search_fields if k in item) return (not search_filter or search_filter.lower() in content.lower()) def included_band(item): if not bands: return True for lo, hi in bands: if lo < chirp_common.parse_freq(item['Frequency']) < hi: return True return False i = 0 for item in sorted(json.loads(open(data_file, 'rb').read())['results'], key=sorter): if not item: continue if item['Operational Status'] != 'On-air': continue if dist and lat and lon and ( distance(lat, lon, float(item.get('Lat') or 0), float(item.get('Long') or 0)) > dist): continue if not match(item): continue if not included_band(item): continue i += 1 try: m = self.item_to_memory(item, i) except Exception as e: LOG.warning('Unable to convert repeater %s: %s', item['Rptr ID'], e) continue if not m: continue # Convert any non-FM repeater to FM if user requested it if m.mode != 'FM' and fmconv and item.get('FM Analog') == 'Yes': LOG.debug('Converting repeater %r from %r to FM: %s', item['Rptr ID'], m.mode, m.comment) m.mode = 'FM' if modes and m.mode not in modes: continue self._memories.append(m) self.MODEL = '%s %s' % (params.get('country'), params.get('service_display') or 'Result') if not self._memories: status.send_fail(_('No results!')) return status.send_end() ROW_COUNTRIES = [ "Albania", "Andorra", "Argentina", "Australia", "Austria", "Azerbaijan", "Bahamas", "Barbados", "Belarus", "Belgium", "Belize", "Bolivia", "Bosnia and Herzegovina", "Brazil", "Bulgaria", "Caribbean Netherlands", "Cayman Islands", "Chile", "China", "Colombia", "Costa Rica", "Croatia", "Curacao", "Cyprus", "Czech Republic", "Denmark", "Dominican Republic", "Ecuador", "El Salvador", "Estonia", "Faroe Islands", "Finland", "France", "Georgia", "Germany", "Greece", "Grenada", "Guatemala", "Guernsey", "Haiti", "Honduras", "Hungary", "Iceland", "India", "Indonesia", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Kosovo", "Kuwait", "Latvia", "Liechtenstein", "Lithuania", "Luxembourg", "Macedonia", "Malaysia", "Malta", "Moldova", "Morocco", "Namibia", "Nepal", "Netherlands", "New Zealand", "Nicaragua", "Norway", "Oman", "Panama", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Romania", "Russian Federation", "Saint Kitts and Nevis", "Saint Vincent and the Grenadines", "San Marino", "Serbia", "Singapore", "Slovakia", "Slovenia", "South Africa", "South Korea", "Spain", "Sri Lanka", "Sweden", "Switzerland", "Taiwan", "Thailand", "Trinidad and Tobago", "Turkey", "Ukraine", "United Arab Emirates", "United Kingdom", "Uruguay", "Venezuela", ] COUNTRIES = list(sorted(NA_COUNTRIES + ROW_COUNTRIES)) chirp-20240224/chirp/sources/base.py0000644000175000017500000000304014430171343016105 0ustar hibbyhibbyimport logging import sys from chirp import CHIRP_VERSION from chirp import chirp_common from chirp import errors LOG = logging.getLogger(__name__) HEADERS = { 'User-Agent': 'chirp/%s Python %i.%i.%i %s' % ( CHIRP_VERSION, sys.version_info.major, sys.version_info.minor, sys.version_info.micro, sys.platform), } class QueryStatus: def send_status(self, status, percent): LOG.info('QueryStatus[%i%%]: %s' % (percent, status)) def send_end(self): LOG.info('QueryStatus: END') def send_fail(self, reason): LOG.error('QueryStatus Failed: %s' % reason) class NetworkResultRadio(chirp_common.NetworkSourceRadio): VENDOR = 'Query' MODEL = 'Result' def __init__(self): self._memories = [] def do_fetch(self, status, params): pass def get_label(self): return 'QueryResult' def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, len(self._memories) - 1) rf.has_rx_dtcs = True rf.has_cross = True rf.has_bank = False rf.has_settings = False rf.has_comment = True rf.valid_skips = [] rf.valid_cross_modes = chirp_common.CROSS_MODES rf.valid_tmodes = chirp_common.TONE_MODES return rf def get_memory(self, number): return self._memories[number] def set_memory(self, memory): raise errors.RadioError('Network source is immutable') def validate_memory(self, memory): return ['Network source is immutable'] chirp-20240224/chirp/sources/przemienniki.py0000644000175000017500000000503114451231774017711 0ustar hibbyhibby# Copyright 2023 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import requests from chirp.drivers import generic_csv from chirp import errors from chirp.sources import base LOG = logging.getLogger(__name__) class Przemienniki(base.NetworkResultRadio): VENDOR = 'przemienniki.net' def get_label(self): return 'przemienniki.net' def do_fetch(self, status, params): status.send_status('Querying', 10) if not params['range'] or int(params['range']) == 0: params.pop('range') LOG.debug('query params: %s' % str(params)) try: r = requests.get('http://przemienniki.net/export/chirp.csv', headers=base.HEADERS, params=params, stream=True) r.raise_for_status() except requests.exceptions.RequestException as e: LOG.error('Failed to query przemienniki: %s' % e) status.send_fail(_('Unable to query')) return status.send_status(_('Parsing'), 20) try: csv = generic_csv.CSVRadio(None) csv._load(x.decode() for x in r.iter_lines()) except errors.InvalidDataError: status.send_fail(_('No results')) return except Exception as e: LOG.error('Error parsing result: %s' % e) status.send_fail(_('Failed to parse result')) return status.send_status(_('Sorting'), 80) self._memories = [csv.get_memory(x) for x in range(1, 999) if not csv.get_memory(x).empty] if not any([params['latitude'], params['longitude']]): LOG.debug('Sorting memories by name') self._memories.sort(key=lambda m: m.name) # Now renumber them for i, mem in enumerate(self._memories): mem.number = i + 1 return status.send_end() chirp-20240224/chirp/sources/__init__.py0000644000175000017500000000000014411666130016725 0ustar hibbyhibbychirp-20240224/chirp/sources/radioreference.py0000644000175000017500000002167614446774561020211 0ustar hibbyhibby# Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import threading from chirp import chirp_common, errors from chirp.sources import base from chirp.wxui import config LOG = logging.getLogger(__name__) CONF = config.get() try: from suds.client import Client from suds import WebFault HAVE_SUDS = True except ImportError: HAVE_SUDS = False MODES = { "FM": "FM", "AM": "AM", "FMN": "NFM", "D-STAR": "DV", "USB": "USB", "LSB": "LSB", "P25": "P25", "DMR": "DMR", } CA_COUNTIES = [] CA_PROVINCES = {} logging.getLogger('suds').setLevel(logging.WARNING) class RadioReferenceCAData(threading.Thread): def __init__(self, callback, username, password): super().__init__() self._callback = callback self._username = username self._password = password def run(self): radio = RadioReferenceRadio() radio.set_auth(self._username, self._password) try: counties, provinces = radio.do_getcanadacounties() LOG.debug('Got counties: %r' % counties) LOG.debug('Got provinces: %r' % provinces) CA_COUNTIES.clear() CA_COUNTIES.extend(counties) CA_PROVINCES.clear() CA_PROVINCES.update(provinces) self._callback(True) except Exception as e: LOG.exception('Failed to query RR: %s' % e) self._callback(e) class RadioReferenceRadio(base.NetworkResultRadio): """RadioReference.com data source""" VENDOR = "RadioReference" URL = "http://api.radioreference.com/soap2/?wsdl" APPKEY = "46785108" def __init__(self): chirp_common.NetworkSourceRadio.__init__(self, None) if not HAVE_SUDS: raise errors.RadioError( "Suds library required for RadioReference.com import.\n" + "Try installing your distribution's python-suds package.") self._auth = {"appKey": self.APPKEY, "username": "", "password": ""} self._client = Client(self.URL) self._freqs = [] self._modes = None self._zipcounty = None self._country = None def set_auth(self, username, password): self._auth["username"] = username self._auth["password"] = password def do_getcanadacounties(self): try: service = self._client.service provincelist = service.getCountryInfo(2, self._auth) provinces = {} clist = [] for province in provincelist: provinces[province[2]] = province[0] provinceinfo = service.getStateInfo(province[0], self._auth) for county in provinceinfo.countyList: if (county[1] != 'UNKNOWN' and county[1] != 'N/A' and county[1] != 'Provincewide'): # some counties are actually cities but whatever fml clist.append([province[0], province[2], county[0], county[1]]) except WebFault as err: raise errors.RadioError(err) return clist, provinces def do_fetch(self, status, params): """Fetches frequencies for all subcategories in a county (or zip if USA).""" status.send_status('Querying...', 5) self._freqs = [] # if this method was accessed for the USA, use the zip; otherwise # use the county ID if params['country'] == 'US': try: service = self._client.service zipcode = service.getZipcodeInfo(params['zipcounty'], self._auth) county = service.getCountyInfo(zipcode.ctid, self._auth) except WebFault as err: raise errors.RadioError(err) elif params['country'] == 'CA': try: service = self._client.service county = service.getCountyInfo(params['zipcounty'], self._auth) except WebFault as err: raise errors.RadioError(err) status_max = 0 status_cur = 0 for cat in county.cats: status_max += len(cat.subcats) status_max += len(county.agencyList) for cat in county.cats: for subcat in cat.subcats: result = self._client.service.getSubcatFreqs(subcat.scid, self._auth) self._freqs += result status_cur += 1 status.send_status( 'Fetching %s:%s' % (cat.cName, subcat.scName), status_cur / status_max * 100) for agency in county.agencyList: agency = self._client.service.getAgencyInfo(agency.aid, self._auth) for cat in agency.cats: status_max += len(cat.subcats) for cat in agency.cats: for subcat in cat.subcats: result = self._client.service.getSubcatFreqs(subcat.scid, self._auth) self._freqs += result status_cur += 1 try: sc_name = subcat.scName except AttributeError: sc_name = 'Unknown Category' status.send_status( 'Fetching agency %s %s:%s' % (agency.aid, cat.cName, sc_name), status_cur / status_max * 100) status.send_end() def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, len(self._freqs)-1) rf.has_bank = False rf.has_ctone = False rf.has_comment = True rf.valid_tmodes = ["", "TSQL", "DTCS"] return rf def get_raw_memory(self, number): return repr(self._freqs[number]) def get_memory(self, number): if not self._freqs: self.do_fetch() freq = self._freqs[number] mem = chirp_common.Memory() mem.number = number mem.name = freq.alpha or freq.descr or "" mem.freq = chirp_common.parse_freq(str(freq.out)) if freq["in"] == 0.0: mem.duplex = "" else: mem.duplex = "split" mem.offset = chirp_common.parse_freq(str(freq["in"])) if freq.tone is not None: if str(freq.tone) == "CSQ": # Carrier Squelch mem.tmode = "" else: try: tone, tmode = freq.tone.split(" ") except Exception: tone, tmode = None, None if tmode == "PL": mem.tmode = "TSQL" mem.rtone = mem.ctone = float(tone) elif tmode == "DPL": mem.tmode = "DTCS" mem.dtcs = int(tone) else: LOG.error("Error: unsupported tone: %s" % freq) try: mem.mode = self._get_mode(freq.mode) except KeyError: LOG.debug('Mode %s (%s) is unsupported' % ( freq.mode, self._modes[int(str(freq.mode))])) # skip memory if mode is unsupported mem.empty = True return mem mem.comment = freq.descr.strip() return mem def _get_mode(self, modeid): if not self._modes: self._modes = {} for mode in self._client.service.getMode("0", self._auth): # sax.text.Text cannot be coerced directly to int self._modes[int(str(mode.mode))] = str(mode.modeName) return MODES[self._modes[int(str(modeid))]] def main(): """ Usage: cd ~/src/chirp.hg python ./chirp/radioreference.py [USERNAME] [PASSWORD] \ [COUNTRY - 2 LETTER] [US ZIP(USA) OR COUNTY ID(CANADA)] """ import sys rrr = RadioReferenceRadio(None) rrr.set_params(username=sys.argv[1], password=sys.argv[2], country=sys.argv[3], zipcounty=sys.argv[4]) rrr.do_fetch() print(rrr.get_raw_memory(0)) print(rrr.get_memory(0)) if __name__ == "__main__": main() chirp-20240224/chirp/cli/0000755000175000017500000000000014566340177013725 5ustar hibbyhibbychirp-20240224/chirp/cli/main.py0000644000175000017500000003372314411666130015220 0ustar hibbyhibby#!/usr/bin/env python # # Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import serial import os import sys import argparse import logging from chirp import logger from chirp import chirp_common, errors, directory, util directory.import_drivers() LOG = logging.getLogger("chirpc") RADIOS = directory.DRV_TO_RADIO def fail_unsupported(): LOG.error("Operation not supported by selected radio") sys.exit(1) def fail_missing_mmap(): LOG.error("mmap-only operation requires specification of an mmap file") sys.exit(1) class ToneAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): value = values[0] if value not in chirp_common.TONES: raise argparse.ArgumentError( self, "Invalid tone value: %.1f" % value) setattr(namespace, self.dest, value) class DTCSAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): value = values[0] if value not in chirp_common.DTCS_CODES: raise argparse.ArgumentError( self, "Invalid DTCS value: %03i" % value) setattr(namespace, self.dest, value) class DTCSPolarityAction(argparse.Action): def __call__(self, parser, namespace, values, option_string=None): value = values[0] if value not in ["NN", "RN", "NR", "RR"]: raise argparse.ArgumentError( self, "Invalid DTCS polarity: %s" % value) setattr(namespace, self.dest, value) def parse_memory_number(radio, args): if len(args) < 1: LOG.error("You must provide an argument specifying the memory number.") sys.exit(1) try: memnum = int(args[0]) except ValueError: memnum = args[0] rf = radio.get_features() start, end = rf.memory_bounds if not (start <= memnum <= end or memnum in rf.valid_special_chans): if len(rf.valid_special_chans) > 0: LOG.error( "memory number must be between %d and %d or one of %s" " (got %s)", start, end, ", ".join(rf.valid_special_chans), memnum) else: LOG.error("memory number must be between %d and %d (got %s)", start, end, memnum) sys.exit(1) return memnum def main(args=None): parser = argparse.ArgumentParser() logger.add_version_argument(parser) parser.add_argument("-s", "--serial", dest="serial", default="mmap", help="Serial port (default: mmap)") parser.add_argument("--list-settings", action="store_true", help="List settings") parser.add_argument("-i", "--id", dest="id", default=False, action="store_true", help="Request radio ID string") memarg = parser.add_argument_group("Memory/Channel Options") memarg.add_argument("--list-mem", action="store_true", help="List all memory locations") memarg.add_argument("--list-special-mem", action="store_true", help="List all special memory locations") memarg.add_argument("--raw", action="store_true", help="Dump raw memory location") memarg.add_argument("--get-mem", action="store_true", help="Get and print memory location") memarg.add_argument("--copy-mem", action="store_true", help="Copy memory location") memarg.add_argument("--clear-mem", action="store_true", help="Clear memory location") memarg.add_argument("--set-mem-name", help="Set memory name") memarg.add_argument("--set-mem-freq", type=float, help="Set memory frequency") memarg.add_argument("--set-mem-tencon", action="store_true", help="Set tone encode enabled flag") memarg.add_argument("--set-mem-tencoff", action="store_true", help="Set tone decode disabled flag") memarg.add_argument("--set-mem-tsqlon", action="store_true", help="Set tone squelch enabled flag") memarg.add_argument("--set-mem-tsqloff", action="store_true", help="Set tone squelch disabled flag") memarg.add_argument("--set-mem-dtcson", action="store_true", help="Set DTCS enabled flag") memarg.add_argument("--set-mem-dtcsoff", action="store_true", help="Set DTCS disabled flag") memarg.add_argument("--set-mem-tenc", type=float, action=ToneAction, nargs=1, help="Set memory encode tone") memarg.add_argument("--set-mem-tsql", type=float, action=ToneAction, nargs=1, help="Set memory squelch tone") memarg.add_argument("--set-mem-dtcs", type=int, action=DTCSAction, nargs=1, help="Set memory DTCS code") memarg.add_argument("--set-mem-dtcspol", action=DTCSPolarityAction, nargs=1, help="Set memory DTCS polarity (NN, NR, RN, RR)") memarg.add_argument("--set-mem-dup", help="Set memory duplex (+,-, or blank)") memarg.add_argument("--set-mem-offset", type=float, help="Set memory duplex offset (in MHz)") memarg.add_argument("--set-mem-mode", help="Set mode (%s)" % ",".join(chirp_common.MODES)) parser.add_argument("-r", "--radio", dest="radio", default=None, help="Radio model (see --list-radios)") parser.add_argument("--list-radios", action="store_true", help="List radio models") parser.add_argument("--mmap", dest="mmap", default=None, help="Radio memory map file location") parser.add_argument("--download-mmap", dest="download_mmap", action="store_true", default=False, help="Download memory map from radio") parser.add_argument("--upload-mmap", dest="upload_mmap", action="store_true", default=False, help="Upload memory map to radio") logger.add_arguments(parser) parser.add_argument("args", metavar="arg", nargs='*', help="Some commands require additional arguments") if len(sys.argv) <= 1: parser.print_help() sys.exit(0) options = parser.parse_args(args) args = options.args logger.handle_options(options) if options.list_radios: print("Supported Radios:\n\t", "\n\t".join(sorted(RADIOS.keys()))) sys.exit(0) if options.id: from chirp import detect md = detect.detect_icom_radio(options.serial) print("Model:\n%s" % md.MODEL) sys.exit(0) if not options.radio: if options.mmap: rclass = directory.get_radio_by_image(options.mmap).__class__ else: print("You must specify a radio model. See --list-radios.") sys.exit(1) else: rclass = directory.get_radio(options.radio) if options.serial == "mmap": if options.mmap: s = options.mmap else: s = options.radio + ".img" if not os.path.exists(s): LOG.error("Image file '%s' does not exist" % s) sys.exit(1) else: LOG.info("opening %s at %i" % (options.serial, rclass.BAUD_RATE)) if '://' in options.serial: s = serial.serial_for_url(options.serial, do_not_open=True) s.timeout = 0.5 s.open() else: s = serial.Serial(port=options.serial, timeout=0.5) radio = rclass(s) if options.list_settings: print(radio.get_settings()) sys.exit(0) if options.list_mem: rf = radio.get_features() start, end = rf.memory_bounds for i in range(start, end + 1): mem = radio.get_memory(i) if mem.empty and not logger.is_visible(logging.INFO): continue print(mem) sys.exit(0) if options.list_special_mem: rf = radio.get_features() for i in sorted(rf.valid_special_chans): mem = radio.get_memory(i) if mem.empty and not logger.is_visible(logging.INFO): continue print(mem) sys.exit(0) if options.copy_mem: src = parse_memory_number(radio, args) dst = parse_memory_number(radio, args[1:]) try: mem = radio.get_memory(src) except errors.InvalidMemoryLocation as e: LOG.exception(e) sys.exit(1) LOG.info("copying memory %s to %s", src, dst) mem.number = dst radio.set_memory(mem) if options.clear_mem: memnum = parse_memory_number(radio, args) try: mem = radio.get_memory(memnum) except errors.InvalidMemoryLocation as e: LOG.exception(e) sys.exit(1) if mem.empty: LOG.warn("memory %s is already empty, deleting again", memnum) mem.empty = True radio.set_memory(mem) if options.raw: memnum = parse_memory_number(radio, args) data = radio.get_raw_memory(memnum) for i in data: if ord(i) > 0x7F: print("Memory location %s (%i):\n%s" % (memnum, len(data), util.hexprint(data))) sys.exit(0) print(data) sys.exit(0) if options.set_mem_dup is not None: if options.set_mem_dup != "+" and \ options.set_mem_dup != "-" and \ options.set_mem_dup != "": LOG.error("Invalid duplex value `%s'" % options.set_mem_dup) LOG.error("Valid values are: '+', '-', ''") sys.exit(1) else: _dup = options.set_mem_dup else: _dup = None if options.set_mem_mode: LOG.info("Set mode: %s" % options.set_mem_mode) if options.set_mem_mode not in chirp_common.MODES: LOG.error("Invalid mode `%s'") sys.exit(1) else: _mode = options.set_mem_mode else: _mode = None if options.set_mem_name or options.set_mem_freq or \ options.set_mem_tencon or options.set_mem_tencoff or \ options.set_mem_tsqlon or options.set_mem_tsqloff or \ options.set_mem_dtcson or options.set_mem_dtcsoff or \ options.set_mem_tenc or options.set_mem_tsql or \ options.set_mem_dtcs or options.set_mem_dup is not None or \ options.set_mem_mode or options.set_mem_dtcspol or\ options.set_mem_offset: memnum = parse_memory_number(radio, args) try: mem = radio.get_memory(memnum) except errors.InvalidMemoryLocation as e: LOG.exception(e) sys.exit(1) if mem.empty: LOG.info("creating new memory (#%s)", memnum) mem = chirp_common.Memory() mem.number = memnum mem.name = options.set_mem_name or mem.name mem.freq = options.set_mem_freq or mem.freq mem.rtone = options.set_mem_tenc or mem.rtone mem.ctone = options.set_mem_tsql or mem.ctone mem.dtcs = options.set_mem_dtcs or mem.dtcs mem.dtcs_polarity = options.set_mem_dtcspol or mem.dtcs_polarity if _dup is not None: mem.duplex = _dup mem.offset = options.set_mem_offset or mem.offset mem.mode = _mode or mem.mode if options.set_mem_tencon: mem.tmode = "Tone" elif options.set_mem_tencoff: mem.tmode = "" if options.set_mem_tsqlon: mem.tmode = "TSQL" elif options.set_mem_tsqloff: mem.tmode = "" if options.set_mem_dtcson: mem.tmode = "DTCS" elif options.set_mem_dtcsoff: mem.tmode = "" radio.set_memory(mem) if options.get_mem: pos = parse_memory_number(radio, args) try: mem = radio.get_memory(pos) except errors.InvalidMemoryLocation: mem = chirp_common.Memory() mem.number = pos print(mem) sys.exit(0) if options.download_mmap: if not issubclass(rclass, chirp_common.CloneModeRadio): LOG.error("%s is not a clone mode radio" % options.radio) sys.exit(1) if not options.mmap: LOG.error("You must specify the destination file name with --mmap") sys.exit(1) try: radio.sync_in() radio.save_mmap(options.mmap) except Exception as e: LOG.exception(e) sys.exit(1) if options.upload_mmap: if not issubclass(rclass, chirp_common.CloneModeRadio): LOG.error("%s is not a clone mode radio" % options.radio) sys.exit(1) if not options.mmap: LOG.error("You must specify the source file name with --mmap") sys.exit(1) try: radio.load_mmap(options.mmap) radio.sync_out() print("Upload successful") except Exception as e: LOG.exception(e) sys.exit(1) if options.mmap and isinstance(radio, chirp_common.CloneModeRadio): radio.save_mmap(options.mmap) chirp-20240224/chirp/cli/__init__.py0000644000175000017500000000000014411666130016011 0ustar hibbyhibbychirp-20240224/chirp/import_logic.py0000644000175000017500000002575714503004432016215 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import chirp_common, errors LOG = logging.getLogger(__name__) class ImportError(Exception): """An import error""" pass class DestNotCompatible(ImportError): """Memory is not compatible with the destination radio""" pass def ensure_has_calls(radio, memory): """Make sure @radio has the necessary D-STAR callsigns for @memory""" ulist_changed = rlist_changed = False ulist = radio.get_urcall_list() rlist = radio.get_repeater_call_list() if memory.dv_urcall and memory.dv_urcall not in ulist: for i in range(0, len(ulist)): if not ulist[i].strip(): ulist[i] = memory.dv_urcall ulist_changed = True break if not ulist_changed: raise errors.RadioError("No room to add callsign %s" % memory.dv_urcall) rlist_add = [] if memory.dv_rpt1call and memory.dv_rpt1call not in rlist: rlist_add.append(memory.dv_rpt1call) if memory.dv_rpt2call and memory.dv_rpt2call not in rlist: rlist_add.append(memory.dv_rpt2call) while rlist_add: call = rlist_add.pop() for i in range(0, len(rlist)): if not rlist[i].strip(): rlist[i] = call call = None rlist_changed = True break if call: raise errors.RadioError("No room to add callsign %s" % call) if ulist_changed: radio.set_urcall_list(ulist) if rlist_changed: radio.set_repeater_call_list(rlist) # Filter the name according to the destination's rules def _import_name(dst_radio, _srcrf, mem): mem.name = dst_radio.filter_name(mem.name) def find_closest_power(needle_watts, levels_haystack): deltas = [abs(needle_watts - chirp_common.dBm_to_watts(int(power))) for power in levels_haystack] return levels_haystack[deltas.index(min(deltas))] def _import_power(dst_radio, _srcrf, mem): levels = dst_radio.get_features().valid_power_levels dstrf = dst_radio.get_features() if not levels: mem.power = None return elif mem.power is None: # Source radio did not support power levels, so choose the # highest level from the destination radio. If the destination radio # has variable power support, choose the middle power level (if there # is one) as that is probably the default. This is kindof a hack to # avoid pushing everything to 1500W in the CSV driver. if dstrf.has_variable_power and len(levels) > 2 and len(levels) % 2: mem.power = levels[len(levels) // 2] else: try: mem.power = next(reversed(sorted(levels))) except StopIteration: # No power levels on the destination, so leave power=None pass return elif dstrf.has_variable_power: # If the destination radio has variable power support, clamp to its # ranges if out of bounds. Otherwise just pass through and let it # interpret the absolute power level. if mem.power < min(levels): mem.power = min(levels) elif mem.power > max(levels): mem.power = max(levels) return # If both radios support discrete power levels, we need to decide how to # convert the source power level to a valid one for the destination # radio. To do that, find the absolute level of the source value # and calculate the difference between it and all the levels of the # destination, choosing the one that matches most closely. Do this in # watts not dBm because we will make the wrong decision otherwise due # to the logarithmic scale. mem.power = find_closest_power(chirp_common.dBm_to_watts(int(mem.power)), levels) def _import_tone(dst_radio, srcrf, mem): dstrf = dst_radio.get_features() # Some radios keep separate tones for Tone and TSQL modes (rtone and # ctone). If we're importing to or from radios with differing models, # do the conversion here. if srcrf.has_ctone and not dstrf.has_ctone: # If copying from a radio with separate rtone/ctone to a radio # without, and the tmode is TSQL, then use the ctone value if mem.tmode == "TSQL": mem.rtone = mem.ctone elif not srcrf.has_ctone and dstrf.has_ctone: # If copying from a radio without separate rtone/ctone to a radio # with it, set the dest ctone to the src rtone if mem.tmode == "TSQL": mem.ctone = mem.rtone def _import_dtcs(dst_radio, srcrf, mem): dstrf = dst_radio.get_features() # Some radios keep separate DTCS codes for tx and rx # If we're importing to or from radios with differing models, # do the conversion here. if srcrf.has_rx_dtcs and not dstrf.has_rx_dtcs: # If copying from a radio with separate codes to a radio # without, and the tmode is DTCS, then use the rx_dtcs value if mem.tmode == "DTCS": mem.dtcs = mem.rx_dtcs elif not srcrf.has_rx_dtcs and dstrf.has_rx_dtcs: # If copying from a radio without separate codes to a radio # with it, set the dest rx_dtcs to the src dtcs if mem.tmode == "DTCS": mem.rx_dtcs = mem.dtcs def _guess_mode_by_frequency(freq): ranges = [ (0, 136000000, "AM"), (136000000, 9999000000, "FM"), ] for lo, hi, mode in ranges: if freq > lo and freq <= hi: return mode # If we don't know, assume FM return "FM" def _import_mode(dst_radio, srcrf, mem): dstrf = dst_radio.get_features() # Some radios support an "Auto" mode. If we're importing from one # that does to one that does not, guess at the proper mode based on the # frequency if mem.mode == "Auto" and mem.mode not in dstrf.valid_modes: mode = _guess_mode_by_frequency(mem.freq) if mode not in dstrf.valid_modes: raise DestNotCompatible("Destination does not support %s" % mode) mem.mode = mode def _make_offset_with_split(rxfreq, txfreq): offset = txfreq - rxfreq if offset == 0: return "", offset elif offset > 0: return "+", offset elif offset < 0: return "-", offset * -1 def _import_duplex(dst_radio, srcrf, mem): dstrf = dst_radio.get_features() if mem.duplex == "split" and mem.duplex not in dstrf.valid_duplexes: # If a radio does not support odd split, we can use an equivalent # offset mem.duplex, mem.offset = _make_offset_with_split(mem.freq, mem.offset) # Enforce maximum offset ranges = [(0, 500000000, 15000000), (500000000, 3000000000, 50000000), ] for lo, hi, limit in ranges: if lo < mem.freq <= hi: if abs(mem.offset) > limit: raise DestNotCompatible("offset is abnormally large.") elif mem.duplex == 'off' and mem.duplex not in dstrf.valid_duplexes: # If a radio does not support duplex=off, we should just convert to # simplex mem.duplex = '' def import_mem(dst_radio, src_features, src_mem, overrides={}, mem_cls=None): """Perform import logic to create a destination memory from src_mem that will be compatible with @dst_radio""" dst_rf = dst_radio.get_features() if isinstance(src_mem, chirp_common.DVMemory): # DV memory import logic: If the radio supports D-STAR and requires # call lists, then we set the call list. Otherwise, if it just # supports DV mode we don't, but allow the memory (i.e. CSV, etc). # If neither, then it's not compatible. if isinstance(dst_radio, chirp_common.IcomDstarSupport): if dst_rf.requires_call_lists: ensure_has_calls(dst_radio, src_mem) elif 'DV' not in dst_rf.valid_modes: raise DestNotCompatible( "Destination radio does not support D-STAR") if mem_cls: dst_mem = mem_cls() dst_mem.clone(src_mem) else: dst_mem = src_mem.dupe() # The source's immutable list almost definitely does not match the # latter, so eliminate that list here and rely on set_memory() on # the destination to enforce anything that should not be set. dst_mem.immutable = [] for k, v in overrides.items(): dst_mem.__dict__[k] = v helpers = [_import_name, _import_power, _import_tone, _import_dtcs, _import_mode, _import_duplex, ] for helper in helpers: helper(dst_radio, src_features, dst_mem) # If we can, grab the current existing destination memory and check the # radio's immutable set_memory() policy if not isinstance(dst_radio, chirp_common.LiveRadio): cur_mem = dst_radio.get_memory(dst_mem.number) dst_radio.check_set_memory_immutable_policy(cur_mem, dst_mem) msgs = dst_radio.validate_memory(dst_mem) errs = [x for x in msgs if isinstance(x, chirp_common.ValidationError)] if errs: raise DestNotCompatible(", ".join(errs)) return dst_mem def _get_bank_model(radio): for model in radio.get_mapping_models(): if isinstance(model, chirp_common.BankModel): return model return None def import_bank(dst_radio, src_radio, dst_mem, src_mem): """Attempt to set the same banks for @mem(by index) in @dst_radio that it has in @src_radio""" dst_bm = _get_bank_model(dst_radio) if not dst_bm: return dst_banks = dst_bm.get_mappings() src_bm = _get_bank_model(src_radio) if not src_bm: return src_banks = src_bm.get_mappings() src_mem_banks = src_bm.get_memory_mappings(src_mem) src_indexes = [src_banks.index(b) for b in src_mem_banks] for bank in dst_bm.get_memory_mappings(dst_mem): dst_bm.remove_memory_from_mapping(dst_mem, bank) for index in src_indexes: try: bank = dst_banks[index] LOG.debug("Adding memory to bank %s" % bank) dst_bm.add_memory_to_mapping(dst_mem, bank) if isinstance(dst_bm, chirp_common.MappingModelIndexInterface): dst_bm.set_memory_index(dst_mem, bank, dst_bm.get_next_mapping_index(bank)) except IndexError: pass chirp-20240224/chirp/bandplan_na.py0000644000175000017500000003234114563632215015762 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import bandplan, bandplan_iaru_r2 SHORTNAME = "north_america" DESC = { "name": "North American Band Plan", "url": "http://www.arrl.org/band-plan" } BANDS_160M = ( bandplan.Band((1800000, 2000000), "160 Meter Band", mode="CW"), bandplan.Band((1800000, 1810000), "Digital Modes"), bandplan.Band((1843000, 2000000), "SSB, SSTV and other wideband modes"), bandplan.Band((1995000, 2000000), "Experimental"), bandplan.Band((1999000, 2000000), "Beacons"), ) BANDS_80M = ( bandplan.Band((3500000, 4000000), "80 Meter Band"), bandplan.Band((3570000, 3600000), "RTTY/Data", mode="RTTY"), bandplan.Band((3790000, 3800000), "DX window"), ) BANDS_40M = ( bandplan.Band((7000000, 7300000), "40 Meter Band"), bandplan.Band((7080000, 7125000), "RTTY/Data", mode="RTTY"), ) BANDS_30M = ( bandplan.Band((10100000, 10150000), "30 Meter Band"), bandplan.Band((10130000, 10140000), "RTTY", mode="RTTY"), bandplan.Band((10140000, 10150000), "Packet"), ) BANDS_20M = ( bandplan.Band((14000000, 14350000), "20 Meter Band"), bandplan.Band((14070000, 14095000), "RTTY", mode="RTTY"), bandplan.Band((14095000, 14099500), "Packet"), bandplan.Band((14100500, 14112000), "Packet"), ) BANDS_17M = ( bandplan.Band((18068000, 18168000), "17 Meter Band"), bandplan.Band((18100000, 18105000), "RTTY", mode="RTTY"), bandplan.Band((18105000, 18110000), "Packet"), ) BANDS_15M = ( bandplan.Band((21000000, 21450000), "15 Meter Band"), bandplan.Band((21070000, 21110000), "RTTY/Data", mode="RTTY"), ) BANDS_12M = ( bandplan.Band((24890000, 24990000), "12 Meter Band"), bandplan.Band((24920000, 24925000), "RTTY", mode="RTTY"), bandplan.Band((24925000, 24930000), "Packet"), ) BANDS_10M = ( bandplan.Band((28000000, 29700000), "10 Meter Band"), bandplan.Band((28000000, 28070000), "CW", mode="CW"), bandplan.Band((28070000, 28150000), "RTTY", mode="RTTY"), bandplan.Band((28150000, 28190000), "CW", mode="CW"), bandplan.Band((28201000, 28300000), "Beacons", mode="CW"), bandplan.Band((28300000, 29300000), "Phone"), bandplan.Band((29000000, 29200000), "AM", mode="AM"), bandplan.Band((29300000, 29510000), "Satellite Downlinks"), bandplan.Band((29520000, 29590000), "Repeater Inputs", step_khz=10, mode="FM"), bandplan.Band((29610000, 29700000), "Repeater Outputs", step_khz=10, mode="FM", input_offset=-890000), ) BANDS_6M = ( bandplan.Band((50000000, 54000000), "6 Meter Band"), bandplan.Band((50000000, 50100000), "CW, beacons", mode="CW"), bandplan.Band((50060000, 50080000), "beacon subband"), bandplan.Band((50100000, 50300000), "SSB, CW", mode="USB"), bandplan.Band((50100000, 50125000), "DX window", mode="USB"), bandplan.Band((50300000, 50600000), "All modes"), bandplan.Band((50600000, 50800000), "Nonvoice communications"), bandplan.Band((50800000, 51000000), "Radio remote control", step_khz=20), bandplan.Band((51000000, 51100000), "Pacific DX window"), bandplan.Band((51120000, 51180000), "Digital repeater inputs", step_khz=10), bandplan.Band((51500000, 51600000), "Simplex"), bandplan.Band((51620000, 51980000), "Repeater outputs A", input_offset=-500000), bandplan.Band((51620000, 51680000), "Digital repeater outputs", input_offset=-500000), bandplan.Band((52020000, 52040000), "FM simplex", mode="FM"), bandplan.Band((52500000, 52980000), "Repeater outputs B", input_offset=-500000, step_khz=20, mode="FM"), bandplan.Band((53000000, 53100000), "FM simplex", mode="FM"), bandplan.Band((53100000, 53400000), "Radio remote control", step_khz=100), bandplan.Band((53500000, 53980000), "Repeater outputs C", input_offset=-500000), bandplan.Band((53500000, 53800000), "Radio remote control", step_khz=100), bandplan.Band((53520000, 53900000), "Simplex"), ) BANDS_2M = ( bandplan.Band((144000000, 148000000), "2 Meter Band"), bandplan.Band((144000000, 144050000), "EME (CW)", mode="CW"), bandplan.Band((144050000, 144100000), "General CW and weak signals", mode="CW"), bandplan.Band((144100000, 144200000), "EME and weak-signal SSB", mode="USB"), bandplan.Band((144200000, 144275000), "General SSB operation", mode="USB"), bandplan.Band((144275000, 144300000), "Propagation beacons", mode="CW"), bandplan.Band((144300000, 144500000), "OSCAR subband"), bandplan.Band((144600000, 144900000), "FM repeater inputs", mode="FM"), bandplan.Band((144900000, 145100000), "Weak signal and FM simplex", mode="FM", step_khz=10), bandplan.Band((145100000, 145200000), "Linear translator outputs", input_offset=-600000), bandplan.Band((145200000, 145500000), "FM repeater outputs", input_offset=-600000, mode="FM",), bandplan.Band((145500000, 145800000), "Misc and experimental modes"), bandplan.Band((145800000, 146000000), "OSCAR subband"), bandplan.Band((146400000, 146580000), "Simplex"), bandplan.Band((146610000, 146970000), "Repeater outputs", input_offset=-600000), bandplan.Band((147000000, 147390000), "Repeater outputs", input_offset=600000), bandplan.Band((147420000, 147570000), "Simplex"), ) BANDS_1_25M = ( bandplan.Band((222000000, 225000000), "1.25 Meter Band"), bandplan.Band((222000000, 222150000), "Weak-signal modes"), bandplan.Band((222000000, 222025000), "EME"), bandplan.Band((222050000, 222060000), "Propagation beacons"), bandplan.Band((222100000, 222150000), "Weak-signal CW & SSB"), bandplan.Band((222150000, 222250000), "Local coordinator's option"), bandplan.Band((223400000, 223520000), "FM simplex", mode="FM"), bandplan.Band((223520000, 223640000), "Digital, packet"), bandplan.Band((223640000, 223700000), "Links, control"), bandplan.Band((223710000, 223850000), "Local coordinator's option"), bandplan.Band((223850000, 224980000), "Repeater outputs only", mode="FM", input_offset=-1600000), ) BANDS_70CM = ( bandplan.Band((420000000, 450000000), "70 Centimeter Band"), bandplan.Band((420000000, 426000000), "ATV repeater or simplex"), bandplan.Band((426000000, 432000000), "ATV simplex"), bandplan.Band((432000000, 432070000), "EME (Earth-Moon-Earth)"), bandplan.Band((432070000, 432100000), "Weak-signal CW", mode="CW"), bandplan.Band((432100000, 432300000), "Mixed-mode and weak-signal work"), bandplan.Band((432300000, 432400000), "Propagation beacons"), bandplan.Band((432400000, 433000000), "Mixed-mode and weak-signal work"), bandplan.Band((433000000, 435000000), "Auxiliary/repeater links"), bandplan.Band((435000000, 438000000), "Satellite only (internationally)"), bandplan.Band((438000000, 444000000), "ATV repeater input/repeater links", input_offset=5000000), bandplan.Band((442000000, 445000000), "Repeater input/output (local option)", input_offset=5000000), bandplan.Band((445000000, 447000000), "Shared by aux and control links, " "repeaters, simplex (local option)"), bandplan.Band((447000000, 450000000), "Repeater inputs and outputs " "(local option)", input_offset=-5000000), ) BANDS_33CM = ( bandplan.Band((902000000, 928000000), "33 Centimeter Band"), bandplan.Band((902075000, 902100000), "CW/SSB, Weak signal"), bandplan.Band((902100000, 902125000), "CW/SSB, Weak signal"), bandplan.Band((903000000, 903100000), "CW/SSB, Beacons and weak signal"), bandplan.Band((903100000, 903400000), "CW/SSB, Weak signal"), bandplan.Band((903400000, 909000000), "Mixed modes, Mixed operations " "including control links"), bandplan.Band((909000000, 915000000), "Analog/digital Broadband multimedia " "including ATV, DATV and SS"), bandplan.Band((915000000, 921000000), "Analog/digital Broadband multimedia " "including ATV, DATV and SS"), bandplan.Band((921000000, 927000000), "Analog/digital Broadband multimedia " "including ATV, DATV and SS"), bandplan.Band((927000000, 927075000), "FM / other including DV or CW/SSB", input_offset=-25000000, step_khz=12.5), bandplan.Band((927075000, 927125000), "FM / other including DV. Simplex"), bandplan.Band((927125000, 928000000), "FM / other including DV", input_offset=-25000000, step_khz=12.5), ) BANDS_23CM = ( bandplan.Band((1240000000, 1300000000), "23 Centimeter Band"), bandplan.Band((1240000000, 1246000000), "ATV Channel #1"), bandplan.Band((1246000000, 1248000000), "Point-to-point links paired " "with 1258.000-1260.000", mode="FM"), bandplan.Band((1248000000, 1252000000), "Digital"), bandplan.Band((1252000000, 1258000000), "ATV Channel #2"), bandplan.Band((1258000000, 1260000000), "Point-to-point links paired with 1246.000-1248.000", mode="FM"), bandplan.Band((1240000000, 1260000000), "Regional option, FM ATV"), bandplan.Band((1260000000, 1270000000), "Satellite uplinks, Experimental, " "Simplex ATV"), bandplan.Band((1270000000, 1276000000), "FM, digital Repeater inputs " "(Regional option)", step_khz=25), bandplan.Band((1276000000, 1282000000), "ATV Channel #3"), bandplan.Band((1282000000, 1288000000), "FM, digital repeater outputs", step_khz=25, input_offset=-12000000), bandplan.Band((1288000000, 1294000000), "Various Broadband Experimental, " "Simplex ATV"), bandplan.Band((1290000000, 1294000000), "FM, digital Repeater outputs " "(Regional option)", step_khz=25, input_offset=-20000000), bandplan.Band((1294000000, 1295000000), "FM simplex", mode="FM"), bandplan.Band((1295000000, 1297000000), "Narrow Band Segment"), bandplan.Band((1295000000, 1295800000), "Narrow Band Image, Experimental"), bandplan.Band((1295800000, 1296080000), "CW, SSB, digital EME"), bandplan.Band((1296080000, 1296200000), "CW, SSB Weak Signal"), bandplan.Band((1296200000, 1296400000), "CW, digital Beacons"), bandplan.Band((1296400000, 1297000000), "General Narrow Band"), bandplan.Band((1297000000, 1300000000), "Digital"), ) BANDS_13CM = ( bandplan.Band((2300000000, 2450000000), "13 Centimeter Band"), bandplan.Band((2300000000, 2303000000), "Analog & Digital 0.05-1.0 MHz, " "including full duplex; paired with 2390-2393"), bandplan.Band((2303000000, 2303750000), "Analog & Digital <50 kHz; " "paired with 2393 - 2393.750"), bandplan.Band((2303750000, 2304000000), "SSB, CW, digital weak-signal"), bandplan.Band((2304000000, 2304100000), "Weak Signal EME Band, <3 kHz"), bandplan.Band((2304100000, 2304300000), "SSB, CW, digital weak-signal, <3 kHz"), bandplan.Band((2304300000, 2304400000), "Beacons, <3 kHz"), bandplan.Band((2304400000, 2304750000), "SSB, CW, digital weak-signal and " "NBFM, <6 kHz"), bandplan.Band((2304750000, 2305000000), "Analog & Digital; paired with " "2394.750-2395, <50 kHz"), bandplan.Band((2305000000, 2310000000), "Analog & Digital, paired with " "2395-2400, 0.05 - 1.0 MHz"), bandplan.Band((2310000000, 2390000000), "NON-AMATEUR"), bandplan.Band((2390000000, 2393000000), "Analog & Digital, including full " "duplex; paired with 2300-2303, 0.05 - 1.0 MHz"), bandplan.Band((2393000000, 2393750000), "Analog & Digital; paired with " "2303-2303.750, < 50 kHz"), bandplan.Band((2393750000, 2394750000), "Experimental"), bandplan.Band((2394750000, 2395000000), "Analog & Digital; paired with " "2304.750-2305, < 50 kHz"), bandplan.Band((2395000000, 2400000000), "Analog & Digital, including full " "duplex; paired with 2305-2310, 0.05-1.0 MHz"), bandplan.Band((2400000000, 2410000000), "Amateur Satellite Communications, " "<6 kHz"), bandplan.Band((2410000000, 2450000000), "Broadband Modes, 22 MHz max."), ) BANDS = bandplan_iaru_r2.BANDS + \ BANDS_160M + BANDS_80M + BANDS_40M + BANDS_30M + BANDS_20M + \ BANDS_17M + BANDS_15M + BANDS_12M + BANDS_10M + BANDS_6M + \ BANDS_2M + BANDS_1_25M + BANDS_70CM + BANDS_33CM + BANDS_23CM + \ BANDS_13CM # US 2017+ GMRS/FRS Frequencies GMRS_LOW = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] GMRS_HHONLY = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] GMRS_HIRPT = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] ALL_GMRS_FREQS = GMRS_LOW + GMRS_HHONLY + GMRS_HIRPT # US MURS Frequencies MURS_NFM = [151820000, 151880000, 151940000] MURS_FM = [154570000, 154600000] ALL_MURS_FREQS = MURS_NFM + MURS_FM chirp-20240224/chirp/detect.py0000644000175000017500000000674514430171343014777 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import serial import logging from chirp import chirp_common, errors, directory from chirp.drivers import ic9x_ll, icf, kenwood_live, icomciv LOG = logging.getLogger(__name__) class DetectorRadio(chirp_common.Radio): """Minimal radio for model detection""" def get_payload(self, data, raw, checksum): return data def _icom_model_data_to_rclass(md): for _rtype, rclass in list(directory.DRV_TO_RADIO.items()): if rclass.VENDOR != "Icom": continue if not hasattr(rclass, 'get_model') or not rclass.get_model(): continue if rclass.get_model()[:4] == md[:4]: return rclass raise errors.RadioError("Unknown radio type %02x%02x%02x%02x" % (ord(md[0]), ord(md[1]), ord(md[2]), ord(md[3]))) def _detect_icom_radio(ser): # ICOM VHF/UHF Clone-type radios @ 9600 baud try: ser.baudrate = 9600 md = icf.get_model_data(DetectorRadio(ser)) return _icom_model_data_to_rclass(md) except errors.RadioError as e: LOG.error("_detect_icom_radio: %s", e) # ICOM IC-91/92 Live-mode radios @ 4800/38400 baud ser.baudrate = 4800 try: ic9x_ll.send_magic(ser) return _icom_model_data_to_rclass("ic9x") except errors.RadioError: pass # ICOM CI/V Radios @ various bauds for rate in [9600, 4800, 19200]: try: ser.baudrate = rate return icomciv.probe_model(ser) except errors.RadioError: pass ser.close() raise errors.RadioError("Unable to get radio model") def detect_icom_radio(port): """Detect which Icom model is connected to @port""" if '://' in port: ser = serial.serial_for_url(port, do_not_open=True) ser.timeout = 0.5 ser.open() else: ser = serial.Serial(port=port, timeout=0.5) try: result = _detect_icom_radio(ser) except Exception: ser.close() raise ser.close() LOG.info("Auto-detected %s %s on %s" % (result.VENDOR, result.MODEL, port)) return result def detect_kenwoodlive_radio(port): """Detect which Kenwood model is connected to @port""" if '://' in port: ser = serial.serial_for_url(port, do_not_open=True) ser.timeout = 0.5 ser.open() else: ser = serial.Serial(port=port, baudrate=9600, timeout=0.5) r_id = kenwood_live.get_id(ser) ser.close() models = {} for rclass in list(directory.DRV_TO_RADIO.values()): if rclass.VENDOR == "Kenwood": models[rclass.MODEL] = rclass if r_id in list(models.keys()): return models[r_id] else: raise errors.RadioError("Unsupported model `%s'" % r_id) DETECT_FUNCTIONS = { "Icom": detect_icom_radio, "Kenwood": detect_kenwoodlive_radio, } chirp-20240224/chirp/pyPEG.py0000644000175000017500000002716614430171343014513 0ustar hibbyhibby# YPL parser 1.5 # written by VB. import re import sys import collections import six class keyword(str): pass class code(str): pass class ignore(object): def __init__(self, regex_text, *args): self.regex = re.compile(regex_text, *args) class _and(object): def __init__(self, something): self.obj = something class _not(_and): pass class Name(str): def __init__(self, *args): self.line = 0 self.file = "" class Symbol(list): def __init__(self, name, what): self.__name__ = name self.append(name) self.what = what self.append(what) def __call__(self): return self.what def __unicode__(self): return 'Symbol(' + repr(self.__name__) + ', ' + repr(self.what) + ')' def __repr__(self): return str(self) word_regex = re.compile(r"\w+") rest_regex = re.compile(r".*") print_trace = False def u(text): return six.text_type(text) def skip(skipper, text, skipWS, skipComments): if skipWS: t = text.lstrip() else: t = text if skipComments: try: while True: skip, t = skipper.parseLine(t, skipComments, [], skipWS, None) if skipWS: t = t.lstrip() except Exception: pass return t class parser(object): def __init__(self, another=False, p=False): self.restlen = -1 if not (another): self.skipper = parser(True, p) self.skipper.packrat = p else: self.skipper = self self.lines = None self.textlen = 0 self.memory = {} self.packrat = p # parseLine(): # textline: text to parse # pattern: pyPEG language description # resultSoFar: parsing result so far (default: blank list []) # skipWS: Flag if whitespace should be skipped (default: True) # skipComments: Python functions returning pyPEG for matching comments # # returns: pyAST, textrest # # raises: SyntaxError(reason) if textline is detected not # being in language described by pattern # # SyntaxError(reason) if pattern is an illegal # language description def parseLine(self, textline, pattern, resultSoFar=[], skipWS=True, skipComments=None): name = None _textline = textline _pattern = pattern def R(result, text): if __debug__: if print_trace: try: if _pattern.__name__ != "comment": sys.stderr.write("match: " + _pattern.__name__ + "\n") except Exception: pass if self.restlen == -1: self.restlen = len(text) else: self.restlen = min(self.restlen, len(text)) res = resultSoFar if name and result: name.line = self.lineNo() res.append(Symbol(name, result)) elif name: name.line = self.lineNo() res.append(Symbol(name, [])) elif result: if isinstance(result, list): res.extend(result) else: res.extend([result]) if self.packrat: self.memory[(len(_textline), id(_pattern))] = (res, text) return res, text def syntaxError(): if self.packrat: self.memory[(len(_textline), id(_pattern))] = False raise SyntaxError() if self.packrat: try: result = self.memory[(len(textline), id(pattern))] if result: return result else: raise SyntaxError() except Exception: pass if isinstance(pattern, collections.abc.Callable): if __debug__: if print_trace: try: if pattern.__name__ != "comment": sys.stderr.write("testing with " + pattern.__name__ + ": " + textline[:40] + "\n") except Exception: pass if pattern.__name__[0] != "_": name = Name(pattern.__name__) pattern = pattern() if isinstance(pattern, collections.abc.Callable): pattern = (pattern,) text = skip(self.skipper, textline, skipWS, skipComments) pattern_type = type(pattern) if pattern_type is str or pattern_type is str: if text[:len(pattern)] == pattern: text = skip(self.skipper, text[len(pattern):], skipWS, skipComments) return R(None, text) else: syntaxError() elif pattern_type is keyword: m = word_regex.match(text) if m: if m.group(0) == pattern: text = skip(self.skipper, text[len(pattern):], skipWS, skipComments) return R(None, text) else: syntaxError() else: syntaxError() elif pattern_type is _not: try: r, t = self.parseLine(text, pattern.obj, [], skipWS, skipComments) except Exception: return resultSoFar, textline syntaxError() elif pattern_type is _and: r, t = self.parseLine(text, pattern.obj, [], skipWS, skipComments) return resultSoFar, textline elif pattern_type is type(word_regex) or pattern_type is ignore: if pattern_type is ignore: pattern = pattern.regex m = pattern.match(text) if m: text = skip(self.skipper, text[len(m.group(0)):], skipWS, skipComments) if pattern_type is ignore: return R(None, text) else: return R(m.group(0), text) else: syntaxError() elif pattern_type is tuple: result = [] n = 1 for p in pattern: if isinstance(p, int): n = p else: if n > 0: for i in range(n): result, text = self.parseLine( text, p, result, skipWS, skipComments) elif n == 0: if text == "": pass else: try: newResult, newText = self.parseLine( text, p, result, skipWS, skipComments) result, text = newResult, newText except SyntaxError: pass elif n < 0: found = False while True: try: newResult, newText = self.parseLine( text, p, result, skipWS, skipComments) result, text, found = newResult, newText, True except SyntaxError: break if n == -2 and not (found): syntaxError() n = 1 return R(result, text) elif pattern_type is list: result = [] found = False for p in pattern: try: result, text = self.parseLine(text, p, result, skipWS, skipComments) found = True except SyntaxError: pass if found: break if found: return R(result, text) else: syntaxError() else: raise SyntaxError("illegal type in grammar: " + u(pattern_type)) def lineNo(self): if not (self.lines): return "" if self.restlen == -1: return "" parsed = self.textlen - self.restlen left, right = 0, len(self.lines) while True: mid = int((right + left) / 2) if self.lines[mid][0] <= parsed: try: if self.lines[mid + 1][0] >= parsed: try: return u(self.lines[mid + 1][1]) + \ ":" + u(self.lines[mid + 1][2]) except Exception: return "" else: left = mid + 1 except Exception: try: return u(self.lines[mid + 1][1]) + \ ":" + u(self.lines[mid + 1][2]) except Exception: return "" else: right = mid - 1 if left > right: return "" # plain module APIs def parseLine(textline, pattern, resultSoFar=[], skipWS=True, skipComments=None, packrat=False): p = parser(p=packrat) text = skip(p.skipper, textline, skipWS, skipComments) ast, text = p.parseLine(text, pattern, resultSoFar, skipWS, skipComments) return ast, text # parse(): # language: pyPEG language description # lineSource: a fileinput.FileInput object # skipWS: Flag if whitespace should be skipped (default: True) # skipComments: Python function which returns pyPEG for matching comments # packrat: use memoization # lineCount: add line number information to AST # # returns: pyAST # # raises: SyntaxError(reason), if a parsed line is not in language # SyntaxError(reason), if the language description is illegal def parse(language, lineSource, skipWS=True, skipComments=None, packrat=False, lineCount=True): lines, lineNo = [], 0 while isinstance(language, collections.abc.Callable): language = language() orig, ld = "", 0 for line in lineSource: if lineSource.isfirstline(): ld = 1 else: ld += 1 lines.append((len(orig), lineSource.filename(), lineSource.lineno() - 1)) orig += u(line) textlen = len(orig) try: p = parser(p=packrat) p.textlen = len(orig) if lineCount: p.lines = lines else: p.line = None text = skip(p.skipper, orig, skipWS, skipComments) result, text = p.parseLine(text, language, [], skipWS, skipComments) if text: raise SyntaxError() except SyntaxError: parsed = textlen - p.restlen textlen = 0 nn, lineNo, file = 0, 0, "" for n, ld, l in lines: if n >= parsed: break else: lineNo = l nn += 1 file = ld lineNo += 1 nn -= 1 lineCont = orig.splitlines()[nn] raise SyntaxError("syntax error in " + u(file) + ":" + u(lineNo) + ": " + lineCont) return result chirp-20240224/chirp/memmap.py0000644000175000017500000001065614430171343014777 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import six from chirp import util class MemoryMapBytes(object): """ This is the proper way for MemoryMap to work, which is in terms of bytes always. """ def __init__(self, data): assert isinstance(data, bytes) self._data = list(data) def printable(self, start=None, end=None): """Return a printable representation of the memory map""" if not start: start = 0 if not end: end = len(self._data) string = util.hexprint(self._data[start:end]) return string def get(self, start, length=1): """Return a chunk of memory of @length bytes from @start""" if length == -1: return bytes(self._data[start:]) else: end = start + length d = self._data[start:end] return bytes(d) def set(self, pos, value): """Set a chunk of memory at @pos to @value""" pos = int(pos) if isinstance(value, int): self._data[pos] = value & 0xFF elif isinstance(value, bytes): for byte in bytes(value): self._data[pos] = byte pos += 1 elif isinstance(value, str): if six.PY3: value = value.encode() for byte in value: self._data[pos] = ord(byte) pos += 1 else: raise ValueError("Unsupported type %s for value" % type(value).__name__) def get_packed(self): """Return the entire memory map as raw data""" return bytes(self._data) def __len__(self): return len(self._data) def __getslice__(self, start, end): return self.get(start, end-start) def __getitem__(self, pos): if isinstance(pos, slice): if pos.stop is None: return self.get(pos.start, -1) return self.get(pos.start, pos.stop - pos.start) else: return self.get(pos) def __setitem__(self, pos, value): """ NB: Setting a value of more than one character overwrites len(value) bytes of the map, unlike a typical array! """ self.set(pos, value) def __str__(self): return self.get_packed() def __repr__(self): return self.printable() def truncate(self, size): """Truncate the memory map to @size""" self._data = self._data[:size] def get_byte_compatible(self): return self class MemoryMap(MemoryMapBytes): """Compatibility version of MemoryMapBytes This deals in strings for compatibility with drivers that do. """ def __init__(self, data): # Fix circular dependency from chirp import bitwise self._bitwise = bitwise if six.PY3 and isinstance(data, bytes): # Be graceful if py3-enabled code uses this, # just don't encode it encode = bytes else: encode = self._bitwise.string_straight_encode super(MemoryMap, self).__init__(encode(data)) def get(self, pos, length=1): return self._bitwise.string_straight_decode( super(MemoryMap, self).get(pos, length=length)) def set(self, pos, value): if isinstance(value, int): # Apparently this is a thing that drivers do, so # be compatible here value = chr(value) super(MemoryMap, self).set( pos, self._bitwise.string_straight_encode(value)) def get_packed(self): return self._bitwise.string_straight_decode( super(MemoryMap, self).get_packed()) def get_byte_compatible(self): mmb = MemoryMapBytes(bytes(self._data)) self._data = mmb._data return mmb chirp-20240224/chirp/bandplan_iaru_r3.py0000644000175000017500000001250514563632215016730 0ustar hibbyhibby# Copyright 2013 Sean Burford # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import bandplan SHORTNAME = "iaru_r3" DESC = { "name": "IARU Region 3 (Asia Pacific)", "updated": "16 October 2009", "url": "http://www.iaru.org/uploads/1/3/0/7/13073366/r3_band_plan.pdf" } # Bands are broken up like this so that other plans can import bits. BANDS_2100M = ( bandplan.Band((135700, 137800), "137 kHz Band", mode="CW"), ) BANDS_160M = ( bandplan.Band((1800000, 2000000), "160 Meter Band"), bandplan.Band((1830000, 1840000), "Digimodes", mode="RTTY"), bandplan.Band((1840000, 2000000), "Phone"), ) BANDS_80M = ( bandplan.Band((3500000, 3900000), "80 Meter Band"), bandplan.Band((3500000, 3510000), "CW, priority for DX", mode="CW"), bandplan.Band((3535000, 3900000), "Phone"), bandplan.Band((3775000, 3800000), "All modes, SSB DX preferred", mode="LSB"), ) BANDS_40M = ( bandplan.Band((7000000, 7300000), "40 Meter Band"), bandplan.Band((7000000, 7025000), "CW, priority for DX", mode="CW"), bandplan.Band((7025000, 7035000), "All narrow band modes, cw", mode="CW"), bandplan.Band((7035000, 7040000), "All narrow band modes, phone"), bandplan.Band((7040000, 7300000), "All modes, digimodes"), ) BANDS_30M = ( bandplan.Band((10100000, 10150000), "30 Meter Band"), bandplan.Band((10100000, 10130000), "CW", mode="CW"), bandplan.Band((10130000, 10150000), "All narrow band digimodes"), ) BANDS_20M = ( bandplan.Band((14000000, 14350000), "20 Meter Band"), bandplan.Band((14000000, 14070000), "CW", mode="CW"), bandplan.Band((14070000, 14099000), "All narrow band modes, digimodes"), bandplan.Band((14099000, 14101000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((14101000, 14112000), "All narrow band modes, digimodes"), bandplan.Band((14101000, 14350000), "All modes, digimodes"), ) BANDS_17M = ( bandplan.Band((18068000, 18168000), "17 Meter Band"), bandplan.Band((18068000, 18100000), "CW", mode="CW"), bandplan.Band((18100000, 18109000), "All narrow band modes, digimodes"), bandplan.Band((18109000, 18111000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((18111000, 18168000), "All modes, digimodes"), ) BANDS_15M = ( bandplan.Band((21000000, 21450000), "15 Meter Band"), bandplan.Band((21000000, 21070000), "CW", mode="CW"), bandplan.Band((21070000, 21125000), "All narrow band modes, digimodes"), bandplan.Band((21125000, 21149000), "All narrow band modes, digimodes"), bandplan.Band((21149000, 21151000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((21151000, 21450000), "All modes", mode="USB"), ) BANDS_12M = ( bandplan.Band((24890000, 24990000), "12 Meter Band"), bandplan.Band((24890000, 24920000), "CW", mode="CW"), bandplan.Band((24920000, 24929000), "All narrow band modes, digimodes"), bandplan.Band((24929000, 24931000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((24931000, 24990000), "All modes, digimodes", mode="USB"), ) BANDS_10M = ( bandplan.Band((28000000, 29700000), "10 Meter Band"), bandplan.Band((28000000, 28050000), "CW", mode="CW"), bandplan.Band((28050000, 28150000), "All narrow band modes, digimodes"), bandplan.Band((28150000, 28190000), "All narrow band modes, digimodes"), bandplan.Band((28190000, 28199000), "Beacons", mode="CW"), bandplan.Band((28199000, 28201000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((28201000, 28300000), "Beacons", mode="CW"), bandplan.Band((28300000, 29300000), "Phone"), bandplan.Band((29300000, 29510000), "Satellite downlink"), bandplan.Band((29510000, 29520000), "Guard band, no transmission allowed"), bandplan.Band((29520000, 29700000), "Wide band", step_khz=10, mode="NFM"), ) BANDS_6M = ( bandplan.Band((50000000, 54000000), "6 Meter Band"), bandplan.Band((50000000, 50100000), "Beacons", mode="CW"), bandplan.Band((50100000, 50500000), "Phone and narrow band"), bandplan.Band((50500000, 54000000), "Wide band"), ) BANDS_2M = ( bandplan.Band((144000000, 148000000), "2 Meter Band"), bandplan.Band((144000000, 144035000), "Earth Moon Earth"), bandplan.Band((145800000, 146000000), "Satellite"), ) BANDS_70CM = ( bandplan.Band((430000000, 450000000), "70cm Band"), bandplan.Band((431900000, 432240000), "Earth Moon Earth"), bandplan.Band((435000000, 438000000), "Satellite"), ) BANDS_23CM = ( bandplan.Band((1240000000, 1300000000), "23cm Band"), bandplan.Band((1260000000, 1270000000), "Satellite"), bandplan.Band((1296000000, 1297000000), "Earth Moon Earth"), ) BANDS = BANDS_2100M + BANDS_160M + BANDS_80M + BANDS_40M + BANDS_30M + \ BANDS_20M + BANDS_17M + BANDS_15M + BANDS_12M + BANDS_10M + \ BANDS_6M + BANDS_2M + BANDS_70CM + BANDS_23CM chirp-20240224/chirp/errors.py0000644000175000017500000000264714411666130015042 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . class InvalidDataError(Exception): """The radio driver encountered some invalid data""" pass class InvalidValueError(Exception): """An invalid value for a given parameter was used""" pass class InvalidMemoryLocation(Exception): """The requested memory location does not exist""" pass class RadioError(Exception): """An error occurred while talking to the radio""" pass class UnsupportedToneError(Exception): """The radio does not support the specified tone value""" pass class ImageDetectFailed(Exception): """The driver for the supplied image could not be determined""" pass class ImageMetadataInvalidModel(Exception): """The image contains metadata but no suitable driver is found""" pass chirp-20240224/chirp/wxui/0000755000175000017500000000000014566340177014152 5ustar hibbyhibbychirp-20240224/chirp/wxui/bankedit.py0000644000175000017500000002577714440315552016315 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import platform import wx import wx.grid from chirp import chirp_common from chirp.wxui import common from chirp.wxui import config from chirp.wxui import memedit CONF = config.get() if platform.system() == 'Linux': BANK_SET_VALUE = 'X' else: BANK_SET_VALUE = '1' class ChirpBankToggleColumn(memedit.ChirpMemoryColumn): def __init__(self, bank, radio): self.bank = bank super().__init__('bank-%s' % bank.get_index(), radio) @property def label(self): return '%s(%s)' % (self.bank.get_name(), self.bank.get_index()) def hidden_for(self, memory): return False def get_editor(self): return wx.grid.GridCellBoolEditor() def get_renderer(self): return wx.grid.GridCellBoolRenderer() class ChirpBankIndexColumn(memedit.ChirpMemoryColumn): def __init__(self, model, radio): self.model = model super().__init__('bank_index', radio) @property def label(self): return _('Index') def get_editor(self): lower, upper = self.model.get_index_bounds() return wx.grid.GridCellNumberEditor(lower, upper) class ChirpBankEdit(common.ChirpEditor): def __init__(self, radio, *a, **k): super(ChirpBankEdit, self).__init__(*a, **k) self._radio = radio self._features = radio.get_features() self._bankmodel = radio.get_bank_model() self._col_defs = self._setup_columns() self._grid = memedit.ChirpMemoryGrid(self) self._grid.CreateGrid( self._features.memory_bounds[1] - self._features.memory_bounds[0] + 1, len(self._col_defs)) # GridSelectNone only available in >=4.2.0 if hasattr(wx.grid.Grid, 'GridSelectNone'): self._grid.SetSelectionMode(wx.grid.Grid.GridSelectNone) self._grid.DisableDragRowSize() self._grid.SetFocus() sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self._grid, proportion=1, flag=wx.EXPAND) self.SetSizer(sizer) self._fixed_font = wx.Font(pointSize=10, family=wx.FONTFAMILY_TELETYPE, style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL) self._variable_font = self._grid.GetDefaultCellFont() self.update_font(False) for col, col_def in enumerate(self._col_defs): self._grid.SetColLabelValue(col, col_def.label) attr = wx.grid.GridCellAttr() if platform.system() != 'Linux': attr.SetEditor(col_def.get_editor()) attr.SetRenderer(col_def.get_renderer()) attr.SetReadOnly(not (isinstance(col_def, ChirpBankToggleColumn) or isinstance(col_def, ChirpBankIndexColumn))) attr.SetAlignment(wx.ALIGN_CENTER, wx.ALIGN_CENTER) self._grid.SetColAttr(col, attr) self._memory_cache = {} self._grid.Bind(wx.grid.EVT_GRID_CELL_CHANGING, self._index_changed) self._grid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self._memory_changed) self._grid.Bind(wx.grid.EVT_GRID_LABEL_LEFT_DCLICK, self._label_click) self._grid.GetGridColLabelWindow().Bind(wx.EVT_MOTION, self._colheader_mouseover) def update_font(self, refresh=True): fixed = CONF.get_bool('font_fixed', 'state', False) large = CONF.get_bool('font_large', 'state', False) if fixed: font = self._fixed_font else: font = self._variable_font if large: font = wx.Font(font) font.SetPointSize(font.PointSize + 2) self._grid.SetDefaultCellFont(font) if refresh: self.refresh() wx.CallAfter(self._grid.AutoSizeColumns, setAsMin=False) wx.CallAfter(self._grid.AutoSizeRows, setAsMin=False) def selected(self): self.refresh_memories() def refresh_memories(self): self._memory_cache = {} lower, upper = self._features.memory_bounds for i in range(lower, upper + 1): mem = self._radio.get_memory(i) self._refresh_memory(mem) wx.CallAfter(self._grid.AutoSizeColumns, setAsMin=True) def _setup_columns(self): defs = [ memedit.ChirpFrequencyColumn('freq', self._radio), memedit.ChirpMemoryColumn('name', self._radio), ] if isinstance(self._bankmodel, chirp_common.MappingModelIndexInterface): defs.append(ChirpBankIndexColumn(self._bankmodel, self._radio)) self._meta_cols = len(defs) self._bank_indexes = {} self._bank_index_order = [] for bank in self._bankmodel.get_mappings(): self._bank_index_order.append(bank.get_index()) self._bank_indexes[bank.get_index()] = bank defs.append(ChirpBankToggleColumn(bank, self._radio)) return defs def col2bank(self, col): if col < self._meta_cols: raise RuntimeError('Error: column %i is not a bank' % col) return col - self._meta_cols def bank2col(self, bank): return bank + self._meta_cols def row2mem(self, row): return row + self._features.memory_bounds[0] def mem2row(self, mem): return mem - self._features.memory_bounds[0] def _colheader_mouseover(self, event): x = event.GetX() y = event.GetY() col = self._grid.XToCol(x, y) tip = '' if col >= self._meta_cols: bank = self._bankmodel.get_mappings()[self.col2bank(col)] if hasattr(bank, 'set_name'): tip = _('Double-click to change bank name') self._grid.GetGridColLabelWindow().SetToolTip(tip) def _label_click(self, event): row = event.GetRow() col = event.GetCol() if row != -1: # Row labels do not change return bank = self._bankmodel.get_mappings()[self.col2bank(col)] if not hasattr(bank, 'set_name'): return d = wx.TextEntryDialog(self, _('Enter a new name for bank %s:') % ( bank.get_index()), _('Rename bank')) d.SetValue(bank.get_name()) if d.ShowModal() == wx.ID_OK: self.change_bank_name(col, bank, d.GetValue()) wx.PostEvent(self, common.EditorChanged(self.GetId())) def change_bank_name(self, col, bank, name): bank.set_name(name) # Refresh the column from the col def to make sure it stuck col_def = self._col_defs[col] self._grid.SetColLabelValue(col, col_def.label) wx.CallAfter(self._grid.AutoSizeColumns, setAsMin=True) @common.error_proof() def _index_changed(self, event): row = event.GetRow() col = event.GetCol() value = event.GetString() if isinstance(self._col_defs[col], ChirpBankIndexColumn): self._change_memory_index(self.row2mem(row), int(value)) def _change_memory_index(self, number, index): for i, bank_index in enumerate(self._bank_index_order): if self._grid.GetCellValue(self.mem2row(number), self.bank2col(i)) == BANK_SET_VALUE: member_bank = self._bank_indexes[bank_index] break else: raise Exception(_('Memory must be in a bank to be edited')) self._bankmodel.set_memory_index(self._memory_cache[number], member_bank, index) wx.PostEvent(self, common.EditorChanged(self.GetId())) @common.error_proof() def _memory_changed(self, event): row = event.GetRow() col = event.GetCol() value = self._grid.GetCellValue(row, col) if isinstance(self._col_defs[col], ChirpBankIndexColumn): event.Skip() elif col < self._meta_cols: event.Skip() else: self._change_memory_mapping(self.row2mem(row), self.col2bank(col), value != BANK_SET_VALUE) def _change_memory_mapping(self, number, bank, present): mem = self._memory_cache[number] bank = self._bank_indexes[self._bank_index_order[bank]] if present: self._bankmodel.add_memory_to_mapping(mem, bank) else: self._bankmodel.remove_memory_from_mapping(mem, bank) self._refresh_memory(mem) wx.PostEvent(self, common.EditorChanged(self.GetId())) @common.error_proof() def _refresh_memory(self, mem): self._memory_cache[mem.number] = mem self._grid.SetRowLabelValue(self.mem2row(mem.number), '%i' % mem.number) bank_index = None member = [bank.get_index() for bank in self._bankmodel.get_memory_mappings(mem)] for i, bank in enumerate(self._bank_indexes.values()): present = bank.get_index() in member and not mem.empty self._grid.SetCellValue(self.mem2row(mem.number), self.bank2col(i), present and BANK_SET_VALUE or '') if present and isinstance(self._bankmodel, chirp_common.MappingModelIndexInterface): # NOTE: if this is somehow an indexed many-to-one model, # we will only get the last index! bank_index = self._bankmodel.get_memory_index(mem, bank) for i in range(0, self._meta_cols): meta_col = self._col_defs[i] if meta_col.name == 'freq': freq = '' if mem.empty else chirp_common.format_freq(mem.freq) self._grid.SetCellValue( self.mem2row(mem.number), i, freq) elif meta_col.name == 'name': self._grid.SetCellValue( self.mem2row(mem.number), i, '' if mem.empty else mem.name) elif meta_col.name == 'bank_index' and bank_index is not None: self._grid.SetCellValue( self.mem2row(mem.number), i, '' if mem.empty else '%i' % bank_index) class ChirpBankEditSync(ChirpBankEdit, common.ChirpSyncEditor): pass chirp-20240224/chirp/wxui/memedit.py0000644000175000017500000025625314566340166016163 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import functools import logging import pickle import sys import wx import wx.lib.newevent import wx.grid import wx.propgrid import wx.lib.mixins.gridlabelrenderer as glr from chirp import chirp_common from chirp import directory from chirp import bandplan from chirp.drivers import generic_csv from chirp import errors from chirp import import_logic from chirp import settings from chirp.wxui import config from chirp.wxui import common from chirp.wxui import developer _ = wx.GetTranslation LOG = logging.getLogger(__name__) CONF = config.get() WX_GTK = 'gtk' in wx.version().lower() class ChirpMemoryGrid(wx.grid.Grid, glr.GridWithLabelRenderersMixin): def __init__(self, *a, **k): wx.grid.Grid.__init__(self, *a, **k) self.SetColLabelSize(wx.grid.GRID_AUTOSIZE) glr.GridWithLabelRenderersMixin.__init__(self) class ChirpRowLabelRenderer(glr.GridDefaultRowLabelRenderer): def __init__(self, *a, **k): super().__init__(*a, **k) self.bgcolor = None def set_error(self): self.bgcolor = '#FF0000' def set_progress(self): self.bgcolor = '#98FB98' def clear_error(self): self.bgcolor = None def Draw(self, grid, dc, rect, row): if self.bgcolor: dc.SetBrush(wx.Brush(self.bgcolor)) dc.SetPen(wx.TRANSPARENT_PEN) dc.DrawRectangle(rect) hAlign, vAlign = grid.GetRowLabelAlignment() text = grid.GetRowLabelValue(row) self.DrawBorder(grid, dc, rect) self.DrawText(grid, dc, rect, text, hAlign, vAlign) DEFAULT_COLUMN_HELP = { 'freq': _('Receive frequency'), 'name': _('Memory label (stored in radio)'), 'tmode': _('Tone squelch mode'), 'rtone': _('Transmit tone'), 'ctone': _('Transmit/receive tone for TSQL mode, else receive tone'), 'dtcs': _('Transmit/receive DTCS code for DTCS mode, else transmit code'), 'rx_dtcs': _('Receive DTCS code'), 'dtcs_polarity': _('TX-RX DTCS polarity (normal or reversed)'), 'cross_mode': _('Complex or non-standard tone squelch mode ' '(starts the tone mode selection wizard)'), 'duplex': _('Transmit shift, split mode, or transmit inhibit'), 'offset': _('Shift amount (or transmit frequency) controlled by duplex'), 'tuning_step': _('Frequency granularity in kHz'), 'skip': _('Scan control (skip, include, priority, etc)'), 'power': _('Transmit Power'), 'comment': _('Human-readable comment (not stored in radio)'), } class ChirpMemoryColumn(object): DEFAULT: object = '' def __init__(self, name, radio, label=None): """ :param name: The name on the Memory object that this represents :param label: Static label override """ self._name = name self._label = label or _(name.title()) self._radio = radio self._features = radio.get_features() self._doc = None @property def name(self): return self._name @property def doc(self): return self._doc or DEFAULT_COLUMN_HELP.get(self.name) @doc.setter def doc(self, value): self._doc = value @property def label(self): labelwords = self._label.replace('_', ' ').split(' ') middle = len(labelwords) // 2 if middle: return '\n'.join([' '.join(labelwords[:middle]), ' '.join(labelwords[middle:])]) else: return ' '.join(labelwords) def hidden_for(self, memory): return False @property def valid(self): if self._name in ['freq', 'rtone']: return True to_try = ['has_%s', 'valid_%ss', 'valid_%ses', 'valid_%s_levels'] for thing in to_try: try: return bool(self._features[thing % self._name]) except KeyError: pass if '.' in self._name: # Assume extra fields are always valid return True LOG.error('Unsure if %r is valid' % self._name) return True def _render_value(self, memory, value): if value is []: raise Exception( _('Found empty list value for %(name)s: %(value)r' % { 'name': self._name, 'value': value})) return str(value) def value(self, memory): if '.' in self._name: parent, child = self._name.split('.', 1) try: return getattr(memory, parent)[child].value except (AttributeError, KeyError): LOG.warning('Memory %s does not have field %s', memory, self._name) else: return getattr(memory, self._name) def render_value(self, memory): if memory.empty: return '' if self.hidden_for(memory): return '' return self._render_value(memory, self.value(memory)) def _digest_value(self, memory, input_value): return str(input_value) def digest_value(self, memory, input_value): if '.' in self._name: parent, child = self._name.split('.', 1) try: getattr(memory, parent)[child].value = self._digest_value( memory, input_value) except (AttributeError, KeyError): LOG.warning('Memory %s does not have field %s', memory, self._name) raise ValueError( _('Unable to set %s on this memory') % self._name) else: setattr(memory, self._name, self._digest_value(memory, input_value)) def get_editor(self): return wx.grid.GridCellTextEditor() def get_renderer(self): return None def get_propeditor(self, memory): class ChirpStringProperty(wx.propgrid.StringProperty): def ValidateValue(myself, value, validationInfo): try: self._digest_value(memory, value) return True except ValueError: validationInfo.SetFailureMessage( _('Invalid value: %r') % value) return False except Exception: LOG.exception('Failed to validate %r for property %s' % ( value, self._name)) validationInfo.SetFailureMessage( _('Invalid value: %r') % value) return False editor = ChirpStringProperty(self.label.replace('\n', ' '), self._name) editor.SetValue(self.render_value(memory)) return editor def get_by_prompt(self, parent, memory, message): common.error_proof.show_error( 'Internal error: unable to prompt for %s' % self._name) class ChirpFrequencyColumn(ChirpMemoryColumn): DEFAULT = 0 def __init__(self, *a, **k): super().__init__(*a, **k) self._wants_split = set() @property def label(self): if self._name == 'offset': return _('Offset') else: return _('Frequency') def hidden_for(self, memory): return (self._name == 'offset' and memory.duplex in ('', 'off') and memory.number not in self._wants_split) def _render_value(self, memory, value): if not value: value = 0 if (self._name == 'offset' and memory.number in self._wants_split and memory.duplex in ('', '-', '+')): # Radio is returning offset but user wants split, so calculate # the TX frequency to render what they expect. value = memory.freq + int('%s%i' % (memory.duplex, value)) return chirp_common.format_freq(value) def _digest_value(self, memory, input_value): if not input_value.strip(): input_value = 0 if self._name == 'offset' and memory.number in self._wants_split: # If we are being edited and the user has requested split for # this memory, we need to keep requesting split, even if the # radio is returning an offset-based memory. Otherwise, radios # that emulate offset-based memories from tx/rx frequencies will # fight with the user. memory.duplex = 'split' return chirp_common.parse_freq(input_value) def get_by_prompt(self, parent, memory, message): if self._name == 'offset': if memory.duplex == 'split': default = self._render_value(memory, memory.freq) else: default = self._render_value(memory, memory.offset) else: default = self._render_value(memory, memory.freq) d = wx.TextEntryDialog(parent, message, _('Enter Frequency'), value=default) while True: r = d.ShowModal() if r == wx.ID_CANCEL: return try: return chirp_common.to_MHz(float(d.GetValue())) except ValueError: common.error_proof.show_error('Invalid frequency') def wants_split(self, memory, split): if split: self._wants_split.add(memory.number) else: self._wants_split.discard(memory.number) class ChirpVariablePowerColumn(ChirpMemoryColumn): @property def level(self): return _('Power') def _digest_value(self, memory, value): return chirp_common.parse_power(value) class ChirpChoiceEditor(wx.grid.GridCellChoiceEditor): """A locking GridCellChoiceEditor. Events to our parent window will cause editing to stop and will close our drop-down box, which is very annoying. This looks the begin/end event to use the EDIT_LOCK to prevent other things from submitting changes while we're in the middle of an edit. """ def __init__(self, *a, **k): super().__init__(*a, **k) self._locked = False def BeginEdit(self, *a, **k): common.EDIT_LOCK.acquire() self._locked = True return super().BeginEdit(*a, **k) def EndEdit(self, row, col, grid, val, **k): common.EDIT_LOCK.release() return self.Control.GetStringSelection() class ChirpChoiceColumn(ChirpMemoryColumn): # This is just here so it is marked for translation __TITLE1 = _('Tuning Step') def __init__(self, name, radio, choices, **k): super(ChirpChoiceColumn, self).__init__(name, radio, **k) self._choices = choices self._str_choices = [str(x) for x in choices] def _digest_value(self, memory, input_value): idx = self._str_choices.index(input_value) return self._choices[idx] def get_editor(self): return ChirpChoiceEditor(self._str_choices) def get_propeditor(self, memory): current = self._render_value(memory, self.value(memory)) # Since self._render_value() returns str(x), we should do the same # for our choices when finding the index, since we could have things # like PowerLevel objects. choice_strs = [str(x) for x in self._choices] try: cur_index = choice_strs.index(current) except ValueError: # This means the memory has some value set that the radio # does not support, like the default cross_mode not being # in rf.valid_cross_modes. This is likely because the memory # just doesn't have that value set, so take the first choice # in this case. cur_index = 0 LOG.warning('Failed to find %r in choices %r for %s', current, choice_strs, self.name) return wx.propgrid.EnumProperty(self.label.replace('\n', ' '), self._name, self._str_choices, range(len(self._str_choices)), cur_index) def get_by_prompt(self, parent, memory, message): d = wx.SingleChoiceDialog(parent, message, _('Choice Required'), self._str_choices, style=wx.OK | wx.CANCEL | wx.CENTER) if d.ShowModal() == wx.ID_OK: return self._digest_value(memory, self._choices[d.GetSelection()]) class ChirpToneColumn(ChirpChoiceColumn): def __init__(self, name, radio): self.rf = radio.get_features() tones = self.rf.valid_tones or chirp_common.TONES tones = [str(x) for x in sorted(tones)] super(ChirpToneColumn, self).__init__(name, radio, tones) @property def label(self): if self._name == 'rtone': return _('Tone') else: return _('Tone Squelch').replace(' ', '\n', 1) def rtone_visible(self, memory): if not self._features.has_ctone: tmodes = ['Tone', 'TSQL', 'TSQL-R'] cross_modes = [x for x in chirp_common.CROSS_MODES if 'Tone' in x] else: tmodes = ['Tone'] cross_modes = [x for x in chirp_common.CROSS_MODES if 'Tone->' in x] if memory.tmode == 'Cross': return memory.cross_mode in cross_modes else: return memory.tmode in tmodes def ctone_visible(self, memory): return memory.tmode == 'TSQL' or (memory.tmode == 'Cross' and '->Tone' in memory.cross_mode) def hidden_for(self, memory): if self._name == 'rtone': return not self.rtone_visible(memory) else: return not self.ctone_visible(memory) def _digest_value(self, memory, input_value): return float(input_value) class ChirpDuplexColumn(ChirpChoiceColumn): # This is just here so it is marked for translation __TITLE = _('Duplex') def __init__(self, *a, **k): super().__init__(*a, **k) self._wants_split = set() def _render_value(self, memory, value): if memory.number in self._wants_split: return 'split' else: return value def _digest_value(self, memory, input_value): if memory.number in self._wants_split: # If we are being edited and the user has requested split for # this memory, we need to avoid requesting a tiny tx frequency # (i.e. an offset), even if the radio is returning an offset-based # memory. Otherwise, radios that emulate offset-based memories # from tx/rx frequencies will fight with the user. memory.offset = memory.freq return super()._digest_value(memory, input_value) def wants_split(self, memory, split): if split: self._wants_split.add(memory.number) else: self._wants_split.discard(memory.number) class ChirpFlagColumn(ChirpChoiceColumn): """Support boolean values as a special case of Choice This allows us to have translated strings for the boolean flags, while retaining choice-like behavior instead of rendering checkboxes, which is very slow on GTK. """ def __init__(self, field, radio, label=None): super().__init__(field, radio, [_('Disabled'), _('Enabled')], label=label) def _render_value(self, memory, value): # Convert RadioSettingValueBoolean (or an actual boolean) to one of # our string choices return self._choices[int(bool(value))] def _digest_value(self, memory, input_value): # Convert one of our string choices back to boolean return input_value == self._choices[1] class ChirpDTCSColumn(ChirpChoiceColumn): def __init__(self, name, radio): rf = radio.get_features() codes = rf.valid_dtcs_codes or chirp_common.DTCS_CODES dtcs_codes = ['%03i' % code for code in sorted(codes)] super(ChirpDTCSColumn, self).__init__(name, radio, dtcs_codes) @property def label(self): if self._name == 'dtcs': return _('DTCS') elif self._name == 'rx_dtcs': return _('RX DTCS') else: return 'ErrDTCS' def _digest_value(self, memory, input_value): return int(input_value) def _render_value(self, memory, value): return '%03i' % value def _dtcs_visible(self, memory): if memory.tmode in ['DTCS', 'DTCS-R']: return True if memory.tmode == 'Cross': if self._features.has_rx_dtcs: # If we have rx_dtcs then this is only visible for cross modes # where we are transmitting DTCS return 'DTCS->' in memory.cross_mode else: # If we do not have rx_dtcs then this is used for either tx # or rx DTCS in cross. return 'DTCS' in memory.cross_mode def _rx_dtcs_visible(self, memory): return (self._features.has_rx_dtcs and memory.tmode == 'Cross' and '>DTCS' in memory.cross_mode) def hidden_for(self, memory): if self._name == 'dtcs': return not self._dtcs_visible(memory) elif self._name == 'rx_dtcs': return not self._rx_dtcs_visible(memory) else: raise Exception('Internal error') class ChirpDTCSPolColumn(ChirpChoiceColumn): def __init__(self, name, radio): super().__init__(name, radio, ['NN', 'NR', 'RN', 'RR']) @property def label(self): return _('DTCS\nPolarity') def hidden_for(self, memory): return not (memory.tmode == 'DTCS' or 'DTCS' in memory.cross_mode) class ChirpCrossModeColumn(ChirpChoiceColumn): # This is just here so it is marked for translation __TITLE = _('Mode') def __init__(self, name, radio): rf = radio.get_features() super(ChirpCrossModeColumn, self).__init__(name, radio, rf.valid_cross_modes) @property def valid(self): return ('Cross' in self._features.valid_tmodes and self._features.valid_cross_modes) @property def label(self): return _('Cross Mode') def hidden_for(self, memory): return memory.tmode != 'Cross' class ChirpCommentColumn(ChirpMemoryColumn): # This is just here so it is marked for translation __TITLE = _('Comment') @property def valid(self): return (self._features.has_comment or isinstance(self._radio, chirp_common.CloneModeRadio)) def _digest_value(self, memory, input_value): # Limit to 128 characters for sanity return str(input_value)[:256] def title_case_special(string): return ' '.join(word.title() if word.upper() != word else word for word in string.split(' ')) def get_column_for_extra(radio, setting): value = setting.value field = 'extra.%s' % setting.get_name() # Lots of these have all-caps acronyms in them, so we need to do a # modified title() operation. label = title_case_special(setting.get_shortname()) if isinstance(value, settings.RadioSettingValueString): return ChirpMemoryColumn(field, radio, label=label) elif isinstance(value, settings.RadioSettingValueList): return ChirpChoiceColumn(field, radio, value.get_options(), label=label) elif isinstance(value, settings.RadioSettingValueBoolean): return ChirpFlagColumn(field, radio, label=label) elif isinstance(value, settings.RadioSettingValueInteger): return ChirpMemoryColumn(field, radio, label=label) class ChirpMemoryDropTarget(wx.DropTarget): def __init__(self, memedit): super().__init__() self._memedit = memedit self.data = wx.DataObjectComposite() self.data.Add(wx.CustomDataObject(common.CHIRP_DATA_MEMORY)) self.SetDataObject(self.data) def parse_data(self): data = self.data.GetObject(common.CHIRP_DATA_MEMORY) return pickle.loads(data.GetData().tobytes()) def OnData(self, x, y, defResult): if not self.GetData(): return wx.DragNone payload = self.parse_data() x, y = self._memedit._grid.CalcUnscrolledPosition(x, y) y -= self._memedit._grid.GetColLabelSize() row, cell = self._memedit._grid.XYToCell(x, y) start_row = self._memedit.mem2row(payload['mems'][0].number) if row < 0 or row == start_row: LOG.debug('Ignoring drag from row %i -> %i', start_row, row) return wx.DragCancel LOG.debug('Memory dropped on row %s,%s' % (row, cell)) original_locs = [m.number for m in payload['mems']] source = self._memedit.FindWindowById(payload.pop('source')) if not self._memedit._cb_paste_memories(payload, row=row): return defResult if source == self._memedit and defResult == wx.DragMove: LOG.debug('Same-memedit move requested') for loc in original_locs: self._memedit.erase_memory(loc) return defResult def OnDragOver(self, x, y, defResult): if self.GetData(): payload = self.parse_data() rows = len(payload['mems']) else: rows = 1 x, y = self._memedit._grid.CalcUnscrolledPosition(x, y) y -= self._memedit._grid.GetColLabelSize() row, cell = self._memedit._grid.XYToCell(x, y) max_row = self._memedit._grid.GetNumberRows() if row >= 0: self._memedit._grid.ClearSelection() for i in range(row, min(max_row, row + rows)): self._memedit._grid.SelectRow(i, addToSelected=True) return defResult def OnDrop(self, x, y): return True class ChirpMemEdit(common.ChirpEditor, common.ChirpSyncEditor): def __init__(self, radio, *a, **k): super(ChirpMemEdit, self).__init__(*a, **k) self.SetDropTarget(ChirpMemoryDropTarget(self)) self._radio = radio self._features = self._radio.get_features() # Cache of memories by *row* self._memory_cache = {} # Maps special memory *names* to rows self._special_rows = {} # Maps special memory *numbers* to rows self._special_numbers = {} # Extra memory column names self._extra_cols = set() # Memory errors by row self._memory_errors = {} self._col_defs = self._setup_columns() self.bandplan = bandplan.BandPlans(CONF) self._grid = ChirpMemoryGrid(self) self._grid.CreateGrid( self._features.memory_bounds[1] - self._features.memory_bounds[0] + len(self._features.valid_special_chans) + 1, len(self._col_defs)) self._grid.SetSelectionMode(wx.grid.Grid.SelectRows) self._grid.DisableDragRowSize() self._grid.EnableDragCell() self._grid.SetFocus() self._default_cell_bg_color = self._grid.GetCellBackgroundColour(0, 0) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self._grid, 1, wx.EXPAND) self.SetSizer(sizer) self._fixed_font = wx.Font(pointSize=10, family=wx.FONTFAMILY_TELETYPE, style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL) self._variable_font = self._grid.GetDefaultCellFont() self.update_font(False) self._grid.Bind(wx.grid.EVT_GRID_CELL_CHANGING, self._memory_edited) self._grid.Bind(wx.grid.EVT_GRID_CELL_CHANGED, self._memory_changed) self._grid.Bind(wx.grid.EVT_GRID_CELL_RIGHT_CLICK, self._memory_rclick) self._grid.Bind(wx.grid.EVT_GRID_LABEL_RIGHT_CLICK, self._memory_rclick) self._grid.Bind(wx.grid.EVT_GRID_CELL_BEGIN_DRAG, self._memory_drag) if WX_GTK: self._grid.Bind(wx.EVT_KEY_DOWN, self._gtk_short_circuit_edit_copy) row_labels = self._grid.GetGridRowLabelWindow() row_labels.Bind(wx.EVT_LEFT_DOWN, self._row_click) row_labels.Bind(wx.EVT_LEFT_UP, self._row_click) row_labels.Bind(wx.EVT_MOTION, self._rowheader_mouseover) col_labels = self._grid.GetGridColLabelWindow() col_labels.Bind(wx.EVT_MOTION, self._colheader_mouseover) self._dragging_rows = None self._dc = wx.ScreenDC() self.set_cell_attrs() def _gtk_short_circuit_edit_copy(self, event): # wxGTK is broken and does not direct Ctrl-C to the menu items # because wx.grid.Grid() tries to implement something for it, # which we don't want. The wxWidgets people say the only way is to # grab it ourselves and direct it appropriately before wx.grid.Grid() # can do it. # https://github.com/wxWidgets/wxWidgets/issues/22625 if (event.GetKeyCode() == ord('C') and event.GetModifiers() == wx.MOD_CONTROL): self.cb_copy(cut=False) else: event.Skip() def _row_click(self, event): # In order to override the drag-to-multi-select behavior of the base # grid, we need to basically reimplement what happens when a user # clicks on a row header. Shift for block select, Ctrl/Cmd for add- # to-selection, and then drag to actually copy/move memories. if sys.platform == 'darwin': multi = event.CmdDown() else: multi = event.ControlDown() cur_selected = self._grid.GetSelectedRows() x, y = self._grid.CalcUnscrolledPosition(event.GetX(), event.GetY()) row, _cell = self._grid.XYToCell(x, y) if event.LeftDown(): # Record where we clicked in case we start to drag, but only if # they started that drag from one of the selected memories. self._dragging_rows = (row, event.GetX(), event.GetY()) elif self._dragging_rows is not None: # Never dragged, so skip to get regular behavior self._dragging_rows = None try: first_row = cur_selected[0] except IndexError: first_row = 0 if event.ShiftDown(): # Find the block the user wants and select all of it start = min(row, first_row) end = max(row, first_row) self._grid.SelectBlock(start, 0, end, 0) elif multi and row in cur_selected: # The row is currently selected and we were clicked with the # multi-select key held, so we need to select everything *but* # the clicked row. cur_selected.remove(row) self._grid.ClearSelection() for row in cur_selected: self._grid.SelectRow(row, addToSelected=True) else: # They clicked on a row, add to selection if the multi-select # key is held, otherwise select only this row. self._grid.SelectRow(row, addToSelected=multi) else: # Unclick but we started a drag self._dragging_rows = None def _rowheader_mouseover(self, event): x, y = self._grid.CalcUnscrolledPosition(event.GetX(), event.GetY()) row, _cell = self._grid.XYToCell(x, y) tip = self._memory_errors.get(row) event.GetEventObject().SetToolTip(tip) if self._dragging_rows is not None: row, x, y = self._dragging_rows if row not in self._grid.GetSelectedRows(): # Drag started from a non-selected cell, so ignore return if abs(event.GetX() - x) > 10 or abs(event.GetY() - y) > 10: # Enough motion to consider this a drag motion self._dragging_rows = None return self._memory_drag(event) def _colheader_mouseover(self, event): x, y = self._grid.CalcUnscrolledPosition(event.GetX(), event.GetY()) _row, cell = self._grid.XYToCell(x, y) col = self._col_defs[cell] event.GetEventObject().SetToolTip(col.doc or None) def _memory_drag(self, event): data = self.cb_copy_getdata() ds = wx.DropSource(self) ds.SetData(data) result = ds.DoDragDrop(wx.Drag_AllowMove) if result in (wx.DragMove, wx.DragCopy): LOG.debug('Target took our memories') else: LOG.debug('Target rejected our memories') @property def editable(self): return not isinstance(self._radio, chirp_common.NetworkSourceRadio) @property def comment_col(self): return self._col_defs.index(self._col_def_by_name('comment')) def set_cell_attrs(self): if WX_GTK: minwidth = 100 else: minwidth = 75 for col, col_def in enumerate(self._col_defs): if not col_def.valid: self._grid.HideCol(col) else: self._grid.SetColLabelValue(col, col_def.label) attr = wx.grid.GridCellAttr() attr.SetEditor(col_def.get_editor()) self._grid.SetColAttr(col, attr) self._grid.SetColMinimalWidth(col, minwidth) try: attr.SetFitMode(wx.grid.GridFitMode.Ellipsize()) except AttributeError: # No SetFitMode() support on wxPython 4.0.7 pass wx.CallAfter(self._grid.AutoSizeColumns, setAsMin=False) @classmethod def get_menu_items(cls): move_up = common.EditorMenuItem( cls, '_move_up', _('Move Up')) # Control-Up is used by default on macOS, so require shift as well if sys.platform == 'darwin': extra_move = wx.MOD_SHIFT else: extra_move = 0 move_up.SetAccel(wx.AcceleratorEntry( extra_move | wx.ACCEL_RAW_CTRL, wx.WXK_UP)) move_dn = common.EditorMenuItem( cls, '_move_dn', _('Move Down')) move_dn.SetAccel(wx.AcceleratorEntry( extra_move | wx.ACCEL_RAW_CTRL, wx.WXK_DOWN)) goto = common.EditorMenuItem(cls, '_goto', _('Goto...')) goto.SetAccel(wx.AcceleratorEntry(wx.MOD_CONTROL, ord('G'))) expand_extra = common.EditorMenuItemToggle( cls, '_set_expand_extra', ('expand_extra', 'state'), _('Show extra fields')) hide_empty = common.EditorMenuItemToggle( cls, '_set_hide_empty', ('hide_empty', 'memedit'), _('Hide empty memories')) return { common.EditorMenuItem.MENU_EDIT: [ goto, move_up, move_dn, ], common.EditorMenuItem.MENU_VIEW: [ expand_extra, hide_empty, ] } def _set_expand_extra(self, event): self.refresh() def _set_hide_empty(self, event): self.refresh() def _goto(self, event): l, u = self._features.memory_bounds a = wx.GetNumberFromUser(_('Goto Memory:'), _('Number'), _('Goto Memory'), 1, l, u, self) if a >= 0: self.cb_goto(a) def _move_dn(self, event): self.cb_move(1) def _move_up(self, event): self.cb_move(-1) def _setup_columns(self): def filter_unknowns(items): return [x for x in items if '?' not in x] # Some drivers report invalid enumerations in their lists # by using strings with question mark characters. Don't let the # users select these. valid_tmodes = filter_unknowns(self._features.valid_tmodes) valid_modes = filter_unknowns(self._features.valid_modes) valid_skips = filter_unknowns(self._features.valid_skips) valid_duplexes = filter_unknowns(self._features.valid_duplexes) valid_tuning_steps = self._features.valid_tuning_steps if self._features.has_variable_power: power_column = ChirpVariablePowerColumn('power', self._radio) else: valid_power_levels = self._features.valid_power_levels power_column = ChirpChoiceColumn('power', self._radio, valid_power_levels) defs = [ ChirpFrequencyColumn('freq', self._radio), ChirpMemoryColumn('name', self._radio), ChirpChoiceColumn('tmode', self._radio, valid_tmodes, label=_('Tone Mode')), ChirpToneColumn('rtone', self._radio), ChirpToneColumn('ctone', self._radio), ChirpDTCSColumn('dtcs', self._radio), ChirpDTCSColumn('rx_dtcs', self._radio), ChirpDTCSPolColumn('dtcs_polarity', self._radio), ChirpCrossModeColumn('cross_mode', self._radio), ChirpDuplexColumn('duplex', self._radio, valid_duplexes), ChirpFrequencyColumn('offset', self._radio), ChirpChoiceColumn('mode', self._radio, valid_modes), ChirpChoiceColumn('tuning_step', self._radio, valid_tuning_steps, label=_('Tuning Step')), ChirpChoiceColumn('skip', self._radio, valid_skips), power_column, ChirpCommentColumn('comment', self._radio), ] return defs def _col_def_by_name(self, name): for coldef in self._col_defs: if coldef._name == name: return coldef LOG.error('No column definition for %s' % name) def mem2row(self, number): if isinstance(number, str): return self._special_rows[number] if number in self._special_numbers: return self._special_rows[self._special_numbers[number]] return number - self._features.memory_bounds[0] def row2mem(self, row): if row in self._special_rows.values(): row2number = {v: k for k, v in self._special_rows.items()} return row2number[row] else: return row + self._features.memory_bounds[0] def special2mem(self, name): name2mem = {v: k for k, v in self._special_numbers.items()} return name2mem[name] def _expand_extra_col(self, setting): # Add this to the list of seen extra columns regardless of if we # support this type so we never try to add it again self._extra_cols.add(setting.get_name()) col = get_column_for_extra(self._radio, setting) if col: col.doc = (setting.__doc__ if setting.__doc__ != setting.get_name() else None) LOG.debug('Adding mem.extra column %s as %s', setting.get_name(), col.__class__.__name__) # We insert extra columns in front of the comment column, which # should always be last index = self.comment_col self._col_defs.insert(index, col) self._grid.InsertCols(index) self.set_cell_attrs() else: LOG.warning('Unsupported mem.extra type %s', setting.value.__class__.__name__) def _expand_extra(self, memory): if not CONF.get_bool('expand_extra', 'state'): return for setting in memory.extra: if setting.get_name() not in self._extra_cols: self._expand_extra_col(setting) def _refresh_memory(self, number, memory, orig_mem=None): row = self.mem2row(number) if isinstance(memory, Exception): LOG.error('Failed to load memory %s as error because: %s' % ( number, memory)) self._row_label_renderers[row].set_error() self._memory_errors[row] = str(memory) self._memory_cache[row] = chirp_common.Memory(number=number, empty=True) self._grid.SetRowLabelValue(row, '!%s' % ( self._grid.GetRowLabelValue(row))) return if row in self._memory_errors: del self._memory_errors[row] hide_empty = CONF.get_bool('hide_empty', 'memedit', False) if memory.empty: # Reset our "wants split" flags if the memory is empty offset_col = self._col_def_by_name('offset') duplex_col = self._col_def_by_name('duplex') offset_col.wants_split(memory, False) duplex_col.wants_split(memory, False) if hide_empty: self._grid.HideRow(row) else: self._grid.ShowRow(row) else: self._grid.ShowRow(row) if memory.extra: self._expand_extra(memory) if orig_mem: delta = orig_mem.debug_diff(memory, '->') if delta: LOG.debug('Driver refresh delta from set: %s', delta) self._memory_cache[row] = memory with wx.grid.GridUpdateLocker(self._grid): self.set_row_finished(row) for col, col_def in enumerate(self._col_defs): self._grid.SetCellValue(row, col, col_def.render_value(memory)) self._grid.SetReadOnly(row, col, col_def.name in memory.immutable or not self.editable) if col_def.name in memory.immutable: color = (0xF5, 0xF5, 0xF5, 0xFF) else: color = self._default_cell_bg_color self._grid.SetCellBackgroundColour(row, col, color) def synchronous_get_memory(self, number): """SYNCHRONOUSLY Get memory with extra properties This should ideally not be used except in situations (like copy) where we really have to do the operation synchronously. """ mem = self._radio.get_memory(number) if isinstance(self._radio, chirp_common.ExternalMemoryProperties): mem = self._radio.get_memory_extra(mem) return mem def set_row_finished(self, row): self._row_label_renderers[row].clear_error() memory = self._memory_cache[row] if memory.extd_number: self._grid.SetRowLabelValue(row, memory.extd_number) else: self._grid.SetRowLabelValue(row, str(memory.number)) def set_row_pending(self, row): self._row_label_renderers[row].set_progress() memory = self._memory_cache[row] if memory.extd_number: self._grid.SetRowLabelValue(row, '*%s' % memory.extd_number) else: self._grid.SetRowLabelValue(row, '*%i' % memory.number) def refresh_memory(self, number, lazy=False, orig_mem=None): if lazy: executor = self.do_lazy_radio else: executor = self.do_radio def extra_cb(job): self._refresh_memory(number, job.result, orig_mem=orig_mem) def get_cb(job): # If get_memory() failed, just refresh with the exception if isinstance(job.result, Exception): self._refresh_memory(job.args[0], job.result) return # If this memory is a special, record the mapping of its driver- # determined virtual number to is special name for use later if job.result.extd_number: self._special_numbers[job.result.number] = ( job.result.extd_number) # Otherwise augment with extra fields and call refresh with that, # if appropriate if isinstance(self._radio, chirp_common.ExternalMemoryProperties): executor(extra_cb, 'get_memory_extra', job.result) else: extra_cb(job) executor(get_cb, 'get_memory', number) def set_memory(self, mem, refresh=True): """Update a memory in the radio and refresh our view on success""" row = self.mem2row(mem.number) orig_mem = mem.dupe() if refresh: self.set_row_pending(row) def extra_cb(job): if refresh: self.refresh_memory(mem.number, orig_mem=orig_mem) def set_cb(job): if isinstance(job.result, Exception): self._row_label_renderers[row].set_error() else: self._row_label_renderers[row].clear_error() if isinstance(self._radio, chirp_common.ExternalMemoryProperties): self.do_radio(extra_cb, 'set_memory_extra', mem) else: extra_cb(job) LOG.debug('Setting memory: %r' % mem) # Use a FrozenMemory for the actual set to catch potential attempts # to modify the memory during set_memory(). self.do_radio(set_cb, 'set_memory', chirp_common.FrozenMemory(mem)) def erase_memory(self, number, refresh=True): """Erase a memory in the radio and refresh our view on success""" row = self.mem2row(number) if refresh: self.set_row_pending(row) def extra_cb(job): if refresh: self.refresh_memory(number) def erase_cb(job): if isinstance(job.result, Exception): self._row_label_renderers[row].set_error() else: self._row_label_renderers[row].clear_error() if isinstance(self._radio, chirp_common.ExternalMemoryProperties): self.do_radio(extra_cb, 'erase_memory_extra', number) else: extra_cb(job) self.do_radio(erase_cb, 'erase_memory', number) def _purge_extra_cols(self): for col in list(self._extra_cols): self._extra_cols.remove(col) index = self.comment_col - 1 # We insert extra columns in front of the comment column, which # should always be last, so delete the one before the comment # column until we're out of extra columns. LOG.debug('Removing extra col %s %s number %s', col, self._col_defs[-1].__class__.__name__, index) del self._col_defs[index] self._grid.DeleteCols(index) def refresh(self): if not CONF.get_bool('expand_extra', 'state'): self._purge_extra_cols() lower, upper = self._features.memory_bounds def setlabel(row, number): self._grid.SetRowLabelValue(row, '%s' % number) # Build our row label renderers so we can set colors to # indicate success or failure self._row_label_renderers = [] for row, _num in enumerate( range(lower, upper + len(self._features.valid_special_chans) + 1)): self._row_label_renderers.append(ChirpRowLabelRenderer()) self._grid.SetRowLabelRenderer(row, self._row_label_renderers[-1]) row = 0 for i in range(lower, upper + 1): setlabel(row, i) row += 1 self.refresh_memory(i, lazy=True) for i in self._features.valid_special_chans: self._special_rows[i] = row setlabel(row, i) row += 1 self.refresh_memory(i, lazy=True) def _set_memory_defaults(self, mem, *only): """This is responsible for setting sane default values on memories. For the most part, this just honors the bandplan rules, but it also tries to do things like calculate the required step for the memory's frequency, etc. If fields are provided as arguments, only set those defaults, else, set them all. """ if not CONF.get_bool('auto_edits', 'state', True): return if not only: only = ['offset', 'duplex', 'tuning_step', 'mode', 'rtone'] for prop in mem.immutable: if prop in only: only.remove(prop) defaults = self.bandplan.get_defaults_for_frequency(mem.freq) features = self._features if not defaults.offset: want_duplex = '' want_offset = None elif defaults.offset > 0: want_duplex = '+' want_offset = defaults.offset elif defaults.offset < 0: want_duplex = '-' want_offset = abs(defaults.offset) else: want_duplex = want_offset = None if want_duplex is not None and want_duplex in features.valid_duplexes: if 'duplex' in only: mem.duplex = want_duplex if want_offset is not None and features.has_offset: if 'offset' in only: mem.offset = want_offset if defaults.step_khz in features.valid_tuning_steps: LOG.debug( 'Chose default step %s from bandplan' % defaults.step_khz) want_tuning_step = defaults.step_khz else: want_tuning_step = 5.0 try: # First calculate the needed step in case it is not supported # by the radio. If we fail to find one the radio supports, # we will use this one and then the error message about it # being unsupported will be accurate. want_tuning_step = chirp_common.required_step(mem.freq) # Now try to find a suitable one that the radio supports. want_tuning_step = chirp_common.required_step( mem.freq, features.valid_tuning_steps) LOG.debug('Chose radio-supported step %s' % want_tuning_step) except errors.InvalidDataError as e: LOG.warning(e) if 'tuning_step' in only and want_tuning_step: mem.tuning_step = want_tuning_step if defaults.mode and defaults.mode in features.valid_modes: if 'mode' in only: mem.mode = defaults.mode if defaults.tones and defaults.tones[0] in features.valid_tones: if 'rtone' in only: mem.rtone = defaults.tones[0] def _resolve_cross_mode(self, mem): # Resolve TX/RX tones/codes when "Cross Mode" is changed txmode, rxmode = mem.cross_mode.split('->') todo = [('TX', txmode, 'rtone', 'dtcs'), ('RX', rxmode, 'ctone', 'rx_dtcs')] setvals = [] for which, mode, tone_prop, dtcs_prop in todo: if mode == 'Tone': msg = _('Choose %s Tone') % which prop = tone_prop elif mode == 'DTCS': msg = _('Choose %s DTCS Code') % which prop = dtcs_prop else: # No value for this element, so do not prompt continue val = self._col_def_by_name(prop).get_by_prompt( self, mem, msg) if val is None: # User hit cancel, so abort return False setattr(mem, prop, val) setvals.append(val) if rxmode == txmode and len(setvals) == 2 and setvals[0] == setvals[1]: if rxmode == 'Tone': mode = 'TSQL' name = 'tones' else: mode = 'DTCS' name = 'codes' wx.MessageBox(_('Channels with equivalent TX and RX %s are ' 'represented by tone mode of "%s"') % (name, mode), _('Information')) return True def _resolve_tmode_cross(self, mem): # Resolve cross_mode when tmode is changed to Cross # Triggers resolve_cross_mode() after a selection is made val = self._col_def_by_name('cross_mode').get_by_prompt( self, mem, _('Choose Cross Mode')) if val is None: return False mem.cross_mode = val return self._resolve_cross_mode(mem) def _resolve_duplex(self, mem): self._set_memory_defaults(mem, 'offset') if mem.duplex == 'split': msg = _('Enter TX Frequency (MHz)') elif mem.duplex == 'off': # Clearly no need to prompt for this duplex return True elif 0 < mem.offset < 70000000: # We don't need to ask, offset looks like an offset return True else: msg = _('Enter Offset (MHz)') offset = self._col_def_by_name('offset').get_by_prompt( self, mem, msg) if offset is None: return False mem.offset = offset return True def _resolve_offset(self, mem): self._set_memory_defaults(mem, 'duplex') if mem.duplex == '': duplex = self._col_def_by_name('duplex').get_by_prompt( self, mem, _('Choose duplex')) if duplex is None: return False mem.duplex = duplex return True @common.error_proof() def _memory_edited(self, event): """ Called when the memory row in the UI is edited. Responsible for updating our copy of the memory with changes from the grid, defaults where appropriate, and extra values when required. Validates the memory with the radio, then writes the memory to the radio and displays an error if needed. """ row = event.GetRow() col = event.GetCol() val = event.GetString() col_def = self._col_defs[col] try: mem = self._memory_cache[row].dupe() except KeyError: # This means we never loaded this memory from the radio in the # first place, likely due to some error. wx.MessageBox(_('Unable to edit memory before radio is loaded')) event.Veto() return orig_mem = mem.dupe() # Filter the name according to the radio's rules before we try to # validate it if col_def.name == 'name': val = self._radio.filter_name(val) # Record the user's desire for this being a split duplex so that # we can represent it consistently to them. The offset and duplex # columns need to know so they can behave appropriately. if col_def.name == 'duplex': offset_col = self._col_def_by_name('offset') duplex_col = self._col_def_by_name('duplex') offset_col.wants_split(mem, val == 'split') duplex_col.wants_split(mem, val == 'split') # Any edited memory is going to be non-empty if mem.empty: mem.empty = False # This is where the column definition actually applies the edit they # made to the memory. col_def.digest_value(mem, val) # If they edited the frequency, we assume that they are likely going # to want band defaults applied (duplex, offset, etc). if col_def.name == 'freq': self._set_memory_defaults(mem) # If they edited cross mode, they definitely want a tone mode of # 'Cross'. For radios that do not store all the tone/code values # all the time, we need to set certain tones or codes at the same # time as this selection was made. if col_def.name == 'cross_mode': mem.tmode = 'Cross' if not self._resolve_cross_mode(mem): event.Veto() return elif col_def.name == 'tmode' and val == 'Cross': if not self._resolve_tmode_cross(mem): event.Veto() return # If they edited one of the tone values and tmode is not Cross, # select the right thing for them. Note that we could get fancy # here and change the TX or RX part of cross_mode, if Cross is # selected. if col_def.name == 'rtone' and mem.tmode != 'Cross': mem.tmode = 'Tone' elif col_def.name == 'ctone' and mem.tmode != 'Cross': mem.tmode = 'TSQL' elif col_def.name == 'dtcs' and mem.tmode != 'Cross': mem.tmode = 'DTCS' # If they edited duplex, we need to prompt them for the value of # offset in some cases. For radios that do not store offset itself, # we need to prompt for the offset so it is set in the same operation. # For split mode, we should always prompt, because trying to set a # TX frequency of 600 kHz is likely to fail on most radios. if col_def.name == 'duplex' and val != '': if not self._resolve_duplex(mem): event.Veto() return if col_def.name == 'offset' and mem.duplex in ('', 'off'): if not self._resolve_offset(mem): event.Veto() return # Try to validate these changes with the radio before we go to store # them, as now is the best time to present an error to the user. warnings, errors = chirp_common.split_validation_msgs( self._radio.validate_memory(mem)) if errors: LOG.warning('Memory failed validation: %r', mem) wx.MessageBox(_('Invalid edit: %s') % '; '.join(errors), _('Invalid Entry')) event.Skip() return if warnings: LOG.warning('Memory validation had warnings: %r', mem) wx.MessageBox(_('Warning: %s') % '; '.join(warnings), _('Warning')) self.set_row_pending(row) LOG.debug('Memory row %i column %i(%s) edited: %s', row, col, col_def.name, orig_mem.debug_diff(mem, '->')) self.set_memory(mem) wx.CallAfter(self._resize_col_after_edit, row, col) def _resize_col_after_edit(self, row, col): """Resize the column if the text in row,col does not fit.""" size = self._dc.GetTextExtent(self._grid.GetCellValue(row, col)) padsize = size[0] + 20 if padsize > self._grid.GetColSize(col): self._grid.SetColSize(col, padsize) def _memory_changed(self, event): """ Called when the memory in the UI has been changed. Responsible for re-requesting the memory from the radio and updating the UI accordingly. Also provides the trigger to the editorset that we have changed. """ row = event.GetRow() self.refresh_memory(self.row2mem(row)) wx.PostEvent(self, common.EditorChanged(self.GetId())) def delete_memory_at(self, row, event): number = self.row2mem(row) if 'empty' in self._memory_cache[row].immutable: raise errors.InvalidMemoryLocation( _('Memory %i is not deletable') % number) self.erase_memory(number) @common.error_proof(errors.InvalidMemoryLocation) def _delete_memories_at(self, rows, event, shift_up=None): if rows: wx.PostEvent(self, common.EditorChanged(self.GetId())) for row in rows: if not self._memory_cache[row].empty: self.delete_memory_at(row, event) elif row in self._memory_errors: LOG.warning('Attempting to clear memory error ' '%r for memory %i at row %i with delete', self._memory_errors[row], self.row2mem(row), row) self.delete_memory_at(row, event) else: LOG.debug('Not re-deleting empty memory at row %i', row) if not shift_up: return LOG.debug('Shifting up...%s' % shift_up) next_row = rows[-1] + 1 delta = len(rows) mems_to_move = [] # Find all the memories we are going to shift up, either to the end # of the current block, or to the end of the list for row in range(next_row, self._grid.GetNumberRows()): if (shift_up == 'block' and self._memory_cache[row].empty): # We found the end of the next block break elif isinstance(self.row2mem(row), str): # We hit the specials, stop here break mems_to_move.append(self.row2mem(row)) if not mems_to_move: LOG.debug('Delete %s has no memories to move' % shift_up) return # Shift them all up by however many we deleted for number in mems_to_move: LOG.debug('Moving memory %i -> %i', number, number - delta) mem = self._memory_cache[self.mem2row(number)] mem.number -= delta if mem.empty: self.erase_memory(mem.number, refresh=False) else: self.set_memory(mem, refresh=False) # Delete the memories that are now the hole we made for number in range(mem.number + 1, mems_to_move[-1] + 1): LOG.debug('Erasing memory %i', number) self.erase_memory(number, refresh=False) # Refresh the entire range from the top of what we deleted to the # hole we created for number in range(self.row2mem(rows[0]), mems_to_move[-1] + 1): self.refresh_memory(number) def _do_sort_memories(self, rows, reverse, sortattr): memories = [self._memory_cache[r] for r in rows] LOG.debug('Sorting %s by %s%s', memories, reverse and '>' or '<', sortattr) memories.sort(key=lambda m: getattr(m, sortattr), reverse=reverse) for i, mem in enumerate(memories): new_number = self.row2mem(rows[0] + i) LOG.debug('Moving memory %i to %i', mem.number, new_number) mem.number = new_number self.set_memory(mem) LOG.debug('Sorted: %s', memories) wx.PostEvent(self, common.EditorChanged(self.GetId())) @common.error_proof() def _sort_memories(self, rows, reverse, event): choices = [x.label.replace('\n', ' ') for x in self._col_defs] sortcol = wx.GetSingleChoice( _('Sort memories'), _('Sort by column:'), choices, parent=self) if not sortcol: return sortattr = self._col_defs[choices.index(sortcol)].name self._do_sort_memories(rows, reverse, sortattr) @common.error_proof() def _arrange_memories(self, rows, event): self._do_sort_memories(rows, False, 'empty') def _memory_rclick(self, event): if event.GetRow() == -1: # This is a right-click on a column header return menu = wx.Menu() selected_rows = self._grid.GetSelectedRows() if not selected_rows: selected_rows = [event.GetRow()] props_item = wx.MenuItem(menu, wx.NewId(), _('Properties')) self.Bind(wx.EVT_MENU, functools.partial(self._mem_properties, selected_rows), props_item) menu.Append(props_item) props_item.Enable(self.editable) insert_item = wx.MenuItem(menu, wx.NewId(), _('Insert Row Above')) self.Bind(wx.EVT_MENU, functools.partial(self._mem_insert, selected_rows[0]), insert_item) menu.Append(insert_item) cut_item = wx.MenuItem(menu, wx.NewId(), _('Cut')) self.Bind(wx.EVT_MENU, lambda e: self.cb_copy(cut=True), cut_item) menu.Append(cut_item) copy_item = wx.MenuItem(menu, wx.NewId(), _('Copy')) self.Bind(wx.EVT_MENU, lambda e: self.cb_copy(cut=False), copy_item) menu.Append(copy_item) paste_item = wx.MenuItem(menu, wx.NewId(), _('Paste')) self.Bind(wx.EVT_MENU, lambda e: self.cb_paste(), paste_item) menu.Append(paste_item) delete_menu = wx.Menu() delete_menu_item = menu.AppendSubMenu(delete_menu, _('Delete')) delete_menu_item.Enable(self.editable) if len(selected_rows) > 1: del_item = wx.MenuItem( delete_menu, wx.NewId(), ngettext('%i Memory', '%i Memories', len(selected_rows)) % len(selected_rows)) del_block_item = wx.MenuItem( delete_menu, wx.NewId(), ngettext('%i Memory and shift block up', '%i Memories and shift block up', len(selected_rows)) % (len(selected_rows))) del_shift_item = wx.MenuItem( delete_menu, wx.NewId(), ngettext('%i Memories and shift all up', '%i Memories and shift all up', len(selected_rows)) % len(selected_rows)) to_delete = selected_rows else: del_item = wx.MenuItem(delete_menu, wx.NewId(), _('This Memory')) del_block_item = wx.MenuItem(delete_menu, wx.NewId(), _('This memory and shift block up')) del_shift_item = wx.MenuItem(delete_menu, wx.NewId(), _('This memory and shift all up')) to_delete = [event.GetRow()] self.Bind(wx.EVT_MENU, functools.partial(self._delete_memories_at, to_delete), del_item) self.Bind(wx.EVT_MENU, functools.partial(self._delete_memories_at, to_delete, shift_up='block'), del_block_item) self.Bind(wx.EVT_MENU, functools.partial(self._delete_memories_at, to_delete, shift_up='all'), del_shift_item) delete_menu.Append(del_item) delete_menu.Append(del_block_item) delete_menu.Append(del_shift_item) # Only offer sort if a contiguous group of non-empty, non-special # memories is selected empty_selected = any([self._memory_cache[r].empty for r in selected_rows]) used_selected = sum([0 if self._memory_cache[r].empty else 1 for r in selected_rows]) special_selected = any([self._memory_cache[r].extd_number for r in selected_rows]) contig_selected = ( selected_rows[-1] - selected_rows[0] == len(selected_rows) - 1) can_sort = (len(selected_rows) > 1 and contig_selected and not empty_selected and not special_selected and self.editable) sort_menu = wx.Menu() sort_menu_item = menu.AppendSubMenu( sort_menu, ngettext('Sort %i memory', 'Sort %i memories', len(selected_rows)) % len(selected_rows)) sortasc_item = wx.MenuItem( sort_menu, wx.NewId(), ngettext('Sort %i memory ascending', 'Sort %i memories ascending', len(selected_rows)) % len(selected_rows)) self.Bind(wx.EVT_MENU, functools.partial(self._sort_memories, selected_rows, False), sortasc_item) sort_menu.Append(sortasc_item) arrange_item = wx.MenuItem( menu, wx.NewId(), ngettext('Cluster %i memory', 'Cluster %i memories', used_selected) % used_selected) self.Bind(wx.EVT_MENU, functools.partial(self._arrange_memories, selected_rows), arrange_item) menu.Append(arrange_item) arrange_item.Enable(empty_selected and used_selected and not special_selected) sortdesc_item = wx.MenuItem( menu, wx.NewId(), ngettext('Sort %i memory descending', 'Sort %i memories descending', len(selected_rows)) % len(selected_rows)) self.Bind(wx.EVT_MENU, functools.partial(self._sort_memories, selected_rows, True), sortdesc_item) sort_menu.Append(sortdesc_item) # Don't allow bulk operations on live radios with pending jobs del_block_item.Enable(not self.busy) del_shift_item.Enable(not self.busy) insert_item.Enable(not self.busy and self.editable) menu.Enable(sort_menu_item.GetId(), not self.busy and can_sort) if CONF.get_bool('developer', 'state'): menu.Append(wx.MenuItem(menu, wx.ID_SEPARATOR)) raw_item = wx.MenuItem(menu, wx.NewId(), _('Show Raw Memory')) self.Bind(wx.EVT_MENU, functools.partial(self._mem_showraw, event.GetRow()), raw_item) menu.Append(raw_item) diff_item = wx.MenuItem(menu, wx.NewId(), _('Diff Raw Memories')) self.Bind(wx.EVT_MENU, functools.partial(self._mem_diff, selected_rows), diff_item) menu.Append(diff_item) menu.Enable(diff_item.GetId(), len(selected_rows) == 2) self.PopupMenu(menu) menu.Destroy() @common.error_proof() def _mem_properties(self, rows, event): memories = [ self.synchronous_get_memory(self.row2mem(row)) for row in rows] with ChirpMemPropDialog(self, memories) as d: if d.ShowModal() == wx.ID_OK: memories = d._memories else: return # Schedule all the set jobs for memory in memories: self.set_memory(memory) wx.PostEvent(self, common.EditorChanged(self.GetId())) @common.error_proof() def _mem_insert(self, row, event): # Traverse memories downward until we find a hole for i in range(row, self.mem2row(self._features.memory_bounds[1] + 1)): mem = self._memory_cache[i] if mem.empty: LOG.debug("Found empty memory %i at row %i" % (mem.number, i)) empty_row = i break else: raise Exception(_('No empty rows below!')) mems_to_refresh = [] # Move memories down in reverse order for target_row in range(empty_row, row, -1): mem = self._memory_cache[target_row - 1] LOG.debug('Moving memory %i -> %i', mem.number, self.row2mem(target_row)) mem.number = self.row2mem(target_row) self.set_memory(mem, refresh=False) mems_to_refresh.append(mem.number) # Erase the memory that is to become the empty row LOG.debug('Erasing memory %i', self.row2mem(row)) self.erase_memory(self.row2mem(row), refresh=False) mems_to_refresh.append(self.row2mem(row)) # Refresh all the memories we touched for number in mems_to_refresh: self.refresh_memory(number) wx.PostEvent(self, common.EditorChanged(self.GetId())) def _mem_showraw(self, row, event): mem = self._radio.get_raw_memory(self.row2mem(row)) with developer.MemoryDialog(mem, self) as d: d.ShowModal() def _mem_diff(self, rows, event): mem_a = self._radio.get_raw_memory(self.row2mem(rows[0])) mem_b = self._radio.get_raw_memory(self.row2mem(rows[1])) with developer.MemoryDialog((mem_a, mem_b), self) as d: d.ShowModal() def update_font(self, refresh=True): fixed = CONF.get_bool('font_fixed', 'state', False) large = CONF.get_bool('font_large', 'state', False) if fixed: font = self._fixed_font else: font = self._variable_font if large: font = wx.Font(font) font.SetPointSize(font.PointSize + 2) self._grid.SetDefaultCellFont(font) if refresh: self.refresh() wx.CallAfter(self._grid.AutoSizeColumns, setAsMin=False) wx.CallAfter(self._grid.AutoSizeRows, setAsMin=False) wx.CallAfter(self._grid.SetRowLabelSize, wx.grid.GRID_AUTOSIZE) def cb_copy_getdata(self, cut=False): rows = self.get_selected_rows_safe() offset = self._features.memory_bounds[0] mems = [] for row in rows: mem = self.synchronous_get_memory(row + offset) mems.append(mem) rcid = directory.radio_class_id(self._radio.__class__) payload = {'mems': mems, 'features': self._radio.get_features(), 'source_radio_id': rcid, 'source': self.GetId()} data = wx.DataObjectComposite() memdata = wx.CustomDataObject(common.CHIRP_DATA_MEMORY) data.Add(memdata) memdata.SetData(pickle.dumps(payload)) strfmt = chirp_common.mem_to_text(mems[0]) textdata = wx.TextDataObject(strfmt) data.Add(textdata) if cut: if any('empty' in mem.immutable for mem in mems): raise errors.InvalidMemoryLocation( _('Some memories are not deletable')) for mem in mems: self.erase_memory(mem.number) if cut: wx.PostEvent(self, common.EditorChanged(self.GetId())) return data def cb_copy(self, cut=False): self.cb_copy_data(self.cb_copy_getdata(cut=cut)) def memedit_import_all(self, source_radio): source_rf = source_radio.get_features() first = max(source_rf.memory_bounds[0], self._features.memory_bounds[0]) last = min(source_rf.memory_bounds[1], self._features.memory_bounds[1]) memories = [source_radio.get_memory(i) for i in range(first, last + 1)] used = [m.number for m in memories if not m.empty] # Update the range to be from just the lowest and highest used memory. # The range of memories that are used in the source will be imported, # including any gaps. first = min(used) last = max(used) row = self.mem2row(first) LOG.info('Importing %i-%i starting from %s %s', first, last, source_radio.VENDOR, source_radio.MODEL) payload = {'mems': [m for m in memories if first <= m.number <= last], 'features': source_rf} self._cb_paste_memories(payload, row=row) def _cb_paste_memories(self, payload, row=None): mems = payload['mems'] srcrf = payload['features'] if row is None: row = self.get_selected_rows_safe()[0] overwrite = [] for i in range(len(mems)): mem = self._memory_cache[row + i] if not mem.empty: overwrite.append(mem.extd_number or mem.number) if overwrite: if len(overwrite) == 1 and len(mems) == 1: msg = _('Pasted memory will overwrite memory %s') % ( overwrite[0]) elif len(overwrite) == 1 and len(mems) > 0: msg = _('Pasted memories will overwrite memory %s') % ( overwrite[0]) elif len(overwrite) > 10: msg = _('Pasted memories will overwrite %s ' 'existing memories') % (len(overwrite)) else: msg = _('Pasted memories will overwrite memories %s') % ( ','.join(str(x) for x in overwrite)) d = wx.MessageDialog(self, msg, _('Overwrite memories?'), wx.YES | wx.NO | wx.YES_DEFAULT) resp = d.ShowModal() if resp == wx.ID_NO: return False same_class = (payload.get('source_radio_id') == directory.radio_class_id(self._radio.__class__)) LOG.debug('Paste is from identical radio class: %s', same_class) errormsgs = [] modified = False for mem in mems: existing = self._memory_cache[row] number = self.row2mem(row) # We need to disable immutable checking while we reassign these # numbers. This might be a flag that we should be copying things # between memories and not reassigning memories to then set. immutable = list(mem.immutable) mem.immutable = [] # Handle potential need to convert between special and regular # memories if isinstance(number, str): mem.extd_number = number mem.number = self.special2mem(number) else: mem.extd_number = '' mem.number = number mem.immutable = immutable row += 1 try: if mem.empty: self.erase_memory(mem.number) self._radio.check_set_memory_immutable_policy(existing, mem) else: mem = import_logic.import_mem(self._radio, srcrf, mem) warns, errs = chirp_common.split_validation_msgs( self._radio.validate_memory(mem)) errormsgs.extend([(mem, e) for e in errs]) errormsgs.extend([(mem, w) for w in warns]) # If we are not pasting into a radio of the same type, # then unset the mem.extra bits which won't be compatible. if not same_class: mem.extra = [] if not errs: # If we got error messages from validate, don't even # try to set the memory, just like if import_logic # was unable to make it compatible. self.set_memory(mem) modified = True except (import_logic.DestNotCompatible, chirp_common.ImmutableValueError, errors.RadioError) as e: LOG.warning('Pasted memory %s incompatible: %s' % ( mem, str(e))) errormsgs.append((mem, e)) except Exception as e: LOG.exception('Failed to paste: %s' % e) errormsgs.append((mem, e)) if modified: wx.PostEvent(self, common.EditorChanged(self.GetId())) if errormsgs: errorextra = '' if len(errormsgs) > 19: errorextra = '\n' + _('...and %i more' % (len(errormsgs) - 19)) errormsgs = errormsgs[:19] d = wx.MessageDialog( self, _('Some memories are incompatible with this radio')) msg = '\n'.join('[%s]: %s' % (mem.extd_number or mem.number, e) for mem, e in errormsgs) msg += errorextra d.SetExtendedMessage(msg) d.ShowModal() return True def cb_paste(self): data = super().cb_paste() if common.CHIRP_DATA_MEMORY in data.GetAllFormats(): payload = pickle.loads(data.GetData().tobytes()) LOG.debug('CHIRP-native paste: %r' % payload) self._cb_paste_memories(payload) elif wx.DF_UNICODETEXT in data.GetAllFormats(): try: mem = chirp_common.mem_from_text( data.GetText()) except Exception as e: LOG.warning('Failed to parse pasted data %r: %s' % ( data.GetText(), e)) return # Since matching the offset is kinda iffy, set our band plan # set the offset, if a rule exists. if mem.duplex in ('-', '+'): self._set_memory_defaults(mem, 'offset') LOG.debug('Generic text paste %r: %s' % ( data.GetText(), mem)) self._cb_paste_memories({'mems': [mem], 'features': self._features}) else: LOG.warning('Unknown data format %s paste' % ( data.GetFormat().Type)) def cb_delete(self): selected_rows = self.get_selected_rows_safe() self._delete_memories_at(selected_rows, None) def get_selected_rows_safe(self): """Return the currently-selected rows If no rows are selected, use the row of the cursor """ selected = self._grid.GetSelectedRows() if not selected: selected = [self._grid.GetGridCursorRow()] return selected def cb_move(self, direction): selected = self.get_selected_rows_safe() last_row = self._grid.GetNumberRows() - 1 if direction < 0 and selected[0] == 0: LOG.warning('Unable to move memories above first row') return elif direction > 0 and selected[-1] == last_row: LOG.warning('Unable to move memories below last row') return elif abs(direction) != 1: LOG.error('Move got direction %i; only +/-1 supported', direction) return first = selected[0] last = selected[-1] new_indexes = [x + direction for x in selected] if direction < 0: transplant = self._memory_cache[first + direction] new_number = self.row2mem(last) elif direction > 0: transplant = self._memory_cache[last + direction] new_number = self.row2mem(first) LOG.debug('Transplanting %s to %i for move indexes: %s -> %s', transplant, new_number, selected, new_indexes) transplant.number = new_number to_set = [transplant] self._grid.ClearSelection() for old_row, new_row in zip(selected, new_indexes): mem = self._memory_cache[old_row] new_number = self.row2mem(new_row) LOG.debug('Moving %s to %i', mem, new_number) mem.number = new_number to_set.append(mem) self._grid.SelectRow(new_row, True) for mem in to_set: self.set_memory(mem) cursor_r, cursor_c = self._grid.GetGridCursorCoords() self._grid.SetGridCursor(cursor_r + direction, cursor_c) wx.PostEvent(self, common.EditorChanged(self.GetId())) def cb_goto(self, number, column=0): self._grid.GoToCell(self.mem2row(number), column) self._grid.SelectRow(self.mem2row(number)) def cb_find(self, text): search_cols = ('freq', 'name', 'comment') cols = [self._col_defs.index(self._col_def_by_name(x)) for x in search_cols] num_rows = self._grid.GetNumberRows() try: current_row = self._grid.GetSelectedRows()[0] + 1 except IndexError: current_row = 0 for row in range(current_row, current_row + num_rows): # Start at current row, and wrap around row_num = row % num_rows for col in cols: if text.lower() in self._grid.GetCellValue( row_num, col).lower(): self.cb_goto(self.row2mem(row_num), col) return True return False def select_all(self): self._grid.SelectAll() def rows_visible(self): first = self._grid.GetFirstFullyVisibleRow() last = first + self._grid.GetScrollPageSize(wx.VERTICAL) return first, last def get_scroll_pos(self): return self._grid.GetViewStart() def set_scroll_pos(self, pos): self._grid.Scroll(*pos) def export_to_file(self, filename): if not filename.lower().endswith('.csv'): raise Exception(_('Export can only write CSV files')) selected = self._grid.GetSelectedRows() if len(selected) <= 1: selected = range(0, self._grid.GetNumberRows()) r = generic_csv.CSVRadio(None) # The CSV driver defaults to a single non-empty memory at location # zero, so delete it before we go to export. r.erase_memory(0) for row in selected: m = self._memory_cache[row] if m.extd_number: # We don't export specials continue if not m.empty: m = import_logic.import_mem(r, self._features, m, mem_cls=chirp_common.Memory) r.set_memory(m) r.save(filename) LOG.info('Wrote exported CSV to %s' % filename) def get_selected_memories(self, or_all=True): rows = self._grid.GetSelectedRows() if len(rows) <= 1 and or_all: rows = list(range(self._grid.GetNumberRows())) return [self._memory_cache[r] for r in rows] class ChirpLiveMemEdit(ChirpMemEdit, common.ChirpAsyncEditor): pass class DVMemoryAsSettings(settings.RadioSettingGroup): def __init__(self, radio, dvmemory): self._dvmemory = dvmemory super(DVMemoryAsSettings, self).__init__('dvmemory', 'DV Memory') features = radio.get_features() fields = {'dv_urcall': 'URCALL', 'dv_rpt1call': 'RPT1Call', 'dv_rpt2call': 'RPT2Call', 'dv_code': _('Digital Code')} for field, title in fields.items(): value = getattr(dvmemory, field) if isinstance(value, int): rsv = settings.RadioSettingValueInteger(0, 99, value) elif features.requires_call_lists and 'call' in field: if 'urcall' in field: calls = radio.get_urcall_list() elif 'rpt' in field: calls = radio.get_repeater_call_list() else: LOG.error('Unhandled call type %s' % field) calls = [] rsv = settings.RadioSettingValueList( calls, getattr(dvmemory, field)) else: rsv = settings.RadioSettingValueString(0, 8, str(value)) rs = settings.RadioSetting(field, title, rsv) self.append(rs) class ChirpMemPropDialog(wx.Dialog): def __init__(self, memedit, memories, *a, **k): if len(memories) == 1: title = _('Edit details for memory %i') % memories[0].number else: title = _('Edit details for %i memories') % len(memories) super().__init__(memedit, *a, title=title, **k) self._memories = [mem.dupe() for mem in memories] self._col_defs = list(memedit._col_defs) self._radio = memedit._radio # The first non-empty memory sets the defaults memory = self._memories[0] for mem in self._memories: if not mem.empty: memory = mem break self.default_memory = memory self._tabs = wx.Notebook(self) vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) vbox.Add(self._tabs, 1, wx.EXPAND) self._pg = wx.propgrid.PropertyGrid(self._tabs, style=wx.propgrid.PG_BOLD_MODIFIED) self._pg.Bind(wx.propgrid.EVT_PG_CHANGED, self._mem_prop_changed) self._tabs.InsertPage(0, self._pg, _('Values')) page_index = 0 self._extra_page = None self._dv_page = None if memory.extra: page_index += 1 self._extra_page = page_index self._extra = common.ChirpSettingGrid(memory.extra, self._tabs) self._tabs.InsertPage(page_index, self._extra, _('Extra')) self._extra.propgrid.Bind(wx.propgrid.EVT_PG_CHANGED, self._mem_extra_changed) if isinstance(memory, chirp_common.DVMemory): page_index += 1 self._dv_page = page_index self._dv = common.ChirpSettingGrid( DVMemoryAsSettings(memedit._radio, memory), self._tabs) self._tabs.InsertPage(page_index, self._dv, _('DV Memory')) self._dv.propgrid.Bind(wx.propgrid.EVT_PG_CHANGED, self._mem_prop_changed) for coldef in self._col_defs: # Exclude mem.extra fields since they are handled on the extra # page separately. if coldef.valid and '.' not in coldef.name: editor = coldef.get_propeditor(memory) self._pg.Append(editor) if coldef.name in memory.immutable: editor.Enable(False) bs = self.CreateButtonSizer(wx.OK | wx.CANCEL) vbox.Add(bs, 0, wx.ALIGN_RIGHT | wx.ALL, border=10) self.Bind(wx.EVT_BUTTON, self._button) # OK button is disabled until something is changed self.FindWindowById(wx.ID_OK).Enable(False) self.SetMinSize((400, 400)) self.Fit() self.Center() wx.CallAfter(self._pg.FitColumns) def _col_def_by_name(self, name): for coldef in self._col_defs: if coldef._name == name: return coldef LOG.error('No column definition for %s' % name) def _update_mem(self, mem, prop, coldef): name = prop.GetName().split(common.INDEX_CHAR)[0] value = prop.GetValueAsString() if coldef: setattr(mem, name, coldef._digest_value(mem, value)) elif value.isdigit(): # Assume this is an integer (dv_code) and set it as # such setattr(mem, name, prop.GetValue()) else: setattr(mem, name, value) LOG.debug('Properties dialog changed mem %i %s=%r', mem.number, name, value) if prop.GetName() == 'freq': mem.empty = False def _mem_prop_changed(self, event): self.FindWindowById(wx.ID_OK).Enable(True) prop = event.GetProperty() coldef = self._col_def_by_name(prop.GetName()) for mem in self._memories: try: self._update_mem(mem, prop, coldef) except chirp_common.ImmutableValueError as e: LOG.warning('Memory %s: %s' % (mem.number, e)) def _mem_extra_changed(self, event): self.FindWindowById(wx.ID_OK).Enable(True) prop = event.GetProperty() name = prop.GetName().split(common.INDEX_CHAR)[0] value = prop.GetValueAsString() for mem in self._memories: for setting in mem.extra: if setting.get_name() == name: if isinstance(setting.value, settings.RadioSettingValueBoolean): setting.value = value = prop.GetValue() else: setting.value = value LOG.debug('Changed mem %i extra %s=%r' % ( mem.number, setting.get_name(), value)) def _validate_memories(self): for mem in self._memories: msgs = self._radio.validate_memory(mem) if msgs: wx.MessageBox(_('Invalid edit: %s') % '; '.join(msgs), 'Invalid Entry', parent=self) raise errors.InvalidValueError() def _button(self, event): button_id = event.GetEventObject().GetId() if button_id == wx.ID_OK: try: self._validate_memories() except errors.InvalidValueError: # Leave the box open return self.EndModal(button_id) chirp-20240224/chirp/wxui/clone.py0000644000175000017500000005745514565616503015642 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import collections import logging import platform import re import textwrap import threading import serial from serial.tools import list_ports import wx import wx.lib.sized_controls from chirp import chirp_common from chirp import directory from chirp.drivers import fake from chirp import errors from chirp.wxui import config from chirp.wxui import common from chirp.wxui import developer _ = wx.GetTranslation LOG = logging.getLogger(__name__) CONF = config.get() HELPME = _('Help Me...') CUSTOM = _('Custom...') FAKES = { 'Fake NOP': developer.FakeSerial(), 'Fake Echo NOP': developer.FakeEchoSerial(), 'Fake F7E': fake.FakeKenwoodSerial(), 'Fake UV17': fake.FakeUV17Serial(), 'Fake UV17Pro': fake.FakeUV17ProSerial(), } class CloneThread(threading.Thread): def __init__(self, radio, dialog, fn): super(CloneThread, self).__init__() self._radio = radio self._dialog = dialog self._fn = getattr(self._radio, fn) self._radio.status_fn = self._status def stop(self): LOG.warning('Stopping clone thread') # Clear out our dialog reference, which should stop us from # eventing to a missing window, and reporting error, when we have # already been asked to cancel self._dialog = None # Close the serial, which should stop the clone soon self._radio.pipe.close() def _status(self, status): self._dialog._status(status) def run(self): try: self._fn() except Exception as e: if self._dialog: LOG.exception('Failed to clone: %s' % e) self._dialog.fail(str(e)) else: LOG.warning('Clone failed after cancel: %s', e) else: if self._dialog: self._dialog.complete() finally: try: self._radio.pipe.close() except OSError: # If we were canceled and we have already closed an active # serial, this will fail with EBADF pass # NOTE: This is the legacy settings thread that facilitates # LiveAdapter to get/fetch settings. class SettingsThread(threading.Thread): def __init__(self, radio, progdialog, settings=None): super(SettingsThread, self).__init__() self._radio = radio self._dialog = progdialog self.settings = settings self._dialog.SetRange(100) self.error = None def run(self): self._radio.pipe.open() try: self._run() except Exception as e: LOG.exception('Failed during setting operation') wx.CallAfter(self._dialog.Update, 100) self.error = str(e) finally: self._radio.pipe.close() def _run(self): if self.settings: msg = _('Applying settings') else: msg = _('Loading settings') wx.CallAfter(self._dialog.Update, 10, newmsg=msg) if self.settings: self._radio.set_settings(self.settings) else: self.settings = self._radio.get_settings() wx.CallAfter(self._dialog.Update, 100, newmsg=_('Complete')) def open_serial(port, rclass): if port.startswith('Fake'): return FAKES[port] if '://' in port: pipe = serial.serial_for_url(port, do_not_open=True) pipe.timeout = 0.25 pipe.rtscts = rclass.HARDWARE_FLOW pipe.rts = rclass.WANTS_RTS pipe.dtr = rclass.WANTS_DTR pipe.open() pipe.baudrate = rclass.BAUD_RATE else: pipe = serial.Serial(baudrate=rclass.BAUD_RATE, rtscts=rclass.HARDWARE_FLOW, timeout=0.25) pipe.rts = rclass.WANTS_RTS pipe.dtr = rclass.WANTS_DTR pipe.port = port pipe.open() LOG.debug('Serial opened: %s (rts=%s dtr=%s)', pipe, pipe.rts, pipe.dtr) return pipe class ChirpRadioPromptDialog(wx.Dialog): def __init__(self, *a, **k): self.radio = k.pop('radio') self.prompt = k.pop('prompt') buttons = k.pop('buttons', wx.OK | wx.CANCEL) super().__init__(*a, **k) prompts = self.radio.get_prompts() self.message = getattr(prompts, self.prompt) if '\n' not in self.message: self.message = '\n'.join(textwrap.wrap(self.message)) bs = self.CreateButtonSizer(buttons) vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) instructions = wx.StaticText(self) instructions.SetLabelMarkup(self.message) vbox.Add(instructions, border=20, flag=wx.ALL) if self.prompt == 'experimental': risk_warning = wx.StaticText(self) risk_warning.SetLabelMarkup(_('Do you accept the risk?')) vbox.Add(risk_warning, border=20, flag=wx.ALL) self.cb = wx.CheckBox( self, label=_("Do not prompt again for %s") % ( '%s %s' % (self.radio.VENDOR, self.radio.MODEL))) vbox.Add(self.cb, border=20, flag=wx.ALL) vbox.Add(bs, flag=wx.ALL, border=10) self.Fit() self.Centre() def persist_flag(self, radio, flag): key = '%s_%s' % (flag, directory.radio_class_id(radio)) CONF.set_bool(key.lower(), not self.cb.IsChecked(), 'clone_prompts') def check_flag(self, radio, flag): key = '%s_%s' % (flag, directory.radio_class_id(radio)) return CONF.get_bool(key.lower(), 'clone_prompts', True) def ShowModal(self): if not self.message: LOG.debug('No %s prompt for radio' % self.prompt) return wx.ID_OK if not self.check_flag(self.radio, self.prompt): LOG.debug('Prompt %s disabled for radio' % self.prompt) return wx.ID_OK LOG.debug('Showing %s prompt' % self.prompt) status = super().ShowModal() if status == wx.ID_OK: LOG.debug('Setting flag for prompt %s' % self.prompt) self.persist_flag(self.radio, self.prompt) else: LOG.debug('No flag change for %s' % self.prompt) return status def port_label(port): if platform.system() == 'Windows': # The OS format for description is "Long Name (COMn)", so use # port: desc to make the port visible early in the string without # changing the description format. label_fmt = '%(dev)s: %(desc)s' else: label_fmt = '%(desc)s (%(dev)s)' dev = port.device if dev.startswith('/dev/'): dev = dev.split('/dev/')[1] if not port.description: return dev elif port.description == 'n/a': return dev else: return label_fmt % ({'desc': port.description, 'dev': dev}) def port_sort_key(port): key = port.device if platform.system() == 'Windows': try: m = re.match('^COM([0-9]+)$', port.device) if m: key = 'COM%08i' % int(m.group(1)) except Exception as e: LOG.warning('Failed to stable format %s: %s', port.device, e) return key # Make this global so it sticks for a session CUSTOM_PORTS = [] class ChirpCloneDialog(wx.Dialog): def __init__(self, *a, **k): allow_detected_models = k.pop('allow_detected_models', False) print('_ is %r' % _) super(ChirpCloneDialog, self).__init__( *a, title=_('Communicate with radio'), **k) self._clone_thread = None grid = wx.FlexGridSizer(2, 5, 5) grid.AddGrowableCol(1) bs = self.CreateButtonSizer(wx.OK | wx.CANCEL) if CONF.get_bool('developer', 'state'): for fakeserial in FAKES.keys(): if fakeserial not in CUSTOM_PORTS: CUSTOM_PORTS.append(fakeserial) def _add_grid(label, control): grid.Add(wx.StaticText(self, label=label), proportion=1, border=10, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) grid.Add(control, proportion=1, border=10, flag=wx.EXPAND | wx.RIGHT | wx.LEFT) self._port = wx.Choice(self, choices=[]) self._port.SetMaxSize((50, -1)) self.set_ports() self.Bind(wx.EVT_CHOICE, self._selected_port, self._port) _add_grid(_('Port'), self._port) self._vendor = wx.Choice(self, choices=['Icom', 'Yaesu']) _add_grid(_('Vendor'), self._vendor) self.Bind(wx.EVT_CHOICE, self._selected_vendor, self._vendor) self._model = wx.Choice(self, choices=[]) _add_grid(_('Model'), self._model) self.Bind(wx.EVT_CHOICE, self._selected_model, self._model) self.gauge = wx.Gauge(self) self.Bind(wx.EVT_BUTTON, self._action) vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(grid, proportion=1, flag=wx.TOP | wx.BOTTOM | wx.EXPAND, border=20) self.status_msg = wx.StaticText( self, label='', style=(wx.ALIGN_CENTER_HORIZONTAL | wx.ST_NO_AUTORESIZE | wx.ELLIPSIZE_END)) vbox.Add(self.status_msg, border=5, proportion=0, flag=wx.EXPAND | wx.BOTTOM) vbox.Add(self.gauge, flag=wx.EXPAND | wx.RIGHT | wx.LEFT, border=10, proportion=0) vbox.Add(wx.StaticLine(self), flag=wx.EXPAND | wx.ALL, border=5) vbox.Add(bs, flag=wx.ALL, border=10) self.SetSizer(vbox) self.Center() self._vendors = collections.defaultdict(list) for rclass in directory.DRV_TO_RADIO.values(): if (not issubclass(rclass, chirp_common.CloneModeRadio) and not issubclass(rclass, chirp_common.LiveRadio)): continue if (getattr(rclass, '_DETECTED_MODEL', False) and not allow_detected_models): continue self._vendors[rclass.VENDOR].append(rclass) self._add_aliases(rclass) for models in self._vendors.values(): models.sort(key=lambda x: '%s %s' % (x.MODEL, x.VARIANT)) self._vendor.Set(sorted(self._vendors.keys())) try: self.select_vendor_model(CONF.get('last_vendor', 'state'), CONF.get('last_model', 'state')) except ValueError: LOG.warning('Last vendor/model not found') self.SetMinSize((400, 200)) self.Fit() def set_ports(self, system_ports=None, select=None): if not system_ports: system_ports = list_ports.comports() # These are ports that we should never offer to the user because # they get picked up by the list but are not usable or relevant. filter_ports = [ # MacOS unpaired bluetooth serial '/dev/cu.Bluetooth-Incoming-Port', ] LOG.debug('All system ports: %s', [x.__dict__ for x in system_ports]) self.ports = [(port.device, port_label(port)) for port in sorted(system_ports, key=port_sort_key) if port.device not in filter_ports] favorite_ports = CONF.get('favorite_ports', 'state') or '' for port in favorite_ports.split(','): if port and port not in [x[0] for x in self.ports]: self.ports.insert(0, (port, port)) for port in CUSTOM_PORTS: if port not in [x[0] for x in self.ports]: self.ports.insert(0, (port, port)) if not select: select = CONF.get('last_port', 'state') if not self.ports: LOG.warning('No ports available; action will be disabled') okay_btn = self.FindWindowById(self.GetAffirmativeId()) okay_btn.Enable(bool(self.ports)) self._port.SetItems([x[1] for x in self.ports] + [CUSTOM, HELPME]) for device, name in self.ports: if device == select: self._port.SetStringSelection(name) break else: if self.ports: port = self.ports[0] self._port.SetStringSelection(port[0]) else: port = '(no ports available)' LOG.warning('Unable to select %r, defaulting to %s', select, port) def get_selected_port(self): selected = self._port.GetStringSelection() for device, name in self.ports: if name == selected: return device LOG.warning('Did not find device for selected port %s' % selected) return selected def _port_assist(self, event): r = wx.MessageBox( _('Unplug your cable (if needed) and then click OK'), _('USB Port Finder'), style=wx.OK | wx.CANCEL | wx.OK_DEFAULT, parent=self) if r == wx.CANCEL: return before = list_ports.comports() r = wx.MessageBox( _('Plug in your cable and then click OK'), _('USB Port Finder'), style=wx.OK | wx.CANCEL | wx.OK_DEFAULT, parent=self) if r == wx.CANCEL: return after = list_ports.comports() changed = set(after) - set(before) found = None if not changed: wx.MessageBox( _('Unable to determine port for your cable. ' 'Check your drivers and connections.'), _('USB Port Finder'), parent=self) self.set_ports(after) return elif len(changed) == 1: found = list(changed)[0] wx.MessageBox( '%s\n%s' % (_('Your cable appears to be on port:'), port_label(found)), _('USB Port Finder'), parent=self) else: wx.MessageBox( _('More than one port found: %s') % ', '.join(changed), _('USB Port Finder'), parent=self) self.set_ports(after) return self.set_ports(after, select=found.device) def _add_aliases(self, rclass): for alias in rclass.ALIASES: class DynamicRadioAlias(rclass): _orig_rclass = rclass VENDOR = alias.VENDOR MODEL = alias.MODEL VARIANT = alias.VARIANT self._vendors[alias.VENDOR].append(DynamicRadioAlias) def disable_model_select(self): self._vendor.Disable() self._model.Disable() def disable_running(self): self._port.Disable() self.FindWindowById(wx.ID_OK).Disable() def _persist_choices(self): CONF.set('last_vendor', self._vendor.GetStringSelection(), 'state') CONF.set('last_model', self._model.GetStringSelection(), 'state') CONF.set('last_port', self.get_selected_port(), 'state') def _selected_port(self, event): if self._port.GetStringSelection() == CUSTOM: port = wx.GetTextFromUser(_('Enter custom port:'), _('Custom Port'), parent=self) if port: CUSTOM_PORTS.append(port) self.set_ports(select=port or None) return elif self._port.GetStringSelection() == HELPME: self._port_assist(event) return self._persist_choices() def _select_vendor(self, vendor): models = [('%s %s' % (x.MODEL, x.VARIANT)).strip() for x in self._vendors[vendor]] self._model.Set(models) self._model.SetSelection(0) def _selected_vendor(self, event): self._select_vendor(event.GetString()) self._persist_choices() def _selected_model(self, event): self._persist_choices() def select_vendor_model(self, vendor, model): self._vendor.SetSelection(self._vendor.GetItems().index(vendor)) self._select_vendor(vendor) self._model.SetSelection(self._model.GetItems().index(model)) def _status(self, status): def _safe_status(): self.gauge.SetRange(status.max) self.gauge.SetValue(min(status.cur, status.max)) self.status_msg.SetLabel(status.msg) wx.CallAfter(_safe_status) def complete(self): self._radio.pipe.close() wx.CallAfter(self.EndModal, wx.ID_OK) def fail(self, message): def safe_fail(): wx.MessageBox(message, _('Error communicating with radio'), wx.ICON_ERROR, parent=self) self.cancel_action() wx.CallAfter(safe_fail) def cancel_action(self): if isinstance(self, ChirpDownloadDialog): self._vendor.Enable() self._model.Enable() self._port.Enable() s = chirp_common.Status() s.cur = 0 s.max = 1 s.msg = '' self._status(s) self.FindWindowById(wx.ID_OK).Enable() def get_selected_rclass(self): vendor = self._vendor.GetStringSelection() model = self._model.GetSelection() LOG.debug('Selected %r' % self._vendors[vendor][model]) return self._vendors[vendor][model] class ChirpDownloadDialog(ChirpCloneDialog): def _selected_model(self, event): super(ChirpDownloadDialog, self)._selected_model(event) rclass = self.get_selected_rclass() prompts = rclass.get_prompts() if prompts.experimental: d = ChirpRadioPromptDialog( self, title=_('Experimental driver'), buttons=wx.YES_NO | wx.NO_DEFAULT, radio=rclass, prompt='experimental') d.SetAffirmativeId(wx.ID_YES) d.SetEscapeId(wx.ID_NO) r = d.ShowModal() if r == wx.ID_CANCEL: LOG.info('User did not accept experimental risk for %s', rclass) self.FindWindowById(wx.ID_OK).Disable() else: LOG.info('User accepted experimental risk for %s', rclass) self.FindWindowById(wx.ID_OK).Enable() def _action(self, event): if event.GetEventObject().GetId() == wx.ID_CANCEL: if self._clone_thread: self._clone_thread.stop() self.EndModal(event.GetEventObject().GetId()) return self._persist_choices() self.disable_model_select() self.disable_running() port = self.get_selected_port() LOG.debug('Using port %r' % port) rclass = self.get_selected_rclass() prompts = rclass.get_prompts() if prompts.info: d = ChirpRadioPromptDialog(self, title=_('Radio information'), radio=rclass, prompt='info') if d.ShowModal() != wx.ID_OK: self.cancel_action() return if prompts.pre_download: d = ChirpRadioPromptDialog(self, title=_('Download instructions'), radio=rclass, prompt='pre_download') if d.ShowModal() != wx.ID_OK: self.cancel_action() return serial = open_serial(port, rclass) # See if the driver detects we should be using a different radio class # to communicate with this model try: rclass = rclass.detect_from_serial(serial) LOG.info('Detected %s from serial', rclass) except NotImplementedError: pass except errors.RadioError as e: LOG.error('Radio serial detection failed: %s', e) self.fail(str(e)) return except Exception as e: LOG.exception('Exception during detection: %s', e) self.fail(_('Internal driver error')) return try: self._radio = rclass(serial) except Exception as e: LOG.exception('Failed to open serial: %s' % e) self.fail(str(e)) return if isinstance(self._radio, chirp_common.LiveRadio): if CONF.get_bool('live_adapter', 'state', False): # Use LiveAdapter to make LiveRadio behave like CloneMode self._radio = common.LiveAdapter(self._radio) else: # Live radios are live # FIXME: This needs to make sure we can talk to the radio first self.EndModal(wx.ID_OK) return self._radio.status_fn = self._status self._clone_thread = CloneThread(self._radio, self, 'sync_in') self._clone_thread.start() class ChirpUploadDialog(ChirpCloneDialog): def __init__(self, radio, *a, **k): super(ChirpUploadDialog, self).__init__(*a, allow_detected_models=True, **k) self._radio = radio self.select_vendor_model( self._radio.VENDOR, ('%s %s' % (self._radio.MODEL, self._radio.VARIANT)).strip()) self.disable_model_select() if isinstance(self._radio, chirp_common.LiveRadio): self._radio = common.LiveAdapter(self._radio) def _action(self, event): if event.GetEventObject().GetId() == wx.ID_CANCEL: if self._clone_thread: self._clone_thread.stop() self.EndModal(event.GetEventObject().GetId()) return self._persist_choices() self.disable_running() port = self.get_selected_port() prompts = self._radio.get_prompts() if prompts.info: d = ChirpRadioPromptDialog(self, title=_('Radio information'), radio=self._radio, prompt='info') if d.ShowModal() != wx.ID_OK: self.cancel_action() return if prompts.display_pre_upload_prompt_before_opening_port: s = None else: LOG.debug('Opening serial %r before upload prompt' % port) s = open_serial(port, self._radio) if prompts.pre_upload: d = ChirpRadioPromptDialog(self, title=_('Upload instructions'), radio=self._radio, prompt='pre_upload') if d.ShowModal() != wx.ID_OK: self.cancel_action() if s: s.close() return baud = self._radio.BAUD_RATE if self._radio.pipe: baud = self._radio.pipe.baudrate if s is None: LOG.debug('Opening serial %r after upload prompt' % port) s = open_serial(port, self._radio) try: self._radio.set_pipe(s) # Short-circuit straight to the previous baudrate for variable- # rate radios to sync back up faster self._radio.pipe.baudrate = baud except Exception as e: self.fail(str(e)) return self._radio._status_fn = self._status self._clone_thread = CloneThread(self._radio, self, 'sync_out') self._clone_thread.start() chirp-20240224/chirp/wxui/settingsedit.py0000644000175000017500000001677314560403070017232 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import copy import logging import wx import wx.dataview from chirp import settings from chirp.wxui import common LOG = logging.getLogger(__name__) class ChirpSettingsEdit(common.ChirpEditor): def __init__(self, radio, *a, **k): super(ChirpSettingsEdit, self).__init__(*a, **k) self._radio = radio self._settings = None self._propgrid = None sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) self._group_control = wx.Treebook(self, style=wx.LB_LEFT) self._group_control.GetTreeCtrl().SetMinSize((250, -1)) sizer.Add(self._group_control, 1, wx.EXPAND) self._initialized = False self._restore_selection = None def _initialize(self, job): self.stop_wait_dialog() with common.error_proof(Exception): if isinstance(job.result, Exception): raise job.result self._settings = job.result self._load_settings() if self._restore_selection is not None: self._group_control.SetSelection(self._restore_selection) self._restore_selection = None def selected(self): if not self._initialized: self._initialized = True self.start_wait_dialog(_('Getting settings')) self.do_radio(lambda job: wx.CallAfter(self._initialize, job), 'get_settings') def get_scroll_pos(self): return self._group_control.GetSelection() def set_scroll_pos(self, pos): try: self._group_control.SetSelection(pos) except AssertionError: # If we're in the middle of a load, stash the position so we will # restore it once we have everything. self._restore_selection = pos def refresh(self): self._restore_selection = self._group_control.GetSelection() self._group_control.DeleteAllPages() # Next select will re-load everything self._initialized = False def _load_settings(self): for group in self._settings: self._add_group(group) self.Layout() def _add_group(self, group, parent=None): propgrid = common.ChirpSettingGrid(group, self._group_control) self._propgrid = propgrid self.Bind(common.EVT_EDITOR_CHANGED, self._changed, propgrid) LOG.debug('Adding page for %s (parent=%s)' % (group.get_shortname(), parent)) if parent is not None: self._group_control.InsertSubPage(parent, propgrid, group.get_shortname()) else: self._group_control.AddPage(propgrid, group.get_shortname()) for element in group.values(): if not isinstance(element, (settings.RadioSetting, settings.RadioSettingSubGroup)): self._add_group(element, parent=self._group_control.FindPage(propgrid)) def cb_copy(self, cut=False): pass def cb_paste(self, data): pass def _apply_settings(self): try: for i in range(self._group_control.GetPageCount()): page = self._group_control.GetPage(i) for name, (setting, val) in page.get_setting_values().items(): if isinstance(setting.value, list): values = setting.value else: values = [setting.value] for j, value in enumerate(values): if not value.get_mutable(): # Do not update immutable settings continue realname, index = name.split(common.INDEX_CHAR) prop = page.propgrid.GetProperty(name) if not prop: LOG.warning('Unable to find property %s in page', name) continue if int(index) == j: try: setting[j] = val finally: if setting[j].get_value() != val: # setting value modified or not accepted in # validate callback, propagate back to GUI prop.SetValue(setting[j].get_value()) return True except Exception as e: LOG.exception('Failed to apply settings') wx.MessageBox(str(e), _('Error applying settings'), wx.OK | wx.ICON_ERROR) return False def _apply_setting_group(self, all_values, group): for element in group.values(): if isinstance(element, settings.RadioSetting): if element.value.get_mutable(): element.value = \ all_values[group.get_name()][element.get_name()] else: self._apply_setting_group(all_values, element) def _set_settings_cb(self, job): if isinstance(job.result, Exception): common.error_proof.show_error(str(job.result)) def _reload(self): self.refresh() self.selected() def _remove_dead_settings(self, root): """Remove any settings that are immutable or uninitialized""" for e in root.values(): if isinstance(e, settings.RadioSetting): # Immutable and uninitialized settings don't get sent to the # radio if not e.value.get_mutable(): LOG.debug('Skipping immutable %s', e.get_name()) del root[e] elif not e.value.initialized: LOG.debug('Skipping uninitialized %s', e.get_name()) del root[e] elif isinstance(e, settings.RadioSettingGroup): self._remove_dead_settings(e) def _changed(self, event): if not self._apply_settings(): return settings = copy.deepcopy(self._settings) for g in settings: self._remove_dead_settings(g) self.do_radio(self._set_settings_cb, 'set_settings', settings) wx.PostEvent(self, common.EditorChanged(self.GetId())) if self._propgrid.needs_reload: LOG.warning('Settings grid needs a reload') wx.CallAfter(self._reload) def saved(self): for i in range(self._group_control.GetPageCount()): page = self._group_control.GetPage(i) page.saved() class ChirpCloneSettingsEdit(ChirpSettingsEdit, common.ChirpSyncEditor): pass class ChirpLiveSettingsEdit(ChirpSettingsEdit, common.ChirpAsyncEditor): pass chirp-20240224/chirp/wxui/radioinfo.py0000644000175000017500000001023614560403070016462 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import wx import wx.propgrid from chirp.drivers import icf from chirp import util from chirp.wxui import common class ChirpRadioInfo(common.ChirpEditor, common.ChirpSyncEditor): def __init__(self, radio, *a, **k): super(ChirpRadioInfo, self).__init__(*a, **k) self._radio = radio self._features = radio.get_features() sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) self._group_control = wx.Listbook(self, style=wx.LB_LEFT) sizer.Add(self._group_control, 1, wx.EXPAND) self._add_features_group() self._add_vendor() self._add_metadata() self._add_driver() def _add_features_group(self): pg = wx.propgrid.PropertyGrid( self, style=wx.propgrid.PG_SPLITTER_AUTO_CENTER) self._group_control.AddPage(pg, _('Features')) for key in self._features._valid_map.keys(): value = getattr(self._features, key) if isinstance(value, list): value = ','.join(str(v) or _('(none)') for v in value) p = wx.propgrid.StringProperty( key, key, value=str(value)) p.Enable(False) pg.Append(p) pg.Sort() def _add_driver(self): pg = wx.propgrid.PropertyGrid( self, style=wx.propgrid.PG_SPLITTER_AUTO_CENTER) self._group_control.AddPage(pg, _('Driver')) try: rclass = self._radio._orig_rclass except AttributeError: rclass = self._radio.__class__ p = wx.propgrid.StringProperty('class', 'class', rclass.__name__) p.Enable(False) pg.Append(p) p = wx.propgrid.StringProperty('module', 'module', rclass.__module__) p.Enable(False) pg.Append(p) pg.Sort() def _add_vendor(self): # This should really be an interface on the radio, but there # is only one example for the moment, so just cheat. if not isinstance(self._radio, icf.IcomCloneModeRadio): return pg = wx.propgrid.PropertyGrid( self, style=wx.propgrid.PG_SPLITTER_AUTO_CENTER) self._group_control.AddPage(pg, 'Icom') attrs = dict(self._radio._icf_data) attrs.update({ 'modelid': ''.join('%02x' % util.byte_to_int(b) for b in self._radio._model), 'endframe': self._radio._endframe, 'raw': self._radio._raw_frames, 'memsize': '0x%X' % self._radio._memsize, }) for key, value in attrs.items(): p = wx.propgrid.StringProperty( key, key, value=str(value)) p.Enable(False) pg.Append(p) pg.Sort() def _add_metadata(self): if not self._radio.metadata: return pg = wx.propgrid.PropertyGrid( self, style=wx.propgrid.PG_SPLITTER_AUTO_CENTER) self._group_control.AddPage(pg, 'Image Metadata') # Don't show the icom fields which are displayed elsewhere, and # don't dump the whole mem_extra blob in here exclude = ('modelid', 'endframe', 'raw', 'memsize', 'mem_extra') for key, value in self._radio.metadata.items(): if key in exclude: continue p = wx.propgrid.StringProperty(key, key, value=str(value)) p.Enable(False) pg.Append(p) pg.Sort() chirp-20240224/chirp/wxui/radiothread.py0000644000175000017500000000707514411666130017010 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import queue import threading import uuid LOG = logging.getLogger(__name__) _JOB_COUNTER = 0 _JOB_COUNTER_LOCK = threading.Lock() def jobnumber(): global _JOB_COUNTER # This shouldn't be called outside the main thread, so this should # not be necessary. But, be careful anyway in case that changes in # the future. with _JOB_COUNTER_LOCK: num = _JOB_COUNTER _JOB_COUNTER += 1 return num class RadioJob: def __init__(self, editor, fn, args, kwargs): self.editor = editor self.fn = fn self.args = args self.kwargs = kwargs self.result = None self.id = str(uuid.uuid4()) self.jobnumber = jobnumber() @property def score(self): if self.fn == 'get_memory': return 20 elif self.fn.startswith('get'): return 10 else: return 0 def __lt__(self, job): # Prioritize jobs with lower scores and jobs submitted before us return self.score < job.score or self.jobnumber < job.jobnumber def __repr__(self): return '<%s@%i>%s(%s,%s)=%r' % ( self.__class__.__name__, self.score, self.fn, ','.join(repr(a) for a in self.args), ','.join('%s=%r' % (k, v) for k, v in self.kwargs.items()), self.result) def dispatch(self, radio): try: self.result = getattr(radio, self.fn)(*self.args, **self.kwargs) except Exception as e: LOG.exception('Failed to run %r' % self) self.result = e LOG.debug('Radio finished %r' % self) class BackgroundRadioJob(RadioJob): @property def score(self): return 100 class RadioThread(threading.Thread): SENTINEL = RadioJob(None, 'END', [], {}) def __init__(self, radio): super().__init__() self._radio = radio self._queue = queue.PriorityQueue() self._log = logging.getLogger('RadioThread') self._waiting = [] def submit(self, editor, fn, *a, **k): job = RadioJob(editor, fn, a, k) self._queue.put(job) return job.id def background(self, editor, fn, *a, **k): job = BackgroundRadioJob(editor, fn, a, k) self._queue.put(job) return job.id def end(self): self._queue.put(self.SENTINEL) def run(self): while True: job = self._queue.get() if job is self.SENTINEL: self._log.info('Exiting on request') return job.dispatch(self._radio) self._waiting.append(job) for job in list(self._waiting): delivered = job.editor.radio_thread_event( job, block=not self.pending) if delivered: self._waiting.remove(job) @property def pending(self): return self._queue.qsize() chirp-20240224/chirp/wxui/report.py0000644000175000017500000000603114411666130016024 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import functools import logging import requests import threading import uuid import platform try: import wx except ImportError: wx = None from chirp import CHIRP_VERSION from chirp.wxui import config CONF = config.get() LOG = logging.getLogger(__name__) logging.getLogger('urllib3.connectionpool').setLevel(logging.INFO) SESSION = None DISABLED = False SEM = threading.Semaphore(2) BASE = 'http://chirp.danplanet.com/report' def get_environment(): if wx: wx_ver = wx.version() else: wx_ver = 'None' return ' // '.join(['Python/%s' % platform.python_version(), '%s/%s' % (platform.system(), platform.platform()), 'CHIRP/%s' % CHIRP_VERSION, 'wx/%s' % wx_ver]) class ReportThread(threading.Thread): def __init__(self, fn): self.__fn = fn super(ReportThread, self).__init__() def run(self): global DISABLED try: self.__fn() except Exception as e: LOG.info('Disabling reporting because %s' % e) DISABLED = True finally: SEM.release() def ensure_session(): global SESSION if SESSION is None: SESSION = requests.Session() SESSION.headers = { 'User-Agent': 'CHIRP/%s' % CHIRP_VERSION, 'X-CHIRP-UUID': CONF.get('seat', 'state'), 'X-CHIRP-Environment': get_environment(), } def with_session(fn): @functools.wraps(fn) def wrapper(*args, **kwargs): global DISABLED if DISABLED: return if not SEM.acquire(False): return if not CONF.is_defined('seat', 'state'): CONF.set('seat', str(uuid.uuid4()), 'state') ensure_session() t = ReportThread(functools.partial(fn, SESSION, *args, **kwargs)) t.start() return wrapper @with_session def check_for_updates(session, callback): r = session.get('%s/latest' % BASE) callback(r.json()['latest']) @with_session def report_model(session, rclass, op): if CONF.get_bool('no_report', 'global', False): return session.post('%s/usage' % BASE, json={'vendor': rclass.VENDOR, 'model': rclass.MODEL, 'variant': rclass.VARIANT, 'op': op}) chirp-20240224/chirp/wxui/common.py0000644000175000017500000005741414561124165016017 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import atexit import contextlib import functools import itertools import logging import os import platform import shutil import tempfile import threading import wx from chirp import chirp_common from chirp.drivers import generic_csv from chirp import errors from chirp import logger from chirp import platform as chirp_platform from chirp import settings from chirp.wxui import config from chirp.wxui import radiothread LOG = logging.getLogger(__name__) CONF = config.get() CHIRP_DATA_MEMORY = wx.DataFormat('x-chirp/memory-channel') EditorChanged, EVT_EDITOR_CHANGED = wx.lib.newevent.NewCommandEvent() StatusMessage, EVT_STATUS_MESSAGE = wx.lib.newevent.NewCommandEvent() INDEX_CHAR = settings.BANNED_NAME_CHARACTERS[0] # This is a lock that can be used to exclude edit-specific operations # from happening at the same time, like radiothread async # operations. This needs to be local to the thing with the wx.Grid as # its child, which is the chirp main window in our case. Making this # global is technically too broad, but in reality, it's equivalent for # us at the moment, and this is easier. EDIT_LOCK = threading.Lock() def closes_clipboard(fn): @functools.wraps(fn) def wrapper(*a, **k): try: return fn(*a, **k) finally: if wx.TheClipboard.IsOpened(): LOG.warning('Closing clipboard left open by %s' % fn) wx.TheClipboard.Close() return wrapper class LiveAdapter(generic_csv.CSVRadio): FILE_EXTENSION = 'img' def __init__(self, liveradio): # Python2 old-style class compatibility generic_csv.CSVRadio.__init__(self, None) self._liveradio = liveradio self.VENDOR = liveradio.VENDOR self.MODEL = liveradio.MODEL self.VARIANT = liveradio.VARIANT self.BAUD_RATE = liveradio.BAUD_RATE self.HARDWARE_FLOW = liveradio.HARDWARE_FLOW self.pipe = liveradio.pipe self._features = self._liveradio.get_features() def get_features(self): return self._features def set_pipe(self, pipe): self.pipe = pipe self._liveradio.pipe = pipe def sync_in(self): for i in range(*self._features.memory_bounds): mem = self._liveradio.get_memory(i) self.set_memory(mem) status = chirp_common.Status() status.max = self._features.memory_bounds[1] status.cur = i status.msg = 'Cloning' self.status_fn(status) def sync_out(self): # FIXME: Handle errors for i in range(*self._features.memory_bounds): mem = self.get_memory(i) if mem.freq == 0: # Convert the CSV notion of emptiness try: self._liveradio.erase_memory(i) except errors.RadioError as e: LOG.error(e) else: try: self._liveradio.set_memory(mem) except errors.RadioError as e: LOG.error(e) status = chirp_common.Status() status.max = self._features.memory_bounds[1] status.cur = i status.msg = _('Cloning') self.status_fn(status) def get_settings(self): return self._liveradio.get_settings() def set_settings(self, settings): return self._liveradio.set_settings(settings) class EditorMenuItem(wx.MenuItem): MENU_VIEW = 'View' MENU_EDIT = 'Edit' ITEMS = {} def __init__(self, cls, callback_name, *a, **k): self._wx_id = wx.NewId() super().__init__(None, self._wx_id, *a, **k) self._cls = cls self._callback_name = callback_name self.ITEMS[self.key] = self._wx_id @property def key(self): return '%s:%s' % (self._cls.__name__, self._callback_name) @property def editor_class(self): return self._cls def editor_callback(self, editor, event): getattr(editor, self._callback_name)(event) def add_menu_callback(self): # Some platforms won't actually set the accelerator (macOS) or allow # enable/check (linux) before we are in a menu. accel = self.GetAccel() self.SetAccel(None) self.SetAccel(accel) class EditorMenuItemToggle(EditorMenuItem): """An EditorMenuItem that manages boolean/check state in CONF""" def __init__(self, cls, callback_name, conf_tuple, *a, **k): k['kind'] = wx.ITEM_CHECK super().__init__(cls, callback_name, *a, **k) self._conf_key, self._conf_section = conf_tuple def editor_callback(self, editor, event): menuitem = event.GetEventObject().FindItemById(event.GetId()) CONF.set_bool(self._conf_key, menuitem.IsChecked(), self._conf_section) super().editor_callback(editor, event) def add_menu_callback(self): super().add_menu_callback() self.Check(CONF.get_bool(self._conf_key, self._conf_section, False)) class ChirpEditor(wx.Panel): def __init__(self, *a, **k): super().__init__(*a, **k) self.setup_radio_interface() self.wait_dialog = None @property def radio(self): return self._radio def start_wait_dialog(self, message): if self.wait_dialog: LOG.error('Wait dialog already in progress!') return self.wait_dialog = wx.ProgressDialog(_('Please wait'), message, 100, parent=self) wx.CallAfter(self.wait_dialog.Show) def bump_wait_dialog(self, value=None, message=None): if value: wx.CallAfter(self.wait_dialog.Update, value, newmsg=message) else: wx.CallAfter(self.wait_dialog.Pulse, message) def stop_wait_dialog(self): def cb(): if self.wait_dialog: self.wait_dialog.Destroy() self.wait_dialog = None wx.CallAfter(cb) def status_message(self, message): wx.PostEvent(self, StatusMessage(self.GetId(), message=message)) def refresh(self): pass def cb_copy(self, cut=False): raise NotImplementedError() @closes_clipboard def cb_copy_data(self, data): if wx.TheClipboard.Open(): wx.TheClipboard.SetData(data) wx.TheClipboard.Close() else: raise RuntimeError(_('Unable to open the clipboard')) @closes_clipboard def cb_paste(self): memdata = wx.CustomDataObject(CHIRP_DATA_MEMORY) textdata = wx.TextDataObject() if wx.TheClipboard.Open(): gotchirpmem = wx.TheClipboard.GetData(memdata) got = wx.TheClipboard.GetData(textdata) wx.TheClipboard.Close() if gotchirpmem: return memdata elif got: return textdata def cb_delete(self): pass def cb_find(self, text): pass def select_all(self): pass def saved(self): pass def selected(self): pass def get_scroll_pos(self): return None def set_scroll_pos(self, pos): LOG.warning('Editor %s does not support set_scroll_pos()' % ( self.__class__.__name__)) def update_font(self): pass @classmethod def get_menu_items(self): """Return a dict of menu items specific to this editor class Example: {'Edit': [wx.MenuItem], 'View': [wx.MenuItem]} """ return {} class ChirpSyncEditor: """Radio interface that makes synchronous calls. This executes RadioJob requests synchronously in the calling thread and directly spawns the callback. To be used only with radio drivers that manipulate in-memory state. """ def do_radio(self, cb, fn, *a, **k): """Synchronous passthrough for non-Live radios""" job = radiothread.RadioJob(self, fn, a, k) try: job.result = getattr(self._radio, fn)(*a, **k) except Exception as e: LOG.exception('Failed to run %s(%s, %s)' % ( fn, ','.join(str(x) for x in a), ','.join('%s=%r' % (k, v) for k, v in k.items()))) job.result = e if cb: cb(job) do_lazy_radio = do_radio def setup_radio_interface(self): pass @property def busy(self): return False class ChirpAsyncEditor(ChirpSyncEditor): """Radio interface that makes async calls in a helper thread. This executes RadioJob requests asynchronously in a thread and schedules the callback via a wx event. """ def do_radio(self, cb, fn, *a, **k): self._jobs[self._radio_thread.submit(self, fn, *a, **k)] = cb def do_lazy_radio(self, cb, fn, *a, **k): self._jobs[self._radio_thread.background(self, fn, *a, **k)] = cb def radio_thread_event(self, job, block=True): if job.fn == 'get_memory': msg = _('Refreshed memory %s') % job.args[0] elif job.fn == 'set_memory': msg = _('Uploaded memory %s') % job.args[0].number elif job.fn == 'get_settings': msg = _('Retrieved settings') elif job.fn == 'set_settings': msg = _('Saved settings') elif job.fn == 'erase_memory': msg = _('Erased memory %s') % job.args[0] else: msg = _('Finished radio job %s') % job.fn if not EDIT_LOCK.acquire(block): return False try: self.status_message(msg) cb = self._jobs.pop(job.id) if cb: wx.CallAfter(cb, job) # Update our status, which may be reset to unmodified wx.PostEvent(self, EditorChanged(self.GetId())) finally: EDIT_LOCK.release() return True def set_radio_thread(self, radio_thread): self._radio_thread = radio_thread def setup_radio_interface(self): self._jobs = {} @property def busy(self): return self._radio_thread.pending != 0 class ChirpSettingGrid(wx.Panel): def __init__(self, settinggroup, *a, **k): super(ChirpSettingGrid, self).__init__(*a, **k) self._group = settinggroup self._settings = {} self._needs_reload = False self.pg = wx.propgrid.PropertyGrid( self, style=wx.propgrid.PG_SPLITTER_AUTO_CENTER | wx.propgrid.PG_BOLD_MODIFIED) self.pg.Bind(wx.propgrid.EVT_PG_CHANGED, self._pg_changed) self.pg.Bind(wx.EVT_MOTION, self._mouseover) sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) sizer.Add(self.pg, 1, wx.EXPAND) self._choices = {} self._add_items(self._group) self.pg.Bind(wx.propgrid.EVT_PG_CHANGING, self._check_change) def _mouseover(self, event): prop = self.pg.HitTest(event.GetPosition()).GetProperty() tip = None if prop: setting = self.get_setting_by_name(prop.GetName()) tip = setting.__doc__ or None if tip and tip == setting.get_name(): # This is the default, which makes no sense, but it's been # that way for ages, so just avoid exposing it here if it's # set to the default. tip = None event.GetEventObject().SetToolTip(tip) def _add_items(self, group, parent=None): def append(item): if parent: self.pg.AppendIn(parent, item) else: self.pg.Append(item) for name, element in group.items(): if isinstance(element, settings.RadioSettingSubGroup): category = wx.propgrid.PropertyCategory( element.get_shortname(), element.get_name()) append(category) self._add_items(element, parent=category) continue elif not isinstance(element, settings.RadioSetting): LOG.debug('Skipping nested group %s' % element) continue if len(element.keys()) > 1: append(wx.propgrid.PropertyCategory( element.get_shortname())) for i in element.keys(): value = element[i] if isinstance(value, settings.RadioSettingValueInteger): editor = self._get_editor_int(element, value) elif isinstance(value, settings.RadioSettingValueFloat): editor = self._get_editor_float(element, value) elif isinstance(value, settings.RadioSettingValueList): editor = self._get_editor_choice(element, value) elif isinstance(value, settings.RadioSettingValueBoolean): editor = self._get_editor_bool(element, value) elif isinstance(value, settings.RadioSettingValueString): editor = self._get_editor_str(element, value) else: LOG.warning('Unsupported setting type %r' % value) editor = None if not editor: continue editor.SetName('%s%s%i' % (name, INDEX_CHAR, i)) if len(element.keys()) > 1: editor.SetLabel('') editor.Enable(value.get_mutable()) append(editor) self._settings[element.get_name()] = element if editor.IsValueUnspecified(): # Mark invalid/unspecified values so the user can fix them self.pg.SetPropertyBackgroundColour(editor.GetName(), wx.YELLOW) self.pg.Bind(wx.propgrid.EVT_PG_CHANGING, self._check_change) def get_setting_by_name(self, name, index=0): if INDEX_CHAR in name: # FIXME: This will only work for single-index settings of course name, _ = name.split(INDEX_CHAR, 1) for setting_name, setting in self._settings.items(): if name == setting_name: return setting def _check_change(self, event): setting = self.get_setting_by_name(event.GetPropertyName()) if not setting: LOG.error('Got change event for unknown setting %s' % ( event.GetPropertyName())) return warning = setting.get_warning(event.GetValue()) if warning: r = wx.MessageBox(warning, _('WARNING!'), wx.OK | wx.CANCEL | wx.CANCEL_DEFAULT) if r == wx.CANCEL: LOG.info('User aborted setting %s=%s with warning message', event.GetPropertyName(), event.GetValue()) event.SetValidationFailureBehavior(0) event.Veto() return else: LOG.info('User made change to %s=%s despite warning', event.GetPropertyName(), event.GetValue()) self._needs_reload = setting.volatile if self.needs_reload: wx.MessageBox(_( 'Changing this setting requires refreshing the settings from ' 'the image, which will happen now.'), _('Refresh required'), wx.OK) # If we were unspecified or otherwise marked, clear those markings self.pg.SetPropertyColoursToDefault(event.GetProperty().GetName()) @property def name(self): return self._group.get_name() @property def needs_reload(self): return self._needs_reload @property def propgrid(self): return self.pg def _pg_changed(self, event): wx.PostEvent(self, EditorChanged(self.GetId())) def _get_editor_int(self, setting, value): e = wx.propgrid.IntProperty(setting.get_shortname(), setting.get_name()) if value.initialized: e.SetValue(int(value)) else: e.SetValueToUnspecified() e.SetEditor('SpinCtrl') e.SetAttribute(wx.propgrid.PG_ATTR_MIN, value.get_min()) e.SetAttribute(wx.propgrid.PG_ATTR_MAX, value.get_max()) e.SetAttribute(wx.propgrid.PG_ATTR_SPINCTRL_STEP, value.get_step()) return e def _get_editor_float(self, setting, value): class ChirpFloatProperty(wx.propgrid.FloatProperty): def ValidateValue(self, val, info): if value.get_min() and not val >= value.get_min(): info.SetFailureMessage( _('Value must be at least %.4f' % value.get_min())) return False if value.get_max() and not val <= value.get_max(): info.SetFailureMessage( _('Value must be at most %.4f' % value.get_max())) return False return True def ValueToString(self, _value, flags=0): return value.format(_value) e = ChirpFloatProperty(setting.get_shortname(), setting.get_name()) if value.initialized: e.SetValue(float(value)) else: e.SetValueToUnspecified() return e def _get_editor_choice(self, setting, value): choices = value.get_options() self._choices[setting.get_name()] = choices current = choices.index(str(value)) return wx.propgrid.EnumProperty(setting.get_shortname(), setting.get_name(), choices, range(len(choices)), current) def _get_editor_bool(self, setting, value): prop = wx.propgrid.BoolProperty(setting.get_shortname(), setting.get_name(), bool(value)) prop.SetAttribute(wx.propgrid.PG_BOOL_USE_CHECKBOX, True) return prop def _get_editor_str(self, setting, value): class ChirpStrProperty(wx.propgrid.StringProperty): def ValidateValue(self, text, info): try: value.set_value(text) except Exception as e: info.SetFailureMessage(str(e)) return False return True e = ChirpStrProperty(setting.get_shortname(), setting.get_name()) if value.initialized: e.SetValue(str(value)) else: e.SetValueToUnspecified() return e def get_setting_values(self): """Return a dict of {name: (RadioSetting, newvalue)}""" values = {} for prop in self.pg._Items(): if prop.IsCategory(): continue if prop.IsValueUnspecified(): continue basename = prop.GetName().split(INDEX_CHAR)[0] if isinstance(prop, wx.propgrid.EnumProperty): value = self._choices[basename][prop.GetValue()] else: value = prop.GetValue() setting = self._settings[basename] values[prop.GetName()] = setting, value return values def get_values(self): """Return a dict of {name: newvalue}""" return {k: v[1] for k, v in self.get_setting_values().items()} def saved(self): for prop in self.pg._Items(): prop.SetModifiedStatus(False) def _error_proof(*expected_errors): """Decorate a method and display an error if it raises. If the method raises something in expected_errors, then log an error, otherwise log exception. """ def show_error(msg): d = wx.MessageDialog(None, str(msg), _('An error has occurred'), style=wx.OK | wx.ICON_ERROR) d.ShowModal() def wrap(fn): @functools.wraps(fn) def inner(*args, **kwargs): try: return fn(*args, **kwargs) except expected_errors as e: LOG.error('%s: %s' % (fn, e)) show_error(e) except Exception as e: LOG.exception('%s raised unexpected exception' % fn) show_error(e) return inner return wrap class error_proof(object): def __init__(self, *expected_exceptions): self._expected = expected_exceptions self.fn = None @staticmethod def show_error(msg): d = wx.MessageDialog(None, str(msg), _('An error has occurred'), style=wx.OK | wx.ICON_ERROR) d.ShowModal() def run_safe(self, fn, args, kwargs): try: return fn(*args, **kwargs) except self._expected as e: LOG.error('%s: %s' % (fn, e)) self.show_error(e) except Exception as e: LOG.exception('%s raised unexpected exception' % fn) self.show_error(e) def __call__(self, fn): self.fn = fn @functools.wraps(fn) def wrapper(*args, **kwargs): return self.run_safe(fn, args, kwargs) return wrapper def __enter__(self): pass def __exit__(self, exc_type, exc_val, traceback): if exc_type: if exc_type in self._expected: LOG.error('%s: %s: %s', self.fn or 'context', exc_type, exc_val) self.show_error(exc_val) return True else: LOG.exception('Context raised unexpected_exception', exc_info=(exc_type, exc_val, traceback)) self.show_error(exc_val) def reveal_location(path): LOG.debug('Revealing path %s', path) system = platform.system() if system == 'Windows': if not os.path.isdir(path): # Windows can only reveal the containing directory of a file path = os.path.dirname(path) wx.Execute('explorer %s' % path) elif system == 'Darwin': wx.Execute('open -R %s' % path) elif system == 'Linux': wx.Execute('open %s' % path) else: raise Exception(_('Unable to reveal %s on this system') % path) def delete_atexit(path_): def do(path): try: os.remove(path) LOG.debug('Removed temporary file %s', path) except Exception as e: LOG.warning('Failed to remove %s: %s', path, e) atexit.register(do, path_) def temporary_debug_log(): """Return a temporary copy of our debug log""" pf = chirp_platform.get_platform() src = pf.config_file('debug.log') fd, dst = tempfile.mkstemp( prefix='chirp_debug-', suffix='.txt') delete_atexit(dst) shutil.copy(src, dst) return dst @contextlib.contextmanager def expose_logs(level, root, label): if not isinstance(root, tuple): root = (root,) mgrs = (logger.log_history(level, x) for x in root) with contextlib.ExitStack() as stack: histories = [stack.enter_context(m) for m in mgrs] try: yield finally: lines = list(itertools.chain.from_iterable(x.get_history() for x in histories)) if lines: msg = os.linesep.join(x.getMessage() for x in lines) d = wx.MessageDialog( None, str(msg), label, style=wx.OK | wx.ICON_INFORMATION) d.ShowModal() chirp-20240224/chirp/wxui/main.py0000644000175000017500000021154314566340166015454 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import datetime import functools import hashlib import logging import os import pickle import platform import sys import time import typing import webbrowser if sys.version_info < (3, 10): import importlib_resources else: import importlib.resources as importlib_resources import wx import wx.aui import wx.lib.newevent from chirp import bandplan from chirp import chirp_common from chirp import directory from chirp import errors from chirp import logger from chirp import platform as chirp_platform from chirp.sources import base from chirp.wxui import config from chirp.wxui import bankedit from chirp.wxui import common from chirp.wxui import clone from chirp.wxui import developer from chirp.wxui import memedit from chirp.wxui import printing from chirp.wxui import query_sources from chirp.wxui import radioinfo from chirp.wxui import radiothread from chirp.wxui import report from chirp.wxui import settingsedit from chirp import CHIRP_VERSION EditorSetChanged, EVT_EDITORSET_CHANGED = wx.lib.newevent.NewCommandEvent() CONF = config.get() LOG = logging.getLogger(__name__) EMPTY_MENU_LABEL = '(none)' KEEP_RECENT = 8 OPEN_RECENT_MENU = None OPEN_STOCK_CONFIG_MENU = None CHIRP_TAB_DF = wx.DataFormat('x-chirp/file-tab') ALL_MAIN_WINDOWS = [] REVEAL_STOCK_DIR = wx.NewId() def get_stock_configs(): default_dir = chirp_platform.get_platform().config_file( "stock_configs") prefs_dir = CONF.get('stock_configs', 'prefs') return prefs_dir or default_dir class ChirpDropTarget(wx.DropTarget): def __init__(self, chirpmain): super().__init__() self._main = chirpmain self.data = wx.DataObjectComposite() tab_df = wx.CustomDataObject(CHIRP_TAB_DF) self.data.Add(tab_df) self.SetDataObject(self.data) self.SetDefaultAction(wx.DragMove) def move_tab(self, source_window, index, target_index): LOG.debug('Moving page %i to %i', index, target_index) source = source_window._editors eset = source.GetPage(index) source.RemovePage(index) eset.Reparent(self._main._editors) self._main.add_editorset(eset, atindex=( target_index if target_index >= 0 else None)) def handle_tab_data(self, x, y): tab_data = self.data.GetObject(CHIRP_TAB_DF) src_wid, index = pickle.loads(tab_data.GetData().tobytes()) source_window = self._main.FindWindowById(src_wid) try: target_index, flags = self._main._editors.HitTest(wx.Point(x, y)) except wx._core.wxAssertionError: # Apparently AUINotebook has no HitTest implementation on Linux LOG.warning('Unable to perform HitTest on target: ' 'no reordering possible') if source_window is self._main: # Defeat drag-to-self on this platform entirely since it is # meaningless return wx.DragNone # Default to append since we cannot define an order target_index = -1 if source_window is self._main and index == target_index: LOG.debug('Drag to self without reorder') return wx.DragNone self.move_tab(source_window, index, target_index) return wx.DragMove def OnData(self, x, y, defResult): if self.GetData(): format = self.data.GetReceivedFormat().GetId() if format == CHIRP_TAB_DF.GetId(): return self.handle_tab_data(x, y) return wx.DragNone def OnDrop(self, x, y): self._main.add_tab_panel.Hide() return True def OnEnter(self, x, y, defResult): self._main.add_tab_panel.SetSize(self._main._editors.GetSize()) self._main.add_tab_panel.Show() return defResult def OnLeave(self): self._main.add_tab_panel.Hide() return super().OnLeave() class ChirpEditorSet(wx.Panel): MEMEDIT_CLS = memedit.ChirpMemEdit SETTINGS_CLS = settingsedit.ChirpCloneSettingsEdit BANK_CLS: typing.Union[type, None] = bankedit.ChirpBankEditSync @property def tab_name(self): if isinstance(self._radio, base.NetworkResultRadio): return self._radio.get_label() return '%s.%s' % (self.default_filename, self._radio.FILE_EXTENSION) def add_editor(self, editor, title): self._editors.AddPage(editor, title) self.Bind(common.EVT_STATUS_MESSAGE, self._editor_status, editor) self._editor_index[title] = editor def _editor_status(self, event): LOG.info('Editor status: %s' % event.message) wx.PostEvent(self, common.StatusMessage(self.GetId(), message=event.message)) def __init__(self, radio, filename, *a, **k): super(ChirpEditorSet, self).__init__(*a, **k) self._radio = radio if filename is None: filename = self.tab_name self._filename = filename self._modified = not os.path.exists(filename) self._editor_index = {} features = radio.get_features() parent_radio = radio if features.has_sub_devices: radios = radio.get_sub_devices() format = '%(type)s (%(variant)s)' if isinstance(parent_radio, chirp_common.ExternalMemoryProperties): parent_radio.link_device_metadata(radios) else: radios = [radio] format = '%(type)s' if len(radios) > 2: LOG.info('Using TreeBook because radio has %i devices', len(radios)) self._editors = wx.Treebook(self, style=wx.NB_RIGHT) self._editors.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self._editor_selected) else: self._editors = wx.Notebook(self, style=wx.NB_TOP) self._editors.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self._editor_selected) sizer = wx.BoxSizer() sizer.Add(self._editors, 1, wx.EXPAND) self.SetSizer(sizer) for radio in radios: edit = self.MEMEDIT_CLS(radio, self._editors) self.add_editor(edit, format % {'type': _('Memories'), 'variant': radio.VARIANT}) edit.refresh() self.Bind(common.EVT_EDITOR_CHANGED, self._editor_changed) sub_features = radio.get_features() if sub_features.has_bank and self.BANK_CLS: banks = self.BANK_CLS(radio, self._editors) self.add_editor(banks, format % {'type': _('Banks'), 'variant': radio.VARIANT}) if features.has_settings: settings = self.SETTINGS_CLS(parent_radio, self._editors) self.add_editor(settings, _('Settings')) if (CONF.get_bool('developer', 'state') and isinstance(radio, chirp_common.CloneModeRadio)): browser = developer.ChirpRadioBrowser(parent_radio, self._editors) browser.Bind(common.EVT_EDITOR_CHANGED, self._refresh_all) self.add_editor(browser, _('Browser')) info = radioinfo.ChirpRadioInfo(parent_radio, self._editors) self.add_editor(info, _('Info')) # After the GUI is built, set focus to the current editor wx.CallAfter(self.current_editor.SetFocus) def _refresh_all(self, event): LOG.info('Radio browser changed; refreshing all others') for i in range(self._editors.GetPageCount()): editor = self._editors.GetPage(i) if editor.GetId() != event.GetId(): LOG.debug('refreshing %s' % editor) editor.refresh() def _editor_changed(self, event): self._modified = True wx.PostEvent(self, EditorSetChanged(self.GetId(), editorset=self)) def _editor_selected(self, event): page_index = event.GetSelection() page = self._editors.GetPage(page_index) page.selected() wx.PostEvent(self, EditorSetChanged(self.GetId(), editorset=self)) def save(self, filename=None): if filename is None: filename = self.filename LOG.debug('Saving to %s' % filename) self._radio.save(filename) self._filename = filename self._modified = False self.current_editor.saved() @property def filename(self): return self._filename @property def modified(self): if isinstance(self._radio, base.NetworkResultRadio): return False return self._modified @property def radio(self): return self._radio @property def default_filename(self): defname_format = CONF.get("default_filename", "global") or \ "{vendor}_{model}_{date}" defname = defname_format.format( vendor=self._radio.VENDOR, model=self._radio.MODEL, date=datetime.datetime.now().strftime('%Y%m%d') ).replace('/', '_') return defname @property def current_editor(self): return self._editors.GetCurrentPage() @property def current_editor_index(self): return self._editors.GetSelection() def select_editor(self, index=None, name=None): if index is None and name: try: index = self._editors.FindPage(self._editor_index[name]) except KeyError: LOG.error('No editor %r to select' % name) return if index is None: LOG.error('Unable to find editor to select (%r/%r', index, name) return self._editors.SetSelection(index) def cb_copy(self, cut=False): return self.current_editor.cb_copy(cut=cut) def cb_paste(self): return self.current_editor.cb_paste() def cb_delete(self): return self.current_editor.cb_delete() def cb_find(self, text): return self.current_editor.cb_find(text) def select_all(self): return self.current_editor.select_all() def close(self): pass @common.error_proof() def export_to_file(self, filename): current = self.current_editor if not isinstance(current, memedit.ChirpMemEdit): raise Exception(_('Only memory tabs may be exported')) current.export_to_file(filename) def update_font(self): for i in range(0, self._editors.PageCount): editor = self._editors.GetPage(i) editor.update_font() class ChirpLiveEditorSet(ChirpEditorSet): MEMEDIT_CLS = memedit.ChirpLiveMemEdit SETTINGS_CLS = settingsedit.ChirpLiveSettingsEdit BANK_CLS = None @property def tab_name(self): return '%s %s@%s' % (self._radio.VENDOR, self._radio.MODEL, _('LIVE')) def __init__(self, radio, *a, **k): self._threads = [] super().__init__(radio, *a, **k) def add_editor(self, editor, title): super(ChirpLiveEditorSet, self).add_editor(editor, title) thread = radiothread.RadioThread(editor._radio) thread.start() self._threads.append(thread) editor.set_radio_thread(thread) def close(self): for thread in self._threads: thread.end() try: self._radio.pipe.close() except Exception as e: LOG.exception('Failed to close %s: %s', self._radio.pipe, e) else: LOG.debug('Closed %s', self._radio.pipe) @property def modified(self): return any(t.pending != 0 for t in self._threads) class ChirpWelcomePanel(wx.Panel): """Fake "editorset" that just displays the welcome image.""" def __init__(self, *a, **k): super(ChirpWelcomePanel, self).__init__(*a, **k) vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) with importlib_resources.as_file( importlib_resources.files('chirp.share') .joinpath('welcome_screen.png') ) as welcome: bmp = wx.Bitmap(str(welcome)) width, height = self.GetSize() img = wx.StaticBitmap(self, wx.ID_ANY, bmp) vbox.Add(img, 1, flag=wx.EXPAND) def close(self): pass @property def modified(self): return False @property def filename(self): return None class ChirpMain(wx.Frame): def __init__(self, *args, **kwargs): super(ChirpMain, self).__init__(*args, **kwargs) self.SetSize(int(CONF.get('window_w', 'state') or 1024), int(CONF.get('window_h', 'state') or 768)) if not ALL_MAIN_WINDOWS and CONF.is_defined('window_x', 'state'): # Only restore position for the first window of the session self.SetPosition((CONF.get_int('window_x', 'state'), CONF.get_int('window_y', 'state'))) ALL_MAIN_WINDOWS.append(self) self.set_icon() self._drop_target = ChirpDropTarget(self) self.SetDropTarget(self._drop_target) d = CONF.get('last_dir', 'state') if d and os.path.isdir(d): chirp_platform.get_platform().set_last_dir(d) self.SetMenuBar(self.make_menubar()) # Stock items look good on linux, terrible on others, # so punt on this for the moment. # self.make_toolbar() self._editors = wx.aui.AuiNotebook( self, style=(wx.aui.AUI_NB_CLOSE_ON_ALL_TABS | wx.aui.AUI_NB_SCROLL_BUTTONS | wx.aui.AUI_NB_WINDOWLIST_BUTTON)) if len(ALL_MAIN_WINDOWS) == 1: # Only add the welcome page to the first window opened welcome_page = ChirpWelcomePanel(self._editors) self._editors.AddPage(welcome_page, _('Welcome'), select=True) self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CLOSE, self._editor_close) self.Bind(wx.aui.EVT_AUINOTEBOOK_PAGE_CHANGED, self._editor_page_changed) self._editors.Bind(wx.aui.EVT_AUINOTEBOOK_BEGIN_DRAG, self._tab_drag) self._editors.Bind(wx.aui.EVT_AUINOTEBOOK_TAB_RIGHT_DOWN, self._tab_rclick) self.Bind(wx.EVT_CLOSE, self._window_close) self.statusbar = self.CreateStatusBar(2) self.statusbar.SetStatusWidths([-1, 200]) self._update_window_for_editor() vbox = wx.BoxSizer() self.SetSizer(vbox) vbox.Add(self._editors, 1, flag=wx.EXPAND) self.add_tab_panel = wx.Panel(self, pos=(0, 0), size=(600, 600)) self.add_tab_panel.Hide() with importlib_resources.as_file( importlib_resources.files('chirp.share') .joinpath('plus-icon.png') ) as icon: self.add_tab_bm = wx.Bitmap(str(icon), wx.BITMAP_TYPE_ANY) self.add_tab_panel.Bind(wx.EVT_PAINT, self._paint_add_tab_panel) def _paint_add_tab_panel(self, event): panel = event.GetEventObject() dc = wx.PaintDC(panel) dc.SetBackground(wx.Brush("BLACK")) img_size = self.add_tab_bm.GetSize() my_size = panel.GetSize() x = (my_size.width // 2) - (img_size.width // 2) y = (my_size.height // 2) - (img_size.width // 2) dc.DrawBitmap(self.add_tab_bm, x, y, True) def _remove_welcome_page(self): def remove(): for i in range(self._editors.GetPageCount()): if isinstance(self._editors.GetPage(i), ChirpWelcomePanel): self._editors.RemovePage(i) break wx.CallAfter(remove) def _tab_drag(self, event): event.Skip() d = wx.CustomDataObject(CHIRP_TAB_DF) index = self._editors.GetSelection() if isinstance(self._editors.GetPage(index), ChirpWelcomePanel): # Don't allow moving the welcome panels return d.SetData(pickle.dumps((self.GetId(), index))) data = wx.DataObjectComposite() data.Add(d) ds = wx.DropSource(self) ds.SetData(data) result = ds.DoDragDrop(wx.Drag_AllowMove) if result == wx.DragMove: LOG.debug('Target took our window') self._update_window_for_editor() else: LOG.debug('Target rejected our window') def _tab_rclick(self, event): selected = event.GetSelection() eset = self._editors.GetPage(selected) if isinstance(eset, ChirpWelcomePanel): return def _detach(event): new = ChirpMain(None, title='CHIRP') self._editors.RemovePage(selected) eset.Reparent(new._editors) new.add_editorset(eset) new.Show() menu = wx.Menu() detach = wx.MenuItem(menu, wx.ID_ANY, _('Open in new window')) self.Bind(wx.EVT_MENU, _detach, detach) menu.Append(detach) self.PopupMenu(menu) def set_icon(self): if sys.platform == 'win32': icon = 'chirp.ico' else: icon = 'chirp.png' with importlib_resources.as_file( importlib_resources.files('chirp.share') .joinpath(icon) ) as path: self.SetIcon(wx.Icon(str(path))) @property def current_editorset(self): eset = self._editors.GetCurrentPage() if isinstance(eset, ChirpEditorSet): return eset @common.error_proof(errors.ImageDetectFailed, FileNotFoundError) def open_file(self, filename, exists=True, select=True, rclass=None): CSVRadio = directory.get_radio('Generic_CSV') label = _('Driver messages') with common.expose_logs(logging.WARNING, 'chirp.drivers', label): if exists: if not os.path.exists(filename): raise FileNotFoundError( _('File does not exist: %s') % filename) if rclass is None: radio = directory.get_radio_by_image(filename) else: radio = rclass(filename) else: radio = CSVRadio(None) if (not isinstance(radio, CSVRadio) or isinstance(radio, chirp_common.NetworkSourceRadio)): report.report_model(radio, 'open') self.adj_menu_open_recent(filename) editorset = ChirpEditorSet(radio, filename, self._editors) self.add_editorset(editorset, select=select) def add_editorset(self, editorset, select=True, atindex=None): self._remove_welcome_page() if atindex is None: self._editors.AddPage(editorset, os.path.basename(editorset.filename), select=select) else: self._editors.InsertPage(atindex, editorset, os.path.basename(editorset.filename), select=select) self.Bind(EVT_EDITORSET_CHANGED, self._editor_changed, editorset) self.Bind(common.EVT_STATUS_MESSAGE, self._editor_status, editorset) self._update_editorset_title(editorset) def add_stock_menu(self): stock = wx.Menu() try: user_stock_dir = get_stock_configs() user_stock_confs = sorted(os.listdir(user_stock_dir)) except FileNotFoundError: user_stock_confs = [] os.makedirs(user_stock_dir, exist_ok=True) dist_stock_confs = sorted( [ (conf.name, hashlib.md5(conf.read_bytes())) for conf in importlib_resources.files('chirp.stock_configs').iterdir() if conf.is_file() ] ) def add_stock(fn): submenu_item = stock.Append(wx.ID_ANY, fn) self.Bind(wx.EVT_MENU, self._menu_open_stock_config, submenu_item) found = [] for fn in user_stock_confs: add_stock(fn) found.append(os.path.basename(fn)) if user_stock_confs: stock.Append(wx.MenuItem(stock, wx.ID_SEPARATOR)) if sys.platform in ('darwin', 'linux', 'win32'): reveal = stock.Append(REVEAL_STOCK_DIR, _('Open stock config directory')) self.Bind(wx.EVT_MENU, self._menu_open_stock_config, reveal) stock.Append(wx.MenuItem(stock, wx.ID_SEPARATOR)) for fn, hash in dist_stock_confs: if os.path.basename(fn) in found: # Remove old stock configs that were copied to the user's # directory by legacy chirp. try: user_fn = os.path.join(get_stock_configs(), os.path.basename(fn)) with open(user_fn, 'rb') as f: user_hash = hashlib.md5(f.read()) if hash.digest() == user_hash.digest(): LOG.info('Removing stale legacy stock config %s', os.path.basename(fn)) os.remove(user_fn) # Since we already added it to the user area, just # don't add it to system this time. At next startup, # it will move to the system section. continue else: raise FileExistsError('File is changed') except Exception as e: LOG.info('Ignoring dist stock conf %s because same name ' 'found in user dir: %s', os.path.basename(fn), e) continue add_stock(fn) return stock def make_menubar(self): self.editor_menu_items = {} memedit_items = memedit.ChirpMemEdit.get_menu_items() self.editor_menu_items.update(memedit_items) file_menu = wx.Menu() new_item = file_menu.Append(wx.ID_NEW) self.Bind(wx.EVT_MENU, self._menu_new, new_item) new_window = file_menu.Append(wx.ID_ANY, _('New Window')) self.Bind(wx.EVT_MENU, self._menu_new_window, new_window) new_window.SetAccel( wx.AcceleratorEntry( wx.MOD_CONTROL | wx.ACCEL_SHIFT, ord('N'))) open_item = file_menu.Append(wx.ID_OPEN) self.Bind(wx.EVT_MENU, self._menu_open, open_item) self.OPEN_STOCK_CONFIG_MENU = self.add_stock_menu() file_menu.AppendSubMenu(self.OPEN_STOCK_CONFIG_MENU, _("Open Stock Config")) self.OPEN_RECENT_MENU = wx.Menu() self.restore_tabs_item = wx.NewId() last_files = [ x for x in (CONF.get('last_open', 'state') or '').split('$') if x] self.adj_menu_open_recent(None) if last_files: submenu_item = self.OPEN_RECENT_MENU.Prepend( self.restore_tabs_item, ngettext('Restore %i tab', 'Restore %i tabs', len(last_files)) % len(last_files)) submenu_item.SetAccel(wx.AcceleratorEntry( wx.MOD_CONTROL | wx.ACCEL_SHIFT, ord('T'))) self.Bind(wx.EVT_MENU, self.restore_tabs, submenu_item) file_menu.AppendSubMenu(self.OPEN_RECENT_MENU, _('Open Recent')) save_item = file_menu.Append(wx.ID_SAVE) self.Bind(wx.EVT_MENU, self._menu_save, save_item) saveas_item = file_menu.Append(wx.ID_SAVEAS) saveas_item.SetAccel(wx.AcceleratorEntry(wx.MOD_CONTROL | wx.ACCEL_ALT, ord('S'))) self.Bind(wx.EVT_MENU, self._menu_save_as, saveas_item) self._import_menu_item = wx.NewId() import_item = file_menu.Append(wx.MenuItem(file_menu, self._import_menu_item, _('Import from file...'))) self.Bind(wx.EVT_MENU, self._menu_import, import_item) self._export_menu_item = wx.NewId() export_item = file_menu.Append(wx.MenuItem(file_menu, self._export_menu_item, _('Export to CSV...'))) export_item.SetAccel(wx.AcceleratorEntry(wx.MOD_CONTROL, ord('E'))) self.Bind(wx.EVT_MENU, self._menu_export, export_item) if CONF.get_bool('developer', 'state'): loadmod_item = file_menu.Append(wx.MenuItem(file_menu, wx.NewId(), _('Load Module...'))) self.Bind(wx.EVT_MENU, self._menu_load_module, loadmod_item) file_menu.Append(wx.MenuItem(file_menu, wx.ID_SEPARATOR)) print_item = file_menu.Append(wx.ID_PRINT) self.Bind(wx.EVT_MENU, self._menu_print, print_item) self._print_preview_item = wx.NewId() print_preview_item = wx.MenuItem(file_menu, self._print_preview_item, _('Print Preview')) self.Bind(wx.EVT_MENU, self._menu_print, print_preview_item) # Linux has integrated preview stuff, and the wx preview dialog # does not work well, so skip this on Linux. if platform.system() != 'Linux': file_menu.Append(print_preview_item) close_item = file_menu.Append(wx.ID_CLOSE) close_item.SetAccel(wx.AcceleratorEntry(wx.MOD_CONTROL, ord('W'))) self.Bind(wx.EVT_MENU, self._menu_close, close_item) exit_item = file_menu.Append(wx.ID_EXIT) self.Bind(wx.EVT_MENU, self._menu_exit, exit_item) edit_menu = wx.Menu() cut_item = edit_menu.Append(wx.ID_CUT) self.Bind(wx.EVT_MENU, functools.partial(self._menu_copy, cut=True), cut_item) copy_item = edit_menu.Append(wx.ID_COPY) self.Bind(wx.EVT_MENU, self._menu_copy, copy_item) paste_item = edit_menu.Append(wx.ID_PASTE) self.Bind(wx.EVT_MENU, self._menu_paste, paste_item) selall_item = edit_menu.Append(wx.ID_SELECTALL) self.Bind(wx.EVT_MENU, self._menu_selall, selall_item) delete_item = edit_menu.Append(wx.ID_DELETE) delete_item.SetAccel(wx.AcceleratorEntry(wx.MOD_CONTROL, wx.WXK_BACK)) self.Bind(wx.EVT_MENU, self._menu_delete, delete_item) edit_menu.Append(wx.MenuItem(edit_menu, wx.ID_SEPARATOR)) self._last_search_text = '' find_item = edit_menu.Append(wx.ID_FIND) edit_menu.SetLabel(wx.ID_FIND, _('Find...')) find_item.SetAccel(wx.AcceleratorEntry(wx.MOD_CONTROL, ord('F'))) self.Bind(wx.EVT_MENU, self._menu_find, find_item) if platform.system() == 'Windows': findnextacc = wx.AcceleratorEntry() findnextacc.FromString('F3') else: findnextacc = wx.AcceleratorEntry(wx.MOD_CONTROL | wx.ACCEL_ALT, ord('F')) self._find_next_item = wx.NewId() find_next_item = edit_menu.Append(wx.MenuItem(edit_menu, self._find_next_item, _('Find Next'))) find_next_item.SetAccel(findnextacc) self.Bind(wx.EVT_MENU, self._menu_find, find_next_item, self._find_next_item) edit_menu.Append(wx.MenuItem(edit_menu, wx.ID_SEPARATOR)) for item in memedit_items[common.EditorMenuItem.MENU_EDIT]: edit_menu.Append(item) self.Bind(wx.EVT_MENU, self.do_editor_callback, item) item.add_menu_callback() view_menu = wx.Menu() for item in memedit_items[common.EditorMenuItem.MENU_VIEW]: view_menu.Append(item) self.Bind(wx.EVT_MENU, self.do_editor_callback, item) item.add_menu_callback() self._fixed_item = wx.NewId() fixed_item = wx.MenuItem(view_menu, self._fixed_item, _('Use fixed-width font'), kind=wx.ITEM_CHECK) view_menu.Append(fixed_item) self.Bind(wx.EVT_MENU, self._menu_fixed_font, fixed_item) fixed_item.Check(CONF.get_bool('font_fixed', 'state', False)) self._large_item = wx.NewId() large_item = wx.MenuItem(view_menu, self._large_item, _('Use larger font'), kind=wx.ITEM_CHECK) view_menu.Append(large_item) self.Bind(wx.EVT_MENU, self._menu_large_font, large_item) large_item.Check(CONF.get_bool('font_large', 'state', False)) restore_tabs = wx.MenuItem(view_menu, wx.NewId(), _('Restore tabs on start'), kind=wx.ITEM_CHECK) view_menu.Append(restore_tabs) self.Bind(wx.EVT_MENU, self._menu_restore_tabs, restore_tabs) restore_tabs.Check(CONF.get_bool('restore_tabs', 'prefs', False)) radio_menu = wx.Menu() if sys.platform == 'darwin': updownmod = wx.MOD_CONTROL else: updownmod = wx.ACCEL_ALT self._download_menu_item = wx.NewId() download_item = wx.MenuItem( radio_menu, self._download_menu_item, _('Download from radio...')) download_item.SetAccel(wx.AcceleratorEntry(updownmod, ord('D'))) self.Bind(wx.EVT_MENU, self._menu_download, download_item) radio_menu.Append(download_item) self._upload_menu_item = wx.NewId() upload_item = wx.MenuItem( radio_menu, self._upload_menu_item, _('Upload to radio...')) upload_item.SetAccel(wx.AcceleratorEntry(updownmod, ord('U'))) self.Bind(wx.EVT_MENU, self._menu_upload, upload_item) radio_menu.Append(upload_item) source_menu = wx.Menu() radio_menu.AppendSubMenu(source_menu, _('Query Source')) query_rr_item = wx.MenuItem(source_menu, wx.NewId(), 'RadioReference.com') self.Bind(wx.EVT_MENU, self._menu_query_rr, query_rr_item) source_menu.Append(query_rr_item) query_rb_item = wx.MenuItem(source_menu, wx.NewId(), 'RepeaterBook') self.Bind(wx.EVT_MENU, self._menu_query_rb, query_rb_item) source_menu.Append(query_rb_item) query_dm_item = wx.MenuItem(source_menu, wx.NewId(), 'DMR-MARC') self.Bind(wx.EVT_MENU, self._menu_query_dm, query_dm_item) source_menu.Append(query_dm_item) query_prz_item = wx.MenuItem(source_menu, wx.NewId(), 'przemienniki.net') self.Bind(wx.EVT_MENU, self._menu_query_prz, query_prz_item) source_menu.Append(query_prz_item) radio_menu.Append(wx.MenuItem(radio_menu, wx.ID_SEPARATOR)) auto_edits = wx.MenuItem(radio_menu, wx.NewId(), _('Enable Automatic Edits'), kind=wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, self._menu_auto_edits, auto_edits) radio_menu.Append(auto_edits) auto_edits.Check(CONF.get_bool('auto_edits', 'state', True)) select_bandplan = wx.MenuItem(radio_menu, wx.NewId(), _('Select Bandplan...')) self.Bind(wx.EVT_MENU, self._menu_select_bandplan, select_bandplan) radio_menu.Append(select_bandplan) if CONF.get_bool('developer', 'state'): radio_menu.Append(wx.MenuItem(file_menu, wx.ID_SEPARATOR)) self._reload_driver_item = wx.NewId() reload_drv_item = wx.MenuItem(radio_menu, self._reload_driver_item, _('Reload Driver')) reload_drv_item.SetAccel( wx.AcceleratorEntry(wx.MOD_CONTROL, ord('R'))) self.Bind(wx.EVT_MENU, self._menu_reload_driver, reload_drv_item) radio_menu.Append(reload_drv_item) self._reload_both_item = wx.NewId() reload_both_item = wx.MenuItem(radio_menu, self._reload_both_item, _('Reload Driver and File')) reload_both_item.SetAccel( wx.AcceleratorEntry( wx.ACCEL_ALT | wx.MOD_CONTROL, ord('R'))) self.Bind( wx.EVT_MENU, functools.partial(self._menu_reload_driver, andfile=True), reload_both_item) radio_menu.Append(reload_both_item) self._interact_driver_item = wx.NewId() interact_drv_item = wx.MenuItem(radio_menu, self._interact_driver_item, _('Interact with driver')) self.Bind(wx.EVT_MENU, self._menu_interact_driver, interact_drv_item) radio_menu.Append(interact_drv_item) else: self._reload_both_item = None self._reload_driver_item = None self._interact_driver_item = None help_menu = wx.Menu() about_item = wx.MenuItem(help_menu, wx.NewId(), _('About')) self.Bind(wx.EVT_MENU, self._menu_about, about_item) help_menu.Append(about_item) developer_menu = wx.MenuItem(help_menu, wx.NewId(), _('Developer Mode'), kind=wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, functools.partial(self._menu_developer, developer_menu), developer_menu) help_menu.Append(developer_menu) developer_menu.Check(CONF.get_bool('developer', 'state')) reporting_menu = wx.MenuItem(help_menu, wx.NewId(), _('Reporting enabled'), kind=wx.ITEM_CHECK) self.Bind(wx.EVT_MENU, functools.partial(self._menu_reporting, reporting_menu), reporting_menu) help_menu.Append(reporting_menu) reporting_menu.Check(not CONF.get_bool('no_report', default=False)) if logger.Logger.instance.has_debug_log_file: # Only expose these debug log menu elements if we are logging to # a debug.log file this session. debug_log_menu = wx.MenuItem(help_menu, wx.NewId(), _('Open debug log')) self.Bind(wx.EVT_MENU, self._menu_debug_log, debug_log_menu) help_menu.Append(debug_log_menu) if platform.system() in ('Windows', 'Darwin'): debug_loc_menu = wx.MenuItem(help_menu, wx.NewId(), _('Show debug log location')) self.Bind(wx.EVT_MENU, self._menu_debug_loc, debug_loc_menu) help_menu.Append(debug_loc_menu) backup_loc_menu = wx.MenuItem(help_menu, wx.NewId(), _('Show image backup location')) self.Bind(wx.EVT_MENU, self._menu_backup_loc, backup_loc_menu) help_menu.Append(backup_loc_menu) lmfi_menu = wx.MenuItem(help_menu, wx.NewId(), _('Load module from issue...')) self.Bind(wx.EVT_MENU, self._menu_load_from_issue, lmfi_menu) help_menu.Append(lmfi_menu) menu_bar = wx.MenuBar() menu_bar.Append(file_menu, wx.GetStockLabel(wx.ID_FILE)) menu_bar.Append(edit_menu, wx.GetStockLabel(wx.ID_EDIT)) menu_bar.Append(view_menu, '&' + _('View')) menu_bar.Append(radio_menu, '&' + _('Radio')) menu_bar.Append(help_menu, _('Help')) return menu_bar def do_editor_callback(self, event): menu = event.GetEventObject() item = menu.FindItemById(event.GetId()) item.editor_callback(self.current_editorset.current_editor, event) def _menu_print(self, event): p = printing.MemoryPrinter( self, self.current_editorset.radio, self.current_editorset.current_editor) mems = self.current_editorset.current_editor.get_selected_memories() if event.GetId() == wx.ID_PRINT: p.print(mems) else: p.print_preview(mems) def make_toolbar(self): tb = self.CreateToolBar() def bm(stock): return wx.ArtProvider.GetBitmap(stock, wx.ART_TOOLBAR, (32, 32)) tbopen = tb.AddTool(wx.NewId(), _('Open'), bm(wx.ART_FILE_OPEN), _('Open a file')) tb.AddTool(wx.NewId(), _('Save'), bm(wx.ART_FILE_SAVE), _('Save file')) tb.AddTool(wx.NewId(), _('Close'), bm(wx.ART_CLOSE), _('Close file')) tb.AddTool(wx.NewId(), _('Download'), bm(wx.ART_GO_DOWN), _('Download from radio')) tb.AddTool(wx.NewId(), 'Upload', bm(wx.ART_GO_UP), _('Upload to radio')) self.Bind(wx.EVT_MENU, self._menu_open, tbopen) tb.Realize() def adj_menu_open_recent(self, filename): """Update the "open recent" menu If filename is passed, arrange for it to be the most-recent recent file. Otherwise just synchronize config and the submenu state. """ if filename: # Don't persist template names that have not been saved or do not # exist. if not os.path.exists(filename): LOG.debug('Ignoring recent file %s', filename) return # Don't add stock config files to the recent files list stock_dir = get_stock_configs() this_dir = os.path.dirname(filename) if (stock_dir and os.path.exists(stock_dir) and this_dir and os.path.samefile(stock_dir, this_dir)): return # Make a list of recent files in config recent = [CONF.get('recent%i' % i, 'state') for i in range(KEEP_RECENT) if CONF.get('recent%i' % i, 'state')] while filename in recent: # The old algorithm could have dupes, so keep looking and # cleaning until they're gone LOG.debug('File exists in recent, moving to front') recent.remove(filename) if filename: recent.insert(0, filename) recent = recent[:KEEP_RECENT] LOG.debug('Recent is now %s' % recent) # Update and clean config for i in range(KEEP_RECENT): try: CONF.set('recent%i' % i, recent[i], 'state') except IndexError: # Clean higher-order entries if they exist CONF.remove_option('recent%i' % i, 'state') config._CONFIG.save() # Clear the menu while self.OPEN_RECENT_MENU.GetMenuItemCount(): self.OPEN_RECENT_MENU.Delete( self.OPEN_RECENT_MENU.FindItemByPosition(0)) # Update the menu to match our list for i, fn in enumerate(recent): mi = self.OPEN_RECENT_MENU.Append(wx.ID_ANY, fn.replace('&', '&&')) self.Bind(wx.EVT_MENU, self._menu_open_recent, mi) def _editor_page_changed(self, event): self._editors.GetPage(event.GetSelection()) self._update_window_for_editor() def _editor_changed(self, event): self._update_editorset_title(event.editorset) self._update_window_for_editor() def _editor_status(self, event): # FIXME: Should probably only do this for the current editorset self.statusbar.SetStatusText(event.message) def _editor_close(self, event): eset = self._editors.GetPage(event.GetSelection()) if self._prompt_to_close_editor(eset): eset.close() wx.CallAfter(self._update_window_for_editor) else: event.Veto() def _update_window_for_editor(self): eset = self.current_editorset can_close = False can_save = False can_saveas = False can_upload = False can_edit = False is_memedit = False is_bank = False if eset is not None: is_live = isinstance(eset.radio, chirp_common.LiveRadio) is_network = isinstance(eset.radio, base.NetworkResultRadio) can_close = True can_save = eset.modified and not is_live and not is_network can_saveas = not is_live and not is_network can_upload = True is_memedit = isinstance(eset.current_editor, memedit.ChirpMemEdit) is_bank = isinstance(eset.current_editor, bankedit.ChirpBankEdit) can_edit = not is_network self.SetTitle('CHIRP (%s)' % os.path.basename(eset.filename)) else: self.SetTitle('CHIRP') if self.current_editorset: radio = self.current_editorset.radio radio_name = '%s %s' % (radio.VENDOR, radio.MODEL) self.statusbar.SetStatusText(radio_name, i=1) else: self.statusbar.SetStatusText('', i=1) items = [ (wx.ID_CLOSE, can_close), (wx.ID_SAVE, can_save), (wx.ID_SAVEAS, can_saveas), (self._upload_menu_item, can_upload), (self._find_next_item, is_memedit), (wx.ID_FIND, is_memedit), (wx.ID_PRINT, is_memedit), (wx.ID_DELETE, is_memedit and can_edit), (wx.ID_CUT, is_memedit and can_edit), (wx.ID_COPY, is_memedit), (wx.ID_PASTE, is_memedit and can_edit), (wx.ID_SELECTALL, is_memedit), (self._print_preview_item, is_memedit), (self._export_menu_item, can_close), (self._fixed_item, is_memedit or is_bank), (self._large_item, is_memedit or is_bank), (self._reload_driver_item, can_saveas), (self._reload_both_item, can_saveas), (self._interact_driver_item, can_close), (self._import_menu_item, is_memedit and can_edit) ] for ident, enabled in items: if ident is None: continue menuitem = self.GetMenuBar().FindItemById(ident) if menuitem: # Some items may not be present on all systems (i.e. # print preview on Linux) menuitem.Enable(enabled) for menu, items in self.editor_menu_items.items(): for item in items: editor_match = ( eset and isinstance(eset.current_editor, item.editor_class) or False) item.Enable(editor_match) def _window_close(self, event): for i in range(self._editors.GetPageCount()): editorset = self._editors.GetPage(i) self._editors.ChangeSelection(i) if not self._prompt_to_close_editor(editorset): if event.CanVeto(): event.Veto() return size = self.GetSize() CONF.set_int('window_w', size.GetWidth(), 'state') CONF.set_int('window_h', size.GetHeight(), 'state') pos = self.GetPosition() CONF.set_int('window_x', pos[0], 'state') CONF.set_int('window_y', pos[1], 'state') CONF.set('last_dir', chirp_platform.get_platform().get_last_dir(), 'state') # Make sure we call close on each editor, so it can end # threads and do other cleanup open_files = [] for i in range(self._editors.GetPageCount()): e = self._editors.GetPage(i) if e.filename not in open_files: open_files.append(e.filename) e.close() CONF.set('last_open', '$'.join(os.path.abspath(fn) for fn in open_files if fn), 'state') config._CONFIG.save() ALL_MAIN_WINDOWS.remove(self) self.Destroy() def _update_editorset_title(self, editorset): index = self._editors.GetPageIndex(editorset) self._editors.SetPageText(index, '%s%s' % ( os.path.basename(editorset.filename), editorset.modified and '*' or '')) def _menu_new(self, event): self.open_file('Untitled.csv', exists=False) def _do_open(self): all_extensions = ['*.img'] formats = [_('Chirp Image Files') + ' (*.img)|*.img', _('All Files') + ' (*.*)|*.*'] for name, pattern, readonly in directory.AUX_FORMATS: formats.insert(1, '%s %s (%s)|%s' % ( name, _('Files'), pattern, pattern)) all_extensions.append(pattern) if CONF.get_bool('open_default_all_formats', 'prefs', True): i_index = 0 else: i_index = len(formats) formats.insert(i_index, (_('All supported formats|') + ';'.join(all_extensions))) wildcard = '|'.join(formats) with wx.FileDialog(self, _('Open a file'), chirp_platform.get_platform().get_last_dir(), wildcard=wildcard, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fd: if fd.ShowModal() == wx.ID_CANCEL: return filename = fd.GetPath() d = fd.GetDirectory() chirp_platform.get_platform().set_last_dir(d) CONF.set('last_dir', d, 'state') config._CONFIG.save() return str(filename) def _menu_open(self, event): filename = self._do_open() if filename is not None: self.open_file(filename) @common.error_proof(FileNotFoundError) def _menu_open_stock_config(self, event): if event.GetId() == REVEAL_STOCK_DIR: common.reveal_location(get_stock_configs()) return fn = self.OPEN_STOCK_CONFIG_MENU.FindItemById( event.GetId()).GetItemLabelText() user_stock_dir = get_stock_configs() user_stock_conf = os.path.join(user_stock_dir, fn) with importlib_resources.as_file( importlib_resources.files('chirp.stock_configs') .joinpath(fn) ) as path: dist_stock_conf = str(path) if os.path.exists(user_stock_conf): filename = user_stock_conf elif os.path.exists(dist_stock_conf): filename = dist_stock_conf else: LOG.error('Unable to find %s or %s' % (user_stock_conf, dist_stock_conf)) common.error_proof.show_error( _('Unable to find stock config %r') % fn) return self.open_file(filename) def restore_tabs(self, event): if self.OPEN_RECENT_MENU.FindItem(self.restore_tabs_item)[0]: self.OPEN_RECENT_MENU.Remove(self.restore_tabs_item) last_files = (CONF.get('last_open', 'state') or '').split('$') for fn in last_files: if fn and os.path.exists(fn): LOG.debug('Restoring tab for file %r' % fn) self.open_file(fn) elif fn: LOG.debug('Previous file %r no longer exists' % fn) return last_files def _menu_open_recent(self, event): filename = self.OPEN_RECENT_MENU.FindItemById( event.GetId()).GetItemLabelText() self.open_file(filename) def _menu_save_as(self, event): eset = self.current_editorset wildcard = ( 'CHIRP %(vendor)s %(model)s %(files)s (*.%(ext)s)|*.%(ext)s' % { 'vendor': eset._radio.VENDOR, 'model': eset._radio.MODEL, 'files': _('Files'), 'ext': eset._radio.FILE_EXTENSION}) for name, pattern, readonly in directory.AUX_FORMATS: if readonly: continue if pattern in wildcard: continue if name in eset.radio.FORMATS: wildcard += '|%s %s (%s)|%s' % ( name, _('Files'), pattern, pattern) style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT | wx.FD_CHANGE_DIR default_filename = os.path.basename(eset.filename) with wx.FileDialog(self, _("Save file"), defaultFile=default_filename, wildcard=wildcard, style=style) as fd: if fd.ShowModal() == wx.ID_CANCEL: return filename = fd.GetPath() chirp_platform.get_platform().set_last_dir( fd.GetDirectory()) eset.save(filename) self.adj_menu_open_recent(filename) self._update_editorset_title(eset) self._update_window_for_editor() return True def _menu_save(self, event): editorset = self.current_editorset if not editorset.modified: return if not os.path.exists(editorset.filename): return self._menu_save_as(event) editorset.save() self._update_editorset_title(self.current_editorset) @common.error_proof(errors.ImageDetectFailed, FileNotFoundError) def _menu_import(self, event): filename = self._do_open() if filename is None: return d = wx.MessageDialog( self, _('The recommended procedure for importing memories is to open ' 'the source file and copy/paste memories from it into your ' 'target image. If you continue with this import function, CHIRP ' 'will replace all memories in your currently-open file with ' 'those in %(file)s. Would you like to open this file to ' 'copy/paste memories across, or proceed with the import?') % { 'file': os.path.basename(filename)}, _('Import not recommended'), wx.ICON_WARNING | wx.YES_NO | wx.CANCEL | wx.NO_DEFAULT) d.SetYesNoLabels(_('Import'), _('Open')) r = d.ShowModal() if r == wx.ID_YES: with common.expose_logs(logging.WARNING, 'chirp.drivers', _('Import messages')): radio = directory.get_radio_by_image(filename) self.current_editorset.current_editor.memedit_import_all(radio) elif r == wx.ID_NO: self.open_file(filename) else: return def _menu_export(self, event): wildcard = 'CSV %s (*.csv)|*.csv' % _('Files') defcsv = os.path.splitext(os.path.basename( self.current_editorset.filename))[0] + '.csv' style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT | wx.FD_CHANGE_DIR with wx.FileDialog(self, _('Export to CSV'), defaultFile=defcsv, wildcard=wildcard, style=style) as fd: if fd.ShowModal() == wx.ID_CANCEL: return self.current_editorset.export_to_file(fd.GetPath()) def _prompt_to_close_editor(self, editorset): """Returns True if it is okay to close the editor, False otherwise""" if not editorset.modified: return True if isinstance(editorset, ChirpLiveEditorSet): return True answer = wx.MessageBox( _('%s has not been saved. Save before closing?') % ( editorset.filename), _('Save before closing?'), wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_WARNING) if answer == wx.NO: # User does not want to save, okay to close return True elif answer == wx.CANCEL: # User wants to cancel, not okay to close return False else: if not os.path.exists(editorset.filename): return self._menu_save_as(None) else: editorset.save() return True def _menu_close(self, event): if self._prompt_to_close_editor(self.current_editorset): self.current_editorset.close() self._editors.DeletePage(self._editors.GetSelection()) self._update_window_for_editor() def _menu_exit(self, event): for w in list(ALL_MAIN_WINDOWS): w.Close(True) @common.error_proof(RuntimeError, errors.InvalidMemoryLocation) def _menu_copy(self, event, cut=False): try: self.current_editorset.cb_copy(cut=cut) except NotImplementedError: LOG.warning('Attempt to cut/copy from %s not supported', self.current_editorset.current_editor) @common.error_proof() def _menu_paste(self, event): try: self.current_editorset.cb_paste() except NotImplementedError: LOG.warning('Attempt to paste to %s not supported', self.current_editorset.current_editor) def _menu_selall(self, event): self.current_editorset.select_all() def _menu_delete(self, event): self.current_editorset.cb_delete() def _menu_new_window(self, event): new = ChirpMain(None, title='CHIRP') new.Show() def _menu_find(self, event): if event.GetId() == wx.ID_FIND: search = wx.GetTextFromUser(_('Find') + ':', _('Find'), self._last_search_text, self) elif not self._last_search_text: return else: search = self._last_search_text if search: self._last_search_text = search self.current_editorset.cb_find(search) def _update_font(self): for i in range(0, self._editors.PageCount): eset = self._editors.GetPage(i) eset.update_font() def _menu_fixed_font(self, event): menuitem = event.GetEventObject().FindItemById(event.GetId()) CONF.set_bool('font_fixed', menuitem.IsChecked(), 'state') self._update_font() def _menu_large_font(self, event): menuitem = event.GetEventObject().FindItemById(event.GetId()) CONF.set_bool('font_large', menuitem.IsChecked(), 'state') self._update_font() def _menu_restore_tabs(self, event): menuitem = event.GetEventObject().FindItemById(event.GetId()) CONF.set_bool('restore_tabs', menuitem.IsChecked(), 'prefs') def _make_backup(self, radio): if not isinstance(radio, chirp_common.CloneModeRadio): LOG.debug('Not backing up %s' % radio) return backup_dir = chirp_platform.get_platform().config_file('backups') now = datetime.datetime.now() fn = os.path.join(backup_dir, '%s_%s' % (directory.radio_class_id(radio.__class__), now.strftime('%Y%m%dT%H%M%S.img'))) try: os.makedirs(backup_dir, exist_ok=True) radio.save(fn) LOG.info('Saved backup to %s', fn) except Exception as e: LOG.warning('Failed to backup %s: %s', radio, e) return try: keep_days = CONF.get_int('keep_backups_days', 'prefs') except TypeError: keep_days = 365 if keep_days < 0: # Never prune return try: files = os.listdir(backup_dir) bydate = [(os.stat(os.path.join(backup_dir, f)).st_mtime, f) for f in files] now = time.time() for mtime, fn in sorted(bydate): age = (now - mtime) // 86400 if age > keep_days: os.remove(os.path.join(backup_dir, fn)) LOG.warning('Pruned backup %s older than %i days', fn, keep_days) elif age + 30 > keep_days: LOG.info('Backup %s will be pruned soon', fn) else: break except Exception as e: LOG.exception('Failed to prune: %s' % e) def _menu_download(self, event): with clone.ChirpDownloadDialog(self) as d: d.Centre() if d.ShowModal() == wx.ID_OK: radio = d._radio self._make_backup(radio) report.report_model(radio, 'download') if isinstance(radio, chirp_common.LiveRadio): editorset = ChirpLiveEditorSet(radio, None, self._editors) else: editorset = ChirpEditorSet(radio, None, self._editors) self.add_editorset(editorset) def _menu_upload(self, event): radio = self.current_editorset.radio report.report_model(radio, 'upload') CSVRadio = directory.get_radio('Generic_CSV') if isinstance(radio, chirp_common.LiveRadio): msg = _('This is a live-mode radio, which means changes are ' 'sent to the radio in real-time as you make them. Upload ' 'is not necessary!') d = wx.MessageDialog(self, msg, _('Live Radio'), wx.ICON_INFORMATION) elif isinstance(radio, (CSVRadio, base.NetworkResultRadio)): msg = _('This is a radio-independent file and cannot be uploaded ' 'directly to a radio. Open a radio image (or download one ' 'from a radio) an then copy/paste items from this tab ' 'into that one in order to upload') d = wx.MessageDialog(self, msg, _('Unable to upload this file'), wx.ICON_INFORMATION) else: d = clone.ChirpUploadDialog(radio, self) d.Centre() d.ShowModal() @common.error_proof() def _menu_reload_driver(self, event, andfile=False): radio = self.current_editorset.radio try: # If we were loaded from a dynamic alias in directory, # get the pointer to the original orig_rclass = radio._orig_rclass except AttributeError: orig_rclass = radio.__class__ # Save a reference to the radio's internal mmap. If the radio does # anything strange or does not follow the typical convention, this # will not work mmap = radio._mmap # Reload the actual module module = sys.modules[orig_rclass.__module__] if hasattr(module, '_was_loaded'): LOG.warning('Reloading loaded module %s' % module) self.load_module(module.__file__) else: LOG.warning('Going to reload %s' % module) directory.enable_reregistrations() import importlib importlib.reload(module) # Grab a new reference to the updated module and pick out the # radio class from it. module = sys.modules[orig_rclass.__module__] rclass = getattr(module, orig_rclass.__name__) filename = self.current_editorset.filename if andfile: # Reload the file while creating the radio new_radio = rclass(filename) else: # Try to reload the driver in place, without # re-reading the file; mimic the file loading # procedure after jamming the memory back in new_radio = rclass(None) new_radio._mmap = mmap new_radio.process_mmap() # Get the currently-selected memedit row so we can re-select it editor_pos = self.current_editorset.current_editor.get_scroll_pos() # Kill the current editorset now that we know the radio loaded # successfully last_editor = self.current_editorset.current_editor_index self.current_editorset.close() self._editors.DeletePage(self._editors.GetSelection()) self._update_window_for_editor() # Mimic the File->Open process to get a new editorset based # on our franken-radio editorset = ChirpEditorSet(new_radio, filename, self._editors) self.add_editorset(editorset, select=True) editorset.select_editor(index=last_editor) editorset.current_editor.set_scroll_pos(editor_pos) LOG.info('Reloaded radio driver%s in place; good luck!' % ( andfile and ' (and file)' or '')) def _menu_interact_driver(self, event): LOG.warning('Going to interact with radio at the console') radio = self.current_editorset.current_editor.radio import code locals = {'main': self, 'radio': radio} if self.current_editorset.radio != radio: locals['parent_radio'] = self.current_editorset.radio code.interact(banner='Locals are: %s' % (', '.join(locals.keys())), local=locals) @common.error_proof() def load_module(self, filename): # We're in development mode, so we need to tell the directory to # allow a loaded module to override an existing driver, against # its normal better judgement directory.enable_reregistrations() self.SetTitle('CHIRP **%s**' % _('Module Loaded')) self.SetBackgroundColour((0xEA, 0x62, 0x62, 0xFF)) with open(filename, 'rb') as module: code = module.read() sha = hashlib.sha256() sha.update(code) LOG.info('Loading module %s SHA256 %s' % (filename, sha.hexdigest())) import importlib.util import sys modname = 'chirp.loaded.%s' % os.path.splitext( os.path.basename(filename))[0] spec = importlib.util.spec_from_file_location(modname, filename) module = importlib.util.module_from_spec(spec) module._was_loaded = True sys.modules[modname] = module try: spec.loader.exec_module(module) return True except Exception as e: LOG.error('Failed to load module: %s' % e) raise Exception(_('Invalid or unsupported module file')) def _menu_load_module(self, event): formats = ['Python %s (*.py)|*.py' % _('Files'), '%s %s (*.mod)|*.mod' % (_('Module'), _('Files'))] r = wx.MessageDialog(self, _('Loading modules can be extremely dangerous, ' 'leading to damage to your computer, radio, ' 'or both. NEVER load a module from a source ' 'you do not trust, and especially not from ' 'anywhere other than the main CHIRP website ' '(chirp.danplanet.com). Loading a module from ' 'another source is akin to giving them direct ' 'access to your computer and everything on ' 'it! Proceed despite this risk?'), 'Warning', wx.ICON_WARNING | wx.YES_NO) if r.ShowModal() != wx.ID_YES: return wildcard = '|'.join(formats) with wx.FileDialog(self, _('Open a module'), chirp_platform.get_platform().get_last_dir(), wildcard=wildcard, style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fd: if fd.ShowModal() == wx.ID_CANCEL: return filename = fd.GetPath() self.load_module(filename) def _menu_about(self, event): pyver = sys.version_info aboutinfo = 'CHIRP %s on Python %s wxPython %s' % ( CHIRP_VERSION, '%s.%s.%s' % (pyver.major, pyver.minor, pyver.micro), wx.version()) wx.MessageBox(aboutinfo, _('About CHIRP'), wx.OK | wx.ICON_INFORMATION) def _menu_developer(self, menuitem, event): CONF.set_bool('developer', menuitem.IsChecked(), 'state') state = menuitem.IsChecked() and _('enabled') or _('disabled') if menuitem.IsChecked(): msg = _( 'Please note that developer mode is intended for use ' 'by developers of the CHIRP project, or under the ' 'direction of a developer. It enables behaviors and ' 'functions that can damage your computer and your ' 'radio if not used with EXTREME care. You have been ' 'warned! Proceed anyway?') d = wx.MessageDialog(self, msg, _('Danger Ahead'), style=wx.ICON_WARNING | wx.YES_NO) if d.ShowModal() != wx.ID_YES: menuitem.Check(False) return wx.MessageBox(_('Developer state is now %s. ' 'CHIRP must be restarted to take effect') % state, _('Restart Required'), wx.OK) def _menu_reporting(self, menuitem, event): if not menuitem.IsChecked(): r = wx.MessageBox( _('Reporting helps the CHIRP project know which ' 'radio models and OS platforms to spend our limited ' 'efforts on. We would really appreciate if you left ' 'it enabled. Really disable reporting?'), _('Disable reporting'), wx.YES_NO | wx.ICON_WARNING | wx.NO_DEFAULT) if r == wx.NO: menuitem.Check(True) return CONF.set_bool('no_report', not menuitem.IsChecked()) @common.error_proof() def _menu_debug_log(self, event): dst = common.temporary_debug_log() wx.LaunchDefaultApplication(dst) @common.error_proof() def _menu_debug_loc(self, event): dst = common.temporary_debug_log() common.reveal_location(dst) @common.error_proof() def _menu_backup_loc(self, event): backup_dir = chirp_platform.get_platform().config_file('backups') common.reveal_location(backup_dir) @common.error_proof() def _menu_load_from_issue(self, event): module = developer.IssueModuleLoader(self).run() if module: if self.load_module(module): wx.MessageBox(_('Module loaded successfully'), _('Success'), wx.ICON_INFORMATION) def _menu_auto_edits(self, event): CONF.set_bool('auto_edits', event.IsChecked(), 'state') LOG.debug('Set auto_edits=%s' % event.IsChecked()) def _menu_select_bandplan(self, event): bandplans = bandplan.BandPlans(CONF) plans = sorted([(shortname, details[0]) for shortname, details in bandplans.plans.items()], key=lambda x: x[1]) d = wx.SingleChoiceDialog(self, _('Select a bandplan'), _('Bandplan'), [x[1] for x in plans]) for index, (shortname, name) in enumerate(plans): if CONF.get_bool(shortname, 'bandplan'): d.SetSelection(index) break r = d.ShowModal() if r == wx.ID_OK: selected = plans[d.GetSelection()][0] LOG.info('Selected bandplan: %s' % selected) for shortname, name in plans: CONF.set_bool(shortname, shortname == selected, 'bandplan') def _do_network_query(self, query_cls): d = query_cls(self, title=_('Query %s') % query_cls.NAME) r = d.ShowModal() if r == wx.ID_OK: report.report_model(d.result_radio, 'query') editorset = ChirpEditorSet(d.result_radio, None, self._editors) self.add_editorset(editorset) def _menu_query_rr(self, event): self._do_network_query(query_sources.RRQueryDialog) def _menu_query_rb(self, event): self._do_network_query(query_sources.RepeaterBookQueryDialog) def _menu_query_dm(self, event): self._do_network_query(query_sources.DMRMARCQueryDialog) def _menu_query_prz(self, event): self._do_network_query(query_sources.PrzemiennikiQueryDialog) def display_update_notice(version): LOG.info('Server reports %s is latest' % version) if version == CHIRP_VERSION: return if CONF.get_bool("skip_update_check", "state"): return if CHIRP_VERSION.endswith('dev'): return # Report new updates occasionally intv = 3600 * 24 * 7 if CONF.is_defined("last_update_check", "state") and \ (time.time() - CONF.get_int("last_update_check", "state")) < intv: return CONF.set_int("last_update_check", int(time.time()), "state") url = 'https://chirp.danplanet.com/projects/chirp/wiki/ChirpNextBuild' msg = _('A new CHIRP version is available. Please visit the ' 'website as soon as possible to download it!') d = wx.MessageDialog(None, msg, _('New version available'), style=wx.OK | wx.CANCEL | wx.ICON_INFORMATION) visit = d.ShowModal() if visit == wx.ID_OK: wx.MessageBox(_('Please be sure to quit CHIRP before installing ' 'the new version!')) webbrowser.open(url) chirp-20240224/chirp/wxui/printing.py0000644000175000017500000001052314411666130016344 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import wx.html import yattag from chirp.wxui import common from chirp.wxui import config from chirp.wxui import report CONF = config.get() class MemoryPrinter(wx.html.HtmlEasyPrinting): def __init__(self, parent, radio, memedit): super().__init__(name=_('Printing'), parentWindow=parent) self._radio = radio self._features = radio.get_features() self._col_defs = memedit._col_defs # Set some default printer and page options. self.GetPrintData().SetPaperId(wx.PAPER_LETTER) # wx.PAPER_A4 self.GetPrintData().SetOrientation(wx.LANDSCAPE) # wx.PORTRAIT # Black and white printing if False. self.GetPrintData().SetColour(False) self.GetPageSetupData().SetMarginTopLeft((0, 5)) self.GetPageSetupData().SetMarginBottomRight((10, 10)) # These are arbitrary defaults that seem to work okay. Let people # override via the config for now try: self._font_size = CONF.get_int('font_size', 'printing') except TypeError: self._font_size = 8 try: self._rows_per_page = CONF.get_int('rows_per_page', 'printing') except TypeError: self._rows_per_page = 35 self._normal_font = CONF.get('normal_font', 'printing') or 'Sans' self._fixed_font = CONF.get('fixed_font', 'printing') or 'Courier' self.SetStandardFonts(self._font_size, self._normal_font, self._fixed_font) def _memory(self, doc, mem): tag = doc.tag with tag('td'): with tag('tt'): doc.text(mem.number) for col_def in self._col_defs: if not col_def.valid: continue with tag('td', 'nowrap'): with tag('tt'): doc.text(col_def.render_value(mem)) def _memory_table(self, doc, memories): tag = doc.tag row = 0 for i in range(0, len(memories), self._rows_per_page): with tag('div', ('style', 'page-break-before:always')): pass with tag('table', ('border', '1'), ('width', '100%'), ('cellspacing', '0')): with tag('tr'): with tag('th'): doc.text('#') for col_def in self._col_defs: if not col_def.valid: continue with tag('th'): pieces = col_def.label.split() for piece in pieces: doc.text(piece) if piece != pieces[-1]: doc.stag('br') for row in range(i, i + self._rows_per_page): try: mem = memories[row] except IndexError: continue with tag('tr'): try: self._memory(doc, mem) except IndexError: pass def _print(self, memories): report.report_model(self._radio, 'print') memories = [m for m in memories if not m.empty] doc, tag, text = yattag.Doc().tagtext() with tag('html'): with tag('body'): self._memory_table(doc, memories) return doc @common.error_proof() def print(self, memories): doc = self._print(memories) self.PrintText(doc.getvalue()) @common.error_proof() def print_preview(self, memories): doc = self._print(memories) return self.PreviewText(doc.getvalue()) chirp-20240224/chirp/wxui/fips.py0000644000175000017500000075212414563632215015472 0ustar hibbyhibby# Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . FIPS_STATES = { "Alaska": 2, "Alabama": 1, "Arkansas": 5, "Arizona": 4, "California": 6, "Colorado": 8, "Connecticut": 9, "District of Columbia": 11, "Delaware": 10, "Florida": 12, "Georgia": 13, "Guam": 66, "Hawaii": 15, "Iowa": 19, "Idaho": 16, "Illinois": 17, "Indiana": 18, "Kansas": 20, "Kentucky": 21, "Louisiana": 22, "Massachusetts": 25, "Maryland": 24, "Maine": 23, "Michigan": 26, "Minnesota": 27, "Missouri": 29, "Mississippi": 28, "Montana": 30, "North Carolina": 37, "North Dakota": 38, "Nebraska": 31, "New Hampshire": 33, "New Jersey": 34, "New Mexico": 35, "Nevada": 32, "New York": 36, "Ohio": 39, "Oklahoma": 40, "Oregon": 41, "Pennsylvania": 42, "Puerto Rico": 72, "Rhode Island": 44, "South Carolina": 45, "South Dakota": 46, "Tennessee": 47, "Texas": 48, "Utah": 49, "Virginia": 51, "Virgin Islands": 78, "Vermont": 50, "Washington": 53, "Wisconsin": 55, "West Virginia": 54, "Wyoming": 56, "Alberta": "CA01", "British Columbia": "CA02", "Manitoba": "CA03", "New Brunswick": "CA04", "Newfoundland": "CA05", "Northwest Territories": "CA13", "Nova Scotia": "CA07", "Nunavut": "CA14", "Ontario": "CA08", "Prince Edward Island": "CA09", "Quebec": "CA10", "Saskatchewan": "CA11", "Yukon Territory": "CA12", } FIPS_COUNTIES = { 1: {'--All--': '%', 'Autauga County, AL': '001', 'Baldwin County, AL': '003', 'Barbour County, AL': '005', 'Bibb County, AL': '007', 'Blount County, AL': '009', 'Bullock County, AL': '011', 'Butler County, AL': '013', 'Calhoun County, AL': '015', 'Chambers County, AL': '017', 'Cherokee County, AL': '019', 'Chilton County, AL': '021', 'Choctaw County, AL': '023', 'Clarke County, AL': '025', 'Clay County, AL': '027', 'Cleburne County, AL': '029', 'Coffee County, AL': '031', 'Colbert County, AL': '033', 'Conecuh County, AL': '035', 'Coosa County, AL': '037', 'Covington County, AL': '039', 'Crenshaw County, AL': '041', 'Cullman County, AL': '043', 'Dale County, AL': '045', 'Dallas County, AL': '047', 'DeKalb County, AL': '049', 'Elmore County, AL': '051', 'Escambia County, AL': '053', 'Etowah County, AL': '055', 'Fayette County, AL': '057', 'Franklin County, AL': '059', 'Geneva County, AL': '061', 'Greene County, AL': '063', 'Hale County, AL': '065', 'Henry County, AL': '067', 'Houston County, AL': '069', 'Jackson County, AL': '071', 'Jefferson County, AL': '073', 'Lamar County, AL': '075', 'Lauderdale County, AL': '077', 'Lawrence County, AL': '079', 'Lee County, AL': '081', 'Limestone County, AL': '083', 'Lowndes County, AL': '085', 'Macon County, AL': '087', 'Madison County, AL': '089', 'Marengo County, AL': '091', 'Marion County, AL': '093', 'Marshall County, AL': '095', 'Mobile County, AL': '097', 'Monroe County, AL': '099', 'Montgomery County, AL': '101', 'Morgan County, AL': '103', 'Perry County, AL': '105', 'Pickens County, AL': '107', 'Pike County, AL': '109', 'Randolph County, AL': '111', 'Russell County, AL': '113', 'Shelby County, AL': '117', 'St. Clair County, AL': '115', 'Sumter County, AL': '119', 'Talladega County, AL': '121', 'Tallapoosa County, AL': '123', 'Tuscaloosa County, AL': '125', 'Walker County, AL': '127', 'Washington County, AL': '129', 'Wilcox County, AL': '131', 'Winston County, AL': '133'}, 2: {'--All--': '%', 'Aleutians East Borough, AK': '013', 'Aleutians West Census Area, AK': '016', 'Anchorage Borough/municipality, AK': '020', 'Bethel Census Area, AK': '050', 'Bristol Bay Borough, AK': '060', 'Denali Borough, AK': '068', 'Dillingham Census Area, AK': '070', 'Fairbanks North Star Borough, AK': '090', 'Haines Borough, AK': '100', 'Juneau Borough/city, AK': '110', 'Kenai Peninsula Borough, AK': '122', 'Ketchikan Gateway Borough, AK': '130', 'Kodiak Island Borough, AK': '150', 'Lake and Peninsula Borough, AK': '164', 'Matanuska-Susitna Borough, AK': '170', 'Nome Census Area, AK': '180', 'North Slope Borough, AK': '185', 'Northwest Arctic Borough, AK': '188', 'Prince of Wales-Outer Ketchikan Census Area, AK': '201', 'Sitka Borough/city, AK': '220', 'Skagway-Hoonah-Angoon Census Area, AK': '232', 'Southeast Fairbanks Census Area, AK': '240', 'Valdez-Cordova Census Area, AK': '261', 'Wade Hampton Census Area, AK': '270', 'Wrangell-Petersburg Census Area, AK': '280', 'Yakutat Borough, AK': '282', 'Yukon-Koyukuk Census Area, AK': '290'}, 4: {'--All--': '%', 'Apache County, AZ': '001', 'Cochise County, AZ': '003', 'Coconino County, AZ': '005', 'Gila County, AZ': '007', 'Graham County, AZ': '009', 'Greenlee County, AZ': '011', 'La Paz County, AZ': '012', 'Maricopa County, AZ': '013', 'Mohave County, AZ': '015', 'Navajo County, AZ': '017', 'Pima County, AZ': '019', 'Pinal County, AZ': '021', 'Santa Cruz County, AZ': '023', 'Yavapai County, AZ': '025', 'Yuma County, AZ': '027'}, 5: {'--All--': '%', 'Arkansas County, AR': '001', 'Ashley County, AR': '003', 'Baxter County, AR': '005', 'Benton County, AR': '007', 'Boone County, AR': '009', 'Bradley County, AR': '011', 'Calhoun County, AR': '013', 'Carroll County, AR': '015', 'Chicot County, AR': '017', 'Clark County, AR': '019', 'Clay County, AR': '021', 'Cleburne County, AR': '023', 'Cleveland County, AR': '025', 'Columbia County, AR': '027', 'Conway County, AR': '029', 'Craighead County, AR': '031', 'Crawford County, AR': '033', 'Crittenden County, AR': '035', 'Cross County, AR': '037', 'Dallas County, AR': '039', 'Desha County, AR': '041', 'Drew County, AR': '043', 'Faulkner County, AR': '045', 'Franklin County, AR': '047', 'Fulton County, AR': '049', 'Garland County, AR': '051', 'Grant County, AR': '053', 'Greene County, AR': '055', 'Hempstead County, AR': '057', 'Hot Spring County, AR': '059', 'Howard County, AR': '061', 'Independence County, AR': '063', 'Izard County, AR': '065', 'Jackson County, AR': '067', 'Jefferson County, AR': '069', 'Johnson County, AR': '071', 'Lafayette County, AR': '073', 'Lawrence County, AR': '075', 'Lee County, AR': '077', 'Lincoln County, AR': '079', 'Little River County, AR': '081', 'Logan County, AR': '083', 'Lonoke County, AR': '085', 'Madison County, AR': '087', 'Marion County, AR': '089', 'Miller County, AR': '091', 'Mississippi County, AR': '093', 'Monroe County, AR': '095', 'Montgomery County, AR': '097', 'Nevada County, AR': '099', 'Newton County, AR': '101', 'Ouachita County, AR': '103', 'Perry County, AR': '105', 'Phillips County, AR': '107', 'Pike County, AR': '109', 'Poinsett County, AR': '111', 'Polk County, AR': '113', 'Pope County, AR': '115', 'Prairie County, AR': '117', 'Pulaski County, AR': '119', 'Randolph County, AR': '121', 'Saline County, AR': '125', 'Scott County, AR': '127', 'Searcy County, AR': '129', 'Sebastian County, AR': '131', 'Sevier County, AR': '133', 'Sharp County, AR': '135', 'St. Francis County, AR': '123', 'Stone County, AR': '137', 'Union County, AR': '139', 'Van Buren County, AR': '141', 'Washington County, AR': '143', 'White County, AR': '145', 'Woodruff County, AR': '147', 'Yell County, AR': '149'}, 6: {'--All--': '%', 'Alameda County, CA': '001', 'Alpine County, CA': '003', 'Amador County, CA': '005', 'Butte County, CA': '007', 'Calaveras County, CA': '009', 'Colusa County, CA': '011', 'Contra Costa County, CA': '013', 'Del Norte County, CA': '015', 'El Dorado County, CA': '017', 'Fresno County, CA': '019', 'Glenn County, CA': '021', 'Humboldt County, CA': '023', 'Imperial County, CA': '025', 'Inyo County, CA': '027', 'Kern County, CA': '029', 'Kings County, CA': '031', 'Lake County, CA': '033', 'Lassen County, CA': '035', 'Los Angeles County, CA': '037', 'Madera County, CA': '039', 'Marin County, CA': '041', 'Mariposa County, CA': '043', 'Mendocino County, CA': '045', 'Merced County, CA': '047', 'Modoc County, CA': '049', 'Mono County, CA': '051', 'Monterey County, CA': '053', 'Napa County, CA': '055', 'Nevada County, CA': '057', 'Orange County, CA': '059', 'Placer County, CA': '061', 'Plumas County, CA': '063', 'Riverside County, CA': '065', 'Sacramento County, CA': '067', 'San Benito County, CA': '069', 'San Bernardino County, CA': '071', 'San Diego County, CA': '073', 'San Francisco County/city, CA': '075', 'San Joaquin County, CA': '077', 'San Luis Obispo County, CA': '079', 'San Mateo County, CA': '081', 'Santa Barbara County, CA': '083', 'Santa Clara County, CA': '085', 'Santa Cruz County, CA': '087', 'Shasta County, CA': '089', 'Sierra County, CA': '091', 'Siskiyou County, CA': '093', 'Solano County, CA': '095', 'Sonoma County, CA': '097', 'Stanislaus County, CA': '099', 'Sutter County, CA': '101', 'Tehama County, CA': '103', 'Trinity County, CA': '105', 'Tulare County, CA': '107', 'Tuolumne County, CA': '109', 'Ventura County, CA': '111', 'Yolo County, CA': '113', 'Yuba County, CA': '115'}, 8: {'--All--': '%', 'Adams County, CO': '001', 'Alamosa County, CO': '003', 'Arapahoe County, CO': '005', 'Archuleta County, CO': '007', 'Baca County, CO': '009', 'Bent County, CO': '011', 'Boulder County, CO': '013', 'Broomfield County/city, CO': '014', 'Chaffee County, CO': '015', 'Cheyenne County, CO': '017', 'Clear Creek County, CO': '019', 'Conejos County, CO': '021', 'Costilla County, CO': '023', 'Crowley County, CO': '025', 'Custer County, CO': '027', 'Delta County, CO': '029', 'Denver County/city, CO': '031', 'Dolores County, CO': '033', 'Douglas County, CO': '035', 'Eagle County, CO': '037', 'El Paso County, CO': '041', 'Elbert County, CO': '039', 'Fremont County, CO': '043', 'Garfield County, CO': '045', 'Gilpin County, CO': '047', 'Grand County, CO': '049', 'Gunnison County, CO': '051', 'Hinsdale County, CO': '053', 'Huerfano County, CO': '055', 'Jackson County, CO': '057', 'Jefferson County, CO': '059', 'Kiowa County, CO': '061', 'Kit Carson County, CO': '063', 'La Plata County, CO': '067', 'Lake County, CO': '065', 'Larimer County, CO': '069', 'Las Animas County, CO': '071', 'Lincoln County, CO': '073', 'Logan County, CO': '075', 'Mesa County, CO': '077', 'Mineral County, CO': '079', 'Moffat County, CO': '081', 'Montezuma County, CO': '083', 'Montrose County, CO': '085', 'Morgan County, CO': '087', 'Otero County, CO': '089', 'Ouray County, CO': '091', 'Park County, CO': '093', 'Phillips County, CO': '095', 'Pitkin County, CO': '097', 'Prowers County, CO': '099', 'Pueblo County, CO': '101', 'Rio Blanco County, CO': '103', 'Rio Grande County, CO': '105', 'Routt County, CO': '107', 'Saguache County, CO': '109', 'San Juan County, CO': '111', 'San Miguel County, CO': '113', 'Sedgwick County, CO': '115', 'Summit County, CO': '117', 'Teller County, CO': '119', 'Washington County, CO': '121', 'Weld County, CO': '123', 'Yuma County, CO': '125'}, 9: {'--All--': '%', 'Fairfield County, CT': '001', 'Hartford County, CT': '003', 'Litchfield County, CT': '005', 'Middlesex County, CT': '007', 'New Haven County, CT': '009', 'New London County, CT': '011', 'Tolland County, CT': '013', 'Windham County, CT': '015'}, 10: {'--All--': '%', 'Kent County, DE': '001', 'New Castle County, DE': '003', 'Sussex County, DE': '005'}, 11: {'--All--': '%', 'District of Columbia': '001'}, 12: {'--All--': '%', 'Alachua County, FL': '001', 'Baker County, FL': '003', 'Bay County, FL': '005', 'Bradford County, FL': '007', 'Brevard County, FL': '009', 'Broward County, FL': '011', 'Calhoun County, FL': '013', 'Charlotte County, FL': '015', 'Citrus County, FL': '017', 'Clay County, FL': '019', 'Collier County, FL': '021', 'Columbia County, FL': '023', 'DeSoto County, FL': '027', 'Dixie County, FL': '029', 'Duval County, FL': '031', 'Escambia County, FL': '033', 'Flagler County, FL': '035', 'Franklin County, FL': '037', 'Gadsden County, FL': '039', 'Gilchrist County, FL': '041', 'Glades County, FL': '043', 'Gulf County, FL': '045', 'Hamilton County, FL': '047', 'Hardee County, FL': '049', 'Hendry County, FL': '051', 'Hernando County, FL': '053', 'Highlands County, FL': '055', 'Hillsborough County, FL': '057', 'Holmes County, FL': '059', 'Indian River County, FL': '061', 'Jackson County, FL': '063', 'Jefferson County, FL': '065', 'Lafayette County, FL': '067', 'Lake County, FL': '069', 'Lee County, FL': '071', 'Leon County, FL': '073', 'Levy County, FL': '075', 'Liberty County, FL': '077', 'Madison County, FL': '079', 'Manatee County, FL': '081', 'Marion County, FL': '083', 'Martin County, FL': '085', 'Miami-Dade County, FL': '086', 'Monroe County, FL': '087', 'Nassau County, FL': '089', 'Okaloosa County, FL': '091', 'Okeechobee County, FL': '093', 'Orange County, FL': '095', 'Osceola County, FL': '097', 'Palm Beach County, FL': '099', 'Pasco County, FL': '101', 'Pinellas County, FL': '103', 'Polk County, FL': '105', 'Putnam County, FL': '107', 'Santa Rosa County, FL': '113', 'Sarasota County, FL': '115', 'Seminole County, FL': '117', 'St. Johns County, FL': '109', 'St. Lucie County, FL': '111', 'Sumter County, FL': '119', 'Suwannee County, FL': '121', 'Taylor County, FL': '123', 'Union County, FL': '125', 'Volusia County, FL': '127', 'Wakulla County, FL': '129', 'Walton County, FL': '131', 'Washington County, FL': '133'}, 13: {'--All--': '%', 'Appling County, GA': '001', 'Atkinson County, GA': '003', 'Bacon County, GA': '005', 'Baker County, GA': '007', 'Baldwin County, GA': '009', 'Banks County, GA': '011', 'Barrow County, GA': '013', 'Bartow County, GA': '015', 'Ben Hill County, GA': '017', 'Berrien County, GA': '019', 'Bibb County, GA': '021', 'Bleckley County, GA': '023', 'Brantley County, GA': '025', 'Brooks County, GA': '027', 'Bryan County, GA': '029', 'Bulloch County, GA': '031', 'Burke County, GA': '033', 'Butts County, GA': '035', 'Calhoun County, GA': '037', 'Camden County, GA': '039', 'Candler County, GA': '043', 'Carroll County, GA': '045', 'Catoosa County, GA': '047', 'Charlton County, GA': '049', 'Chatham County, GA': '051', 'Chattahoochee County, GA': '053', 'Chattooga County, GA': '055', 'Cherokee County, GA': '057', 'Clarke County, GA': '059', 'Clay County, GA': '061', 'Clayton County, GA': '063', 'Clinch County, GA': '065', 'Cobb County, GA': '067', 'Coffee County, GA': '069', 'Colquitt County, GA': '071', 'Columbia County, GA': '073', 'Cook County, GA': '075', 'Coweta County, GA': '077', 'Crawford County, GA': '079', 'Crisp County, GA': '081', 'Dade County, GA': '083', 'Dawson County, GA': '085', 'DeKalb County, GA': '089', 'Decatur County, GA': '087', 'Dodge County, GA': '091', 'Dooly County, GA': '093', 'Dougherty County, GA': '095', 'Douglas County, GA': '097', 'Early County, GA': '099', 'Echols County, GA': '101', 'Effingham County, GA': '103', 'Elbert County, GA': '105', 'Emanuel County, GA': '107', 'Evans County, GA': '109', 'Fannin County, GA': '111', 'Fayette County, GA': '113', 'Floyd County, GA': '115', 'Forsyth County, GA': '117', 'Franklin County, GA': '119', 'Fulton County, GA': '121', 'Gilmer County, GA': '123', 'Glascock County, GA': '125', 'Glynn County, GA': '127', 'Gordon County, GA': '129', 'Grady County, GA': '131', 'Greene County, GA': '133', 'Gwinnett County, GA': '135', 'Habersham County, GA': '137', 'Hall County, GA': '139', 'Hancock County, GA': '141', 'Haralson County, GA': '143', 'Harris County, GA': '145', 'Hart County, GA': '147', 'Heard County, GA': '149', 'Henry County, GA': '151', 'Houston County, GA': '153', 'Irwin County, GA': '155', 'Jackson County, GA': '157', 'Jasper County, GA': '159', 'Jeff Davis County, GA': '161', 'Jefferson County, GA': '163', 'Jenkins County, GA': '165', 'Johnson County, GA': '167', 'Jones County, GA': '169', 'Lamar County, GA': '171', 'Lanier County, GA': '173', 'Laurens County, GA': '175', 'Lee County, GA': '177', 'Liberty County, GA': '179', 'Lincoln County, GA': '181', 'Long County, GA': '183', 'Lowndes County, GA': '185', 'Lumpkin County, GA': '187', 'Macon County, GA': '193', 'Madison County, GA': '195', 'Marion County, GA': '197', 'McDuffie County, GA': '189', 'McIntosh County, GA': '191', 'Meriwether County, GA': '199', 'Miller County, GA': '201', 'Mitchell County, GA': '205', 'Monroe County, GA': '207', 'Montgomery County, GA': '209', 'Morgan County, GA': '211', 'Murray County, GA': '213', 'Muscogee County, GA': '215', 'Newton County, GA': '217', 'Oconee County, GA': '219', 'Oglethorpe County, GA': '221', 'Paulding County, GA': '223', 'Peach County, GA': '225', 'Pickens County, GA': '227', 'Pierce County, GA': '229', 'Pike County, GA': '231', 'Polk County, GA': '233', 'Pulaski County, GA': '235', 'Putnam County, GA': '237', 'Quitman County, GA': '239', 'Rabun County, GA': '241', 'Randolph County, GA': '243', 'Richmond County, GA': '245', 'Rockdale County, GA': '247', 'Schley County, GA': '249', 'Screven County, GA': '251', 'Seminole County, GA': '253', 'Spalding County, GA': '255', 'Stephens County, GA': '257', 'Stewart County, GA': '259', 'Sumter County, GA': '261', 'Talbot County, GA': '263', 'Taliaferro County, GA': '265', 'Tattnall County, GA': '267', 'Taylor County, GA': '269', 'Telfair County, GA': '271', 'Terrell County, GA': '273', 'Thomas County, GA': '275', 'Tift County, GA': '277', 'Toombs County, GA': '279', 'Towns County, GA': '281', 'Treutlen County, GA': '283', 'Troup County, GA': '285', 'Turner County, GA': '287', 'Twiggs County, GA': '289', 'Union County, GA': '291', 'Upson County, GA': '293', 'Walker County, GA': '295', 'Walton County, GA': '297', 'Ware County, GA': '299', 'Warren County, GA': '301', 'Washington County, GA': '303', 'Wayne County, GA': '305', 'Webster County, GA': '307', 'Wheeler County, GA': '309', 'White County, GA': '311', 'Whitfield County, GA': '313', 'Wilcox County, GA': '315', 'Wilkes County, GA': '317', 'Wilkinson County, GA': '319', 'Worth County, GA': '321'}, 15: {'--All--': '%', 'Hawaii County, HI': '001', 'Honolulu County/city, HI': '003', 'Kauai County, HI': '007', 'Maui County, HI': '009'}, 16: {'--All--': '%', 'Ada County, ID': '001', 'Adams County, ID': '003', 'Bannock County, ID': '005', 'Bear Lake County, ID': '007', 'Benewah County, ID': '009', 'Bingham County, ID': '011', 'Blaine County, ID': '013', 'Boise County, ID': '015', 'Bonner County, ID': '017', 'Bonneville County, ID': '019', 'Boundary County, ID': '021', 'Butte County, ID': '023', 'Camas County, ID': '025', 'Canyon County, ID': '027', 'Caribou County, ID': '029', 'Cassia County, ID': '031', 'Clark County, ID': '033', 'Clearwater County, ID': '035', 'Custer County, ID': '037', 'Elmore County, ID': '039', 'Franklin County, ID': '041', 'Fremont County, ID': '043', 'Gem County, ID': '045', 'Gooding County, ID': '047', 'Idaho County, ID': '049', 'Jefferson County, ID': '051', 'Jerome County, ID': '053', 'Kootenai County, ID': '055', 'Latah County, ID': '057', 'Lemhi County, ID': '059', 'Lewis County, ID': '061', 'Lincoln County, ID': '063', 'Madison County, ID': '065', 'Minidoka County, ID': '067', 'Nez Perce County, ID': '069', 'Oneida County, ID': '071', 'Owyhee County, ID': '073', 'Payette County, ID': '075', 'Power County, ID': '077', 'Shoshone County, ID': '079', 'Teton County, ID': '081', 'Twin Falls County, ID': '083', 'Valley County, ID': '085', 'Washington County, ID': '087'}, 17: {'--All--': '%', 'Adams County, IL': '001', 'Alexander County, IL': '003', 'Bond County, IL': '005', 'Boone County, IL': '007', 'Brown County, IL': '009', 'Bureau County, IL': '011', 'Calhoun County, IL': '013', 'Carroll County, IL': '015', 'Cass County, IL': '017', 'Champaign County, IL': '019', 'Christian County, IL': '021', 'Clark County, IL': '023', 'Clay County, IL': '025', 'Clinton County, IL': '027', 'Coles County, IL': '029', 'Cook County, IL': '031', 'Crawford County, IL': '033', 'Cumberland County, IL': '035', 'De Witt County, IL': '039', 'DeKalb County, IL': '037', 'Douglas County, IL': '041', 'DuPage County, IL': '043', 'Edgar County, IL': '045', 'Edwards County, IL': '047', 'Effingham County, IL': '049', 'Fayette County, IL': '051', 'Ford County, IL': '053', 'Franklin County, IL': '055', 'Fulton County, IL': '057', 'Gallatin County, IL': '059', 'Greene County, IL': '061', 'Grundy County, IL': '063', 'Hamilton County, IL': '065', 'Hancock County, IL': '067', 'Hardin County, IL': '069', 'Henderson County, IL': '071', 'Henry County, IL': '073', 'Iroquois County, IL': '075', 'Jackson County, IL': '077', 'Jasper County, IL': '079', 'Jefferson County, IL': '081', 'Jersey County, IL': '083', 'Jo Daviess County, IL': '085', 'Johnson County, IL': '087', 'Kane County, IL': '089', 'Kankakee County, IL': '091', 'Kendall County, IL': '093', 'Knox County, IL': '095', 'La Salle County, IL': '099', 'Lake County, IL': '097', 'Lawrence County, IL': '101', 'Lee County, IL': '103', 'Livingston County, IL': '105', 'Logan County, IL': '107', 'Macon County, IL': '115', 'Macoupin County, IL': '117', 'Madison County, IL': '119', 'Marion County, IL': '121', 'Marshall County, IL': '123', 'Mason County, IL': '125', 'Massac County, IL': '127', 'McDonough County, IL': '109', 'McHenry County, IL': '111', 'McLean County, IL': '113', 'Menard County, IL': '129', 'Mercer County, IL': '131', 'Monroe County, IL': '133', 'Montgomery County, IL': '135', 'Morgan County, IL': '137', 'Moultrie County, IL': '139', 'Ogle County, IL': '141', 'Peoria County, IL': '143', 'Perry County, IL': '145', 'Piatt County, IL': '147', 'Pike County, IL': '149', 'Pope County, IL': '151', 'Pulaski County, IL': '153', 'Putnam County, IL': '155', 'Randolph County, IL': '157', 'Richland County, IL': '159', 'Rock Island County, IL': '161', 'Saline County, IL': '165', 'Sangamon County, IL': '167', 'Schuyler County, IL': '169', 'Scott County, IL': '171', 'Shelby County, IL': '173', 'St. Clair County, IL': '163', 'Stark County, IL': '175', 'Stephenson County, IL': '177', 'Tazewell County, IL': '179', 'Union County, IL': '181', 'Vermilion County, IL': '183', 'Wabash County, IL': '185', 'Warren County, IL': '187', 'Washington County, IL': '189', 'Wayne County, IL': '191', 'White County, IL': '193', 'Whiteside County, IL': '195', 'Will County, IL': '197', 'Williamson County, IL': '199', 'Winnebago County, IL': '201', 'Woodford County, IL': '203'}, 18: {'--All--': '%', 'Adams County, IN': '001', 'Allen County, IN': '003', 'Bartholomew County, IN': '005', 'Benton County, IN': '007', 'Blackford County, IN': '009', 'Boone County, IN': '011', 'Brown County, IN': '013', 'Carroll County, IN': '015', 'Cass County, IN': '017', 'Clark County, IN': '019', 'Clay County, IN': '021', 'Clinton County, IN': '023', 'Crawford County, IN': '025', 'Daviess County, IN': '027', 'DeKalb County, IN': '033', 'Dearborn County, IN': '029', 'Decatur County, IN': '031', 'Delaware County, IN': '035', 'Dubois County, IN': '037', 'Elkhart County, IN': '039', 'Fayette County, IN': '041', 'Floyd County, IN': '043', 'Fountain County, IN': '045', 'Franklin County, IN': '047', 'Fulton County, IN': '049', 'Gibson County, IN': '051', 'Grant County, IN': '053', 'Greene County, IN': '055', 'Hamilton County, IN': '057', 'Hancock County, IN': '059', 'Harrison County, IN': '061', 'Hendricks County, IN': '063', 'Henry County, IN': '065', 'Howard County, IN': '067', 'Huntington County, IN': '069', 'Jackson County, IN': '071', 'Jasper County, IN': '073', 'Jay County, IN': '075', 'Jefferson County, IN': '077', 'Jennings County, IN': '079', 'Johnson County, IN': '081', 'Knox County, IN': '083', 'Kosciusko County, IN': '085', 'LaGrange County, IN': '087', 'LaPorte County, IN': '091', 'Lake County, IN': '089', 'Lawrence County, IN': '093', 'Madison County, IN': '095', 'Marion County, IN': '097', 'Marshall County, IN': '099', 'Martin County, IN': '101', 'Miami County, IN': '103', 'Monroe County, IN': '105', 'Montgomery County, IN': '107', 'Morgan County, IN': '109', 'Newton County, IN': '111', 'Noble County, IN': '113', 'Ohio County, IN': '115', 'Orange County, IN': '117', 'Owen County, IN': '119', 'Parke County, IN': '121', 'Perry County, IN': '123', 'Pike County, IN': '125', 'Porter County, IN': '127', 'Posey County, IN': '129', 'Pulaski County, IN': '131', 'Putnam County, IN': '133', 'Randolph County, IN': '135', 'Ripley County, IN': '137', 'Rush County, IN': '139', 'Scott County, IN': '143', 'Shelby County, IN': '145', 'Spencer County, IN': '147', 'St. Joseph County, IN': '141', 'Starke County, IN': '149', 'Steuben County, IN': '151', 'Sullivan County, IN': '153', 'Switzerland County, IN': '155', 'Tippecanoe County, IN': '157', 'Tipton County, IN': '159', 'Union County, IN': '161', 'Vanderburgh County, IN': '163', 'Vermillion County, IN': '165', 'Vigo County, IN': '167', 'Wabash County, IN': '169', 'Warren County, IN': '171', 'Warrick County, IN': '173', 'Washington County, IN': '175', 'Wayne County, IN': '177', 'Wells County, IN': '179', 'White County, IN': '181', 'Whitley County, IN': '183'}, 19: {'--All--': '%', 'Adair County, IA': '001', 'Adams County, IA': '003', 'Allamakee County, IA': '005', 'Appanoose County, IA': '007', 'Audubon County, IA': '009', 'Benton County, IA': '011', 'Black Hawk County, IA': '013', 'Boone County, IA': '015', 'Bremer County, IA': '017', 'Buchanan County, IA': '019', 'Buena Vista County, IA': '021', 'Butler County, IA': '023', 'Calhoun County, IA': '025', 'Carroll County, IA': '027', 'Cass County, IA': '029', 'Cedar County, IA': '031', 'Cerro Gordo County, IA': '033', 'Cherokee County, IA': '035', 'Chickasaw County, IA': '037', 'Clarke County, IA': '039', 'Clay County, IA': '041', 'Clayton County, IA': '043', 'Clinton County, IA': '045', 'Crawford County, IA': '047', 'Dallas County, IA': '049', 'Davis County, IA': '051', 'Decatur County, IA': '053', 'Delaware County, IA': '055', 'Des Moines County, IA': '057', 'Dickinson County, IA': '059', 'Dubuque County, IA': '061', 'Emmet County, IA': '063', 'Fayette County, IA': '065', 'Floyd County, IA': '067', 'Franklin County, IA': '069', 'Fremont County, IA': '071', 'Greene County, IA': '073', 'Grundy County, IA': '075', 'Guthrie County, IA': '077', 'Hamilton County, IA': '079', 'Hancock County, IA': '081', 'Hardin County, IA': '083', 'Harrison County, IA': '085', 'Henry County, IA': '087', 'Howard County, IA': '089', 'Humboldt County, IA': '091', 'Ida County, IA': '093', 'Iowa County, IA': '095', 'Jackson County, IA': '097', 'Jasper County, IA': '099', 'Jefferson County, IA': '101', 'Johnson County, IA': '103', 'Jones County, IA': '105', 'Keokuk County, IA': '107', 'Kossuth County, IA': '109', 'Lee County, IA': '111', 'Linn County, IA': '113', 'Louisa County, IA': '115', 'Lucas County, IA': '117', 'Lyon County, IA': '119', 'Madison County, IA': '121', 'Mahaska County, IA': '123', 'Marion County, IA': '125', 'Marshall County, IA': '127', 'Mills County, IA': '129', 'Mitchell County, IA': '131', 'Monona County, IA': '133', 'Monroe County, IA': '135', 'Montgomery County, IA': '137', 'Muscatine County, IA': '139', "O'Brien County, IA": '141', 'Osceola County, IA': '143', 'Page County, IA': '145', 'Palo Alto County, IA': '147', 'Plymouth County, IA': '149', 'Pocahontas County, IA': '151', 'Polk County, IA': '153', 'Pottawattamie County, IA': '155', 'Poweshiek County, IA': '157', 'Ringgold County, IA': '159', 'Sac County, IA': '161', 'Scott County, IA': '163', 'Shelby County, IA': '165', 'Sioux County, IA': '167', 'Story County, IA': '169', 'Tama County, IA': '171', 'Taylor County, IA': '173', 'Union County, IA': '175', 'Van Buren County, IA': '177', 'Wapello County, IA': '179', 'Warren County, IA': '181', 'Washington County, IA': '183', 'Wayne County, IA': '185', 'Webster County, IA': '187', 'Winnebago County, IA': '189', 'Winneshiek County, IA': '191', 'Woodbury County, IA': '193', 'Worth County, IA': '195', 'Wright County, IA': '197'}, 20: {'--All--': '%', 'Allen County, KS': '001', 'Anderson County, KS': '003', 'Atchison County, KS': '005', 'Barber County, KS': '007', 'Barton County, KS': '009', 'Bourbon County, KS': '011', 'Brown County, KS': '013', 'Butler County, KS': '015', 'Chase County, KS': '017', 'Chautauqua County, KS': '019', 'Cherokee County, KS': '021', 'Cheyenne County, KS': '023', 'Clark County, KS': '025', 'Clay County, KS': '027', 'Cloud County, KS': '029', 'Coffey County, KS': '031', 'Comanche County, KS': '033', 'Cowley County, KS': '035', 'Crawford County, KS': '037', 'Decatur County, KS': '039', 'Dickinson County, KS': '041', 'Doniphan County, KS': '043', 'Douglas County, KS': '045', 'Edwards County, KS': '047', 'Elk County, KS': '049', 'Ellis County, KS': '051', 'Ellsworth County, KS': '053', 'Finney County, KS': '055', 'Ford County, KS': '057', 'Franklin County, KS': '059', 'Geary County, KS': '061', 'Gove County, KS': '063', 'Graham County, KS': '065', 'Grant County, KS': '067', 'Gray County, KS': '069', 'Greeley County, KS': '071', 'Greenwood County, KS': '073', 'Hamilton County, KS': '075', 'Harper County, KS': '077', 'Harvey County, KS': '079', 'Haskell County, KS': '081', 'Hodgeman County, KS': '083', 'Jackson County, KS': '085', 'Jefferson County, KS': '087', 'Jewell County, KS': '089', 'Johnson County, KS': '091', 'Kearny County, KS': '093', 'Kingman County, KS': '095', 'Kiowa County, KS': '097', 'Labette County, KS': '099', 'Lane County, KS': '101', 'Leavenworth County, KS': '103', 'Lincoln County, KS': '105', 'Linn County, KS': '107', 'Logan County, KS': '109', 'Lyon County, KS': '111', 'Marion County, KS': '115', 'Marshall County, KS': '117', 'McPherson County, KS': '113', 'Meade County, KS': '119', 'Miami County, KS': '121', 'Mitchell County, KS': '123', 'Montgomery County, KS': '125', 'Morris County, KS': '127', 'Morton County, KS': '129', 'Nemaha County, KS': '131', 'Neosho County, KS': '133', 'Ness County, KS': '135', 'Norton County, KS': '137', 'Osage County, KS': '139', 'Osborne County, KS': '141', 'Ottawa County, KS': '143', 'Pawnee County, KS': '145', 'Phillips County, KS': '147', 'Pottawatomie County, KS': '149', 'Pratt County, KS': '151', 'Rawlins County, KS': '153', 'Reno County, KS': '155', 'Republic County, KS': '157', 'Rice County, KS': '159', 'Riley County, KS': '161', 'Rooks County, KS': '163', 'Rush County, KS': '165', 'Russell County, KS': '167', 'Saline County, KS': '169', 'Scott County, KS': '171', 'Sedgwick County, KS': '173', 'Seward County, KS': '175', 'Shawnee County, KS': '177', 'Sheridan County, KS': '179', 'Sherman County, KS': '181', 'Smith County, KS': '183', 'Stafford County, KS': '185', 'Stanton County, KS': '187', 'Stevens County, KS': '189', 'Sumner County, KS': '191', 'Thomas County, KS': '193', 'Trego County, KS': '195', 'Wabaunsee County, KS': '197', 'Wallace County, KS': '199', 'Washington County, KS': '201', 'Wichita County, KS': '203', 'Wilson County, KS': '205', 'Woodson County, KS': '207', 'Wyandotte County, KS': '209'}, 21: {'--All--': '%', 'Adair County, KY': '001', 'Allen County, KY': '003', 'Anderson County, KY': '005', 'Ballard County, KY': '007', 'Barren County, KY': '009', 'Bath County, KY': '011', 'Bell County, KY': '013', 'Boone County, KY': '015', 'Bourbon County, KY': '017', 'Boyd County, KY': '019', 'Boyle County, KY': '021', 'Bracken County, KY': '023', 'Breathitt County, KY': '025', 'Breckinridge County, KY': '027', 'Bullitt County, KY': '029', 'Butler County, KY': '031', 'Caldwell County, KY': '033', 'Calloway County, KY': '035', 'Campbell County, KY': '037', 'Carlisle County, KY': '039', 'Carroll County, KY': '041', 'Carter County, KY': '043', 'Casey County, KY': '045', 'Christian County, KY': '047', 'Clark County, KY': '049', 'Clay County, KY': '051', 'Clinton County, KY': '053', 'Crittenden County, KY': '055', 'Cumberland County, KY': '057', 'Daviess County, KY': '059', 'Edmonson County, KY': '061', 'Elliott County, KY': '063', 'Estill County, KY': '065', 'Fayette County, KY': '067', 'Fleming County, KY': '069', 'Floyd County, KY': '071', 'Franklin County, KY': '073', 'Fulton County, KY': '075', 'Gallatin County, KY': '077', 'Garrard County, KY': '079', 'Grant County, KY': '081', 'Graves County, KY': '083', 'Grayson County, KY': '085', 'Green County, KY': '087', 'Greenup County, KY': '089', 'Hancock County, KY': '091', 'Hardin County, KY': '093', 'Harlan County, KY': '095', 'Harrison County, KY': '097', 'Hart County, KY': '099', 'Henderson County, KY': '101', 'Henry County, KY': '103', 'Hickman County, KY': '105', 'Hopkins County, KY': '107', 'Jackson County, KY': '109', 'Jefferson County, KY': '111', 'Jessamine County, KY': '113', 'Johnson County, KY': '115', 'Kenton County, KY': '117', 'Knott County, KY': '119', 'Knox County, KY': '121', 'Larue County, KY': '123', 'Laurel County, KY': '125', 'Lawrence County, KY': '127', 'Lee County, KY': '129', 'Leslie County, KY': '131', 'Letcher County, KY': '133', 'Lewis County, KY': '135', 'Lincoln County, KY': '137', 'Livingston County, KY': '139', 'Logan County, KY': '141', 'Lyon County, KY': '143', 'Madison County, KY': '151', 'Magoffin County, KY': '153', 'Marion County, KY': '155', 'Marshall County, KY': '157', 'Martin County, KY': '159', 'Mason County, KY': '161', 'McCracken County, KY': '145', 'McCreary County, KY': '147', 'McLean County, KY': '149', 'Meade County, KY': '163', 'Menifee County, KY': '165', 'Mercer County, KY': '167', 'Metcalfe County, KY': '169', 'Monroe County, KY': '171', 'Montgomery County, KY': '173', 'Morgan County, KY': '175', 'Muhlenberg County, KY': '177', 'Nelson County, KY': '179', 'Nicholas County, KY': '181', 'Ohio County, KY': '183', 'Oldham County, KY': '185', 'Owen County, KY': '187', 'Owsley County, KY': '189', 'Pendleton County, KY': '191', 'Perry County, KY': '193', 'Pike County, KY': '195', 'Powell County, KY': '197', 'Pulaski County, KY': '199', 'Robertson County, KY': '201', 'Rockcastle County, KY': '203', 'Rowan County, KY': '205', 'Russell County, KY': '207', 'Scott County, KY': '209', 'Shelby County, KY': '211', 'Simpson County, KY': '213', 'Spencer County, KY': '215', 'Taylor County, KY': '217', 'Todd County, KY': '219', 'Trigg County, KY': '221', 'Trimble County, KY': '223', 'Union County, KY': '225', 'Warren County, KY': '227', 'Washington County, KY': '229', 'Wayne County, KY': '231', 'Webster County, KY': '233', 'Whitley County, KY': '235', 'Wolfe County, KY': '237', 'Woodford County, KY': '239'}, 22: {'--All--': '%', 'Acadia Parish, LA': '001', 'Allen Parish, LA': '003', 'Ascension Parish, LA': '005', 'Assumption Parish, LA': '007', 'Avoyelles Parish, LA': '009', 'Beauregard Parish, LA': '011', 'Bienville Parish, LA': '013', 'Bossier Parish, LA': '015', 'Caddo Parish, LA': '017', 'Calcasieu Parish, LA': '019', 'Caldwell Parish, LA': '021', 'Cameron Parish, LA': '023', 'Catahoula Parish, LA': '025', 'Claiborne Parish, LA': '027', 'Concordia Parish, LA': '029', 'De Soto Parish, LA': '031', 'East Baton Rouge Parish, LA': '033', 'East Carroll Parish, LA': '035', 'East Feliciana Parish, LA': '037', 'Evangeline Parish, LA': '039', 'Franklin Parish, LA': '041', 'Grant Parish, LA': '043', 'Iberia Parish, LA': '045', 'Iberville Parish, LA': '047', 'Jackson Parish, LA': '049', 'Jefferson Davis Parish, LA': '053', 'Jefferson Parish, LA': '051', 'La Salle Parish, LA': '059', 'Lafayette Parish, LA': '055', 'Lafourche Parish, LA': '057', 'Lincoln Parish, LA': '061', 'Livingston Parish, LA': '063', 'Madison Parish, LA': '065', 'Morehouse Parish, LA': '067', 'Natchitoches Parish, LA': '069', 'Orleans Parish, LA': '071', 'Ouachita Parish, LA': '073', 'Plaquemines Parish, LA': '075', 'Pointe Coupee Parish, LA': '077', 'Rapides Parish, LA': '079', 'Red River Parish, LA': '081', 'Richland Parish, LA': '083', 'Sabine Parish, LA': '085', 'St. Bernard Parish, LA': '087', 'St. Charles Parish, LA': '089', 'St. Helena Parish, LA': '091', 'St. James Parish, LA': '093', 'St. John the Baptist Parish, LA': '095', 'St. Landry Parish, LA': '097', 'St. Martin Parish, LA': '099', 'St. Mary Parish, LA': '101', 'St. Tammany Parish, LA': '103', 'Tangipahoa Parish, LA': '105', 'Tensas Parish, LA': '107', 'Terrebonne Parish, LA': '109', 'Union Parish, LA': '111', 'Vermilion Parish, LA': '113', 'Vernon Parish, LA': '115', 'Washington Parish, LA': '117', 'Webster Parish, LA': '119', 'West Baton Rouge Parish, LA': '121', 'West Carroll Parish, LA': '123', 'West Feliciana Parish, LA': '125', 'Winn Parish, LA': '127'}, 23: {'--All--': '%', 'Androscoggin County, ME': '001', 'Aroostook County, ME': '003', 'Cumberland County, ME': '005', 'Franklin County, ME': '007', 'Hancock County, ME': '009', 'Kennebec County, ME': '011', 'Knox County, ME': '013', 'Lincoln County, ME': '015', 'Oxford County, ME': '017', 'Penobscot County, ME': '019', 'Piscataquis County, ME': '021', 'Sagadahoc County, ME': '023', 'Somerset County, ME': '025', 'Waldo County, ME': '027', 'Washington County, ME': '029', 'York County, ME': '031'}, 24: {'--All--': '%', 'Allegany County, MD': '001', 'Anne Arundel County, MD': '003', 'Baltimore County, MD': '005', 'Baltimore city, MD': '510', 'Calvert County, MD': '009', 'Caroline County, MD': '011', 'Carroll County, MD': '013', 'Cecil County, MD': '015', 'Charles County, MD': '017', 'Dorchester County, MD': '019', 'Frederick County, MD': '021', 'Garrett County, MD': '023', 'Harford County, MD': '025', 'Howard County, MD': '027', 'Kent County, MD': '029', 'Montgomery County, MD': '031', "Prince George's County, MD": '033', "Queen Anne's County, MD": '035', 'Somerset County, MD': '039', "St. Mary's County, MD": '037', 'Talbot County, MD': '041', 'Washington County, MD': '043', 'Wicomico County, MD': '045', 'Worcester County, MD': '047'}, 25: {'--All--': '%', 'Barnstable County, MA': '001', 'Berkshire County, MA': '003', 'Bristol County, MA': '005', 'Dukes County, MA': '007', 'Essex County, MA': '009', 'Franklin County, MA': '011', 'Hampden County, MA': '013', 'Hampshire County, MA': '015', 'Middlesex County, MA': '017', 'Nantucket County/town, MA': '019', 'Norfolk County, MA': '021', 'Plymouth County, MA': '023', 'Suffolk County, MA': '025', 'Worcester County, MA': '027'}, 26: {'--All--': '%', 'Alcona County, MI': '001', 'Alger County, MI': '003', 'Allegan County, MI': '005', 'Alpena County, MI': '007', 'Antrim County, MI': '009', 'Arenac County, MI': '011', 'Baraga County, MI': '013', 'Barry County, MI': '015', 'Bay County, MI': '017', 'Benzie County, MI': '019', 'Berrien County, MI': '021', 'Branch County, MI': '023', 'Calhoun County, MI': '025', 'Cass County, MI': '027', 'Charlevoix County, MI': '029', 'Cheboygan County, MI': '031', 'Chippewa County, MI': '033', 'Clare County, MI': '035', 'Clinton County, MI': '037', 'Crawford County, MI': '039', 'Delta County, MI': '041', 'Dickinson County, MI': '043', 'Eaton County, MI': '045', 'Emmet County, MI': '047', 'Genesee County, MI': '049', 'Gladwin County, MI': '051', 'Gogebic County, MI': '053', 'Grand Traverse County, MI': '055', 'Gratiot County, MI': '057', 'Hillsdale County, MI': '059', 'Houghton County, MI': '061', 'Huron County, MI': '063', 'Ingham County, MI': '065', 'Ionia County, MI': '067', 'Iosco County, MI': '069', 'Iron County, MI': '071', 'Isabella County, MI': '073', 'Jackson County, MI': '075', 'Kalamazoo County, MI': '077', 'Kalkaska County, MI': '079', 'Kent County, MI': '081', 'Keweenaw County, MI': '083', 'Lake County, MI': '085', 'Lapeer County, MI': '087', 'Leelanau County, MI': '089', 'Lenawee County, MI': '091', 'Livingston County, MI': '093', 'Luce County, MI': '095', 'Mackinac County, MI': '097', 'Macomb County, MI': '099', 'Manistee County, MI': '101', 'Marquette County, MI': '103', 'Mason County, MI': '105', 'Mecosta County, MI': '107', 'Menominee County, MI': '109', 'Midland County, MI': '111', 'Missaukee County, MI': '113', 'Monroe County, MI': '115', 'Montcalm County, MI': '117', 'Montmorency County, MI': '119', 'Muskegon County, MI': '121', 'Newaygo County, MI': '123', 'Oakland County, MI': '125', 'Oceana County, MI': '127', 'Ogemaw County, MI': '129', 'Ontonagon County, MI': '131', 'Osceola County, MI': '133', 'Oscoda County, MI': '135', 'Otsego County, MI': '137', 'Ottawa County, MI': '139', 'Presque Isle County, MI': '141', 'Roscommon County, MI': '143', 'Saginaw County, MI': '145', 'Sanilac County, MI': '151', 'Schoolcraft County, MI': '153', 'Shiawassee County, MI': '155', 'St. Clair County, MI': '147', 'St. Joseph County, MI': '149', 'Tuscola County, MI': '157', 'Van Buren County, MI': '159', 'Washtenaw County, MI': '161', 'Wayne County, MI': '163', 'Wexford County, MI': '165'}, 27: {'--All--': '%', 'Aitkin County, MN': '001', 'Anoka County, MN': '003', 'Becker County, MN': '005', 'Beltrami County, MN': '007', 'Benton County, MN': '009', 'Big Stone County, MN': '011', 'Blue Earth County, MN': '013', 'Brown County, MN': '015', 'Carlton County, MN': '017', 'Carver County, MN': '019', 'Cass County, MN': '021', 'Chippewa County, MN': '023', 'Chisago County, MN': '025', 'Clay County, MN': '027', 'Clearwater County, MN': '029', 'Cook County, MN': '031', 'Cottonwood County, MN': '033', 'Crow Wing County, MN': '035', 'Dakota County, MN': '037', 'Dodge County, MN': '039', 'Douglas County, MN': '041', 'Faribault County, MN': '043', 'Fillmore County, MN': '045', 'Freeborn County, MN': '047', 'Goodhue County, MN': '049', 'Grant County, MN': '051', 'Hennepin County, MN': '053', 'Houston County, MN': '055', 'Hubbard County, MN': '057', 'Isanti County, MN': '059', 'Itasca County, MN': '061', 'Jackson County, MN': '063', 'Kanabec County, MN': '065', 'Kandiyohi County, MN': '067', 'Kittson County, MN': '069', 'Koochiching County, MN': '071', 'Lac qui Parle County, MN': '073', 'Lake County, MN': '075', 'Lake of the Woods County, MN': '077', 'Le Sueur County, MN': '079', 'Lincoln County, MN': '081', 'Lyon County, MN': '083', 'Mahnomen County, MN': '087', 'Marshall County, MN': '089', 'Martin County, MN': '091', 'McLeod County, MN': '085', 'Meeker County, MN': '093', 'Mille Lacs County, MN': '095', 'Morrison County, MN': '097', 'Mower County, MN': '099', 'Murray County, MN': '101', 'Nicollet County, MN': '103', 'Nobles County, MN': '105', 'Norman County, MN': '107', 'Olmsted County, MN': '109', 'Otter Tail County, MN': '111', 'Pennington County, MN': '113', 'Pine County, MN': '115', 'Pipestone County, MN': '117', 'Polk County, MN': '119', 'Pope County, MN': '121', 'Ramsey County, MN': '123', 'Red Lake County, MN': '125', 'Redwood County, MN': '127', 'Renville County, MN': '129', 'Rice County, MN': '131', 'Rock County, MN': '133', 'Roseau County, MN': '135', 'Scott County, MN': '139', 'Sherburne County, MN': '141', 'Sibley County, MN': '143', 'St. Louis County, MN': '137', 'Stearns County, MN': '145', 'Steele County, MN': '147', 'Stevens County, MN': '149', 'Swift County, MN': '151', 'Todd County, MN': '153', 'Traverse County, MN': '155', 'Wabasha County, MN': '157', 'Wadena County, MN': '159', 'Waseca County, MN': '161', 'Washington County, MN': '163', 'Watonwan County, MN': '165', 'Wilkin County, MN': '167', 'Winona County, MN': '169', 'Wright County, MN': '171', 'Yellow Medicine County, MN': '173'}, 28: {'--All--': '%', 'Adams County, MS': '001', 'Alcorn County, MS': '003', 'Amite County, MS': '005', 'Attala County, MS': '007', 'Benton County, MS': '009', 'Bolivar County, MS': '011', 'Calhoun County, MS': '013', 'Carroll County, MS': '015', 'Chickasaw County, MS': '017', 'Choctaw County, MS': '019', 'Claiborne County, MS': '021', 'Clarke County, MS': '023', 'Clay County, MS': '025', 'Coahoma County, MS': '027', 'Copiah County, MS': '029', 'Covington County, MS': '031', 'DeSoto County, MS': '033', 'Forrest County, MS': '035', 'Franklin County, MS': '037', 'George County, MS': '039', 'Greene County, MS': '041', 'Grenada County, MS': '043', 'Hancock County, MS': '045', 'Harrison County, MS': '047', 'Hinds County, MS': '049', 'Holmes County, MS': '051', 'Humphreys County, MS': '053', 'Issaquena County, MS': '055', 'Itawamba County, MS': '057', 'Jackson County, MS': '059', 'Jasper County, MS': '061', 'Jefferson County, MS': '063', 'Jefferson Davis County, MS': '065', 'Jones County, MS': '067', 'Kemper County, MS': '069', 'Lafayette County, MS': '071', 'Lamar County, MS': '073', 'Lauderdale County, MS': '075', 'Lawrence County, MS': '077', 'Leake County, MS': '079', 'Lee County, MS': '081', 'Leflore County, MS': '083', 'Lincoln County, MS': '085', 'Lowndes County, MS': '087', 'Madison County, MS': '089', 'Marion County, MS': '091', 'Marshall County, MS': '093', 'Monroe County, MS': '095', 'Montgomery County, MS': '097', 'Neshoba County, MS': '099', 'Newton County, MS': '101', 'Noxubee County, MS': '103', 'Oktibbeha County, MS': '105', 'Panola County, MS': '107', 'Pearl River County, MS': '109', 'Perry County, MS': '111', 'Pike County, MS': '113', 'Pontotoc County, MS': '115', 'Prentiss County, MS': '117', 'Quitman County, MS': '119', 'Rankin County, MS': '121', 'Scott County, MS': '123', 'Sharkey County, MS': '125', 'Simpson County, MS': '127', 'Smith County, MS': '129', 'Stone County, MS': '131', 'Sunflower County, MS': '133', 'Tallahatchie County, MS': '135', 'Tate County, MS': '137', 'Tippah County, MS': '139', 'Tishomingo County, MS': '141', 'Tunica County, MS': '143', 'Union County, MS': '145', 'Walthall County, MS': '147', 'Warren County, MS': '149', 'Washington County, MS': '151', 'Wayne County, MS': '153', 'Webster County, MS': '155', 'Wilkinson County, MS': '157', 'Winston County, MS': '159', 'Yalobusha County, MS': '161', 'Yazoo County, MS': '163'}, 29: {'--All--': '%', 'Adair County, MO': '001', 'Andrew County, MO': '003', 'Atchison County, MO': '005', 'Audrain County, MO': '007', 'Barry County, MO': '009', 'Barton County, MO': '011', 'Bates County, MO': '013', 'Benton County, MO': '015', 'Bollinger County, MO': '017', 'Boone County, MO': '019', 'Buchanan County, MO': '021', 'Butler County, MO': '023', 'Caldwell County, MO': '025', 'Callaway County, MO': '027', 'Camden County, MO': '029', 'Cape Girardeau County, MO': '031', 'Carroll County, MO': '033', 'Carter County, MO': '035', 'Cass County, MO': '037', 'Cedar County, MO': '039', 'Chariton County, MO': '041', 'Christian County, MO': '043', 'Clark County, MO': '045', 'Clay County, MO': '047', 'Clinton County, MO': '049', 'Cole County, MO': '051', 'Cooper County, MO': '053', 'Crawford County, MO': '055', 'Dade County, MO': '057', 'Dallas County, MO': '059', 'Daviess County, MO': '061', 'DeKalb County, MO': '063', 'Dent County, MO': '065', 'Douglas County, MO': '067', 'Dunklin County, MO': '069', 'Franklin County, MO': '071', 'Gasconade County, MO': '073', 'Gentry County, MO': '075', 'Greene County, MO': '077', 'Grundy County, MO': '079', 'Harrison County, MO': '081', 'Henry County, MO': '083', 'Hickory County, MO': '085', 'Holt County, MO': '087', 'Howard County, MO': '089', 'Howell County, MO': '091', 'Iron County, MO': '093', 'Jackson County, MO': '095', 'Jasper County, MO': '097', 'Jefferson County, MO': '099', 'Johnson County, MO': '101', 'Knox County, MO': '103', 'Laclede County, MO': '105', 'Lafayette County, MO': '107', 'Lawrence County, MO': '109', 'Lewis County, MO': '111', 'Lincoln County, MO': '113', 'Linn County, MO': '115', 'Livingston County, MO': '117', 'Macon County, MO': '121', 'Madison County, MO': '123', 'Maries County, MO': '125', 'Marion County, MO': '127', 'McDonald County, MO': '119', 'Mercer County, MO': '129', 'Miller County, MO': '131', 'Mississippi County, MO': '133', 'Moniteau County, MO': '135', 'Monroe County, MO': '137', 'Montgomery County, MO': '139', 'Morgan County, MO': '141', 'New Madrid County, MO': '143', 'Newton County, MO': '145', 'Nodaway County, MO': '147', 'Oregon County, MO': '149', 'Osage County, MO': '151', 'Ozark County, MO': '153', 'Pemiscot County, MO': '155', 'Perry County, MO': '157', 'Pettis County, MO': '159', 'Phelps County, MO': '161', 'Pike County, MO': '163', 'Platte County, MO': '165', 'Polk County, MO': '167', 'Pulaski County, MO': '169', 'Putnam County, MO': '171', 'Ralls County, MO': '173', 'Randolph County, MO': '175', 'Ray County, MO': '177', 'Reynolds County, MO': '179', 'Ripley County, MO': '181', 'Saline County, MO': '195', 'Schuyler County, MO': '197', 'Scotland County, MO': '199', 'Scott County, MO': '201', 'Shannon County, MO': '203', 'Shelby County, MO': '205', 'St. Charles County, MO': '183', 'St. Clair County, MO': '185', 'St. Francois County, MO': '187', 'St. Louis County, MO': '189', 'St. Louis city, MO': '510', 'Ste. Genevieve County, MO': '186', 'Stoddard County, MO': '207', 'Stone County, MO': '209', 'Sullivan County, MO': '211', 'Taney County, MO': '213', 'Texas County, MO': '215', 'Vernon County, MO': '217', 'Warren County, MO': '219', 'Washington County, MO': '221', 'Wayne County, MO': '223', 'Webster County, MO': '225', 'Worth County, MO': '227', 'Wright County, MO': '229'}, 30: {'--All--': '%', 'Beaverhead County, MT': '001', 'Big Horn County, MT': '003', 'Blaine County, MT': '005', 'Broadwater County, MT': '007', 'Carbon County, MT': '009', 'Carter County, MT': '011', 'Cascade County, MT': '013', 'Chouteau County, MT': '015', 'Custer County, MT': '017', 'Daniels County, MT': '019', 'Dawson County, MT': '021', 'Deer Lodge County, MT': '023', 'Fallon County, MT': '025', 'Fergus County, MT': '027', 'Flathead County, MT': '029', 'Gallatin County, MT': '031', 'Garfield County, MT': '033', 'Glacier County, MT': '035', 'Golden Valley County, MT': '037', 'Granite County, MT': '039', 'Hill County, MT': '041', 'Jefferson County, MT': '043', 'Judith Basin County, MT': '045', 'Lake County, MT': '047', 'Lewis and Clark County, MT': '049', 'Liberty County, MT': '051', 'Lincoln County, MT': '053', 'Madison County, MT': '057', 'McCone County, MT': '055', 'Meagher County, MT': '059', 'Mineral County, MT': '061', 'Missoula County, MT': '063', 'Musselshell County, MT': '065', 'Park County, MT': '067', 'Petroleum County, MT': '069', 'Phillips County, MT': '071', 'Pondera County, MT': '073', 'Powder River County, MT': '075', 'Powell County, MT': '077', 'Prairie County, MT': '079', 'Ravalli County, MT': '081', 'Richland County, MT': '083', 'Roosevelt County, MT': '085', 'Rosebud County, MT': '087', 'Sanders County, MT': '089', 'Sheridan County, MT': '091', 'Silver Bow County, MT': '093', 'Stillwater County, MT': '095', 'Sweet Grass County, MT': '097', 'Teton County, MT': '099', 'Toole County, MT': '101', 'Treasure County, MT': '103', 'Valley County, MT': '105', 'Wheatland County, MT': '107', 'Wibaux County, MT': '109', 'Yellowstone County, MT': '111'}, 31: {'--All--': '%', 'Adams County, NE': '001', 'Antelope County, NE': '003', 'Arthur County, NE': '005', 'Banner County, NE': '007', 'Blaine County, NE': '009', 'Boone County, NE': '011', 'Box Butte County, NE': '013', 'Boyd County, NE': '015', 'Brown County, NE': '017', 'Buffalo County, NE': '019', 'Burt County, NE': '021', 'Butler County, NE': '023', 'Cass County, NE': '025', 'Cedar County, NE': '027', 'Chase County, NE': '029', 'Cherry County, NE': '031', 'Cheyenne County, NE': '033', 'Clay County, NE': '035', 'Colfax County, NE': '037', 'Cuming County, NE': '039', 'Custer County, NE': '041', 'Dakota County, NE': '043', 'Dawes County, NE': '045', 'Dawson County, NE': '047', 'Deuel County, NE': '049', 'Dixon County, NE': '051', 'Dodge County, NE': '053', 'Douglas County, NE': '055', 'Dundy County, NE': '057', 'Fillmore County, NE': '059', 'Franklin County, NE': '061', 'Frontier County, NE': '063', 'Furnas County, NE': '065', 'Gage County, NE': '067', 'Garden County, NE': '069', 'Garfield County, NE': '071', 'Gosper County, NE': '073', 'Grant County, NE': '075', 'Greeley County, NE': '077', 'Hall County, NE': '079', 'Hamilton County, NE': '081', 'Harlan County, NE': '083', 'Hayes County, NE': '085', 'Hitchcock County, NE': '087', 'Holt County, NE': '089', 'Hooker County, NE': '091', 'Howard County, NE': '093', 'Jefferson County, NE': '095', 'Johnson County, NE': '097', 'Kearney County, NE': '099', 'Keith County, NE': '101', 'Keya Paha County, NE': '103', 'Kimball County, NE': '105', 'Knox County, NE': '107', 'Lancaster County, NE': '109', 'Lincoln County, NE': '111', 'Logan County, NE': '113', 'Loup County, NE': '115', 'Madison County, NE': '119', 'McPherson County, NE': '117', 'Merrick County, NE': '121', 'Morrill County, NE': '123', 'Nance County, NE': '125', 'Nemaha County, NE': '127', 'Nuckolls County, NE': '129', 'Otoe County, NE': '131', 'Pawnee County, NE': '133', 'Perkins County, NE': '135', 'Phelps County, NE': '137', 'Pierce County, NE': '139', 'Platte County, NE': '141', 'Polk County, NE': '143', 'Red Willow County, NE': '145', 'Richardson County, NE': '147', 'Rock County, NE': '149', 'Saline County, NE': '151', 'Sarpy County, NE': '153', 'Saunders County, NE': '155', 'Scotts Bluff County, NE': '157', 'Seward County, NE': '159', 'Sheridan County, NE': '161', 'Sherman County, NE': '163', 'Sioux County, NE': '165', 'Stanton County, NE': '167', 'Thayer County, NE': '169', 'Thomas County, NE': '171', 'Thurston County, NE': '173', 'Valley County, NE': '175', 'Washington County, NE': '177', 'Wayne County, NE': '179', 'Webster County, NE': '181', 'Wheeler County, NE': '183', 'York County, NE': '185'}, 32: {'--All--': '%', 'Carson City, NV': '510', 'Churchill County, NV': '001', 'Clark County, NV': '003', 'Douglas County, NV': '005', 'Elko County, NV': '007', 'Esmeralda County, NV': '009', 'Eureka County, NV': '011', 'Humboldt County, NV': '013', 'Lander County, NV': '015', 'Lincoln County, NV': '017', 'Lyon County, NV': '019', 'Mineral County, NV': '021', 'Nye County, NV': '023', 'Pershing County, NV': '027', 'Storey County, NV': '029', 'Washoe County, NV': '031', 'White Pine County, NV': '033'}, 33: {'--All--': '%', 'Belknap County, NH': '001', 'Carroll County, NH': '003', 'Cheshire County, NH': '005', 'Coos County, NH': '007', 'Grafton County, NH': '009', 'Hillsborough County, NH': '011', 'Merrimack County, NH': '013', 'Rockingham County, NH': '015', 'Strafford County, NH': '017', 'Sullivan County, NH': '019'}, 34: {'--All--': '%', 'Atlantic County, NJ': '001', 'Bergen County, NJ': '003', 'Burlington County, NJ': '005', 'Camden County, NJ': '007', 'Cape May County, NJ': '009', 'Cumberland County, NJ': '011', 'Essex County, NJ': '013', 'Gloucester County, NJ': '015', 'Hudson County, NJ': '017', 'Hunterdon County, NJ': '019', 'Mercer County, NJ': '021', 'Middlesex County, NJ': '023', 'Monmouth County, NJ': '025', 'Morris County, NJ': '027', 'Ocean County, NJ': '029', 'Passaic County, NJ': '031', 'Salem County, NJ': '033', 'Somerset County, NJ': '035', 'Sussex County, NJ': '037', 'Union County, NJ': '039', 'Warren County, NJ': '041'}, 35: {'--All--': '%', 'Bernalillo County, NM': '001', 'Catron County, NM': '003', 'Chaves County, NM': '005', 'Cibola County, NM': '006', 'Colfax County, NM': '007', 'Curry County, NM': '009', 'DeBaca County, NM': '011', 'Dona Ana County, NM': '013', 'Eddy County, NM': '015', 'Grant County, NM': '017', 'Guadalupe County, NM': '019', 'Harding County, NM': '021', 'Hidalgo County, NM': '023', 'Lea County, NM': '025', 'Lincoln County, NM': '027', 'Los Alamos County, NM': '028', 'Luna County, NM': '029', 'McKinley County, NM': '031', 'Mora County, NM': '033', 'Otero County, NM': '035', 'Quay County, NM': '037', 'Rio Arriba County, NM': '039', 'Roosevelt County, NM': '041', 'San Juan County, NM': '045', 'San Miguel County, NM': '047', 'Sandoval County, NM': '043', 'Santa Fe County, NM': '049', 'Sierra County, NM': '051', 'Socorro County, NM': '053', 'Taos County, NM': '055', 'Torrance County, NM': '057', 'Union County, NM': '059', 'Valencia County, NM': '061'}, 36: {'--All--': '%', 'Albany County, NY': '001', 'Allegany County, NY': '003', 'Bronx County, NY': '005', 'Broome County, NY': '007', 'Cattaraugus County, NY': '009', 'Cayuga County, NY': '011', 'Chautauqua County, NY': '013', 'Chemung County, NY': '015', 'Chenango County, NY': '017', 'Clinton County, NY': '019', 'Columbia County, NY': '021', 'Cortland County, NY': '023', 'Delaware County, NY': '025', 'Dutchess County, NY': '027', 'Erie County, NY': '029', 'Essex County, NY': '031', 'Franklin County, NY': '033', 'Fulton County, NY': '035', 'Genesee County, NY': '037', 'Greene County, NY': '039', 'Hamilton County, NY': '041', 'Herkimer County, NY': '043', 'Jefferson County, NY': '045', 'Kings County, NY': '047', 'Lewis County, NY': '049', 'Livingston County, NY': '051', 'Madison County, NY': '053', 'Monroe County, NY': '055', 'Montgomery County, NY': '057', 'Nassau County, NY': '059', 'New York County, NY': '061', 'Niagara County, NY': '063', 'Oneida County, NY': '065', 'Onondaga County, NY': '067', 'Ontario County, NY': '069', 'Orange County, NY': '071', 'Orleans County, NY': '073', 'Oswego County, NY': '075', 'Otsego County, NY': '077', 'Putnam County, NY': '079', 'Queens County, NY': '081', 'Rensselaer County, NY': '083', 'Richmond County, NY': '085', 'Rockland County, NY': '087', 'Saratoga County, NY': '091', 'Schenectady County, NY': '093', 'Schoharie County, NY': '095', 'Schuyler County, NY': '097', 'Seneca County, NY': '099', 'St. Lawrence County, NY': '089', 'Steuben County, NY': '101', 'Suffolk County, NY': '103', 'Sullivan County, NY': '105', 'Tioga County, NY': '107', 'Tompkins County, NY': '109', 'Ulster County, NY': '111', 'Warren County, NY': '113', 'Washington County, NY': '115', 'Wayne County, NY': '117', 'Westchester County, NY': '119', 'Wyoming County, NY': '121', 'Yates County, NY': '123'}, 37: {'--All--': '%', 'Alamance County, NC': '001', 'Alexander County, NC': '003', 'Alleghany County, NC': '005', 'Anson County, NC': '007', 'Ashe County, NC': '009', 'Avery County, NC': '011', 'Beaufort County, NC': '013', 'Bertie County, NC': '015', 'Bladen County, NC': '017', 'Brunswick County, NC': '019', 'Buncombe County, NC': '021', 'Burke County, NC': '023', 'Cabarrus County, NC': '025', 'Caldwell County, NC': '027', 'Camden County, NC': '029', 'Carteret County, NC': '031', 'Caswell County, NC': '033', 'Catawba County, NC': '035', 'Chatham County, NC': '037', 'Cherokee County, NC': '039', 'Chowan County, NC': '041', 'Clay County, NC': '043', 'Cleveland County, NC': '045', 'Columbus County, NC': '047', 'Craven County, NC': '049', 'Cumberland County, NC': '051', 'Currituck County, NC': '053', 'Dare County, NC': '055', 'Davidson County, NC': '057', 'Davie County, NC': '059', 'Duplin County, NC': '061', 'Durham County, NC': '063', 'Edgecombe County, NC': '065', 'Forsyth County, NC': '067', 'Franklin County, NC': '069', 'Gaston County, NC': '071', 'Gates County, NC': '073', 'Graham County, NC': '075', 'Granville County, NC': '077', 'Greene County, NC': '079', 'Guilford County, NC': '081', 'Halifax County, NC': '083', 'Harnett County, NC': '085', 'Haywood County, NC': '087', 'Henderson County, NC': '089', 'Hertford County, NC': '091', 'Hoke County, NC': '093', 'Hyde County, NC': '095', 'Iredell County, NC': '097', 'Jackson County, NC': '099', 'Johnston County, NC': '101', 'Jones County, NC': '103', 'Lee County, NC': '105', 'Lenoir County, NC': '107', 'Lincoln County, NC': '109', 'Macon County, NC': '113', 'Madison County, NC': '115', 'Martin County, NC': '117', 'McDowell County, NC': '111', 'Mecklenburg County, NC': '119', 'Mitchell County, NC': '121', 'Montgomery County, NC': '123', 'Moore County, NC': '125', 'Nash County, NC': '127', 'New Hanover County, NC': '129', 'Northampton County, NC': '131', 'Onslow County, NC': '133', 'Orange County, NC': '135', 'Pamlico County, NC': '137', 'Pasquotank County, NC': '139', 'Pender County, NC': '141', 'Perquimans County, NC': '143', 'Person County, NC': '145', 'Pitt County, NC': '147', 'Polk County, NC': '149', 'Randolph County, NC': '151', 'Richmond County, NC': '153', 'Robeson County, NC': '155', 'Rockingham County, NC': '157', 'Rowan County, NC': '159', 'Rutherford County, NC': '161', 'Sampson County, NC': '163', 'Scotland County, NC': '165', 'Stanly County, NC': '167', 'Stokes County, NC': '169', 'Surry County, NC': '171', 'Swain County, NC': '173', 'Transylvania County, NC': '175', 'Tyrrell County, NC': '177', 'Union County, NC': '179', 'Vance County, NC': '181', 'Wake County, NC': '183', 'Warren County, NC': '185', 'Washington County, NC': '187', 'Watauga County, NC': '189', 'Wayne County, NC': '191', 'Wilkes County, NC': '193', 'Wilson County, NC': '195', 'Yadkin County, NC': '197', 'Yancey County, NC': '199'}, 38: {'--All--': '%', 'Adams County, ND': '001', 'Barnes County, ND': '003', 'Benson County, ND': '005', 'Billings County, ND': '007', 'Bottineau County, ND': '009', 'Bowman County, ND': '011', 'Burke County, ND': '013', 'Burleigh County, ND': '015', 'Cass County, ND': '017', 'Cavalier County, ND': '019', 'Dickey County, ND': '021', 'Divide County, ND': '023', 'Dunn County, ND': '025', 'Eddy County, ND': '027', 'Emmons County, ND': '029', 'Foster County, ND': '031', 'Golden Valley County, ND': '033', 'Grand Forks County, ND': '035', 'Grant County, ND': '037', 'Griggs County, ND': '039', 'Hettinger County, ND': '041', 'Kidder County, ND': '043', 'LaMoure County, ND': '045', 'Logan County, ND': '047', 'McHenry County, ND': '049', 'McIntosh County, ND': '051', 'McKenzie County, ND': '053', 'McLean County, ND': '055', 'Mercer County, ND': '057', 'Morton County, ND': '059', 'Mountrail County, ND': '061', 'Nelson County, ND': '063', 'Oliver County, ND': '065', 'Pembina County, ND': '067', 'Pierce County, ND': '069', 'Ramsey County, ND': '071', 'Ransom County, ND': '073', 'Renville County, ND': '075', 'Richland County, ND': '077', 'Rolette County, ND': '079', 'Sargent County, ND': '081', 'Sheridan County, ND': '083', 'Sioux County, ND': '085', 'Slope County, ND': '087', 'Stark County, ND': '089', 'Steele County, ND': '091', 'Stutsman County, ND': '093', 'Towner County, ND': '095', 'Traill County, ND': '097', 'Walsh County, ND': '099', 'Ward County, ND': '101', 'Wells County, ND': '103', 'Williams County, ND': '105'}, 39: {'--All--': '%', 'Adams County, OH': '001', 'Allen County, OH': '003', 'Ashland County, OH': '005', 'Ashtabula County, OH': '007', 'Athens County, OH': '009', 'Auglaize County, OH': '011', 'Belmont County, OH': '013', 'Brown County, OH': '015', 'Butler County, OH': '017', 'Carroll County, OH': '019', 'Champaign County, OH': '021', 'Clark County, OH': '023', 'Clermont County, OH': '025', 'Clinton County, OH': '027', 'Columbiana County, OH': '029', 'Coshocton County, OH': '031', 'Crawford County, OH': '033', 'Cuyahoga County, OH': '035', 'Darke County, OH': '037', 'Defiance County, OH': '039', 'Delaware County, OH': '041', 'Erie County, OH': '043', 'Fairfield County, OH': '045', 'Fayette County, OH': '047', 'Franklin County, OH': '049', 'Fulton County, OH': '051', 'Gallia County, OH': '053', 'Geauga County, OH': '055', 'Greene County, OH': '057', 'Guernsey County, OH': '059', 'Hamilton County, OH': '061', 'Hancock County, OH': '063', 'Hardin County, OH': '065', 'Harrison County, OH': '067', 'Henry County, OH': '069', 'Highland County, OH': '071', 'Hocking County, OH': '073', 'Holmes County, OH': '075', 'Huron County, OH': '077', 'Jackson County, OH': '079', 'Jefferson County, OH': '081', 'Knox County, OH': '083', 'Lake County, OH': '085', 'Lawrence County, OH': '087', 'Licking County, OH': '089', 'Logan County, OH': '091', 'Lorain County, OH': '093', 'Lucas County, OH': '095', 'Madison County, OH': '097', 'Mahoning County, OH': '099', 'Marion County, OH': '101', 'Medina County, OH': '103', 'Meigs County, OH': '105', 'Mercer County, OH': '107', 'Miami County, OH': '109', 'Monroe County, OH': '111', 'Montgomery County, OH': '113', 'Morgan County, OH': '115', 'Morrow County, OH': '117', 'Muskingum County, OH': '119', 'Noble County, OH': '121', 'Ottawa County, OH': '123', 'Paulding County, OH': '125', 'Perry County, OH': '127', 'Pickaway County, OH': '129', 'Pike County, OH': '131', 'Portage County, OH': '133', 'Preble County, OH': '135', 'Putnam County, OH': '137', 'Richland County, OH': '139', 'Ross County, OH': '141', 'Sandusky County, OH': '143', 'Scioto County, OH': '145', 'Seneca County, OH': '147', 'Shelby County, OH': '149', 'Stark County, OH': '151', 'Summit County, OH': '153', 'Trumbull County, OH': '155', 'Tuscarawas County, OH': '157', 'Union County, OH': '159', 'Van Wert County, OH': '161', 'Vinton County, OH': '163', 'Warren County, OH': '165', 'Washington County, OH': '167', 'Wayne County, OH': '169', 'Williams County, OH': '171', 'Wood County, OH': '173', 'Wyandot County, OH': '175'}, 40: {'--All--': '%', 'Adair County, OK': '001', 'Alfalfa County, OK': '003', 'Atoka County, OK': '005', 'Beaver County, OK': '007', 'Beckham County, OK': '009', 'Blaine County, OK': '011', 'Bryan County, OK': '013', 'Caddo County, OK': '015', 'Canadian County, OK': '017', 'Carter County, OK': '019', 'Cherokee County, OK': '021', 'Choctaw County, OK': '023', 'Cimarron County, OK': '025', 'Cleveland County, OK': '027', 'Coal County, OK': '029', 'Comanche County, OK': '031', 'Cotton County, OK': '033', 'Craig County, OK': '035', 'Creek County, OK': '037', 'Custer County, OK': '039', 'Delaware County, OK': '041', 'Dewey County, OK': '043', 'Ellis County, OK': '045', 'Garfield County, OK': '047', 'Garvin County, OK': '049', 'Grady County, OK': '051', 'Grant County, OK': '053', 'Greer County, OK': '055', 'Harmon County, OK': '057', 'Harper County, OK': '059', 'Haskell County, OK': '061', 'Hughes County, OK': '063', 'Jackson County, OK': '065', 'Jefferson County, OK': '067', 'Johnston County, OK': '069', 'Kay County, OK': '071', 'Kingfisher County, OK': '073', 'Kiowa County, OK': '075', 'Latimer County, OK': '077', 'Le Flore County, OK': '079', 'Lincoln County, OK': '081', 'Logan County, OK': '083', 'Love County, OK': '085', 'Major County, OK': '093', 'Marshall County, OK': '095', 'Mayes County, OK': '097', 'McClain County, OK': '087', 'McCurtain County, OK': '089', 'McIntosh County, OK': '091', 'Murray County, OK': '099', 'Muskogee County, OK': '101', 'Noble County, OK': '103', 'Nowata County, OK': '105', 'Okfuskee County, OK': '107', 'Oklahoma County, OK': '109', 'Okmulgee County, OK': '111', 'Osage County, OK': '113', 'Ottawa County, OK': '115', 'Pawnee County, OK': '117', 'Payne County, OK': '119', 'Pittsburg County, OK': '121', 'Pontotoc County, OK': '123', 'Pottawatomie County, OK': '125', 'Pushmataha County, OK': '127', 'Roger Mills County, OK': '129', 'Rogers County, OK': '131', 'Seminole County, OK': '133', 'Sequoyah County, OK': '135', 'Stephens County, OK': '137', 'Texas County, OK': '139', 'Tillman County, OK': '141', 'Tulsa County, OK': '143', 'Wagoner County, OK': '145', 'Washington County, OK': '147', 'Washita County, OK': '149', 'Woods County, OK': '151', 'Woodward County, OK': '153'}, 41: {'--All--': '%', 'Baker County, OR': '001', 'Benton County, OR': '003', 'Clackamas County, OR': '005', 'Clatsop County, OR': '007', 'Columbia County, OR': '009', 'Coos County, OR': '011', 'Crook County, OR': '013', 'Curry County, OR': '015', 'Deschutes County, OR': '017', 'Douglas County, OR': '019', 'Gilliam County, OR': '021', 'Grant County, OR': '023', 'Harney County, OR': '025', 'Hood River County, OR': '027', 'Jackson County, OR': '029', 'Jefferson County, OR': '031', 'Josephine County, OR': '033', 'Klamath County, OR': '035', 'Lake County, OR': '037', 'Lane County, OR': '039', 'Lincoln County, OR': '041', 'Linn County, OR': '043', 'Malheur County, OR': '045', 'Marion County, OR': '047', 'Morrow County, OR': '049', 'Multnomah County, OR': '051', 'Polk County, OR': '053', 'Sherman County, OR': '055', 'Tillamook County, OR': '057', 'Umatilla County, OR': '059', 'Union County, OR': '061', 'Wallowa County, OR': '063', 'Wasco County, OR': '065', 'Washington County, OR': '067', 'Wheeler County, OR': '069', 'Yamhill County, OR': '071'}, 42: {'--All--': '%', 'Adams County, PA': '001', 'Allegheny County, PA': '003', 'Armstrong County, PA': '005', 'Beaver County, PA': '007', 'Bedford County, PA': '009', 'Berks County, PA': '011', 'Blair County, PA': '013', 'Bradford County, PA': '015', 'Bucks County, PA': '017', 'Butler County, PA': '019', 'Cambria County, PA': '021', 'Cameron County, PA': '023', 'Carbon County, PA': '025', 'Centre County, PA': '027', 'Chester County, PA': '029', 'Clarion County, PA': '031', 'Clearfield County, PA': '033', 'Clinton County, PA': '035', 'Columbia County, PA': '037', 'Crawford County, PA': '039', 'Cumberland County, PA': '041', 'Dauphin County, PA': '043', 'Delaware County, PA': '045', 'Elk County, PA': '047', 'Erie County, PA': '049', 'Fayette County, PA': '051', 'Forest County, PA': '053', 'Franklin County, PA': '055', 'Fulton County, PA': '057', 'Greene County, PA': '059', 'Huntingdon County, PA': '061', 'Indiana County, PA': '063', 'Jefferson County, PA': '065', 'Juniata County, PA': '067', 'Lackawanna County, PA': '069', 'Lancaster County, PA': '071', 'Lawrence County, PA': '073', 'Lebanon County, PA': '075', 'Lehigh County, PA': '077', 'Luzerne County, PA': '079', 'Lycoming County, PA': '081', 'McKean County, PA': '083', 'Mercer County, PA': '085', 'Mifflin County, PA': '087', 'Monroe County, PA': '089', 'Montgomery County, PA': '091', 'Montour County, PA': '093', 'Northampton County, PA': '095', 'Northumberland County, PA': '097', 'Perry County, PA': '099', 'Philadelphia County/city, PA': '101', 'Pike County, PA': '103', 'Potter County, PA': '105', 'Schuylkill County, PA': '107', 'Snyder County, PA': '109', 'Somerset County, PA': '111', 'Sullivan County, PA': '113', 'Susquehanna County, PA': '115', 'Tioga County, PA': '117', 'Union County, PA': '119', 'Venango County, PA': '121', 'Warren County, PA': '123', 'Washington County, PA': '125', 'Wayne County, PA': '127', 'Westmoreland County, PA': '129', 'Wyoming County, PA': '131', 'York County, PA': '133'}, 44: {'--All--': '%', 'Bristol County, RI': '001', 'Kent County, RI': '003', 'Newport County, RI': '005', 'Providence County, RI': '007', 'Washington County, RI': '009'}, 45: {'--All--': '%', 'Abbeville County, SC': '001', 'Aiken County, SC': '003', 'Allendale County, SC': '005', 'Anderson County, SC': '007', 'Bamberg County, SC': '009', 'Barnwell County, SC': '011', 'Beaufort County, SC': '013', 'Berkeley County, SC': '015', 'Calhoun County, SC': '017', 'Charleston County, SC': '019', 'Cherokee County, SC': '021', 'Chester County, SC': '023', 'Chesterfield County, SC': '025', 'Clarendon County, SC': '027', 'Colleton County, SC': '029', 'Darlington County, SC': '031', 'Dillon County, SC': '033', 'Dorchester County, SC': '035', 'Edgefield County, SC': '037', 'Fairfield County, SC': '039', 'Florence County, SC': '041', 'Georgetown County, SC': '043', 'Greenville County, SC': '045', 'Greenwood County, SC': '047', 'Hampton County, SC': '049', 'Horry County, SC': '051', 'Jasper County, SC': '053', 'Kershaw County, SC': '055', 'Lancaster County, SC': '057', 'Laurens County, SC': '059', 'Lee County, SC': '061', 'Lexington County, SC': '063', 'Marion County, SC': '067', 'Marlboro County, SC': '069', 'McCormick County, SC': '065', 'Newberry County, SC': '071', 'Oconee County, SC': '073', 'Orangeburg County, SC': '075', 'Pickens County, SC': '077', 'Richland County, SC': '079', 'Saluda County, SC': '081', 'Spartanburg County, SC': '083', 'Sumter County, SC': '085', 'Union County, SC': '087', 'Williamsburg County, SC': '089', 'York County, SC': '091'}, 46: {'--All--': '%', 'Aurora County, SD': '003', 'Beadle County, SD': '005', 'Bennett County, SD': '007', 'Bon Homme County, SD': '009', 'Brookings County, SD': '011', 'Brown County, SD': '013', 'Brule County, SD': '015', 'Buffalo County, SD': '017', 'Butte County, SD': '019', 'Campbell County, SD': '021', 'Charles Mix County, SD': '023', 'Clark County, SD': '025', 'Clay County, SD': '027', 'Codington County, SD': '029', 'Corson County, SD': '031', 'Custer County, SD': '033', 'Davison County, SD': '035', 'Day County, SD': '037', 'Deuel County, SD': '039', 'Dewey County, SD': '041', 'Douglas County, SD': '043', 'Edmunds County, SD': '045', 'Fall River County, SD': '047', 'Faulk County, SD': '049', 'Grant County, SD': '051', 'Gregory County, SD': '053', 'Haakon County, SD': '055', 'Hamlin County, SD': '057', 'Hand County, SD': '059', 'Hanson County, SD': '061', 'Harding County, SD': '063', 'Hughes County, SD': '065', 'Hutchinson County, SD': '067', 'Hyde County, SD': '069', 'Jackson County, SD': '071', 'Jerauld County, SD': '073', 'Jones County, SD': '075', 'Kingsbury County, SD': '077', 'Lake County, SD': '079', 'Lawrence County, SD': '081', 'Lincoln County, SD': '083', 'Lyman County, SD': '085', 'Marshall County, SD': '091', 'McCook County, SD': '087', 'McPherson County, SD': '089', 'Meade County, SD': '093', 'Mellette County, SD': '095', 'Miner County, SD': '097', 'Minnehaha County, SD': '099', 'Moody County, SD': '101', 'Pennington County, SD': '103', 'Perkins County, SD': '105', 'Potter County, SD': '107', 'Roberts County, SD': '109', 'Sanborn County, SD': '111', 'Shannon County, SD': '113', 'Spink County, SD': '115', 'Stanley County, SD': '117', 'Sully County, SD': '119', 'Todd County, SD': '121', 'Tripp County, SD': '123', 'Turner County, SD': '125', 'Union County, SD': '127', 'Walworth County, SD': '129', 'Yankton County, SD': '135', 'Ziebach County, SD': '137'}, 47: {'--All--': '%', 'Anderson County, TN': '001', 'Bedford County, TN': '003', 'Benton County, TN': '005', 'Bledsoe County, TN': '007', 'Blount County, TN': '009', 'Bradley County, TN': '011', 'Campbell County, TN': '013', 'Cannon County, TN': '015', 'Carroll County, TN': '017', 'Carter County, TN': '019', 'Cheatham County, TN': '021', 'Chester County, TN': '023', 'Claiborne County, TN': '025', 'Clay County, TN': '027', 'Cocke County, TN': '029', 'Coffee County, TN': '031', 'Crockett County, TN': '033', 'Cumberland County, TN': '035', 'Davidson County, TN': '037', 'DeKalb County, TN': '041', 'Decatur County, TN': '039', 'Dickson County, TN': '043', 'Dyer County, TN': '045', 'Fayette County, TN': '047', 'Fentress County, TN': '049', 'Franklin County, TN': '051', 'Gibson County, TN': '053', 'Giles County, TN': '055', 'Grainger County, TN': '057', 'Greene County, TN': '059', 'Grundy County, TN': '061', 'Hamblen County, TN': '063', 'Hamilton County, TN': '065', 'Hancock County, TN': '067', 'Hardeman County, TN': '069', 'Hardin County, TN': '071', 'Hawkins County, TN': '073', 'Haywood County, TN': '075', 'Henderson County, TN': '077', 'Henry County, TN': '079', 'Hickman County, TN': '081', 'Houston County, TN': '083', 'Humphreys County, TN': '085', 'Jackson County, TN': '087', 'Jefferson County, TN': '089', 'Johnson County, TN': '091', 'Knox County, TN': '093', 'Lake County, TN': '095', 'Lauderdale County, TN': '097', 'Lawrence County, TN': '099', 'Lewis County, TN': '101', 'Lincoln County, TN': '103', 'Loudon County, TN': '105', 'Macon County, TN': '111', 'Madison County, TN': '113', 'Marion County, TN': '115', 'Marshall County, TN': '117', 'Maury County, TN': '119', 'McMinn County, TN': '107', 'McNairy County, TN': '109', 'Meigs County, TN': '121', 'Monroe County, TN': '123', 'Montgomery County, TN': '125', 'Moore County, TN': '127', 'Morgan County, TN': '129', 'Obion County, TN': '131', 'Overton County, TN': '133', 'Perry County, TN': '135', 'Pickett County, TN': '137', 'Polk County, TN': '139', 'Putnam County, TN': '141', 'Rhea County, TN': '143', 'Roane County, TN': '145', 'Robertson County, TN': '147', 'Rutherford County, TN': '149', 'Scott County, TN': '151', 'Sequatchie County, TN': '153', 'Sevier County, TN': '155', 'Shelby County, TN': '157', 'Smith County, TN': '159', 'Stewart County, TN': '161', 'Sullivan County, TN': '163', 'Sumner County, TN': '165', 'Tipton County, TN': '167', 'Trousdale County, TN': '169', 'Unicoi County, TN': '171', 'Union County, TN': '173', 'Van Buren County, TN': '175', 'Warren County, TN': '177', 'Washington County, TN': '179', 'Wayne County, TN': '181', 'Weakley County, TN': '183', 'White County, TN': '185', 'Williamson County, TN': '187', 'Wilson County, TN': '189'}, 48: {'--All--': '%', 'Anderson County, TX': '001', 'Andrews County, TX': '003', 'Angelina County, TX': '005', 'Aransas County, TX': '007', 'Archer County, TX': '009', 'Armstrong County, TX': '011', 'Atascosa County, TX': '013', 'Austin County, TX': '015', 'Bailey County, TX': '017', 'Bandera County, TX': '019', 'Bastrop County, TX': '021', 'Baylor County, TX': '023', 'Bee County, TX': '025', 'Bell County, TX': '027', 'Bexar County, TX': '029', 'Blanco County, TX': '031', 'Borden County, TX': '033', 'Bosque County, TX': '035', 'Bowie County, TX': '037', 'Brazoria County, TX': '039', 'Brazos County, TX': '041', 'Brewster County, TX': '043', 'Briscoe County, TX': '045', 'Brooks County, TX': '047', 'Brown County, TX': '049', 'Burleson County, TX': '051', 'Burnet County, TX': '053', 'Caldwell County, TX': '055', 'Calhoun County, TX': '057', 'Callahan County, TX': '059', 'Cameron County, TX': '061', 'Camp County, TX': '063', 'Carson County, TX': '065', 'Cass County, TX': '067', 'Castro County, TX': '069', 'Chambers County, TX': '071', 'Cherokee County, TX': '073', 'Childress County, TX': '075', 'Clay County, TX': '077', 'Cochran County, TX': '079', 'Coke County, TX': '081', 'Coleman County, TX': '083', 'Collin County, TX': '085', 'Collingsworth County, TX': '087', 'Colorado County, TX': '089', 'Comal County, TX': '091', 'Comanche County, TX': '093', 'Concho County, TX': '095', 'Cooke County, TX': '097', 'Coryell County, TX': '099', 'Cottle County, TX': '101', 'Crane County, TX': '103', 'Crockett County, TX': '105', 'Crosby County, TX': '107', 'Culberson County, TX': '109', 'Dallam County, TX': '111', 'Dallas County, TX': '113', 'Dawson County, TX': '115', 'DeWitt County, TX': '123', 'Deaf Smith County, TX': '117', 'Delta County, TX': '119', 'Denton County, TX': '121', 'Dickens County, TX': '125', 'Dimmit County, TX': '127', 'Donley County, TX': '129', 'Duval County, TX': '131', 'Eastland County, TX': '133', 'Ector County, TX': '135', 'Edwards County, TX': '137', 'El Paso County, TX': '141', 'Ellis County, TX': '139', 'Erath County, TX': '143', 'Falls County, TX': '145', 'Fannin County, TX': '147', 'Fayette County, TX': '149', 'Fisher County, TX': '151', 'Floyd County, TX': '153', 'Foard County, TX': '155', 'Fort Bend County, TX': '157', 'Franklin County, TX': '159', 'Freestone County, TX': '161', 'Frio County, TX': '163', 'Gaines County, TX': '165', 'Galveston County, TX': '167', 'Garza County, TX': '169', 'Gillespie County, TX': '171', 'Glasscock County, TX': '173', 'Goliad County, TX': '175', 'Gonzales County, TX': '177', 'Gray County, TX': '179', 'Grayson County, TX': '181', 'Gregg County, TX': '183', 'Grimes County, TX': '185', 'Guadalupe County, TX': '187', 'Hale County, TX': '189', 'Hall County, TX': '191', 'Hamilton County, TX': '193', 'Hansford County, TX': '195', 'Hardeman County, TX': '197', 'Hardin County, TX': '199', 'Harris County, TX': '201', 'Harrison County, TX': '203', 'Hartley County, TX': '205', 'Haskell County, TX': '207', 'Hays County, TX': '209', 'Hemphill County, TX': '211', 'Henderson County, TX': '213', 'Hidalgo County, TX': '215', 'Hill County, TX': '217', 'Hockley County, TX': '219', 'Hood County, TX': '221', 'Hopkins County, TX': '223', 'Houston County, TX': '225', 'Howard County, TX': '227', 'Hudspeth County, TX': '229', 'Hunt County, TX': '231', 'Hutchinson County, TX': '233', 'Irion County, TX': '235', 'Jack County, TX': '237', 'Jackson County, TX': '239', 'Jasper County, TX': '241', 'Jeff Davis County, TX': '243', 'Jefferson County, TX': '245', 'Jim Hogg County, TX': '247', 'Jim Wells County, TX': '249', 'Johnson County, TX': '251', 'Jones County, TX': '253', 'Karnes County, TX': '255', 'Kaufman County, TX': '257', 'Kendall County, TX': '259', 'Kenedy County, TX': '261', 'Kent County, TX': '263', 'Kerr County, TX': '265', 'Kimble County, TX': '267', 'King County, TX': '269', 'Kinney County, TX': '271', 'Kleberg County, TX': '273', 'Knox County, TX': '275', 'La Salle County, TX': '283', 'Lamar County, TX': '277', 'Lamb County, TX': '279', 'Lampasas County, TX': '281', 'Lavaca County, TX': '285', 'Lee County, TX': '287', 'Leon County, TX': '289', 'Liberty County, TX': '291', 'Limestone County, TX': '293', 'Lipscomb County, TX': '295', 'Live Oak County, TX': '297', 'Llano County, TX': '299', 'Loving County, TX': '301', 'Lubbock County, TX': '303', 'Lynn County, TX': '305', 'Madison County, TX': '313', 'Marion County, TX': '315', 'Martin County, TX': '317', 'Mason County, TX': '319', 'Matagorda County, TX': '321', 'Maverick County, TX': '323', 'McCulloch County, TX': '307', 'McLennan County, TX': '309', 'McMullen County, TX': '311', 'Medina County, TX': '325', 'Menard County, TX': '327', 'Midland County, TX': '329', 'Milam County, TX': '331', 'Mills County, TX': '333', 'Mitchell County, TX': '335', 'Montague County, TX': '337', 'Montgomery County, TX': '339', 'Moore County, TX': '341', 'Morris County, TX': '343', 'Motley County, TX': '345', 'Nacogdoches County, TX': '347', 'Navarro County, TX': '349', 'Newton County, TX': '351', 'Nolan County, TX': '353', 'Nueces County, TX': '355', 'Ochiltree County, TX': '357', 'Oldham County, TX': '359', 'Orange County, TX': '361', 'Palo Pinto County, TX': '363', 'Panola County, TX': '365', 'Parker County, TX': '367', 'Parmer County, TX': '369', 'Pecos County, TX': '371', 'Polk County, TX': '373', 'Potter County, TX': '375', 'Presidio County, TX': '377', 'Rains County, TX': '379', 'Randall County, TX': '381', 'Reagan County, TX': '383', 'Real County, TX': '385', 'Red River County, TX': '387', 'Reeves County, TX': '389', 'Refugio County, TX': '391', 'Roberts County, TX': '393', 'Robertson County, TX': '395', 'Rockwall County, TX': '397', 'Runnels County, TX': '399', 'Rusk County, TX': '401', 'Sabine County, TX': '403', 'San Augustine County, TX': '405', 'San Jacinto County, TX': '407', 'San Patricio County, TX': '409', 'San Saba County, TX': '411', 'Schleicher County, TX': '413', 'Scurry County, TX': '415', 'Shackelford County, TX': '417', 'Shelby County, TX': '419', 'Sherman County, TX': '421', 'Smith County, TX': '423', 'Somervell County, TX': '425', 'Starr County, TX': '427', 'Stephens County, TX': '429', 'Sterling County, TX': '431', 'Stonewall County, TX': '433', 'Sutton County, TX': '435', 'Swisher County, TX': '437', 'Tarrant County, TX': '439', 'Taylor County, TX': '441', 'Terrell County, TX': '443', 'Terry County, TX': '445', 'Throckmorton County, TX': '447', 'Titus County, TX': '449', 'Tom Green County, TX': '451', 'Travis County, TX': '453', 'Trinity County, TX': '455', 'Tyler County, TX': '457', 'Upshur County, TX': '459', 'Upton County, TX': '461', 'Uvalde County, TX': '463', 'Val Verde County, TX': '465', 'Van Zandt County, TX': '467', 'Victoria County, TX': '469', 'Walker County, TX': '471', 'Waller County, TX': '473', 'Ward County, TX': '475', 'Washington County, TX': '477', 'Webb County, TX': '479', 'Wharton County, TX': '481', 'Wheeler County, TX': '483', 'Wichita County, TX': '485', 'Wilbarger County, TX': '487', 'Willacy County, TX': '489', 'Williamson County, TX': '491', 'Wilson County, TX': '493', 'Winkler County, TX': '495', 'Wise County, TX': '497', 'Wood County, TX': '499', 'Yoakum County, TX': '501', 'Young County, TX': '503', 'Zapata County, TX': '505', 'Zavala County, TX': '507'}, 49: {'--All--': '%', 'Beaver County, UT': '001', 'Box Elder County, UT': '003', 'Cache County, UT': '005', 'Carbon County, UT': '007', 'Daggett County, UT': '009', 'Davis County, UT': '011', 'Duchesne County, UT': '013', 'Emery County, UT': '015', 'Garfield County, UT': '017', 'Grand County, UT': '019', 'Iron County, UT': '021', 'Juab County, UT': '023', 'Kane County, UT': '025', 'Millard County, UT': '027', 'Morgan County, UT': '029', 'Piute County, UT': '031', 'Rich County, UT': '033', 'Salt Lake County, UT': '035', 'San Juan County, UT': '037', 'Sanpete County, UT': '039', 'Sevier County, UT': '041', 'Summit County, UT': '043', 'Tooele County, UT': '045', 'Uintah County, UT': '047', 'Utah County, UT': '049', 'Wasatch County, UT': '051', 'Washington County, UT': '053', 'Wayne County, UT': '055', 'Weber County, UT': '057'}, 50: {'--All--': '%', 'Addison County, VT': '001', 'Bennington County, VT': '003', 'Caledonia County, VT': '005', 'Chittenden County, VT': '007', 'Essex County, VT': '009', 'Franklin County, VT': '011', 'Grand Isle County, VT': '013', 'Lamoille County, VT': '015', 'Orange County, VT': '017', 'Orleans County, VT': '019', 'Rutland County, VT': '021', 'Washington County, VT': '023', 'Windham County, VT': '025', 'Windsor County, VT': '027'}, 51: {'--All--': '%', 'Accomack County, VA': '001', 'Albemarle County, VA': '003', 'Alexandria city, VA': '510', 'Alleghany County, VA': '005', 'Amelia County, VA': '007', 'Amherst County, VA': '009', 'Appomattox County, VA': '011', 'Arlington County, VA': '013', 'Augusta County, VA': '015', 'Bath County, VA': '017', 'Bedford County, VA': '019', 'Bedford city, VA': '515', 'Bland County, VA': '021', 'Botetourt County, VA': '023', 'Bristol city, VA': '520', 'Brunswick County, VA': '025', 'Buchanan County, VA': '027', 'Buckingham County, VA': '029', 'Buena Vista city, VA': '530', 'Campbell County, VA': '031', 'Caroline County, VA': '033', 'Carroll County, VA': '035', 'Charles City County, VA': '036', 'Charlotte County, VA': '037', 'Charlottesville city, VA': '540', 'Chesapeake city, VA': '550', 'Chesterfield County, VA': '041', 'Clarke County, VA': '043', 'Colonial Heights city, VA': '570', 'Covington city, VA': '580', 'Craig County, VA': '045', 'Culpeper County, VA': '047', 'Cumberland County, VA': '049', 'Danville city, VA': '590', 'Dickenson County, VA': '051', 'Dinwiddie County, VA': '053', 'Emporia city, VA': '595', 'Essex County, VA': '057', 'Fairfax County, VA': '059', 'Fairfax city, VA': '600', 'Falls Church city, VA': '610', 'Fauquier County, VA': '061', 'Floyd County, VA': '063', 'Fluvanna County, VA': '065', 'Franklin County, VA': '067', 'Franklin city, VA': '620', 'Frederick County, VA': '069', 'Fredericksburg city, VA': '630', 'Galax city, VA': '640', 'Giles County, VA': '071', 'Gloucester County, VA': '073', 'Goochland County, VA': '075', 'Grayson County, VA': '077', 'Greene County, VA': '079', 'Greensville County, VA': '081', 'Halifax County, VA': '083', 'Hampton city, VA': '650', 'Hanover County, VA': '085', 'Harrisonburg city, VA': '660', 'Henrico County, VA': '087', 'Henry County, VA': '089', 'Highland County, VA': '091', 'Hopewell city, VA': '670', 'Isle of Wight County, VA': '093', 'James City County, VA': '095', 'King George County, VA': '099', 'King William County, VA': '101', 'King and Queen County, VA': '097', 'Lancaster County, VA': '103', 'Lee County, VA': '105', 'Lexington city, VA': '678', 'Loudoun County, VA': '107', 'Louisa County, VA': '109', 'Lunenburg County, VA': '111', 'Lynchburg city, VA': '680', 'Madison County, VA': '113', 'Manassas Park city, VA': '685', 'Manassas city, VA': '683', 'Martinsville city, VA': '690', 'Mathews County, VA': '115', 'Mecklenburg County, VA': '117', 'Middlesex County, VA': '119', 'Montgomery County, VA': '121', 'Nelson County, VA': '125', 'New Kent County, VA': '127', 'Newport News city, VA': '700', 'Norfolk city, VA': '710', 'Northampton County, VA': '131', 'Northumberland County, VA': '133', 'Norton city, VA': '720', 'Nottoway County, VA': '135', 'Orange County, VA': '137', 'Page County, VA': '139', 'Patrick County, VA': '141', 'Petersburg city, VA': '730', 'Pittsylvania County, VA': '143', 'Poquoson city, VA': '735', 'Portsmouth city, VA': '740', 'Powhatan County, VA': '145', 'Prince Edward County, VA': '147', 'Prince George County, VA': '149', 'Prince William County, VA': '153', 'Pulaski County, VA': '155', 'Radford city, VA': '750', 'Rappahannock County, VA': '157', 'Richmond County, VA': '159', 'Richmond city, VA': '760', 'Roanoke County, VA': '161', 'Roanoke city, VA': '770', 'Rockbridge County, VA': '163', 'Rockingham County, VA': '165', 'Russell County, VA': '167', 'Salem city, VA': '775', 'Scott County, VA': '169', 'Shenandoah County, VA': '171', 'Smyth County, VA': '173', 'Southampton County, VA': '175', 'Spotsylvania County, VA': '177', 'Stafford County, VA': '179', 'Staunton city, VA': '790', 'Suffolk city, VA': '800', 'Surry County, VA': '181', 'Sussex County, VA': '183', 'Tazewell County, VA': '185', 'Virginia Beach city, VA': '810', 'Warren County, VA': '187', 'Washington County, VA': '191', 'Waynesboro city, VA': '820', 'Westmoreland County, VA': '193', 'Williamsburg city, VA': '830', 'Winchester city, VA': '840', 'Wise County, VA': '195', 'Wythe County, VA': '197', 'York County, VA': '199'}, 53: {'--All--': '%', 'Adams County, WA': '001', 'Asotin County, WA': '003', 'Benton County, WA': '005', 'Chelan County, WA': '007', 'Clallam County, WA': '009', 'Clark County, WA': '011', 'Columbia County, WA': '013', 'Cowlitz County, WA': '015', 'Douglas County, WA': '017', 'Ferry County, WA': '019', 'Franklin County, WA': '021', 'Garfield County, WA': '023', 'Grant County, WA': '025', 'Grays Harbor County, WA': '027', 'Island County, WA': '029', 'Jefferson County, WA': '031', 'King County, WA': '033', 'Kitsap County, WA': '035', 'Kittitas County, WA': '037', 'Klickitat County, WA': '039', 'Lewis County, WA': '041', 'Lincoln County, WA': '043', 'Mason County, WA': '045', 'Okanogan County, WA': '047', 'Pacific County, WA': '049', 'Pend Oreille County, WA': '051', 'Pierce County, WA': '053', 'San Juan County, WA': '055', 'Skagit County, WA': '057', 'Skamania County, WA': '059', 'Snohomish County, WA': '061', 'Spokane County, WA': '063', 'Stevens County, WA': '065', 'Thurston County, WA': '067', 'Wahkiakum County, WA': '069', 'Walla Walla County, WA': '071', 'Whatcom County, WA': '073', 'Whitman County, WA': '075', 'Yakima County, WA': '077'}, 54: {'--All--': '%', 'Barbour County, WV': '001', 'Berkeley County, WV': '003', 'Boone County, WV': '005', 'Braxton County, WV': '007', 'Brooke County, WV': '009', 'Cabell County, WV': '011', 'Calhoun County, WV': '013', 'Clay County, WV': '015', 'Doddridge County, WV': '017', 'Fayette County, WV': '019', 'Gilmer County, WV': '021', 'Grant County, WV': '023', 'Greenbrier County, WV': '025', 'Hampshire County, WV': '027', 'Hancock County, WV': '029', 'Hardy County, WV': '031', 'Harrison County, WV': '033', 'Jackson County, WV': '035', 'Jefferson County, WV': '037', 'Kanawha County, WV': '039', 'Lewis County, WV': '041', 'Lincoln County, WV': '043', 'Logan County, WV': '045', 'Marion County, WV': '049', 'Marshall County, WV': '051', 'Mason County, WV': '053', 'McDowell County, WV': '047', 'Mercer County, WV': '055', 'Mineral County, WV': '057', 'Mingo County, WV': '059', 'Monongalia County, WV': '061', 'Monroe County, WV': '063', 'Morgan County, WV': '065', 'Nicholas County, WV': '067', 'Ohio County, WV': '069', 'Pendleton County, WV': '071', 'Pleasants County, WV': '073', 'Pocahontas County, WV': '075', 'Preston County, WV': '077', 'Putnam County, WV': '079', 'Raleigh County, WV': '081', 'Randolph County, WV': '083', 'Ritchie County, WV': '085', 'Roane County, WV': '087', 'Summers County, WV': '089', 'Taylor County, WV': '091', 'Tucker County, WV': '093', 'Tyler County, WV': '095', 'Upshur County, WV': '097', 'Wayne County, WV': '099', 'Webster County, WV': '101', 'Wetzel County, WV': '103', 'Wirt County, WV': '105', 'Wood County, WV': '107', 'Wyoming County, WV': '109'}, 55: {'--All--': '%', 'Adams County, WI': '001', 'Ashland County, WI': '003', 'Barron County, WI': '005', 'Bayfield County, WI': '007', 'Brown County, WI': '009', 'Buffalo County, WI': '011', 'Burnett County, WI': '013', 'Calumet County, WI': '015', 'Chippewa County, WI': '017', 'Clark County, WI': '019', 'Columbia County, WI': '021', 'Crawford County, WI': '023', 'Dane County, WI': '025', 'Dodge County, WI': '027', 'Door County, WI': '029', 'Douglas County, WI': '031', 'Dunn County, WI': '033', 'Eau Claire County, WI': '035', 'Florence County, WI': '037', 'Fond du Lac County, WI': '039', 'Forest County, WI': '041', 'Grant County, WI': '043', 'Green County, WI': '045', 'Green Lake County, WI': '047', 'Iowa County, WI': '049', 'Iron County, WI': '051', 'Jackson County, WI': '053', 'Jefferson County, WI': '055', 'Juneau County, WI': '057', 'Kenosha County, WI': '059', 'Kewaunee County, WI': '061', 'La Crosse County, WI': '063', 'Lafayette County, WI': '065', 'Langlade County, WI': '067', 'Lincoln County, WI': '069', 'Manitowoc County, WI': '071', 'Marathon County, WI': '073', 'Marinette County, WI': '075', 'Marquette County, WI': '077', 'Menominee County, WI': '078', 'Milwaukee County, WI': '079', 'Monroe County, WI': '081', 'Oconto County, WI': '083', 'Oneida County, WI': '085', 'Outagamie County, WI': '087', 'Ozaukee County, WI': '089', 'Pepin County, WI': '091', 'Pierce County, WI': '093', 'Polk County, WI': '095', 'Portage County, WI': '097', 'Price County, WI': '099', 'Racine County, WI': '101', 'Richland County, WI': '103', 'Rock County, WI': '105', 'Rusk County, WI': '107', 'Sauk County, WI': '111', 'Sawyer County, WI': '113', 'Shawano County, WI': '115', 'Sheboygan County, WI': '117', 'St. Croix County, WI': '109', 'Taylor County, WI': '119', 'Trempealeau County, WI': '121', 'Vernon County, WI': '123', 'Vilas County, WI': '125', 'Walworth County, WI': '127', 'Washburn County, WI': '129', 'Washington County, WI': '131', 'Waukesha County, WI': '133', 'Waupaca County, WI': '135', 'Waushara County, WI': '137', 'Winnebago County, WI': '139', 'Wood County, WI': '141'}, 56: {'--All--': '%', 'Albany County, WY': '001', 'Big Horn County, WY': '003', 'Campbell County, WY': '005', 'Carbon County, WY': '007', 'Converse County, WY': '009', 'Crook County, WY': '011', 'Fremont County, WY': '013', 'Goshen County, WY': '015', 'Hot Springs County, WY': '017', 'Johnson County, WY': '019', 'Laramie County, WY': '021', 'Lincoln County, WY': '023', 'Natrona County, WY': '025', 'Niobrara County, WY': '027', 'Park County, WY': '029', 'Platte County, WY': '031', 'Sheridan County, WY': '033', 'Sublette County, WY': '035', 'Sweetwater County, WY': '037', 'Teton County, WY': '039', 'Uinta County, WY': '041', 'Washakie County, WY': '043', 'Weston County, WY': '045'}, 72: {'--All--': '%', 'Adjuntas Municipio, PR': '001', 'Aguada Municipio, PR': '003', 'Aguadilla Municipio, PR': '005', 'Aguas Buenas Municipio, PR': '007', 'Aibonito Municipio, PR': '009', 'Anasco Municipio, PR': '011', 'Arecibo Municipio, PR': '013', 'Arroyo Municipio, PR': '015', 'Barceloneta Municipio, PR': '017', 'Barranquitas Municipio, PR': '019', 'Bayamon Municipio, PR': '021', 'Cabo Rojo Municipio, PR': '023', 'Caguas Municipio, PR': '025', 'Camuy Municipio, PR': '027', 'Canovanas Municipio, PR': '029', 'Carolina Municipio, PR': '031', 'Catano Municipio, PR': '033', 'Cayey Municipio, PR': '035', 'Ceiba Municipio, PR': '037', 'Ciales Municipio, PR': '039', 'Cidra Municipio, PR': '041', 'Coamo Municipio, PR': '043', 'Comerio Municipio, PR': '045', 'Corozal Municipio, PR': '047', 'Culebra Municipio, PR': '049', 'Dorado Municipio, PR': '051', 'Fajardo Municipio, PR': '053', 'Florida Municipio, PR': '054', 'Guanica Municipio, PR': '055', 'Guayama Municipio, PR': '057', 'Guayanilla Municipio, PR': '059', 'Guaynabo Municipio, PR': '061', 'Gurabo Municipio, PR': '063', 'Hatillo Municipio, PR': '065', 'Hormigueros Municipio, PR': '067', 'Humacao Municipio, PR': '069', 'Isabela Municipio, PR': '071', 'Jayuya Municipio, PR': '073', 'Juana Diaz Municipio, PR': '075', 'Juncos Municipio, PR': '077', 'Lajas Municipio, PR': '079', 'Lares Municipio, PR': '081', 'Las Marias Municipio, PR': '083', 'Las Piedras Municipio, PR': '085', 'Loiza Municipio, PR': '087', 'Luquillo Municipio, PR': '089', 'Manati Municipio, PR': '091', 'Maricao Municipio, PR': '093', 'Maunabo Municipio, PR': '095', 'Mayaguez Municipio, PR': '097', 'Moca Municipio, PR': '099', 'Morovis Municipio, PR': '101', 'Naguabo Municipio, PR': '103', 'Naranjito Municipio, PR': '105', 'Orocovis Municipio, PR': '107', 'Patillas Municipio, PR': '109', 'Penuelas Municipio, PR': '111', 'Ponce Municipio, PR': '113', 'Quebradillas Municipio, PR': '115', 'Rincon Municipio, PR': '117', 'Rio Grande Municipio, PR': '119', 'Sabana Grande Municipio, PR': '121', 'Salinas Municipio, PR': '123', 'San German Municipio, PR': '125', 'San Juan Municipio, PR': '127', 'San Lorenzo Municipio, PR': '129', 'San Sebastian Municipio, PR': '131', 'Santa Isabel Municipio, PR': '133', 'Toa Alta Municipio, PR': '135', 'Toa Baja Municipio, PR': '137', 'Trujillo Alto Municipio, PR': '139', 'Utuado Municipio, PR': '141', 'Vega Alta Municipio, PR': '143', 'Vega Baja Municipio, PR': '145', 'Vieques Municipio, PR': '147', 'Villalba Municipio, PR': '149', 'Yabucoa Municipio, PR': '151', 'Yauco Municipio, PR': '153'}, '01': {'Autauga County, AL': '001', 'Baldwin County, AL': '003', 'Barbour County, AL': '005', 'Bibb County, AL': '007', 'Blount County, AL': '009', 'Bullock County, AL': '011', 'Butler County, AL': '013', 'Calhoun County, AL': '015', 'Chambers County, AL': '017', 'Cherokee County, AL': '019', 'Chilton County, AL': '021', 'Choctaw County, AL': '023', 'Clarke County, AL': '025', 'Clay County, AL': '027', 'Cleburne County, AL': '029', 'Coffee County, AL': '031', 'Colbert County, AL': '033', 'Conecuh County, AL': '035', 'Coosa County, AL': '037', 'Covington County, AL': '039', 'Crenshaw County, AL': '041', 'Cullman County, AL': '043', 'Dale County, AL': '045', 'Dallas County, AL': '047', 'DeKalb County, AL': '049', 'Elmore County, AL': '051', 'Escambia County, AL': '053', 'Etowah County, AL': '055', 'Fayette County, AL': '057', 'Franklin County, AL': '059', 'Geneva County, AL': '061', 'Greene County, AL': '063', 'Hale County, AL': '065', 'Henry County, AL': '067', 'Houston County, AL': '069', 'Jackson County, AL': '071', 'Jefferson County, AL': '073', 'Lamar County, AL': '075', 'Lauderdale County, AL': '077', 'Lawrence County, AL': '079', 'Lee County, AL': '081', 'Limestone County, AL': '083', 'Lowndes County, AL': '085', 'Macon County, AL': '087', 'Madison County, AL': '089', 'Marengo County, AL': '091', 'Marion County, AL': '093', 'Marshall County, AL': '095', 'Mobile County, AL': '097', 'Monroe County, AL': '099', 'Montgomery County, AL': '101', 'Morgan County, AL': '103', 'Perry County, AL': '105', 'Pickens County, AL': '107', 'Pike County, AL': '109', 'Randolph County, AL': '111', 'Russell County, AL': '113', 'Shelby County, AL': '117', 'St. Clair County, AL': '115', 'Sumter County, AL': '119', 'Talladega County, AL': '121', 'Tallapoosa County, AL': '123', 'Tuscaloosa County, AL': '125', 'Walker County, AL': '127', 'Washington County, AL': '129', 'Wilcox County, AL': '131', 'Winston County, AL': '133'}, '02': {'Aleutians East Borough, AK': '013', 'Aleutians West Census Area, AK': '016', 'Anchorage Borough/municipality, AK': '020', 'Bethel Census Area, AK': '050', 'Bristol Bay Borough, AK': '060', 'Denali Borough, AK': '068', 'Dillingham Census Area, AK': '070', 'Fairbanks North Star Borough, AK': '090', 'Haines Borough, AK': '100', 'Juneau Borough/city, AK': '110', 'Kenai Peninsula Borough, AK': '122', 'Ketchikan Gateway Borough, AK': '130', 'Kodiak Island Borough, AK': '150', 'Lake and Peninsula Borough, AK': '164', 'Matanuska-Susitna Borough, AK': '170', 'Nome Census Area, AK': '180', 'North Slope Borough, AK': '185', 'Northwest Arctic Borough, AK': '188', 'Prince of Wales-Outer Ketchikan Census Area, AK': '201', 'Sitka Borough/city, AK': '220', 'Skagway-Hoonah-Angoon Census Area, AK': '232', 'Southeast Fairbanks Census Area, AK': '240', 'Valdez-Cordova Census Area, AK': '261', 'Wade Hampton Census Area, AK': '270', 'Wrangell-Petersburg Census Area, AK': '280', 'Yakutat Borough, AK': '282', 'Yukon-Koyukuk Census Area, AK': '290'}, '04': {'Apache County, AZ': '001', 'Cochise County, AZ': '003', 'Coconino County, AZ': '005', 'Gila County, AZ': '007', 'Graham County, AZ': '009', 'Greenlee County, AZ': '011', 'La Paz County, AZ': '012', 'Maricopa County, AZ': '013', 'Mohave County, AZ': '015', 'Navajo County, AZ': '017', 'Pima County, AZ': '019', 'Pinal County, AZ': '021', 'Santa Cruz County, AZ': '023', 'Yavapai County, AZ': '025', 'Yuma County, AZ': '027'}, '05': {'Arkansas County, AR': '001', 'Ashley County, AR': '003', 'Baxter County, AR': '005', 'Benton County, AR': '007', 'Boone County, AR': '009', 'Bradley County, AR': '011', 'Calhoun County, AR': '013', 'Carroll County, AR': '015', 'Chicot County, AR': '017', 'Clark County, AR': '019', 'Clay County, AR': '021', 'Cleburne County, AR': '023', 'Cleveland County, AR': '025', 'Columbia County, AR': '027', 'Conway County, AR': '029', 'Craighead County, AR': '031', 'Crawford County, AR': '033', 'Crittenden County, AR': '035', 'Cross County, AR': '037', 'Dallas County, AR': '039', 'Desha County, AR': '041', 'Drew County, AR': '043', 'Faulkner County, AR': '045', 'Franklin County, AR': '047', 'Fulton County, AR': '049', 'Garland County, AR': '051', 'Grant County, AR': '053', 'Greene County, AR': '055', 'Hempstead County, AR': '057', 'Hot Spring County, AR': '059', 'Howard County, AR': '061', 'Independence County, AR': '063', 'Izard County, AR': '065', 'Jackson County, AR': '067', 'Jefferson County, AR': '069', 'Johnson County, AR': '071', 'Lafayette County, AR': '073', 'Lawrence County, AR': '075', 'Lee County, AR': '077', 'Lincoln County, AR': '079', 'Little River County, AR': '081', 'Logan County, AR': '083', 'Lonoke County, AR': '085', 'Madison County, AR': '087', 'Marion County, AR': '089', 'Miller County, AR': '091', 'Mississippi County, AR': '093', 'Monroe County, AR': '095', 'Montgomery County, AR': '097', 'Nevada County, AR': '099', 'Newton County, AR': '101', 'Ouachita County, AR': '103', 'Perry County, AR': '105', 'Phillips County, AR': '107', 'Pike County, AR': '109', 'Poinsett County, AR': '111', 'Polk County, AR': '113', 'Pope County, AR': '115', 'Prairie County, AR': '117', 'Pulaski County, AR': '119', 'Randolph County, AR': '121', 'Saline County, AR': '125', 'Scott County, AR': '127', 'Searcy County, AR': '129', 'Sebastian County, AR': '131', 'Sevier County, AR': '133', 'Sharp County, AR': '135', 'St. Francis County, AR': '123', 'Stone County, AR': '137', 'Union County, AR': '139', 'Van Buren County, AR': '141', 'Washington County, AR': '143', 'White County, AR': '145', 'Woodruff County, AR': '147', 'Yell County, AR': '149'}, '06': {'Alameda County, CA': '001', 'Alpine County, CA': '003', 'Amador County, CA': '005', 'Butte County, CA': '007', 'Calaveras County, CA': '009', 'Colusa County, CA': '011', 'Contra Costa County, CA': '013', 'Del Norte County, CA': '015', 'El Dorado County, CA': '017', 'Fresno County, CA': '019', 'Glenn County, CA': '021', 'Humboldt County, CA': '023', 'Imperial County, CA': '025', 'Inyo County, CA': '027', 'Kern County, CA': '029', 'Kings County, CA': '031', 'Lake County, CA': '033', 'Lassen County, CA': '035', 'Los Angeles County, CA': '037', 'Madera County, CA': '039', 'Marin County, CA': '041', 'Mariposa County, CA': '043', 'Mendocino County, CA': '045', 'Merced County, CA': '047', 'Modoc County, CA': '049', 'Mono County, CA': '051', 'Monterey County, CA': '053', 'Napa County, CA': '055', 'Nevada County, CA': '057', 'Orange County, CA': '059', 'Placer County, CA': '061', 'Plumas County, CA': '063', 'Riverside County, CA': '065', 'Sacramento County, CA': '067', 'San Benito County, CA': '069', 'San Bernardino County, CA': '071', 'San Diego County, CA': '073', 'San Francisco County/city, CA': '075', 'San Joaquin County, CA': '077', 'San Luis Obispo County, CA': '079', 'San Mateo County, CA': '081', 'Santa Barbara County, CA': '083', 'Santa Clara County, CA': '085', 'Santa Cruz County, CA': '087', 'Shasta County, CA': '089', 'Sierra County, CA': '091', 'Siskiyou County, CA': '093', 'Solano County, CA': '095', 'Sonoma County, CA': '097', 'Stanislaus County, CA': '099', 'Sutter County, CA': '101', 'Tehama County, CA': '103', 'Trinity County, CA': '105', 'Tulare County, CA': '107', 'Tuolumne County, CA': '109', 'Ventura County, CA': '111', 'Yolo County, CA': '113', 'Yuba County, CA': '115'}, '08': {'Adams County, CO': '001', 'Alamosa County, CO': '003', 'Arapahoe County, CO': '005', 'Archuleta County, CO': '007', 'Baca County, CO': '009', 'Bent County, CO': '011', 'Boulder County, CO': '013', 'Broomfield County/city, CO': '014', 'Chaffee County, CO': '015', 'Cheyenne County, CO': '017', 'Clear Creek County, CO': '019', 'Conejos County, CO': '021', 'Costilla County, CO': '023', 'Crowley County, CO': '025', 'Custer County, CO': '027', 'Delta County, CO': '029', 'Denver County/city, CO': '031', 'Dolores County, CO': '033', 'Douglas County, CO': '035', 'Eagle County, CO': '037', 'El Paso County, CO': '041', 'Elbert County, CO': '039', 'Fremont County, CO': '043', 'Garfield County, CO': '045', 'Gilpin County, CO': '047', 'Grand County, CO': '049', 'Gunnison County, CO': '051', 'Hinsdale County, CO': '053', 'Huerfano County, CO': '055', 'Jackson County, CO': '057', 'Jefferson County, CO': '059', 'Kiowa County, CO': '061', 'Kit Carson County, CO': '063', 'La Plata County, CO': '067', 'Lake County, CO': '065', 'Larimer County, CO': '069', 'Las Animas County, CO': '071', 'Lincoln County, CO': '073', 'Logan County, CO': '075', 'Mesa County, CO': '077', 'Mineral County, CO': '079', 'Moffat County, CO': '081', 'Montezuma County, CO': '083', 'Montrose County, CO': '085', 'Morgan County, CO': '087', 'Otero County, CO': '089', 'Ouray County, CO': '091', 'Park County, CO': '093', 'Phillips County, CO': '095', 'Pitkin County, CO': '097', 'Prowers County, CO': '099', 'Pueblo County, CO': '101', 'Rio Blanco County, CO': '103', 'Rio Grande County, CO': '105', 'Routt County, CO': '107', 'Saguache County, CO': '109', 'San Juan County, CO': '111', 'San Miguel County, CO': '113', 'Sedgwick County, CO': '115', 'Summit County, CO': '117', 'Teller County, CO': '119', 'Washington County, CO': '121', 'Weld County, CO': '123', 'Yuma County, CO': '125'}, '09': {'Fairfield County, CT': '001', 'Hartford County, CT': '003', 'Litchfield County, CT': '005', 'Middlesex County, CT': '007', 'New Haven County, CT': '009', 'New London County, CT': '011', 'Tolland County, CT': '013', 'Windham County, CT': '015'}, '10': {'Kent County, DE': '001', 'New Castle County, DE': '003', 'Sussex County, DE': '005'}, '11': {'District of Columbia': '001'}, '12': {'Alachua County, FL': '001', 'Baker County, FL': '003', 'Bay County, FL': '005', 'Bradford County, FL': '007', 'Brevard County, FL': '009', 'Broward County, FL': '011', 'Calhoun County, FL': '013', 'Charlotte County, FL': '015', 'Citrus County, FL': '017', 'Clay County, FL': '019', 'Collier County, FL': '021', 'Columbia County, FL': '023', 'DeSoto County, FL': '027', 'Dixie County, FL': '029', 'Duval County, FL': '031', 'Escambia County, FL': '033', 'Flagler County, FL': '035', 'Franklin County, FL': '037', 'Gadsden County, FL': '039', 'Gilchrist County, FL': '041', 'Glades County, FL': '043', 'Gulf County, FL': '045', 'Hamilton County, FL': '047', 'Hardee County, FL': '049', 'Hendry County, FL': '051', 'Hernando County, FL': '053', 'Highlands County, FL': '055', 'Hillsborough County, FL': '057', 'Holmes County, FL': '059', 'Indian River County, FL': '061', 'Jackson County, FL': '063', 'Jefferson County, FL': '065', 'Lafayette County, FL': '067', 'Lake County, FL': '069', 'Lee County, FL': '071', 'Leon County, FL': '073', 'Levy County, FL': '075', 'Liberty County, FL': '077', 'Madison County, FL': '079', 'Manatee County, FL': '081', 'Marion County, FL': '083', 'Martin County, FL': '085', 'Miami-Dade County, FL': '086', 'Monroe County, FL': '087', 'Nassau County, FL': '089', 'Okaloosa County, FL': '091', 'Okeechobee County, FL': '093', 'Orange County, FL': '095', 'Osceola County, FL': '097', 'Palm Beach County, FL': '099', 'Pasco County, FL': '101', 'Pinellas County, FL': '103', 'Polk County, FL': '105', 'Putnam County, FL': '107', 'Santa Rosa County, FL': '113', 'Sarasota County, FL': '115', 'Seminole County, FL': '117', 'St. Johns County, FL': '109', 'St. Lucie County, FL': '111', 'Sumter County, FL': '119', 'Suwannee County, FL': '121', 'Taylor County, FL': '123', 'Union County, FL': '125', 'Volusia County, FL': '127', 'Wakulla County, FL': '129', 'Walton County, FL': '131', 'Washington County, FL': '133'}, '13': {'Appling County, GA': '001', 'Atkinson County, GA': '003', 'Bacon County, GA': '005', 'Baker County, GA': '007', 'Baldwin County, GA': '009', 'Banks County, GA': '011', 'Barrow County, GA': '013', 'Bartow County, GA': '015', 'Ben Hill County, GA': '017', 'Berrien County, GA': '019', 'Bibb County, GA': '021', 'Bleckley County, GA': '023', 'Brantley County, GA': '025', 'Brooks County, GA': '027', 'Bryan County, GA': '029', 'Bulloch County, GA': '031', 'Burke County, GA': '033', 'Butts County, GA': '035', 'Calhoun County, GA': '037', 'Camden County, GA': '039', 'Candler County, GA': '043', 'Carroll County, GA': '045', 'Catoosa County, GA': '047', 'Charlton County, GA': '049', 'Chatham County, GA': '051', 'Chattahoochee County, GA': '053', 'Chattooga County, GA': '055', 'Cherokee County, GA': '057', 'Clarke County, GA': '059', 'Clay County, GA': '061', 'Clayton County, GA': '063', 'Clinch County, GA': '065', 'Cobb County, GA': '067', 'Coffee County, GA': '069', 'Colquitt County, GA': '071', 'Columbia County, GA': '073', 'Cook County, GA': '075', 'Coweta County, GA': '077', 'Crawford County, GA': '079', 'Crisp County, GA': '081', 'Dade County, GA': '083', 'Dawson County, GA': '085', 'DeKalb County, GA': '089', 'Decatur County, GA': '087', 'Dodge County, GA': '091', 'Dooly County, GA': '093', 'Dougherty County, GA': '095', 'Douglas County, GA': '097', 'Early County, GA': '099', 'Echols County, GA': '101', 'Effingham County, GA': '103', 'Elbert County, GA': '105', 'Emanuel County, GA': '107', 'Evans County, GA': '109', 'Fannin County, GA': '111', 'Fayette County, GA': '113', 'Floyd County, GA': '115', 'Forsyth County, GA': '117', 'Franklin County, GA': '119', 'Fulton County, GA': '121', 'Gilmer County, GA': '123', 'Glascock County, GA': '125', 'Glynn County, GA': '127', 'Gordon County, GA': '129', 'Grady County, GA': '131', 'Greene County, GA': '133', 'Gwinnett County, GA': '135', 'Habersham County, GA': '137', 'Hall County, GA': '139', 'Hancock County, GA': '141', 'Haralson County, GA': '143', 'Harris County, GA': '145', 'Hart County, GA': '147', 'Heard County, GA': '149', 'Henry County, GA': '151', 'Houston County, GA': '153', 'Irwin County, GA': '155', 'Jackson County, GA': '157', 'Jasper County, GA': '159', 'Jeff Davis County, GA': '161', 'Jefferson County, GA': '163', 'Jenkins County, GA': '165', 'Johnson County, GA': '167', 'Jones County, GA': '169', 'Lamar County, GA': '171', 'Lanier County, GA': '173', 'Laurens County, GA': '175', 'Lee County, GA': '177', 'Liberty County, GA': '179', 'Lincoln County, GA': '181', 'Long County, GA': '183', 'Lowndes County, GA': '185', 'Lumpkin County, GA': '187', 'Macon County, GA': '193', 'Madison County, GA': '195', 'Marion County, GA': '197', 'McDuffie County, GA': '189', 'McIntosh County, GA': '191', 'Meriwether County, GA': '199', 'Miller County, GA': '201', 'Mitchell County, GA': '205', 'Monroe County, GA': '207', 'Montgomery County, GA': '209', 'Morgan County, GA': '211', 'Murray County, GA': '213', 'Muscogee County, GA': '215', 'Newton County, GA': '217', 'Oconee County, GA': '219', 'Oglethorpe County, GA': '221', 'Paulding County, GA': '223', 'Peach County, GA': '225', 'Pickens County, GA': '227', 'Pierce County, GA': '229', 'Pike County, GA': '231', 'Polk County, GA': '233', 'Pulaski County, GA': '235', 'Putnam County, GA': '237', 'Quitman County, GA': '239', 'Rabun County, GA': '241', 'Randolph County, GA': '243', 'Richmond County, GA': '245', 'Rockdale County, GA': '247', 'Schley County, GA': '249', 'Screven County, GA': '251', 'Seminole County, GA': '253', 'Spalding County, GA': '255', 'Stephens County, GA': '257', 'Stewart County, GA': '259', 'Sumter County, GA': '261', 'Talbot County, GA': '263', 'Taliaferro County, GA': '265', 'Tattnall County, GA': '267', 'Taylor County, GA': '269', 'Telfair County, GA': '271', 'Terrell County, GA': '273', 'Thomas County, GA': '275', 'Tift County, GA': '277', 'Toombs County, GA': '279', 'Towns County, GA': '281', 'Treutlen County, GA': '283', 'Troup County, GA': '285', 'Turner County, GA': '287', 'Twiggs County, GA': '289', 'Union County, GA': '291', 'Upson County, GA': '293', 'Walker County, GA': '295', 'Walton County, GA': '297', 'Ware County, GA': '299', 'Warren County, GA': '301', 'Washington County, GA': '303', 'Wayne County, GA': '305', 'Webster County, GA': '307', 'Wheeler County, GA': '309', 'White County, GA': '311', 'Whitfield County, GA': '313', 'Wilcox County, GA': '315', 'Wilkes County, GA': '317', 'Wilkinson County, GA': '319', 'Worth County, GA': '321'}, '15': {'Hawaii County, HI': '001', 'Honolulu County/city, HI': '003', 'Kauai County, HI': '007', 'Maui County, HI': '009'}, '16': {'Ada County, ID': '001', 'Adams County, ID': '003', 'Bannock County, ID': '005', 'Bear Lake County, ID': '007', 'Benewah County, ID': '009', 'Bingham County, ID': '011', 'Blaine County, ID': '013', 'Boise County, ID': '015', 'Bonner County, ID': '017', 'Bonneville County, ID': '019', 'Boundary County, ID': '021', 'Butte County, ID': '023', 'Camas County, ID': '025', 'Canyon County, ID': '027', 'Caribou County, ID': '029', 'Cassia County, ID': '031', 'Clark County, ID': '033', 'Clearwater County, ID': '035', 'Custer County, ID': '037', 'Elmore County, ID': '039', 'Franklin County, ID': '041', 'Fremont County, ID': '043', 'Gem County, ID': '045', 'Gooding County, ID': '047', 'Idaho County, ID': '049', 'Jefferson County, ID': '051', 'Jerome County, ID': '053', 'Kootenai County, ID': '055', 'Latah County, ID': '057', 'Lemhi County, ID': '059', 'Lewis County, ID': '061', 'Lincoln County, ID': '063', 'Madison County, ID': '065', 'Minidoka County, ID': '067', 'Nez Perce County, ID': '069', 'Oneida County, ID': '071', 'Owyhee County, ID': '073', 'Payette County, ID': '075', 'Power County, ID': '077', 'Shoshone County, ID': '079', 'Teton County, ID': '081', 'Twin Falls County, ID': '083', 'Valley County, ID': '085', 'Washington County, ID': '087'}, '17': {'Adams County, IL': '001', 'Alexander County, IL': '003', 'Bond County, IL': '005', 'Boone County, IL': '007', 'Brown County, IL': '009', 'Bureau County, IL': '011', 'Calhoun County, IL': '013', 'Carroll County, IL': '015', 'Cass County, IL': '017', 'Champaign County, IL': '019', 'Christian County, IL': '021', 'Clark County, IL': '023', 'Clay County, IL': '025', 'Clinton County, IL': '027', 'Coles County, IL': '029', 'Cook County, IL': '031', 'Crawford County, IL': '033', 'Cumberland County, IL': '035', 'De Witt County, IL': '039', 'DeKalb County, IL': '037', 'Douglas County, IL': '041', 'DuPage County, IL': '043', 'Edgar County, IL': '045', 'Edwards County, IL': '047', 'Effingham County, IL': '049', 'Fayette County, IL': '051', 'Ford County, IL': '053', 'Franklin County, IL': '055', 'Fulton County, IL': '057', 'Gallatin County, IL': '059', 'Greene County, IL': '061', 'Grundy County, IL': '063', 'Hamilton County, IL': '065', 'Hancock County, IL': '067', 'Hardin County, IL': '069', 'Henderson County, IL': '071', 'Henry County, IL': '073', 'Iroquois County, IL': '075', 'Jackson County, IL': '077', 'Jasper County, IL': '079', 'Jefferson County, IL': '081', 'Jersey County, IL': '083', 'Jo Daviess County, IL': '085', 'Johnson County, IL': '087', 'Kane County, IL': '089', 'Kankakee County, IL': '091', 'Kendall County, IL': '093', 'Knox County, IL': '095', 'La Salle County, IL': '099', 'Lake County, IL': '097', 'Lawrence County, IL': '101', 'Lee County, IL': '103', 'Livingston County, IL': '105', 'Logan County, IL': '107', 'Macon County, IL': '115', 'Macoupin County, IL': '117', 'Madison County, IL': '119', 'Marion County, IL': '121', 'Marshall County, IL': '123', 'Mason County, IL': '125', 'Massac County, IL': '127', 'McDonough County, IL': '109', 'McHenry County, IL': '111', 'McLean County, IL': '113', 'Menard County, IL': '129', 'Mercer County, IL': '131', 'Monroe County, IL': '133', 'Montgomery County, IL': '135', 'Morgan County, IL': '137', 'Moultrie County, IL': '139', 'Ogle County, IL': '141', 'Peoria County, IL': '143', 'Perry County, IL': '145', 'Piatt County, IL': '147', 'Pike County, IL': '149', 'Pope County, IL': '151', 'Pulaski County, IL': '153', 'Putnam County, IL': '155', 'Randolph County, IL': '157', 'Richland County, IL': '159', 'Rock Island County, IL': '161', 'Saline County, IL': '165', 'Sangamon County, IL': '167', 'Schuyler County, IL': '169', 'Scott County, IL': '171', 'Shelby County, IL': '173', 'St. Clair County, IL': '163', 'Stark County, IL': '175', 'Stephenson County, IL': '177', 'Tazewell County, IL': '179', 'Union County, IL': '181', 'Vermilion County, IL': '183', 'Wabash County, IL': '185', 'Warren County, IL': '187', 'Washington County, IL': '189', 'Wayne County, IL': '191', 'White County, IL': '193', 'Whiteside County, IL': '195', 'Will County, IL': '197', 'Williamson County, IL': '199', 'Winnebago County, IL': '201', 'Woodford County, IL': '203'}, '18': {'Adams County, IN': '001', 'Allen County, IN': '003', 'Bartholomew County, IN': '005', 'Benton County, IN': '007', 'Blackford County, IN': '009', 'Boone County, IN': '011', 'Brown County, IN': '013', 'Carroll County, IN': '015', 'Cass County, IN': '017', 'Clark County, IN': '019', 'Clay County, IN': '021', 'Clinton County, IN': '023', 'Crawford County, IN': '025', 'Daviess County, IN': '027', 'DeKalb County, IN': '033', 'Dearborn County, IN': '029', 'Decatur County, IN': '031', 'Delaware County, IN': '035', 'Dubois County, IN': '037', 'Elkhart County, IN': '039', 'Fayette County, IN': '041', 'Floyd County, IN': '043', 'Fountain County, IN': '045', 'Franklin County, IN': '047', 'Fulton County, IN': '049', 'Gibson County, IN': '051', 'Grant County, IN': '053', 'Greene County, IN': '055', 'Hamilton County, IN': '057', 'Hancock County, IN': '059', 'Harrison County, IN': '061', 'Hendricks County, IN': '063', 'Henry County, IN': '065', 'Howard County, IN': '067', 'Huntington County, IN': '069', 'Jackson County, IN': '071', 'Jasper County, IN': '073', 'Jay County, IN': '075', 'Jefferson County, IN': '077', 'Jennings County, IN': '079', 'Johnson County, IN': '081', 'Knox County, IN': '083', 'Kosciusko County, IN': '085', 'LaGrange County, IN': '087', 'LaPorte County, IN': '091', 'Lake County, IN': '089', 'Lawrence County, IN': '093', 'Madison County, IN': '095', 'Marion County, IN': '097', 'Marshall County, IN': '099', 'Martin County, IN': '101', 'Miami County, IN': '103', 'Monroe County, IN': '105', 'Montgomery County, IN': '107', 'Morgan County, IN': '109', 'Newton County, IN': '111', 'Noble County, IN': '113', 'Ohio County, IN': '115', 'Orange County, IN': '117', 'Owen County, IN': '119', 'Parke County, IN': '121', 'Perry County, IN': '123', 'Pike County, IN': '125', 'Porter County, IN': '127', 'Posey County, IN': '129', 'Pulaski County, IN': '131', 'Putnam County, IN': '133', 'Randolph County, IN': '135', 'Ripley County, IN': '137', 'Rush County, IN': '139', 'Scott County, IN': '143', 'Shelby County, IN': '145', 'Spencer County, IN': '147', 'St. Joseph County, IN': '141', 'Starke County, IN': '149', 'Steuben County, IN': '151', 'Sullivan County, IN': '153', 'Switzerland County, IN': '155', 'Tippecanoe County, IN': '157', 'Tipton County, IN': '159', 'Union County, IN': '161', 'Vanderburgh County, IN': '163', 'Vermillion County, IN': '165', 'Vigo County, IN': '167', 'Wabash County, IN': '169', 'Warren County, IN': '171', 'Warrick County, IN': '173', 'Washington County, IN': '175', 'Wayne County, IN': '177', 'Wells County, IN': '179', 'White County, IN': '181', 'Whitley County, IN': '183'}, '19': {'Adair County, IA': '001', 'Adams County, IA': '003', 'Allamakee County, IA': '005', 'Appanoose County, IA': '007', 'Audubon County, IA': '009', 'Benton County, IA': '011', 'Black Hawk County, IA': '013', 'Boone County, IA': '015', 'Bremer County, IA': '017', 'Buchanan County, IA': '019', 'Buena Vista County, IA': '021', 'Butler County, IA': '023', 'Calhoun County, IA': '025', 'Carroll County, IA': '027', 'Cass County, IA': '029', 'Cedar County, IA': '031', 'Cerro Gordo County, IA': '033', 'Cherokee County, IA': '035', 'Chickasaw County, IA': '037', 'Clarke County, IA': '039', 'Clay County, IA': '041', 'Clayton County, IA': '043', 'Clinton County, IA': '045', 'Crawford County, IA': '047', 'Dallas County, IA': '049', 'Davis County, IA': '051', 'Decatur County, IA': '053', 'Delaware County, IA': '055', 'Des Moines County, IA': '057', 'Dickinson County, IA': '059', 'Dubuque County, IA': '061', 'Emmet County, IA': '063', 'Fayette County, IA': '065', 'Floyd County, IA': '067', 'Franklin County, IA': '069', 'Fremont County, IA': '071', 'Greene County, IA': '073', 'Grundy County, IA': '075', 'Guthrie County, IA': '077', 'Hamilton County, IA': '079', 'Hancock County, IA': '081', 'Hardin County, IA': '083', 'Harrison County, IA': '085', 'Henry County, IA': '087', 'Howard County, IA': '089', 'Humboldt County, IA': '091', 'Ida County, IA': '093', 'Iowa County, IA': '095', 'Jackson County, IA': '097', 'Jasper County, IA': '099', 'Jefferson County, IA': '101', 'Johnson County, IA': '103', 'Jones County, IA': '105', 'Keokuk County, IA': '107', 'Kossuth County, IA': '109', 'Lee County, IA': '111', 'Linn County, IA': '113', 'Louisa County, IA': '115', 'Lucas County, IA': '117', 'Lyon County, IA': '119', 'Madison County, IA': '121', 'Mahaska County, IA': '123', 'Marion County, IA': '125', 'Marshall County, IA': '127', 'Mills County, IA': '129', 'Mitchell County, IA': '131', 'Monona County, IA': '133', 'Monroe County, IA': '135', 'Montgomery County, IA': '137', 'Muscatine County, IA': '139', "O'Brien County, IA": '141', 'Osceola County, IA': '143', 'Page County, IA': '145', 'Palo Alto County, IA': '147', 'Plymouth County, IA': '149', 'Pocahontas County, IA': '151', 'Polk County, IA': '153', 'Pottawattamie County, IA': '155', 'Poweshiek County, IA': '157', 'Ringgold County, IA': '159', 'Sac County, IA': '161', 'Scott County, IA': '163', 'Shelby County, IA': '165', 'Sioux County, IA': '167', 'Story County, IA': '169', 'Tama County, IA': '171', 'Taylor County, IA': '173', 'Union County, IA': '175', 'Van Buren County, IA': '177', 'Wapello County, IA': '179', 'Warren County, IA': '181', 'Washington County, IA': '183', 'Wayne County, IA': '185', 'Webster County, IA': '187', 'Winnebago County, IA': '189', 'Winneshiek County, IA': '191', 'Woodbury County, IA': '193', 'Worth County, IA': '195', 'Wright County, IA': '197'}, '20': {'Allen County, KS': '001', 'Anderson County, KS': '003', 'Atchison County, KS': '005', 'Barber County, KS': '007', 'Barton County, KS': '009', 'Bourbon County, KS': '011', 'Brown County, KS': '013', 'Butler County, KS': '015', 'Chase County, KS': '017', 'Chautauqua County, KS': '019', 'Cherokee County, KS': '021', 'Cheyenne County, KS': '023', 'Clark County, KS': '025', 'Clay County, KS': '027', 'Cloud County, KS': '029', 'Coffey County, KS': '031', 'Comanche County, KS': '033', 'Cowley County, KS': '035', 'Crawford County, KS': '037', 'Decatur County, KS': '039', 'Dickinson County, KS': '041', 'Doniphan County, KS': '043', 'Douglas County, KS': '045', 'Edwards County, KS': '047', 'Elk County, KS': '049', 'Ellis County, KS': '051', 'Ellsworth County, KS': '053', 'Finney County, KS': '055', 'Ford County, KS': '057', 'Franklin County, KS': '059', 'Geary County, KS': '061', 'Gove County, KS': '063', 'Graham County, KS': '065', 'Grant County, KS': '067', 'Gray County, KS': '069', 'Greeley County, KS': '071', 'Greenwood County, KS': '073', 'Hamilton County, KS': '075', 'Harper County, KS': '077', 'Harvey County, KS': '079', 'Haskell County, KS': '081', 'Hodgeman County, KS': '083', 'Jackson County, KS': '085', 'Jefferson County, KS': '087', 'Jewell County, KS': '089', 'Johnson County, KS': '091', 'Kearny County, KS': '093', 'Kingman County, KS': '095', 'Kiowa County, KS': '097', 'Labette County, KS': '099', 'Lane County, KS': '101', 'Leavenworth County, KS': '103', 'Lincoln County, KS': '105', 'Linn County, KS': '107', 'Logan County, KS': '109', 'Lyon County, KS': '111', 'Marion County, KS': '115', 'Marshall County, KS': '117', 'McPherson County, KS': '113', 'Meade County, KS': '119', 'Miami County, KS': '121', 'Mitchell County, KS': '123', 'Montgomery County, KS': '125', 'Morris County, KS': '127', 'Morton County, KS': '129', 'Nemaha County, KS': '131', 'Neosho County, KS': '133', 'Ness County, KS': '135', 'Norton County, KS': '137', 'Osage County, KS': '139', 'Osborne County, KS': '141', 'Ottawa County, KS': '143', 'Pawnee County, KS': '145', 'Phillips County, KS': '147', 'Pottawatomie County, KS': '149', 'Pratt County, KS': '151', 'Rawlins County, KS': '153', 'Reno County, KS': '155', 'Republic County, KS': '157', 'Rice County, KS': '159', 'Riley County, KS': '161', 'Rooks County, KS': '163', 'Rush County, KS': '165', 'Russell County, KS': '167', 'Saline County, KS': '169', 'Scott County, KS': '171', 'Sedgwick County, KS': '173', 'Seward County, KS': '175', 'Shawnee County, KS': '177', 'Sheridan County, KS': '179', 'Sherman County, KS': '181', 'Smith County, KS': '183', 'Stafford County, KS': '185', 'Stanton County, KS': '187', 'Stevens County, KS': '189', 'Sumner County, KS': '191', 'Thomas County, KS': '193', 'Trego County, KS': '195', 'Wabaunsee County, KS': '197', 'Wallace County, KS': '199', 'Washington County, KS': '201', 'Wichita County, KS': '203', 'Wilson County, KS': '205', 'Woodson County, KS': '207', 'Wyandotte County, KS': '209'}, '21': {'Adair County, KY': '001', 'Allen County, KY': '003', 'Anderson County, KY': '005', 'Ballard County, KY': '007', 'Barren County, KY': '009', 'Bath County, KY': '011', 'Bell County, KY': '013', 'Boone County, KY': '015', 'Bourbon County, KY': '017', 'Boyd County, KY': '019', 'Boyle County, KY': '021', 'Bracken County, KY': '023', 'Breathitt County, KY': '025', 'Breckinridge County, KY': '027', 'Bullitt County, KY': '029', 'Butler County, KY': '031', 'Caldwell County, KY': '033', 'Calloway County, KY': '035', 'Campbell County, KY': '037', 'Carlisle County, KY': '039', 'Carroll County, KY': '041', 'Carter County, KY': '043', 'Casey County, KY': '045', 'Christian County, KY': '047', 'Clark County, KY': '049', 'Clay County, KY': '051', 'Clinton County, KY': '053', 'Crittenden County, KY': '055', 'Cumberland County, KY': '057', 'Daviess County, KY': '059', 'Edmonson County, KY': '061', 'Elliott County, KY': '063', 'Estill County, KY': '065', 'Fayette County, KY': '067', 'Fleming County, KY': '069', 'Floyd County, KY': '071', 'Franklin County, KY': '073', 'Fulton County, KY': '075', 'Gallatin County, KY': '077', 'Garrard County, KY': '079', 'Grant County, KY': '081', 'Graves County, KY': '083', 'Grayson County, KY': '085', 'Green County, KY': '087', 'Greenup County, KY': '089', 'Hancock County, KY': '091', 'Hardin County, KY': '093', 'Harlan County, KY': '095', 'Harrison County, KY': '097', 'Hart County, KY': '099', 'Henderson County, KY': '101', 'Henry County, KY': '103', 'Hickman County, KY': '105', 'Hopkins County, KY': '107', 'Jackson County, KY': '109', 'Jefferson County, KY': '111', 'Jessamine County, KY': '113', 'Johnson County, KY': '115', 'Kenton County, KY': '117', 'Knott County, KY': '119', 'Knox County, KY': '121', 'Larue County, KY': '123', 'Laurel County, KY': '125', 'Lawrence County, KY': '127', 'Lee County, KY': '129', 'Leslie County, KY': '131', 'Letcher County, KY': '133', 'Lewis County, KY': '135', 'Lincoln County, KY': '137', 'Livingston County, KY': '139', 'Logan County, KY': '141', 'Lyon County, KY': '143', 'Madison County, KY': '151', 'Magoffin County, KY': '153', 'Marion County, KY': '155', 'Marshall County, KY': '157', 'Martin County, KY': '159', 'Mason County, KY': '161', 'McCracken County, KY': '145', 'McCreary County, KY': '147', 'McLean County, KY': '149', 'Meade County, KY': '163', 'Menifee County, KY': '165', 'Mercer County, KY': '167', 'Metcalfe County, KY': '169', 'Monroe County, KY': '171', 'Montgomery County, KY': '173', 'Morgan County, KY': '175', 'Muhlenberg County, KY': '177', 'Nelson County, KY': '179', 'Nicholas County, KY': '181', 'Ohio County, KY': '183', 'Oldham County, KY': '185', 'Owen County, KY': '187', 'Owsley County, KY': '189', 'Pendleton County, KY': '191', 'Perry County, KY': '193', 'Pike County, KY': '195', 'Powell County, KY': '197', 'Pulaski County, KY': '199', 'Robertson County, KY': '201', 'Rockcastle County, KY': '203', 'Rowan County, KY': '205', 'Russell County, KY': '207', 'Scott County, KY': '209', 'Shelby County, KY': '211', 'Simpson County, KY': '213', 'Spencer County, KY': '215', 'Taylor County, KY': '217', 'Todd County, KY': '219', 'Trigg County, KY': '221', 'Trimble County, KY': '223', 'Union County, KY': '225', 'Warren County, KY': '227', 'Washington County, KY': '229', 'Wayne County, KY': '231', 'Webster County, KY': '233', 'Whitley County, KY': '235', 'Wolfe County, KY': '237', 'Woodford County, KY': '239'}, '22': {'Acadia Parish, LA': '001', 'Allen Parish, LA': '003', 'Ascension Parish, LA': '005', 'Assumption Parish, LA': '007', 'Avoyelles Parish, LA': '009', 'Beauregard Parish, LA': '011', 'Bienville Parish, LA': '013', 'Bossier Parish, LA': '015', 'Caddo Parish, LA': '017', 'Calcasieu Parish, LA': '019', 'Caldwell Parish, LA': '021', 'Cameron Parish, LA': '023', 'Catahoula Parish, LA': '025', 'Claiborne Parish, LA': '027', 'Concordia Parish, LA': '029', 'De Soto Parish, LA': '031', 'East Baton Rouge Parish, LA': '033', 'East Carroll Parish, LA': '035', 'East Feliciana Parish, LA': '037', 'Evangeline Parish, LA': '039', 'Franklin Parish, LA': '041', 'Grant Parish, LA': '043', 'Iberia Parish, LA': '045', 'Iberville Parish, LA': '047', 'Jackson Parish, LA': '049', 'Jefferson Davis Parish, LA': '053', 'Jefferson Parish, LA': '051', 'La Salle Parish, LA': '059', 'Lafayette Parish, LA': '055', 'Lafourche Parish, LA': '057', 'Lincoln Parish, LA': '061', 'Livingston Parish, LA': '063', 'Madison Parish, LA': '065', 'Morehouse Parish, LA': '067', 'Natchitoches Parish, LA': '069', 'Orleans Parish, LA': '071', 'Ouachita Parish, LA': '073', 'Plaquemines Parish, LA': '075', 'Pointe Coupee Parish, LA': '077', 'Rapides Parish, LA': '079', 'Red River Parish, LA': '081', 'Richland Parish, LA': '083', 'Sabine Parish, LA': '085', 'St. Bernard Parish, LA': '087', 'St. Charles Parish, LA': '089', 'St. Helena Parish, LA': '091', 'St. James Parish, LA': '093', 'St. John the Baptist Parish, LA': '095', 'St. Landry Parish, LA': '097', 'St. Martin Parish, LA': '099', 'St. Mary Parish, LA': '101', 'St. Tammany Parish, LA': '103', 'Tangipahoa Parish, LA': '105', 'Tensas Parish, LA': '107', 'Terrebonne Parish, LA': '109', 'Union Parish, LA': '111', 'Vermilion Parish, LA': '113', 'Vernon Parish, LA': '115', 'Washington Parish, LA': '117', 'Webster Parish, LA': '119', 'West Baton Rouge Parish, LA': '121', 'West Carroll Parish, LA': '123', 'West Feliciana Parish, LA': '125', 'Winn Parish, LA': '127'}, '23': {'Androscoggin County, ME': '001', 'Aroostook County, ME': '003', 'Cumberland County, ME': '005', 'Franklin County, ME': '007', 'Hancock County, ME': '009', 'Kennebec County, ME': '011', 'Knox County, ME': '013', 'Lincoln County, ME': '015', 'Oxford County, ME': '017', 'Penobscot County, ME': '019', 'Piscataquis County, ME': '021', 'Sagadahoc County, ME': '023', 'Somerset County, ME': '025', 'Waldo County, ME': '027', 'Washington County, ME': '029', 'York County, ME': '031'}, '24': {'Allegany County, MD': '001', 'Anne Arundel County, MD': '003', 'Baltimore County, MD': '005', 'Baltimore city, MD': '510', 'Calvert County, MD': '009', 'Caroline County, MD': '011', 'Carroll County, MD': '013', 'Cecil County, MD': '015', 'Charles County, MD': '017', 'Dorchester County, MD': '019', 'Frederick County, MD': '021', 'Garrett County, MD': '023', 'Harford County, MD': '025', 'Howard County, MD': '027', 'Kent County, MD': '029', 'Montgomery County, MD': '031', "Prince George's County, MD": '033', "Queen Anne's County, MD": '035', 'Somerset County, MD': '039', "St. Mary's County, MD": '037', 'Talbot County, MD': '041', 'Washington County, MD': '043', 'Wicomico County, MD': '045', 'Worcester County, MD': '047'}, '25': {'Barnstable County, MA': '001', 'Berkshire County, MA': '003', 'Bristol County, MA': '005', 'Dukes County, MA': '007', 'Essex County, MA': '009', 'Franklin County, MA': '011', 'Hampden County, MA': '013', 'Hampshire County, MA': '015', 'Middlesex County, MA': '017', 'Nantucket County/town, MA': '019', 'Norfolk County, MA': '021', 'Plymouth County, MA': '023', 'Suffolk County, MA': '025', 'Worcester County, MA': '027'}, '26': {'Alcona County, MI': '001', 'Alger County, MI': '003', 'Allegan County, MI': '005', 'Alpena County, MI': '007', 'Antrim County, MI': '009', 'Arenac County, MI': '011', 'Baraga County, MI': '013', 'Barry County, MI': '015', 'Bay County, MI': '017', 'Benzie County, MI': '019', 'Berrien County, MI': '021', 'Branch County, MI': '023', 'Calhoun County, MI': '025', 'Cass County, MI': '027', 'Charlevoix County, MI': '029', 'Cheboygan County, MI': '031', 'Chippewa County, MI': '033', 'Clare County, MI': '035', 'Clinton County, MI': '037', 'Crawford County, MI': '039', 'Delta County, MI': '041', 'Dickinson County, MI': '043', 'Eaton County, MI': '045', 'Emmet County, MI': '047', 'Genesee County, MI': '049', 'Gladwin County, MI': '051', 'Gogebic County, MI': '053', 'Grand Traverse County, MI': '055', 'Gratiot County, MI': '057', 'Hillsdale County, MI': '059', 'Houghton County, MI': '061', 'Huron County, MI': '063', 'Ingham County, MI': '065', 'Ionia County, MI': '067', 'Iosco County, MI': '069', 'Iron County, MI': '071', 'Isabella County, MI': '073', 'Jackson County, MI': '075', 'Kalamazoo County, MI': '077', 'Kalkaska County, MI': '079', 'Kent County, MI': '081', 'Keweenaw County, MI': '083', 'Lake County, MI': '085', 'Lapeer County, MI': '087', 'Leelanau County, MI': '089', 'Lenawee County, MI': '091', 'Livingston County, MI': '093', 'Luce County, MI': '095', 'Mackinac County, MI': '097', 'Macomb County, MI': '099', 'Manistee County, MI': '101', 'Marquette County, MI': '103', 'Mason County, MI': '105', 'Mecosta County, MI': '107', 'Menominee County, MI': '109', 'Midland County, MI': '111', 'Missaukee County, MI': '113', 'Monroe County, MI': '115', 'Montcalm County, MI': '117', 'Montmorency County, MI': '119', 'Muskegon County, MI': '121', 'Newaygo County, MI': '123', 'Oakland County, MI': '125', 'Oceana County, MI': '127', 'Ogemaw County, MI': '129', 'Ontonagon County, MI': '131', 'Osceola County, MI': '133', 'Oscoda County, MI': '135', 'Otsego County, MI': '137', 'Ottawa County, MI': '139', 'Presque Isle County, MI': '141', 'Roscommon County, MI': '143', 'Saginaw County, MI': '145', 'Sanilac County, MI': '151', 'Schoolcraft County, MI': '153', 'Shiawassee County, MI': '155', 'St. Clair County, MI': '147', 'St. Joseph County, MI': '149', 'Tuscola County, MI': '157', 'Van Buren County, MI': '159', 'Washtenaw County, MI': '161', 'Wayne County, MI': '163', 'Wexford County, MI': '165'}, '27': {'Aitkin County, MN': '001', 'Anoka County, MN': '003', 'Becker County, MN': '005', 'Beltrami County, MN': '007', 'Benton County, MN': '009', 'Big Stone County, MN': '011', 'Blue Earth County, MN': '013', 'Brown County, MN': '015', 'Carlton County, MN': '017', 'Carver County, MN': '019', 'Cass County, MN': '021', 'Chippewa County, MN': '023', 'Chisago County, MN': '025', 'Clay County, MN': '027', 'Clearwater County, MN': '029', 'Cook County, MN': '031', 'Cottonwood County, MN': '033', 'Crow Wing County, MN': '035', 'Dakota County, MN': '037', 'Dodge County, MN': '039', 'Douglas County, MN': '041', 'Faribault County, MN': '043', 'Fillmore County, MN': '045', 'Freeborn County, MN': '047', 'Goodhue County, MN': '049', 'Grant County, MN': '051', 'Hennepin County, MN': '053', 'Houston County, MN': '055', 'Hubbard County, MN': '057', 'Isanti County, MN': '059', 'Itasca County, MN': '061', 'Jackson County, MN': '063', 'Kanabec County, MN': '065', 'Kandiyohi County, MN': '067', 'Kittson County, MN': '069', 'Koochiching County, MN': '071', 'Lac qui Parle County, MN': '073', 'Lake County, MN': '075', 'Lake of the Woods County, MN': '077', 'Le Sueur County, MN': '079', 'Lincoln County, MN': '081', 'Lyon County, MN': '083', 'Mahnomen County, MN': '087', 'Marshall County, MN': '089', 'Martin County, MN': '091', 'McLeod County, MN': '085', 'Meeker County, MN': '093', 'Mille Lacs County, MN': '095', 'Morrison County, MN': '097', 'Mower County, MN': '099', 'Murray County, MN': '101', 'Nicollet County, MN': '103', 'Nobles County, MN': '105', 'Norman County, MN': '107', 'Olmsted County, MN': '109', 'Otter Tail County, MN': '111', 'Pennington County, MN': '113', 'Pine County, MN': '115', 'Pipestone County, MN': '117', 'Polk County, MN': '119', 'Pope County, MN': '121', 'Ramsey County, MN': '123', 'Red Lake County, MN': '125', 'Redwood County, MN': '127', 'Renville County, MN': '129', 'Rice County, MN': '131', 'Rock County, MN': '133', 'Roseau County, MN': '135', 'Scott County, MN': '139', 'Sherburne County, MN': '141', 'Sibley County, MN': '143', 'St. Louis County, MN': '137', 'Stearns County, MN': '145', 'Steele County, MN': '147', 'Stevens County, MN': '149', 'Swift County, MN': '151', 'Todd County, MN': '153', 'Traverse County, MN': '155', 'Wabasha County, MN': '157', 'Wadena County, MN': '159', 'Waseca County, MN': '161', 'Washington County, MN': '163', 'Watonwan County, MN': '165', 'Wilkin County, MN': '167', 'Winona County, MN': '169', 'Wright County, MN': '171', 'Yellow Medicine County, MN': '173'}, '28': {'Adams County, MS': '001', 'Alcorn County, MS': '003', 'Amite County, MS': '005', 'Attala County, MS': '007', 'Benton County, MS': '009', 'Bolivar County, MS': '011', 'Calhoun County, MS': '013', 'Carroll County, MS': '015', 'Chickasaw County, MS': '017', 'Choctaw County, MS': '019', 'Claiborne County, MS': '021', 'Clarke County, MS': '023', 'Clay County, MS': '025', 'Coahoma County, MS': '027', 'Copiah County, MS': '029', 'Covington County, MS': '031', 'DeSoto County, MS': '033', 'Forrest County, MS': '035', 'Franklin County, MS': '037', 'George County, MS': '039', 'Greene County, MS': '041', 'Grenada County, MS': '043', 'Hancock County, MS': '045', 'Harrison County, MS': '047', 'Hinds County, MS': '049', 'Holmes County, MS': '051', 'Humphreys County, MS': '053', 'Issaquena County, MS': '055', 'Itawamba County, MS': '057', 'Jackson County, MS': '059', 'Jasper County, MS': '061', 'Jefferson County, MS': '063', 'Jefferson Davis County, MS': '065', 'Jones County, MS': '067', 'Kemper County, MS': '069', 'Lafayette County, MS': '071', 'Lamar County, MS': '073', 'Lauderdale County, MS': '075', 'Lawrence County, MS': '077', 'Leake County, MS': '079', 'Lee County, MS': '081', 'Leflore County, MS': '083', 'Lincoln County, MS': '085', 'Lowndes County, MS': '087', 'Madison County, MS': '089', 'Marion County, MS': '091', 'Marshall County, MS': '093', 'Monroe County, MS': '095', 'Montgomery County, MS': '097', 'Neshoba County, MS': '099', 'Newton County, MS': '101', 'Noxubee County, MS': '103', 'Oktibbeha County, MS': '105', 'Panola County, MS': '107', 'Pearl River County, MS': '109', 'Perry County, MS': '111', 'Pike County, MS': '113', 'Pontotoc County, MS': '115', 'Prentiss County, MS': '117', 'Quitman County, MS': '119', 'Rankin County, MS': '121', 'Scott County, MS': '123', 'Sharkey County, MS': '125', 'Simpson County, MS': '127', 'Smith County, MS': '129', 'Stone County, MS': '131', 'Sunflower County, MS': '133', 'Tallahatchie County, MS': '135', 'Tate County, MS': '137', 'Tippah County, MS': '139', 'Tishomingo County, MS': '141', 'Tunica County, MS': '143', 'Union County, MS': '145', 'Walthall County, MS': '147', 'Warren County, MS': '149', 'Washington County, MS': '151', 'Wayne County, MS': '153', 'Webster County, MS': '155', 'Wilkinson County, MS': '157', 'Winston County, MS': '159', 'Yalobusha County, MS': '161', 'Yazoo County, MS': '163'}, '29': {'Adair County, MO': '001', 'Andrew County, MO': '003', 'Atchison County, MO': '005', 'Audrain County, MO': '007', 'Barry County, MO': '009', 'Barton County, MO': '011', 'Bates County, MO': '013', 'Benton County, MO': '015', 'Bollinger County, MO': '017', 'Boone County, MO': '019', 'Buchanan County, MO': '021', 'Butler County, MO': '023', 'Caldwell County, MO': '025', 'Callaway County, MO': '027', 'Camden County, MO': '029', 'Cape Girardeau County, MO': '031', 'Carroll County, MO': '033', 'Carter County, MO': '035', 'Cass County, MO': '037', 'Cedar County, MO': '039', 'Chariton County, MO': '041', 'Christian County, MO': '043', 'Clark County, MO': '045', 'Clay County, MO': '047', 'Clinton County, MO': '049', 'Cole County, MO': '051', 'Cooper County, MO': '053', 'Crawford County, MO': '055', 'Dade County, MO': '057', 'Dallas County, MO': '059', 'Daviess County, MO': '061', 'DeKalb County, MO': '063', 'Dent County, MO': '065', 'Douglas County, MO': '067', 'Dunklin County, MO': '069', 'Franklin County, MO': '071', 'Gasconade County, MO': '073', 'Gentry County, MO': '075', 'Greene County, MO': '077', 'Grundy County, MO': '079', 'Harrison County, MO': '081', 'Henry County, MO': '083', 'Hickory County, MO': '085', 'Holt County, MO': '087', 'Howard County, MO': '089', 'Howell County, MO': '091', 'Iron County, MO': '093', 'Jackson County, MO': '095', 'Jasper County, MO': '097', 'Jefferson County, MO': '099', 'Johnson County, MO': '101', 'Knox County, MO': '103', 'Laclede County, MO': '105', 'Lafayette County, MO': '107', 'Lawrence County, MO': '109', 'Lewis County, MO': '111', 'Lincoln County, MO': '113', 'Linn County, MO': '115', 'Livingston County, MO': '117', 'Macon County, MO': '121', 'Madison County, MO': '123', 'Maries County, MO': '125', 'Marion County, MO': '127', 'McDonald County, MO': '119', 'Mercer County, MO': '129', 'Miller County, MO': '131', 'Mississippi County, MO': '133', 'Moniteau County, MO': '135', 'Monroe County, MO': '137', 'Montgomery County, MO': '139', 'Morgan County, MO': '141', 'New Madrid County, MO': '143', 'Newton County, MO': '145', 'Nodaway County, MO': '147', 'Oregon County, MO': '149', 'Osage County, MO': '151', 'Ozark County, MO': '153', 'Pemiscot County, MO': '155', 'Perry County, MO': '157', 'Pettis County, MO': '159', 'Phelps County, MO': '161', 'Pike County, MO': '163', 'Platte County, MO': '165', 'Polk County, MO': '167', 'Pulaski County, MO': '169', 'Putnam County, MO': '171', 'Ralls County, MO': '173', 'Randolph County, MO': '175', 'Ray County, MO': '177', 'Reynolds County, MO': '179', 'Ripley County, MO': '181', 'Saline County, MO': '195', 'Schuyler County, MO': '197', 'Scotland County, MO': '199', 'Scott County, MO': '201', 'Shannon County, MO': '203', 'Shelby County, MO': '205', 'St. Charles County, MO': '183', 'St. Clair County, MO': '185', 'St. Francois County, MO': '187', 'St. Louis County, MO': '189', 'St. Louis city, MO': '510', 'Ste. Genevieve County, MO': '186', 'Stoddard County, MO': '207', 'Stone County, MO': '209', 'Sullivan County, MO': '211', 'Taney County, MO': '213', 'Texas County, MO': '215', 'Vernon County, MO': '217', 'Warren County, MO': '219', 'Washington County, MO': '221', 'Wayne County, MO': '223', 'Webster County, MO': '225', 'Worth County, MO': '227', 'Wright County, MO': '229'}, '30': {'Beaverhead County, MT': '001', 'Big Horn County, MT': '003', 'Blaine County, MT': '005', 'Broadwater County, MT': '007', 'Carbon County, MT': '009', 'Carter County, MT': '011', 'Cascade County, MT': '013', 'Chouteau County, MT': '015', 'Custer County, MT': '017', 'Daniels County, MT': '019', 'Dawson County, MT': '021', 'Deer Lodge County, MT': '023', 'Fallon County, MT': '025', 'Fergus County, MT': '027', 'Flathead County, MT': '029', 'Gallatin County, MT': '031', 'Garfield County, MT': '033', 'Glacier County, MT': '035', 'Golden Valley County, MT': '037', 'Granite County, MT': '039', 'Hill County, MT': '041', 'Jefferson County, MT': '043', 'Judith Basin County, MT': '045', 'Lake County, MT': '047', 'Lewis and Clark County, MT': '049', 'Liberty County, MT': '051', 'Lincoln County, MT': '053', 'Madison County, MT': '057', 'McCone County, MT': '055', 'Meagher County, MT': '059', 'Mineral County, MT': '061', 'Missoula County, MT': '063', 'Musselshell County, MT': '065', 'Park County, MT': '067', 'Petroleum County, MT': '069', 'Phillips County, MT': '071', 'Pondera County, MT': '073', 'Powder River County, MT': '075', 'Powell County, MT': '077', 'Prairie County, MT': '079', 'Ravalli County, MT': '081', 'Richland County, MT': '083', 'Roosevelt County, MT': '085', 'Rosebud County, MT': '087', 'Sanders County, MT': '089', 'Sheridan County, MT': '091', 'Silver Bow County, MT': '093', 'Stillwater County, MT': '095', 'Sweet Grass County, MT': '097', 'Teton County, MT': '099', 'Toole County, MT': '101', 'Treasure County, MT': '103', 'Valley County, MT': '105', 'Wheatland County, MT': '107', 'Wibaux County, MT': '109', 'Yellowstone County, MT': '111'}, '31': {'Adams County, NE': '001', 'Antelope County, NE': '003', 'Arthur County, NE': '005', 'Banner County, NE': '007', 'Blaine County, NE': '009', 'Boone County, NE': '011', 'Box Butte County, NE': '013', 'Boyd County, NE': '015', 'Brown County, NE': '017', 'Buffalo County, NE': '019', 'Burt County, NE': '021', 'Butler County, NE': '023', 'Cass County, NE': '025', 'Cedar County, NE': '027', 'Chase County, NE': '029', 'Cherry County, NE': '031', 'Cheyenne County, NE': '033', 'Clay County, NE': '035', 'Colfax County, NE': '037', 'Cuming County, NE': '039', 'Custer County, NE': '041', 'Dakota County, NE': '043', 'Dawes County, NE': '045', 'Dawson County, NE': '047', 'Deuel County, NE': '049', 'Dixon County, NE': '051', 'Dodge County, NE': '053', 'Douglas County, NE': '055', 'Dundy County, NE': '057', 'Fillmore County, NE': '059', 'Franklin County, NE': '061', 'Frontier County, NE': '063', 'Furnas County, NE': '065', 'Gage County, NE': '067', 'Garden County, NE': '069', 'Garfield County, NE': '071', 'Gosper County, NE': '073', 'Grant County, NE': '075', 'Greeley County, NE': '077', 'Hall County, NE': '079', 'Hamilton County, NE': '081', 'Harlan County, NE': '083', 'Hayes County, NE': '085', 'Hitchcock County, NE': '087', 'Holt County, NE': '089', 'Hooker County, NE': '091', 'Howard County, NE': '093', 'Jefferson County, NE': '095', 'Johnson County, NE': '097', 'Kearney County, NE': '099', 'Keith County, NE': '101', 'Keya Paha County, NE': '103', 'Kimball County, NE': '105', 'Knox County, NE': '107', 'Lancaster County, NE': '109', 'Lincoln County, NE': '111', 'Logan County, NE': '113', 'Loup County, NE': '115', 'Madison County, NE': '119', 'McPherson County, NE': '117', 'Merrick County, NE': '121', 'Morrill County, NE': '123', 'Nance County, NE': '125', 'Nemaha County, NE': '127', 'Nuckolls County, NE': '129', 'Otoe County, NE': '131', 'Pawnee County, NE': '133', 'Perkins County, NE': '135', 'Phelps County, NE': '137', 'Pierce County, NE': '139', 'Platte County, NE': '141', 'Polk County, NE': '143', 'Red Willow County, NE': '145', 'Richardson County, NE': '147', 'Rock County, NE': '149', 'Saline County, NE': '151', 'Sarpy County, NE': '153', 'Saunders County, NE': '155', 'Scotts Bluff County, NE': '157', 'Seward County, NE': '159', 'Sheridan County, NE': '161', 'Sherman County, NE': '163', 'Sioux County, NE': '165', 'Stanton County, NE': '167', 'Thayer County, NE': '169', 'Thomas County, NE': '171', 'Thurston County, NE': '173', 'Valley County, NE': '175', 'Washington County, NE': '177', 'Wayne County, NE': '179', 'Webster County, NE': '181', 'Wheeler County, NE': '183', 'York County, NE': '185'}, '32': {'Carson City, NV': '510', 'Churchill County, NV': '001', 'Clark County, NV': '003', 'Douglas County, NV': '005', 'Elko County, NV': '007', 'Esmeralda County, NV': '009', 'Eureka County, NV': '011', 'Humboldt County, NV': '013', 'Lander County, NV': '015', 'Lincoln County, NV': '017', 'Lyon County, NV': '019', 'Mineral County, NV': '021', 'Nye County, NV': '023', 'Pershing County, NV': '027', 'Storey County, NV': '029', 'Washoe County, NV': '031', 'White Pine County, NV': '033'}, '33': {'Belknap County, NH': '001', 'Carroll County, NH': '003', 'Cheshire County, NH': '005', 'Coos County, NH': '007', 'Grafton County, NH': '009', 'Hillsborough County, NH': '011', 'Merrimack County, NH': '013', 'Rockingham County, NH': '015', 'Strafford County, NH': '017', 'Sullivan County, NH': '019'}, '34': {'Atlantic County, NJ': '001', 'Bergen County, NJ': '003', 'Burlington County, NJ': '005', 'Camden County, NJ': '007', 'Cape May County, NJ': '009', 'Cumberland County, NJ': '011', 'Essex County, NJ': '013', 'Gloucester County, NJ': '015', 'Hudson County, NJ': '017', 'Hunterdon County, NJ': '019', 'Mercer County, NJ': '021', 'Middlesex County, NJ': '023', 'Monmouth County, NJ': '025', 'Morris County, NJ': '027', 'Ocean County, NJ': '029', 'Passaic County, NJ': '031', 'Salem County, NJ': '033', 'Somerset County, NJ': '035', 'Sussex County, NJ': '037', 'Union County, NJ': '039', 'Warren County, NJ': '041'}, '35': {'Bernalillo County, NM': '001', 'Catron County, NM': '003', 'Chaves County, NM': '005', 'Cibola County, NM': '006', 'Colfax County, NM': '007', 'Curry County, NM': '009', 'DeBaca County, NM': '011', 'Dona Ana County, NM': '013', 'Eddy County, NM': '015', 'Grant County, NM': '017', 'Guadalupe County, NM': '019', 'Harding County, NM': '021', 'Hidalgo County, NM': '023', 'Lea County, NM': '025', 'Lincoln County, NM': '027', 'Los Alamos County, NM': '028', 'Luna County, NM': '029', 'McKinley County, NM': '031', 'Mora County, NM': '033', 'Otero County, NM': '035', 'Quay County, NM': '037', 'Rio Arriba County, NM': '039', 'Roosevelt County, NM': '041', 'San Juan County, NM': '045', 'San Miguel County, NM': '047', 'Sandoval County, NM': '043', 'Santa Fe County, NM': '049', 'Sierra County, NM': '051', 'Socorro County, NM': '053', 'Taos County, NM': '055', 'Torrance County, NM': '057', 'Union County, NM': '059', 'Valencia County, NM': '061'}, '36': {'Albany County, NY': '001', 'Allegany County, NY': '003', 'Bronx County, NY': '005', 'Broome County, NY': '007', 'Cattaraugus County, NY': '009', 'Cayuga County, NY': '011', 'Chautauqua County, NY': '013', 'Chemung County, NY': '015', 'Chenango County, NY': '017', 'Clinton County, NY': '019', 'Columbia County, NY': '021', 'Cortland County, NY': '023', 'Delaware County, NY': '025', 'Dutchess County, NY': '027', 'Erie County, NY': '029', 'Essex County, NY': '031', 'Franklin County, NY': '033', 'Fulton County, NY': '035', 'Genesee County, NY': '037', 'Greene County, NY': '039', 'Hamilton County, NY': '041', 'Herkimer County, NY': '043', 'Jefferson County, NY': '045', 'Kings County, NY': '047', 'Lewis County, NY': '049', 'Livingston County, NY': '051', 'Madison County, NY': '053', 'Monroe County, NY': '055', 'Montgomery County, NY': '057', 'Nassau County, NY': '059', 'New York County, NY': '061', 'Niagara County, NY': '063', 'Oneida County, NY': '065', 'Onondaga County, NY': '067', 'Ontario County, NY': '069', 'Orange County, NY': '071', 'Orleans County, NY': '073', 'Oswego County, NY': '075', 'Otsego County, NY': '077', 'Putnam County, NY': '079', 'Queens County, NY': '081', 'Rensselaer County, NY': '083', 'Richmond County, NY': '085', 'Rockland County, NY': '087', 'Saratoga County, NY': '091', 'Schenectady County, NY': '093', 'Schoharie County, NY': '095', 'Schuyler County, NY': '097', 'Seneca County, NY': '099', 'St. Lawrence County, NY': '089', 'Steuben County, NY': '101', 'Suffolk County, NY': '103', 'Sullivan County, NY': '105', 'Tioga County, NY': '107', 'Tompkins County, NY': '109', 'Ulster County, NY': '111', 'Warren County, NY': '113', 'Washington County, NY': '115', 'Wayne County, NY': '117', 'Westchester County, NY': '119', 'Wyoming County, NY': '121', 'Yates County, NY': '123'}, '37': {'Alamance County, NC': '001', 'Alexander County, NC': '003', 'Alleghany County, NC': '005', 'Anson County, NC': '007', 'Ashe County, NC': '009', 'Avery County, NC': '011', 'Beaufort County, NC': '013', 'Bertie County, NC': '015', 'Bladen County, NC': '017', 'Brunswick County, NC': '019', 'Buncombe County, NC': '021', 'Burke County, NC': '023', 'Cabarrus County, NC': '025', 'Caldwell County, NC': '027', 'Camden County, NC': '029', 'Carteret County, NC': '031', 'Caswell County, NC': '033', 'Catawba County, NC': '035', 'Chatham County, NC': '037', 'Cherokee County, NC': '039', 'Chowan County, NC': '041', 'Clay County, NC': '043', 'Cleveland County, NC': '045', 'Columbus County, NC': '047', 'Craven County, NC': '049', 'Cumberland County, NC': '051', 'Currituck County, NC': '053', 'Dare County, NC': '055', 'Davidson County, NC': '057', 'Davie County, NC': '059', 'Duplin County, NC': '061', 'Durham County, NC': '063', 'Edgecombe County, NC': '065', 'Forsyth County, NC': '067', 'Franklin County, NC': '069', 'Gaston County, NC': '071', 'Gates County, NC': '073', 'Graham County, NC': '075', 'Granville County, NC': '077', 'Greene County, NC': '079', 'Guilford County, NC': '081', 'Halifax County, NC': '083', 'Harnett County, NC': '085', 'Haywood County, NC': '087', 'Henderson County, NC': '089', 'Hertford County, NC': '091', 'Hoke County, NC': '093', 'Hyde County, NC': '095', 'Iredell County, NC': '097', 'Jackson County, NC': '099', 'Johnston County, NC': '101', 'Jones County, NC': '103', 'Lee County, NC': '105', 'Lenoir County, NC': '107', 'Lincoln County, NC': '109', 'Macon County, NC': '113', 'Madison County, NC': '115', 'Martin County, NC': '117', 'McDowell County, NC': '111', 'Mecklenburg County, NC': '119', 'Mitchell County, NC': '121', 'Montgomery County, NC': '123', 'Moore County, NC': '125', 'Nash County, NC': '127', 'New Hanover County, NC': '129', 'Northampton County, NC': '131', 'Onslow County, NC': '133', 'Orange County, NC': '135', 'Pamlico County, NC': '137', 'Pasquotank County, NC': '139', 'Pender County, NC': '141', 'Perquimans County, NC': '143', 'Person County, NC': '145', 'Pitt County, NC': '147', 'Polk County, NC': '149', 'Randolph County, NC': '151', 'Richmond County, NC': '153', 'Robeson County, NC': '155', 'Rockingham County, NC': '157', 'Rowan County, NC': '159', 'Rutherford County, NC': '161', 'Sampson County, NC': '163', 'Scotland County, NC': '165', 'Stanly County, NC': '167', 'Stokes County, NC': '169', 'Surry County, NC': '171', 'Swain County, NC': '173', 'Transylvania County, NC': '175', 'Tyrrell County, NC': '177', 'Union County, NC': '179', 'Vance County, NC': '181', 'Wake County, NC': '183', 'Warren County, NC': '185', 'Washington County, NC': '187', 'Watauga County, NC': '189', 'Wayne County, NC': '191', 'Wilkes County, NC': '193', 'Wilson County, NC': '195', 'Yadkin County, NC': '197', 'Yancey County, NC': '199'}, '38': {'Adams County, ND': '001', 'Barnes County, ND': '003', 'Benson County, ND': '005', 'Billings County, ND': '007', 'Bottineau County, ND': '009', 'Bowman County, ND': '011', 'Burke County, ND': '013', 'Burleigh County, ND': '015', 'Cass County, ND': '017', 'Cavalier County, ND': '019', 'Dickey County, ND': '021', 'Divide County, ND': '023', 'Dunn County, ND': '025', 'Eddy County, ND': '027', 'Emmons County, ND': '029', 'Foster County, ND': '031', 'Golden Valley County, ND': '033', 'Grand Forks County, ND': '035', 'Grant County, ND': '037', 'Griggs County, ND': '039', 'Hettinger County, ND': '041', 'Kidder County, ND': '043', 'LaMoure County, ND': '045', 'Logan County, ND': '047', 'McHenry County, ND': '049', 'McIntosh County, ND': '051', 'McKenzie County, ND': '053', 'McLean County, ND': '055', 'Mercer County, ND': '057', 'Morton County, ND': '059', 'Mountrail County, ND': '061', 'Nelson County, ND': '063', 'Oliver County, ND': '065', 'Pembina County, ND': '067', 'Pierce County, ND': '069', 'Ramsey County, ND': '071', 'Ransom County, ND': '073', 'Renville County, ND': '075', 'Richland County, ND': '077', 'Rolette County, ND': '079', 'Sargent County, ND': '081', 'Sheridan County, ND': '083', 'Sioux County, ND': '085', 'Slope County, ND': '087', 'Stark County, ND': '089', 'Steele County, ND': '091', 'Stutsman County, ND': '093', 'Towner County, ND': '095', 'Traill County, ND': '097', 'Walsh County, ND': '099', 'Ward County, ND': '101', 'Wells County, ND': '103', 'Williams County, ND': '105'}, '39': {'Adams County, OH': '001', 'Allen County, OH': '003', 'Ashland County, OH': '005', 'Ashtabula County, OH': '007', 'Athens County, OH': '009', 'Auglaize County, OH': '011', 'Belmont County, OH': '013', 'Brown County, OH': '015', 'Butler County, OH': '017', 'Carroll County, OH': '019', 'Champaign County, OH': '021', 'Clark County, OH': '023', 'Clermont County, OH': '025', 'Clinton County, OH': '027', 'Columbiana County, OH': '029', 'Coshocton County, OH': '031', 'Crawford County, OH': '033', 'Cuyahoga County, OH': '035', 'Darke County, OH': '037', 'Defiance County, OH': '039', 'Delaware County, OH': '041', 'Erie County, OH': '043', 'Fairfield County, OH': '045', 'Fayette County, OH': '047', 'Franklin County, OH': '049', 'Fulton County, OH': '051', 'Gallia County, OH': '053', 'Geauga County, OH': '055', 'Greene County, OH': '057', 'Guernsey County, OH': '059', 'Hamilton County, OH': '061', 'Hancock County, OH': '063', 'Hardin County, OH': '065', 'Harrison County, OH': '067', 'Henry County, OH': '069', 'Highland County, OH': '071', 'Hocking County, OH': '073', 'Holmes County, OH': '075', 'Huron County, OH': '077', 'Jackson County, OH': '079', 'Jefferson County, OH': '081', 'Knox County, OH': '083', 'Lake County, OH': '085', 'Lawrence County, OH': '087', 'Licking County, OH': '089', 'Logan County, OH': '091', 'Lorain County, OH': '093', 'Lucas County, OH': '095', 'Madison County, OH': '097', 'Mahoning County, OH': '099', 'Marion County, OH': '101', 'Medina County, OH': '103', 'Meigs County, OH': '105', 'Mercer County, OH': '107', 'Miami County, OH': '109', 'Monroe County, OH': '111', 'Montgomery County, OH': '113', 'Morgan County, OH': '115', 'Morrow County, OH': '117', 'Muskingum County, OH': '119', 'Noble County, OH': '121', 'Ottawa County, OH': '123', 'Paulding County, OH': '125', 'Perry County, OH': '127', 'Pickaway County, OH': '129', 'Pike County, OH': '131', 'Portage County, OH': '133', 'Preble County, OH': '135', 'Putnam County, OH': '137', 'Richland County, OH': '139', 'Ross County, OH': '141', 'Sandusky County, OH': '143', 'Scioto County, OH': '145', 'Seneca County, OH': '147', 'Shelby County, OH': '149', 'Stark County, OH': '151', 'Summit County, OH': '153', 'Trumbull County, OH': '155', 'Tuscarawas County, OH': '157', 'Union County, OH': '159', 'Van Wert County, OH': '161', 'Vinton County, OH': '163', 'Warren County, OH': '165', 'Washington County, OH': '167', 'Wayne County, OH': '169', 'Williams County, OH': '171', 'Wood County, OH': '173', 'Wyandot County, OH': '175'}, '40': {'Adair County, OK': '001', 'Alfalfa County, OK': '003', 'Atoka County, OK': '005', 'Beaver County, OK': '007', 'Beckham County, OK': '009', 'Blaine County, OK': '011', 'Bryan County, OK': '013', 'Caddo County, OK': '015', 'Canadian County, OK': '017', 'Carter County, OK': '019', 'Cherokee County, OK': '021', 'Choctaw County, OK': '023', 'Cimarron County, OK': '025', 'Cleveland County, OK': '027', 'Coal County, OK': '029', 'Comanche County, OK': '031', 'Cotton County, OK': '033', 'Craig County, OK': '035', 'Creek County, OK': '037', 'Custer County, OK': '039', 'Delaware County, OK': '041', 'Dewey County, OK': '043', 'Ellis County, OK': '045', 'Garfield County, OK': '047', 'Garvin County, OK': '049', 'Grady County, OK': '051', 'Grant County, OK': '053', 'Greer County, OK': '055', 'Harmon County, OK': '057', 'Harper County, OK': '059', 'Haskell County, OK': '061', 'Hughes County, OK': '063', 'Jackson County, OK': '065', 'Jefferson County, OK': '067', 'Johnston County, OK': '069', 'Kay County, OK': '071', 'Kingfisher County, OK': '073', 'Kiowa County, OK': '075', 'Latimer County, OK': '077', 'Le Flore County, OK': '079', 'Lincoln County, OK': '081', 'Logan County, OK': '083', 'Love County, OK': '085', 'Major County, OK': '093', 'Marshall County, OK': '095', 'Mayes County, OK': '097', 'McClain County, OK': '087', 'McCurtain County, OK': '089', 'McIntosh County, OK': '091', 'Murray County, OK': '099', 'Muskogee County, OK': '101', 'Noble County, OK': '103', 'Nowata County, OK': '105', 'Okfuskee County, OK': '107', 'Oklahoma County, OK': '109', 'Okmulgee County, OK': '111', 'Osage County, OK': '113', 'Ottawa County, OK': '115', 'Pawnee County, OK': '117', 'Payne County, OK': '119', 'Pittsburg County, OK': '121', 'Pontotoc County, OK': '123', 'Pottawatomie County, OK': '125', 'Pushmataha County, OK': '127', 'Roger Mills County, OK': '129', 'Rogers County, OK': '131', 'Seminole County, OK': '133', 'Sequoyah County, OK': '135', 'Stephens County, OK': '137', 'Texas County, OK': '139', 'Tillman County, OK': '141', 'Tulsa County, OK': '143', 'Wagoner County, OK': '145', 'Washington County, OK': '147', 'Washita County, OK': '149', 'Woods County, OK': '151', 'Woodward County, OK': '153'}, '41': {'Baker County, OR': '001', 'Benton County, OR': '003', 'Clackamas County, OR': '005', 'Clatsop County, OR': '007', 'Columbia County, OR': '009', 'Coos County, OR': '011', 'Crook County, OR': '013', 'Curry County, OR': '015', 'Deschutes County, OR': '017', 'Douglas County, OR': '019', 'Gilliam County, OR': '021', 'Grant County, OR': '023', 'Harney County, OR': '025', 'Hood River County, OR': '027', 'Jackson County, OR': '029', 'Jefferson County, OR': '031', 'Josephine County, OR': '033', 'Klamath County, OR': '035', 'Lake County, OR': '037', 'Lane County, OR': '039', 'Lincoln County, OR': '041', 'Linn County, OR': '043', 'Malheur County, OR': '045', 'Marion County, OR': '047', 'Morrow County, OR': '049', 'Multnomah County, OR': '051', 'Polk County, OR': '053', 'Sherman County, OR': '055', 'Tillamook County, OR': '057', 'Umatilla County, OR': '059', 'Union County, OR': '061', 'Wallowa County, OR': '063', 'Wasco County, OR': '065', 'Washington County, OR': '067', 'Wheeler County, OR': '069', 'Yamhill County, OR': '071'}, '42': {'Adams County, PA': '001', 'Allegheny County, PA': '003', 'Armstrong County, PA': '005', 'Beaver County, PA': '007', 'Bedford County, PA': '009', 'Berks County, PA': '011', 'Blair County, PA': '013', 'Bradford County, PA': '015', 'Bucks County, PA': '017', 'Butler County, PA': '019', 'Cambria County, PA': '021', 'Cameron County, PA': '023', 'Carbon County, PA': '025', 'Centre County, PA': '027', 'Chester County, PA': '029', 'Clarion County, PA': '031', 'Clearfield County, PA': '033', 'Clinton County, PA': '035', 'Columbia County, PA': '037', 'Crawford County, PA': '039', 'Cumberland County, PA': '041', 'Dauphin County, PA': '043', 'Delaware County, PA': '045', 'Elk County, PA': '047', 'Erie County, PA': '049', 'Fayette County, PA': '051', 'Forest County, PA': '053', 'Franklin County, PA': '055', 'Fulton County, PA': '057', 'Greene County, PA': '059', 'Huntingdon County, PA': '061', 'Indiana County, PA': '063', 'Jefferson County, PA': '065', 'Juniata County, PA': '067', 'Lackawanna County, PA': '069', 'Lancaster County, PA': '071', 'Lawrence County, PA': '073', 'Lebanon County, PA': '075', 'Lehigh County, PA': '077', 'Luzerne County, PA': '079', 'Lycoming County, PA': '081', 'McKean County, PA': '083', 'Mercer County, PA': '085', 'Mifflin County, PA': '087', 'Monroe County, PA': '089', 'Montgomery County, PA': '091', 'Montour County, PA': '093', 'Northampton County, PA': '095', 'Northumberland County, PA': '097', 'Perry County, PA': '099', 'Philadelphia County/city, PA': '101', 'Pike County, PA': '103', 'Potter County, PA': '105', 'Schuylkill County, PA': '107', 'Snyder County, PA': '109', 'Somerset County, PA': '111', 'Sullivan County, PA': '113', 'Susquehanna County, PA': '115', 'Tioga County, PA': '117', 'Union County, PA': '119', 'Venango County, PA': '121', 'Warren County, PA': '123', 'Washington County, PA': '125', 'Wayne County, PA': '127', 'Westmoreland County, PA': '129', 'Wyoming County, PA': '131', 'York County, PA': '133'}, '44': {'Bristol County, RI': '001', 'Kent County, RI': '003', 'Newport County, RI': '005', 'Providence County, RI': '007', 'Washington County, RI': '009'}, '45': {'Abbeville County, SC': '001', 'Aiken County, SC': '003', 'Allendale County, SC': '005', 'Anderson County, SC': '007', 'Bamberg County, SC': '009', 'Barnwell County, SC': '011', 'Beaufort County, SC': '013', 'Berkeley County, SC': '015', 'Calhoun County, SC': '017', 'Charleston County, SC': '019', 'Cherokee County, SC': '021', 'Chester County, SC': '023', 'Chesterfield County, SC': '025', 'Clarendon County, SC': '027', 'Colleton County, SC': '029', 'Darlington County, SC': '031', 'Dillon County, SC': '033', 'Dorchester County, SC': '035', 'Edgefield County, SC': '037', 'Fairfield County, SC': '039', 'Florence County, SC': '041', 'Georgetown County, SC': '043', 'Greenville County, SC': '045', 'Greenwood County, SC': '047', 'Hampton County, SC': '049', 'Horry County, SC': '051', 'Jasper County, SC': '053', 'Kershaw County, SC': '055', 'Lancaster County, SC': '057', 'Laurens County, SC': '059', 'Lee County, SC': '061', 'Lexington County, SC': '063', 'Marion County, SC': '067', 'Marlboro County, SC': '069', 'McCormick County, SC': '065', 'Newberry County, SC': '071', 'Oconee County, SC': '073', 'Orangeburg County, SC': '075', 'Pickens County, SC': '077', 'Richland County, SC': '079', 'Saluda County, SC': '081', 'Spartanburg County, SC': '083', 'Sumter County, SC': '085', 'Union County, SC': '087', 'Williamsburg County, SC': '089', 'York County, SC': '091'}, '46': {'Aurora County, SD': '003', 'Beadle County, SD': '005', 'Bennett County, SD': '007', 'Bon Homme County, SD': '009', 'Brookings County, SD': '011', 'Brown County, SD': '013', 'Brule County, SD': '015', 'Buffalo County, SD': '017', 'Butte County, SD': '019', 'Campbell County, SD': '021', 'Charles Mix County, SD': '023', 'Clark County, SD': '025', 'Clay County, SD': '027', 'Codington County, SD': '029', 'Corson County, SD': '031', 'Custer County, SD': '033', 'Davison County, SD': '035', 'Day County, SD': '037', 'Deuel County, SD': '039', 'Dewey County, SD': '041', 'Douglas County, SD': '043', 'Edmunds County, SD': '045', 'Fall River County, SD': '047', 'Faulk County, SD': '049', 'Grant County, SD': '051', 'Gregory County, SD': '053', 'Haakon County, SD': '055', 'Hamlin County, SD': '057', 'Hand County, SD': '059', 'Hanson County, SD': '061', 'Harding County, SD': '063', 'Hughes County, SD': '065', 'Hutchinson County, SD': '067', 'Hyde County, SD': '069', 'Jackson County, SD': '071', 'Jerauld County, SD': '073', 'Jones County, SD': '075', 'Kingsbury County, SD': '077', 'Lake County, SD': '079', 'Lawrence County, SD': '081', 'Lincoln County, SD': '083', 'Lyman County, SD': '085', 'Marshall County, SD': '091', 'McCook County, SD': '087', 'McPherson County, SD': '089', 'Meade County, SD': '093', 'Mellette County, SD': '095', 'Miner County, SD': '097', 'Minnehaha County, SD': '099', 'Moody County, SD': '101', 'Pennington County, SD': '103', 'Perkins County, SD': '105', 'Potter County, SD': '107', 'Roberts County, SD': '109', 'Sanborn County, SD': '111', 'Shannon County, SD': '113', 'Spink County, SD': '115', 'Stanley County, SD': '117', 'Sully County, SD': '119', 'Todd County, SD': '121', 'Tripp County, SD': '123', 'Turner County, SD': '125', 'Union County, SD': '127', 'Walworth County, SD': '129', 'Yankton County, SD': '135', 'Ziebach County, SD': '137'}, '47': {'Anderson County, TN': '001', 'Bedford County, TN': '003', 'Benton County, TN': '005', 'Bledsoe County, TN': '007', 'Blount County, TN': '009', 'Bradley County, TN': '011', 'Campbell County, TN': '013', 'Cannon County, TN': '015', 'Carroll County, TN': '017', 'Carter County, TN': '019', 'Cheatham County, TN': '021', 'Chester County, TN': '023', 'Claiborne County, TN': '025', 'Clay County, TN': '027', 'Cocke County, TN': '029', 'Coffee County, TN': '031', 'Crockett County, TN': '033', 'Cumberland County, TN': '035', 'Davidson County, TN': '037', 'DeKalb County, TN': '041', 'Decatur County, TN': '039', 'Dickson County, TN': '043', 'Dyer County, TN': '045', 'Fayette County, TN': '047', 'Fentress County, TN': '049', 'Franklin County, TN': '051', 'Gibson County, TN': '053', 'Giles County, TN': '055', 'Grainger County, TN': '057', 'Greene County, TN': '059', 'Grundy County, TN': '061', 'Hamblen County, TN': '063', 'Hamilton County, TN': '065', 'Hancock County, TN': '067', 'Hardeman County, TN': '069', 'Hardin County, TN': '071', 'Hawkins County, TN': '073', 'Haywood County, TN': '075', 'Henderson County, TN': '077', 'Henry County, TN': '079', 'Hickman County, TN': '081', 'Houston County, TN': '083', 'Humphreys County, TN': '085', 'Jackson County, TN': '087', 'Jefferson County, TN': '089', 'Johnson County, TN': '091', 'Knox County, TN': '093', 'Lake County, TN': '095', 'Lauderdale County, TN': '097', 'Lawrence County, TN': '099', 'Lewis County, TN': '101', 'Lincoln County, TN': '103', 'Loudon County, TN': '105', 'Macon County, TN': '111', 'Madison County, TN': '113', 'Marion County, TN': '115', 'Marshall County, TN': '117', 'Maury County, TN': '119', 'McMinn County, TN': '107', 'McNairy County, TN': '109', 'Meigs County, TN': '121', 'Monroe County, TN': '123', 'Montgomery County, TN': '125', 'Moore County, TN': '127', 'Morgan County, TN': '129', 'Obion County, TN': '131', 'Overton County, TN': '133', 'Perry County, TN': '135', 'Pickett County, TN': '137', 'Polk County, TN': '139', 'Putnam County, TN': '141', 'Rhea County, TN': '143', 'Roane County, TN': '145', 'Robertson County, TN': '147', 'Rutherford County, TN': '149', 'Scott County, TN': '151', 'Sequatchie County, TN': '153', 'Sevier County, TN': '155', 'Shelby County, TN': '157', 'Smith County, TN': '159', 'Stewart County, TN': '161', 'Sullivan County, TN': '163', 'Sumner County, TN': '165', 'Tipton County, TN': '167', 'Trousdale County, TN': '169', 'Unicoi County, TN': '171', 'Union County, TN': '173', 'Van Buren County, TN': '175', 'Warren County, TN': '177', 'Washington County, TN': '179', 'Wayne County, TN': '181', 'Weakley County, TN': '183', 'White County, TN': '185', 'Williamson County, TN': '187', 'Wilson County, TN': '189'}, '48': {'Anderson County, TX': '001', 'Andrews County, TX': '003', 'Angelina County, TX': '005', 'Aransas County, TX': '007', 'Archer County, TX': '009', 'Armstrong County, TX': '011', 'Atascosa County, TX': '013', 'Austin County, TX': '015', 'Bailey County, TX': '017', 'Bandera County, TX': '019', 'Bastrop County, TX': '021', 'Baylor County, TX': '023', 'Bee County, TX': '025', 'Bell County, TX': '027', 'Bexar County, TX': '029', 'Blanco County, TX': '031', 'Borden County, TX': '033', 'Bosque County, TX': '035', 'Bowie County, TX': '037', 'Brazoria County, TX': '039', 'Brazos County, TX': '041', 'Brewster County, TX': '043', 'Briscoe County, TX': '045', 'Brooks County, TX': '047', 'Brown County, TX': '049', 'Burleson County, TX': '051', 'Burnet County, TX': '053', 'Caldwell County, TX': '055', 'Calhoun County, TX': '057', 'Callahan County, TX': '059', 'Cameron County, TX': '061', 'Camp County, TX': '063', 'Carson County, TX': '065', 'Cass County, TX': '067', 'Castro County, TX': '069', 'Chambers County, TX': '071', 'Cherokee County, TX': '073', 'Childress County, TX': '075', 'Clay County, TX': '077', 'Cochran County, TX': '079', 'Coke County, TX': '081', 'Coleman County, TX': '083', 'Collin County, TX': '085', 'Collingsworth County, TX': '087', 'Colorado County, TX': '089', 'Comal County, TX': '091', 'Comanche County, TX': '093', 'Concho County, TX': '095', 'Cooke County, TX': '097', 'Coryell County, TX': '099', 'Cottle County, TX': '101', 'Crane County, TX': '103', 'Crockett County, TX': '105', 'Crosby County, TX': '107', 'Culberson County, TX': '109', 'Dallam County, TX': '111', 'Dallas County, TX': '113', 'Dawson County, TX': '115', 'DeWitt County, TX': '123', 'Deaf Smith County, TX': '117', 'Delta County, TX': '119', 'Denton County, TX': '121', 'Dickens County, TX': '125', 'Dimmit County, TX': '127', 'Donley County, TX': '129', 'Duval County, TX': '131', 'Eastland County, TX': '133', 'Ector County, TX': '135', 'Edwards County, TX': '137', 'El Paso County, TX': '141', 'Ellis County, TX': '139', 'Erath County, TX': '143', 'Falls County, TX': '145', 'Fannin County, TX': '147', 'Fayette County, TX': '149', 'Fisher County, TX': '151', 'Floyd County, TX': '153', 'Foard County, TX': '155', 'Fort Bend County, TX': '157', 'Franklin County, TX': '159', 'Freestone County, TX': '161', 'Frio County, TX': '163', 'Gaines County, TX': '165', 'Galveston County, TX': '167', 'Garza County, TX': '169', 'Gillespie County, TX': '171', 'Glasscock County, TX': '173', 'Goliad County, TX': '175', 'Gonzales County, TX': '177', 'Gray County, TX': '179', 'Grayson County, TX': '181', 'Gregg County, TX': '183', 'Grimes County, TX': '185', 'Guadalupe County, TX': '187', 'Hale County, TX': '189', 'Hall County, TX': '191', 'Hamilton County, TX': '193', 'Hansford County, TX': '195', 'Hardeman County, TX': '197', 'Hardin County, TX': '199', 'Harris County, TX': '201', 'Harrison County, TX': '203', 'Hartley County, TX': '205', 'Haskell County, TX': '207', 'Hays County, TX': '209', 'Hemphill County, TX': '211', 'Henderson County, TX': '213', 'Hidalgo County, TX': '215', 'Hill County, TX': '217', 'Hockley County, TX': '219', 'Hood County, TX': '221', 'Hopkins County, TX': '223', 'Houston County, TX': '225', 'Howard County, TX': '227', 'Hudspeth County, TX': '229', 'Hunt County, TX': '231', 'Hutchinson County, TX': '233', 'Irion County, TX': '235', 'Jack County, TX': '237', 'Jackson County, TX': '239', 'Jasper County, TX': '241', 'Jeff Davis County, TX': '243', 'Jefferson County, TX': '245', 'Jim Hogg County, TX': '247', 'Jim Wells County, TX': '249', 'Johnson County, TX': '251', 'Jones County, TX': '253', 'Karnes County, TX': '255', 'Kaufman County, TX': '257', 'Kendall County, TX': '259', 'Kenedy County, TX': '261', 'Kent County, TX': '263', 'Kerr County, TX': '265', 'Kimble County, TX': '267', 'King County, TX': '269', 'Kinney County, TX': '271', 'Kleberg County, TX': '273', 'Knox County, TX': '275', 'La Salle County, TX': '283', 'Lamar County, TX': '277', 'Lamb County, TX': '279', 'Lampasas County, TX': '281', 'Lavaca County, TX': '285', 'Lee County, TX': '287', 'Leon County, TX': '289', 'Liberty County, TX': '291', 'Limestone County, TX': '293', 'Lipscomb County, TX': '295', 'Live Oak County, TX': '297', 'Llano County, TX': '299', 'Loving County, TX': '301', 'Lubbock County, TX': '303', 'Lynn County, TX': '305', 'Madison County, TX': '313', 'Marion County, TX': '315', 'Martin County, TX': '317', 'Mason County, TX': '319', 'Matagorda County, TX': '321', 'Maverick County, TX': '323', 'McCulloch County, TX': '307', 'McLennan County, TX': '309', 'McMullen County, TX': '311', 'Medina County, TX': '325', 'Menard County, TX': '327', 'Midland County, TX': '329', 'Milam County, TX': '331', 'Mills County, TX': '333', 'Mitchell County, TX': '335', 'Montague County, TX': '337', 'Montgomery County, TX': '339', 'Moore County, TX': '341', 'Morris County, TX': '343', 'Motley County, TX': '345', 'Nacogdoches County, TX': '347', 'Navarro County, TX': '349', 'Newton County, TX': '351', 'Nolan County, TX': '353', 'Nueces County, TX': '355', 'Ochiltree County, TX': '357', 'Oldham County, TX': '359', 'Orange County, TX': '361', 'Palo Pinto County, TX': '363', 'Panola County, TX': '365', 'Parker County, TX': '367', 'Parmer County, TX': '369', 'Pecos County, TX': '371', 'Polk County, TX': '373', 'Potter County, TX': '375', 'Presidio County, TX': '377', 'Rains County, TX': '379', 'Randall County, TX': '381', 'Reagan County, TX': '383', 'Real County, TX': '385', 'Red River County, TX': '387', 'Reeves County, TX': '389', 'Refugio County, TX': '391', 'Roberts County, TX': '393', 'Robertson County, TX': '395', 'Rockwall County, TX': '397', 'Runnels County, TX': '399', 'Rusk County, TX': '401', 'Sabine County, TX': '403', 'San Augustine County, TX': '405', 'San Jacinto County, TX': '407', 'San Patricio County, TX': '409', 'San Saba County, TX': '411', 'Schleicher County, TX': '413', 'Scurry County, TX': '415', 'Shackelford County, TX': '417', 'Shelby County, TX': '419', 'Sherman County, TX': '421', 'Smith County, TX': '423', 'Somervell County, TX': '425', 'Starr County, TX': '427', 'Stephens County, TX': '429', 'Sterling County, TX': '431', 'Stonewall County, TX': '433', 'Sutton County, TX': '435', 'Swisher County, TX': '437', 'Tarrant County, TX': '439', 'Taylor County, TX': '441', 'Terrell County, TX': '443', 'Terry County, TX': '445', 'Throckmorton County, TX': '447', 'Titus County, TX': '449', 'Tom Green County, TX': '451', 'Travis County, TX': '453', 'Trinity County, TX': '455', 'Tyler County, TX': '457', 'Upshur County, TX': '459', 'Upton County, TX': '461', 'Uvalde County, TX': '463', 'Val Verde County, TX': '465', 'Van Zandt County, TX': '467', 'Victoria County, TX': '469', 'Walker County, TX': '471', 'Waller County, TX': '473', 'Ward County, TX': '475', 'Washington County, TX': '477', 'Webb County, TX': '479', 'Wharton County, TX': '481', 'Wheeler County, TX': '483', 'Wichita County, TX': '485', 'Wilbarger County, TX': '487', 'Willacy County, TX': '489', 'Williamson County, TX': '491', 'Wilson County, TX': '493', 'Winkler County, TX': '495', 'Wise County, TX': '497', 'Wood County, TX': '499', 'Yoakum County, TX': '501', 'Young County, TX': '503', 'Zapata County, TX': '505', 'Zavala County, TX': '507'}, '49': {'Beaver County, UT': '001', 'Box Elder County, UT': '003', 'Cache County, UT': '005', 'Carbon County, UT': '007', 'Daggett County, UT': '009', 'Davis County, UT': '011', 'Duchesne County, UT': '013', 'Emery County, UT': '015', 'Garfield County, UT': '017', 'Grand County, UT': '019', 'Iron County, UT': '021', 'Juab County, UT': '023', 'Kane County, UT': '025', 'Millard County, UT': '027', 'Morgan County, UT': '029', 'Piute County, UT': '031', 'Rich County, UT': '033', 'Salt Lake County, UT': '035', 'San Juan County, UT': '037', 'Sanpete County, UT': '039', 'Sevier County, UT': '041', 'Summit County, UT': '043', 'Tooele County, UT': '045', 'Uintah County, UT': '047', 'Utah County, UT': '049', 'Wasatch County, UT': '051', 'Washington County, UT': '053', 'Wayne County, UT': '055', 'Weber County, UT': '057'}, '50': {'Addison County, VT': '001', 'Bennington County, VT': '003', 'Caledonia County, VT': '005', 'Chittenden County, VT': '007', 'Essex County, VT': '009', 'Franklin County, VT': '011', 'Grand Isle County, VT': '013', 'Lamoille County, VT': '015', 'Orange County, VT': '017', 'Orleans County, VT': '019', 'Rutland County, VT': '021', 'Washington County, VT': '023', 'Windham County, VT': '025', 'Windsor County, VT': '027'}, '51': {'Accomack County, VA': '001', 'Albemarle County, VA': '003', 'Alexandria city, VA': '510', 'Alleghany County, VA': '005', 'Amelia County, VA': '007', 'Amherst County, VA': '009', 'Appomattox County, VA': '011', 'Arlington County, VA': '013', 'Augusta County, VA': '015', 'Bath County, VA': '017', 'Bedford County, VA': '019', 'Bedford city, VA': '515', 'Bland County, VA': '021', 'Botetourt County, VA': '023', 'Bristol city, VA': '520', 'Brunswick County, VA': '025', 'Buchanan County, VA': '027', 'Buckingham County, VA': '029', 'Buena Vista city, VA': '530', 'Campbell County, VA': '031', 'Caroline County, VA': '033', 'Carroll County, VA': '035', 'Charles City County, VA': '036', 'Charlotte County, VA': '037', 'Charlottesville city, VA': '540', 'Chesapeake city, VA': '550', 'Chesterfield County, VA': '041', 'Clarke County, VA': '043', 'Colonial Heights city, VA': '570', 'Covington city, VA': '580', 'Craig County, VA': '045', 'Culpeper County, VA': '047', 'Cumberland County, VA': '049', 'Danville city, VA': '590', 'Dickenson County, VA': '051', 'Dinwiddie County, VA': '053', 'Emporia city, VA': '595', 'Essex County, VA': '057', 'Fairfax County, VA': '059', 'Fairfax city, VA': '600', 'Falls Church city, VA': '610', 'Fauquier County, VA': '061', 'Floyd County, VA': '063', 'Fluvanna County, VA': '065', 'Franklin County, VA': '067', 'Franklin city, VA': '620', 'Frederick County, VA': '069', 'Fredericksburg city, VA': '630', 'Galax city, VA': '640', 'Giles County, VA': '071', 'Gloucester County, VA': '073', 'Goochland County, VA': '075', 'Grayson County, VA': '077', 'Greene County, VA': '079', 'Greensville County, VA': '081', 'Halifax County, VA': '083', 'Hampton city, VA': '650', 'Hanover County, VA': '085', 'Harrisonburg city, VA': '660', 'Henrico County, VA': '087', 'Henry County, VA': '089', 'Highland County, VA': '091', 'Hopewell city, VA': '670', 'Isle of Wight County, VA': '093', 'James City County, VA': '095', 'King George County, VA': '099', 'King William County, VA': '101', 'King and Queen County, VA': '097', 'Lancaster County, VA': '103', 'Lee County, VA': '105', 'Lexington city, VA': '678', 'Loudoun County, VA': '107', 'Louisa County, VA': '109', 'Lunenburg County, VA': '111', 'Lynchburg city, VA': '680', 'Madison County, VA': '113', 'Manassas Park city, VA': '685', 'Manassas city, VA': '683', 'Martinsville city, VA': '690', 'Mathews County, VA': '115', 'Mecklenburg County, VA': '117', 'Middlesex County, VA': '119', 'Montgomery County, VA': '121', 'Nelson County, VA': '125', 'New Kent County, VA': '127', 'Newport News city, VA': '700', 'Norfolk city, VA': '710', 'Northampton County, VA': '131', 'Northumberland County, VA': '133', 'Norton city, VA': '720', 'Nottoway County, VA': '135', 'Orange County, VA': '137', 'Page County, VA': '139', 'Patrick County, VA': '141', 'Petersburg city, VA': '730', 'Pittsylvania County, VA': '143', 'Poquoson city, VA': '735', 'Portsmouth city, VA': '740', 'Powhatan County, VA': '145', 'Prince Edward County, VA': '147', 'Prince George County, VA': '149', 'Prince William County, VA': '153', 'Pulaski County, VA': '155', 'Radford city, VA': '750', 'Rappahannock County, VA': '157', 'Richmond County, VA': '159', 'Richmond city, VA': '760', 'Roanoke County, VA': '161', 'Roanoke city, VA': '770', 'Rockbridge County, VA': '163', 'Rockingham County, VA': '165', 'Russell County, VA': '167', 'Salem city, VA': '775', 'Scott County, VA': '169', 'Shenandoah County, VA': '171', 'Smyth County, VA': '173', 'Southampton County, VA': '175', 'Spotsylvania County, VA': '177', 'Stafford County, VA': '179', 'Staunton city, VA': '790', 'Suffolk city, VA': '800', 'Surry County, VA': '181', 'Sussex County, VA': '183', 'Tazewell County, VA': '185', 'Virginia Beach city, VA': '810', 'Warren County, VA': '187', 'Washington County, VA': '191', 'Waynesboro city, VA': '820', 'Westmoreland County, VA': '193', 'Williamsburg city, VA': '830', 'Winchester city, VA': '840', 'Wise County, VA': '195', 'Wythe County, VA': '197', 'York County, VA': '199'}, '53': {'Adams County, WA': '001', 'Asotin County, WA': '003', 'Benton County, WA': '005', 'Chelan County, WA': '007', 'Clallam County, WA': '009', 'Clark County, WA': '011', 'Columbia County, WA': '013', 'Cowlitz County, WA': '015', 'Douglas County, WA': '017', 'Ferry County, WA': '019', 'Franklin County, WA': '021', 'Garfield County, WA': '023', 'Grant County, WA': '025', 'Grays Harbor County, WA': '027', 'Island County, WA': '029', 'Jefferson County, WA': '031', 'King County, WA': '033', 'Kitsap County, WA': '035', 'Kittitas County, WA': '037', 'Klickitat County, WA': '039', 'Lewis County, WA': '041', 'Lincoln County, WA': '043', 'Mason County, WA': '045', 'Okanogan County, WA': '047', 'Pacific County, WA': '049', 'Pend Oreille County, WA': '051', 'Pierce County, WA': '053', 'San Juan County, WA': '055', 'Skagit County, WA': '057', 'Skamania County, WA': '059', 'Snohomish County, WA': '061', 'Spokane County, WA': '063', 'Stevens County, WA': '065', 'Thurston County, WA': '067', 'Wahkiakum County, WA': '069', 'Walla Walla County, WA': '071', 'Whatcom County, WA': '073', 'Whitman County, WA': '075', 'Yakima County, WA': '077'}, '54': {'Barbour County, WV': '001', 'Berkeley County, WV': '003', 'Boone County, WV': '005', 'Braxton County, WV': '007', 'Brooke County, WV': '009', 'Cabell County, WV': '011', 'Calhoun County, WV': '013', 'Clay County, WV': '015', 'Doddridge County, WV': '017', 'Fayette County, WV': '019', 'Gilmer County, WV': '021', 'Grant County, WV': '023', 'Greenbrier County, WV': '025', 'Hampshire County, WV': '027', 'Hancock County, WV': '029', 'Hardy County, WV': '031', 'Harrison County, WV': '033', 'Jackson County, WV': '035', 'Jefferson County, WV': '037', 'Kanawha County, WV': '039', 'Lewis County, WV': '041', 'Lincoln County, WV': '043', 'Logan County, WV': '045', 'Marion County, WV': '049', 'Marshall County, WV': '051', 'Mason County, WV': '053', 'McDowell County, WV': '047', 'Mercer County, WV': '055', 'Mineral County, WV': '057', 'Mingo County, WV': '059', 'Monongalia County, WV': '061', 'Monroe County, WV': '063', 'Morgan County, WV': '065', 'Nicholas County, WV': '067', 'Ohio County, WV': '069', 'Pendleton County, WV': '071', 'Pleasants County, WV': '073', 'Pocahontas County, WV': '075', 'Preston County, WV': '077', 'Putnam County, WV': '079', 'Raleigh County, WV': '081', 'Randolph County, WV': '083', 'Ritchie County, WV': '085', 'Roane County, WV': '087', 'Summers County, WV': '089', 'Taylor County, WV': '091', 'Tucker County, WV': '093', 'Tyler County, WV': '095', 'Upshur County, WV': '097', 'Wayne County, WV': '099', 'Webster County, WV': '101', 'Wetzel County, WV': '103', 'Wirt County, WV': '105', 'Wood County, WV': '107', 'Wyoming County, WV': '109'}, '55': {'Adams County, WI': '001', 'Ashland County, WI': '003', 'Barron County, WI': '005', 'Bayfield County, WI': '007', 'Brown County, WI': '009', 'Buffalo County, WI': '011', 'Burnett County, WI': '013', 'Calumet County, WI': '015', 'Chippewa County, WI': '017', 'Clark County, WI': '019', 'Columbia County, WI': '021', 'Crawford County, WI': '023', 'Dane County, WI': '025', 'Dodge County, WI': '027', 'Door County, WI': '029', 'Douglas County, WI': '031', 'Dunn County, WI': '033', 'Eau Claire County, WI': '035', 'Florence County, WI': '037', 'Fond du Lac County, WI': '039', 'Forest County, WI': '041', 'Grant County, WI': '043', 'Green County, WI': '045', 'Green Lake County, WI': '047', 'Iowa County, WI': '049', 'Iron County, WI': '051', 'Jackson County, WI': '053', 'Jefferson County, WI': '055', 'Juneau County, WI': '057', 'Kenosha County, WI': '059', 'Kewaunee County, WI': '061', 'La Crosse County, WI': '063', 'Lafayette County, WI': '065', 'Langlade County, WI': '067', 'Lincoln County, WI': '069', 'Manitowoc County, WI': '071', 'Marathon County, WI': '073', 'Marinette County, WI': '075', 'Marquette County, WI': '077', 'Menominee County, WI': '078', 'Milwaukee County, WI': '079', 'Monroe County, WI': '081', 'Oconto County, WI': '083', 'Oneida County, WI': '085', 'Outagamie County, WI': '087', 'Ozaukee County, WI': '089', 'Pepin County, WI': '091', 'Pierce County, WI': '093', 'Polk County, WI': '095', 'Portage County, WI': '097', 'Price County, WI': '099', 'Racine County, WI': '101', 'Richland County, WI': '103', 'Rock County, WI': '105', 'Rusk County, WI': '107', 'Sauk County, WI': '111', 'Sawyer County, WI': '113', 'Shawano County, WI': '115', 'Sheboygan County, WI': '117', 'St. Croix County, WI': '109', 'Taylor County, WI': '119', 'Trempealeau County, WI': '121', 'Vernon County, WI': '123', 'Vilas County, WI': '125', 'Walworth County, WI': '127', 'Washburn County, WI': '129', 'Washington County, WI': '131', 'Waukesha County, WI': '133', 'Waupaca County, WI': '135', 'Waushara County, WI': '137', 'Winnebago County, WI': '139', 'Wood County, WI': '141'}, '56': {'Albany County, WY': '001', 'Big Horn County, WY': '003', 'Campbell County, WY': '005', 'Carbon County, WY': '007', 'Converse County, WY': '009', 'Crook County, WY': '011', 'Fremont County, WY': '013', 'Goshen County, WY': '015', 'Hot Springs County, WY': '017', 'Johnson County, WY': '019', 'Laramie County, WY': '021', 'Lincoln County, WY': '023', 'Natrona County, WY': '025', 'Niobrara County, WY': '027', 'Park County, WY': '029', 'Platte County, WY': '031', 'Sheridan County, WY': '033', 'Sublette County, WY': '035', 'Sweetwater County, WY': '037', 'Teton County, WY': '039', 'Uinta County, WY': '041', 'Washakie County, WY': '043', 'Weston County, WY': '045'}, '72': {'Adjuntas Municipio, PR': '001', 'Aguada Municipio, PR': '003', 'Aguadilla Municipio, PR': '005', 'Aguas Buenas Municipio, PR': '007', 'Aibonito Municipio, PR': '009', 'Anasco Municipio, PR': '011', 'Arecibo Municipio, PR': '013', 'Arroyo Municipio, PR': '015', 'Barceloneta Municipio, PR': '017', 'Barranquitas Municipio, PR': '019', 'Bayamon Municipio, PR': '021', 'Cabo Rojo Municipio, PR': '023', 'Caguas Municipio, PR': '025', 'Camuy Municipio, PR': '027', 'Canovanas Municipio, PR': '029', 'Carolina Municipio, PR': '031', 'Catano Municipio, PR': '033', 'Cayey Municipio, PR': '035', 'Ceiba Municipio, PR': '037', 'Ciales Municipio, PR': '039', 'Cidra Municipio, PR': '041', 'Coamo Municipio, PR': '043', 'Comerio Municipio, PR': '045', 'Corozal Municipio, PR': '047', 'Culebra Municipio, PR': '049', 'Dorado Municipio, PR': '051', 'Fajardo Municipio, PR': '053', 'Florida Municipio, PR': '054', 'Guanica Municipio, PR': '055', 'Guayama Municipio, PR': '057', 'Guayanilla Municipio, PR': '059', 'Guaynabo Municipio, PR': '061', 'Gurabo Municipio, PR': '063', 'Hatillo Municipio, PR': '065', 'Hormigueros Municipio, PR': '067', 'Humacao Municipio, PR': '069', 'Isabela Municipio, PR': '071', 'Jayuya Municipio, PR': '073', 'Juana Diaz Municipio, PR': '075', 'Juncos Municipio, PR': '077', 'Lajas Municipio, PR': '079', 'Lares Municipio, PR': '081', 'Las Marias Municipio, PR': '083', 'Las Piedras Municipio, PR': '085', 'Loiza Municipio, PR': '087', 'Luquillo Municipio, PR': '089', 'Manati Municipio, PR': '091', 'Maricao Municipio, PR': '093', 'Maunabo Municipio, PR': '095', 'Mayaguez Municipio, PR': '097', 'Moca Municipio, PR': '099', 'Morovis Municipio, PR': '101', 'Naguabo Municipio, PR': '103', 'Naranjito Municipio, PR': '105', 'Orocovis Municipio, PR': '107', 'Patillas Municipio, PR': '109', 'Penuelas Municipio, PR': '111', 'Ponce Municipio, PR': '113', 'Quebradillas Municipio, PR': '115', 'Rincon Municipio, PR': '117', 'Rio Grande Municipio, PR': '119', 'Sabana Grande Municipio, PR': '121', 'Salinas Municipio, PR': '123', 'San German Municipio, PR': '125', 'San Juan Municipio, PR': '127', 'San Lorenzo Municipio, PR': '129', 'San Sebastian Municipio, PR': '131', 'Santa Isabel Municipio, PR': '133', 'Toa Alta Municipio, PR': '135', 'Toa Baja Municipio, PR': '137', 'Trujillo Alto Municipio, PR': '139', 'Utuado Municipio, PR': '141', 'Vega Alta Municipio, PR': '143', 'Vega Baja Municipio, PR': '145', 'Vieques Municipio, PR': '147', 'Villalba Municipio, PR': '149', 'Yabucoa Municipio, PR': '151', 'Yauco Municipio, PR': '153'}, "CA01": {'--All--': '%', }, "CA02": {'--All--': '%', }, "CA03": {'--All--': '%', }, "CA04": {'--All--': '%', }, "CA05": {'--All--': '%', }, "CA13": {'--All--': '%', }, "CA07": {'--All--': '%', }, "CA14": {'--All--': '%', }, "CA08": {'--All--': '%', }, "CA09": {'--All--': '%', }, "CA10": {'--All--': '%', }, "CA11": {'--All--': '%', }, "CA12": {'--All--': '%', }, } def fips_to_state(fips_code): if isinstance(fips_code, str) and fips_code.isdigit(): fips_code = int(fips_code) for state, code in FIPS_STATES.items(): if code == fips_code: return state raise KeyError('No state found for fips %r' % fips_code) def state_name_to_abbrev(state): fipscode = FIPS_STATES[state] firstcounty = sorted(FIPS_COUNTIES[fipscode].keys())[1] return firstcounty.rsplit(',')[-1].strip() if __name__ == "__main__": from sys import argv from pprint import PrettyPrinter pp = PrettyPrinter(indent=2) import csv fipsreader = csv.reader(open(argv[1], 'r'), delimiter=',', quotechar='"') for row in fipsreader: try: FIPS_COUNTIES[int(row[1])][row[3]] = row[2] except KeyError: FIPS_COUNTIES[int(row[1])] = {'--All--': '%'} FIPS_COUNTIES[int(row[1])][row[3]] = row[2] pp.pprint(FIPS_COUNTIES) chirp-20240224/chirp/wxui/config.py0000644000175000017500000001325114436331157015765 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import base64 import binascii from chirp import platform try: from ConfigParser import ConfigParser except ImportError: from configparser import ConfigParser import os class ChirpConfig: def __init__(self, basepath, name="chirp.config"): self.__basepath = basepath self.__name = name self._default_section = "global" self.__config = ConfigParser(interpolation=None) cfg = os.path.join(basepath, name) if os.path.exists(cfg): self.__config.read(cfg) def save(self): cfg = os.path.join(self.__basepath, self.__name) with open(cfg, "w") as cfg_file: self.__config.write(cfg_file) def get(self, key, section, raw=False): if not self.__config.has_section(section): return None if not self.__config.has_option(section, key): return None return self.__config.get(section, key, raw=raw) def set(self, key, value, section): if not self.__config.has_section(section): self.__config.add_section(section) self.__config.set(section, key, value) def is_defined(self, key, section): return self.__config.has_option(section, key) def remove_option(self, section, key): self.__config.remove_option(section, key) if not self.__config.items(section): self.__config.remove_section(section) class ChirpConfigProxy: def __init__(self, config, section="global"): self._config = config self._section = section def get(self, key, section=None, raw=False): return self._config.get(key, section or self._section, raw=raw) def get_password(self, key, section): # So, we used to store the password in plaintext in $key. Then some # dumb guy stored the base64-encoded password in $key also. However, # if the plaintext password happens to be valid base64, we'll decode it # to some random binary, and then fail to decode UTF-8 from it. So, # for people already in this situation, first try the "new" location # of $key_encoded, if it exists. If it doesn't honor the old place # and return the exact string if base64 or UTF-8 decoding fails, # otherwise return the fully decoded thing. Conversion will happen # when people update passwords and set_passwoord() is called, which # always stores the new format. encoded = self.get('%s_encoded' % key, section) if encoded is None: encoded = self.get(key, section) if encoded: try: return base64.b64decode(encoded.encode()).decode() except binascii.Error: # Likely not stored encoded, return as-is return encoded except UnicodeDecodeError: # This means it must be stored in plaintext but we did # actually decode it with base64, but not to a valid string return encoded else: return encoded def set(self, key, value, section=None): return self._config.set(key, value, section or self._section) def set_password(self, key, value, section): """Store a password slightly obfuscated. THIS IS NOT SECURE. It just avoids storing the password in complete cleartext. It is trivial to read them in this format. """ value = base64.b64encode(value.encode()).decode() # Clean up old cleartext passwords if self.is_defined(key, section): self.remove_option(key, section) self.set('%s_encoded' % key, value, section) def get_int(self, key, section=None): try: return int(self.get(key, section)) except ValueError: return 0 def set_int(self, key, value, section=None): if not isinstance(value, int): raise ValueError("Value is not an integer") self.set(key, "%i" % value, section) def get_float(self, key, section=None): try: return float(self.get(key, section)) except ValueError: return 0 def set_float(self, key, value, section=None): if not isinstance(value, float): raise ValueError("Value is not an integer") self.set(key, "%i" % value, section) def get_bool(self, key, section=None, default=False): val = self.get(key, section) if val is None: return default else: return val == "True" def set_bool(self, key, value, section=None): self.set(key, str(bool(value)), section) def is_defined(self, key, section=None): return self._config.is_defined(key, section or self._section) def remove_option(self, key, section): self._config.remove_option(section, key) _CONFIG = None def get(section="global"): global _CONFIG p = platform.get_platform() if not _CONFIG: _CONFIG = ChirpConfig(p.config_dir()) return ChirpConfigProxy(_CONFIG, section) chirp-20240224/chirp/wxui/developer.py0000644000175000017500000004763514551723752016526 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import functools import logging import os import serial import sys import tempfile import requests import wx import wx.richtext import wx.lib.scrolledpanel from chirp import bitwise from chirp import util from chirp.wxui import common from chirp.wxui import report LOG = logging.getLogger(__name__) BrowserChanged, EVT_BROWSER_CHANGED = wx.lib.newevent.NewCommandEvent() FROZEN = getattr(sys, 'frozen', False) def simple_diff(a, b, diffsonly=False): lines_a = a.split(os.linesep) lines_b = b.split(os.linesep) blankprinted = True diff = "" for i in range(0, len(lines_a)): if lines_a[i] != lines_b[i]: diff += "-%s%s" % (lines_a[i], os.linesep) diff += "+%s%s" % (lines_b[i], os.linesep) blankprinted = False elif diffsonly is True: if blankprinted: continue diff += os.linesep blankprinted = True else: diff += " %s%s" % (lines_a[i], os.linesep) return diff class MemoryDialog(wx.Dialog): def __init__(self, mem, *a, **k): super(MemoryDialog, self).__init__(*a, **k) sizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(sizer) self.text = wx.richtext.RichTextCtrl( self, style=wx.VSCROLL | wx.HSCROLL | wx.NO_BORDER) sizer.Add(self.text, 1, wx.EXPAND) sizer.Add(wx.StaticLine(self), 0) bs = self.CreateButtonSizer(wx.OK | wx.OK_DEFAULT) sizer.Add(bs) self.Bind(wx.EVT_BUTTON, lambda e: self.EndModal(wx.CLOSE)) font = wx.Font(12, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) self.text.BeginFont(font) if isinstance(mem, tuple): mem_a, mem_b = mem self._diff_memories(mem_a, mem_b) self.SetTitle(_('Diff Raw Memories')) else: self._raw_memory(mem) self.SetTitle(_('Show Raw Memory')) self.SetSize(640, 480) self.Centre() def _raw_memory(self, mem): self.text.WriteText(mem) def _diff_memories(self, mem_a, mem_b): diff = simple_diff(mem_a, mem_b) for line in diff.split(os.linesep): color = None if line.startswith('+'): self.text.BeginTextColour((255, 0, 0)) color = True elif line.startswith('-'): self.text.BeginTextColour((0, 0, 255)) color = True self.text.WriteText(line) self.text.Newline() if color: self.text.EndTextColour() class ChirpEditor(wx.Panel): def __init__(self, parent, obj): super(ChirpEditor, self).__init__(parent, ) self._obj = obj self._fixed_font = wx.Font(pointSize=10, family=wx.FONTFAMILY_TELETYPE, style=wx.FONTSTYLE_NORMAL, weight=wx.FONTWEIGHT_NORMAL) self._changed_color = wx.Colour(0, 255, 0) self._error_color = wx.Colour(255, 0, 0) def refresh(self): """Called to refresh the widget from memory""" pass def set_up(self): pass def _mark_changed(self, thing): thing.SetBackgroundColour(self._changed_color) tt = thing.GetToolTip() if not tt: tt = wx.ToolTip('') thing.SetToolTip(tt) tt.SetTip(_('Press enter to set this in memory')) def _mark_unchanged(self, thing, mem_changed=True): thing.SetBackgroundColour(wx.NullColour) thing.UnsetToolTip() if mem_changed: wx.PostEvent(self, BrowserChanged(self.GetId())) def _mark_error(self, thing, reason): tt = thing.GetToolTip() if not tt: tt = wx.ToolTip('') thing.SetToolTip(tt) tt.SetTip(reason) thing.SetBackgroundColour(self._error_color) def __repr__(self): addr = '0x%02x' % int(self._obj._offset) def typestr(c): return c.__class__.__name__.lower().replace('dataelement', '') if isinstance(self._obj, bitwise.arrayDataElement): innertype = list(self._obj.items())[0][1] return '%s[%i] (%i %s) @ %s' % (typestr(innertype), len(self._obj), innertype.size() / 8, _('bytes each'), addr) elif self._obj.size() % 8 == 0: return '%s (%i %s) @ %s' % (typestr(self._obj), self._obj.size() / 8, _('bytes'), addr) else: return '%s %s @ %s' % (self._obj.size(), _('bits'), addr) class ChirpStringEditor(ChirpEditor): def set_up(self): sizer = wx.BoxSizer(wx.HORIZONTAL) self._entry = wx.TextCtrl(self, value=str(self._obj), style=wx.TE_PROCESS_ENTER) self._entry.SetMaxLength(len(self._obj)) self.SetSizer(sizer) sizer.Add(self._entry, 1, wx.EXPAND) self._entry.Bind(wx.EVT_TEXT, self._edited) self._entry.Bind(wx.EVT_TEXT_ENTER, self._changed) self._entry.SetEditable(not FROZEN) def refresh(self): self._entry.SetValue(str(self._obj)) self._mark_unchanged(self._entry, mem_changed=False) def _edited(self, event): entry = event.GetEventObject() value = entry.GetValue() if len(value) == len(self._obj): self._mark_changed(entry) else: self._mark_error(entry, _('Length must be %i') % len(self._obj)) @common.error_proof() def _changed(self, event): entry = event.GetEventObject() value = entry.GetValue() self._obj.set_value(value) self._mark_unchanged(entry) LOG.debug('Set value: %r' % value) class ChirpIntegerEditor(ChirpEditor): def set_up(self): sizer = wx.BoxSizer(wx.HORIZONTAL) self.SetSizer(sizer) hexdigits = (self._obj.size() / 4) + (self._obj.size() % 4 and 1 or 0) bindigits = self._obj.size() self._editors = {_('Hex'): (16, '{:0%iX}' % hexdigits), _('Dec'): (10, '{:d}'), _('Bin'): (2, '{:0%ib}' % bindigits)} self._entries = {} for name, (base, fmt) in self._editors.items(): label = wx.StaticText(self, label=name) entry = wx.TextCtrl(self, value=fmt.format(int(self._obj)), style=wx.TE_PROCESS_ENTER) entry.SetFont(self._fixed_font) entry.SetEditable(not FROZEN) sizer.Add(label, 0, wx.ALIGN_CENTER) sizer.Add(entry, 1, flag=wx.EXPAND) self._entries[name] = entry entry.Bind(wx.EVT_TEXT, functools.partial(self._edited, base=base)) entry.Bind(wx.EVT_TEXT_ENTER, functools.partial(self._changed, base=base)) def refresh(self): for name, (base, fmt) in self._editors.items(): self._entries[name].SetValue(fmt.format(int(self._obj))) self._mark_unchanged(self._entries[name], mem_changed=False) def _edited(self, event, base=10): entry = event.GetEventObject() others = {n: e for n, e in self._entries.items() if e != entry} try: val = int(entry.GetValue(), base) assert val >= 0, _('Value must be zero or greater') assert val < pow(2, self._obj.size()), \ _('Value does not fit in %i bits') % self._obj.size() except (ValueError, AssertionError) as e: self._mark_error(entry, str(e)) return else: self._mark_changed(entry) for name, entry in others.items(): base, fmt = self._editors[name] entry.ChangeValue(fmt.format(val)) @common.error_proof() def _changed(self, event, base=10): entry = event.GetEventObject() val = int(entry.GetValue(), base) self._obj.set_value(val) self._mark_unchanged(entry) LOG.debug('Set value: %r' % val) class ChirpBCDEditor(ChirpEditor): def set_up(self): sizer = wx.BoxSizer(wx.HORIZONTAL) self.SetSizer(sizer) self._entry = wx.TextCtrl(self, value=str(int(self._obj)), style=wx.TE_PROCESS_ENTER) self._entry.SetFont(self._fixed_font) self._entry.SetEditable(not FROZEN) sizer.Add(self._entry, 1, wx.EXPAND) self._entry.Bind(wx.EVT_TEXT, self._edited) self._entry.Bind(wx.EVT_TEXT_ENTER, self._changed) def refresh(self): self._entry.SetValue(str(int(self._obj))) self._mark_unchanged(self._entry, mem_changed=False) def _edited(self, event): entry = event.GetEventObject() try: val = int(entry.GetValue()) digits = self._obj.size() // 4 assert val >= 0, _('Value must be zero or greater') assert len(entry.GetValue()) == digits, \ _('Value must be exactly %i decimal digits') % digits except (ValueError, AssertionError) as e: self._mark_error(entry, str(e)) else: self._mark_changed(entry) @common.error_proof() def _changed(self, event): entry = event.GetEventObject() val = int(entry.GetValue()) self._obj.set_value(val) self._mark_unchanged(entry) LOG.debug('Set Value: %r' % val) class ChirpBrowserPanel(wx.lib.scrolledpanel.ScrolledPanel): def __init__(self, parent, memobj): super(ChirpBrowserPanel, self).__init__(parent) self._sizer = wx.FlexGridSizer(2) self._sizer.AddGrowableCol(1) self.SetSizer(self._sizer) self.SetupScrolling() self._parent = parent self._memobj = memobj self._editors = {} self._initialized = False def add_editor(self, name, editor): self._editors[name] = editor editor.Bind(EVT_BROWSER_CHANGED, self._panel_changed) def _panel_changed(self, event): wx.PostEvent(self, BrowserChanged(self.GetId())) def _initialize(self): for name, obj in self._memobj.items(): editor = None if isinstance(obj, bitwise.arrayDataElement): if isinstance(obj[0], bitwise.charDataElement): editor = ChirpStringEditor(self, obj) elif isinstance(obj[0], bitwise.bcdDataElement): editor = ChirpBCDEditor(self, obj) else: self._parent.add_sub_panel(name, obj, self) elif isinstance(obj, bitwise.intDataElement): editor = ChirpIntegerEditor(self, obj) elif isinstance(obj, bitwise.structDataElement): self._parent.add_sub_panel(name, obj, self) if editor: self.add_editor(name, editor) self._initialized = True def add_sub_panel(self, name, obj, parent): # This just forwards until we get to the browser self._parent.add_sub_panel(name, obj, parent) def selected(self): if not self._initialized: self._initialize() label = wx.StaticText(self) pos = wx.StaticText(self, label='%i bits (%i bytes) at 0x%06x' % ( self._memobj.size(), self._memobj.size() // 8, self._memobj.get_offset())) self._sizer.Add(label, 0, wx.ALIGN_CENTER) self._sizer.Add(pos, 1, flag=wx.EXPAND) for name, editor in self._editors.items(): editor.set_up() label = wx.StaticText(self, label='%s: ' % name) tt = wx.ToolTip(repr(editor)) label.SetToolTip(tt) self._sizer.Add(label, 0, wx.ALIGN_CENTER) self._sizer.Add(editor, 1, flag=wx.EXPAND) else: for editor in self._editors.values(): editor.refresh() self._sizer.Layout() self.FitInside() class ChirpRadioBrowser(common.ChirpEditor, common.ChirpSyncEditor): def __init__(self, radio, *a, **k): super(ChirpRadioBrowser, self).__init__(*a, **k) self._loaded = False self._radio = radio self._features = radio.get_features() self._treebook = ChirpBrowserTreeBook(self) try: view = self._treebook.GetTreeCtrl() except AttributeError: # https://github.com/wxWidgets/Phoenix/issues/918 view = self._treebook.GetChildren()[0] view.SetMinSize((250, 0)) self._treebook.Bind(wx.EVT_TREEBOOK_PAGE_CHANGED, self.page_selected) sizer = wx.BoxSizer(wx.VERTICAL) sizer.Add(self._treebook, 1, wx.EXPAND) self.SetSizer(sizer) def selected(self): if self._loaded: self._treebook.CurrentPage.selected() return self.start_wait_dialog(_('Building Radio Browser')) self._loaded = True try: self._treebook.add_sub_panel('%s %s' % (self._radio.VENDOR, self._radio.MODEL), self._radio._memobj, self._treebook) except Exception as e: LOG.exception('Failed to load browser: %s' % e) common.error_proof.show_error(_('Failed to load radio browser')) finally: self.stop_wait_dialog() if self._treebook.GetPageCount(): self._treebook.ExpandNode(0) def page_selected(self, event): page = self._treebook.GetPage(event.GetSelection()) page.selected() class ChirpBrowserTreeBook(wx.Treebook): def add_sub_panel(self, name, memobj, parent): LOG.debug('Adding sub panel for %s' % name) page = ChirpBrowserPanel(self, memobj) page.Bind(EVT_BROWSER_CHANGED, self._page_changed) if parent != self: pos = self.FindPage(parent) self.InsertSubPage(pos, page, name) self.ExpandNode(pos) else: self.AddPage(page, name) def _page_changed(self, event): wx.PostEvent(self, common.EditorChanged(self.GetId())) class FakeSerial(serial.SerialBase): def write(self, buf): LOG.debug('Fake serial write:\n%s' % util.hexprint(buf)) def read(self, count): LOG.debug('Fake serial read %i' % count) return b'' class FakeEchoSerial(FakeSerial): def __init__(self, *a, **k): super().__init__(*a, **k) self._buf = [] def write(self, buf): super().write(buf) self._buf.extend(b for b in buf) def read(self, count): super().read(count) try: return bytes([self._buf.pop(0)]) except IndexError: LOG.warning('Empty echo buffer') return b'' class IssueModuleLoader: def __init__(self, parent): self._parent = parent report.ensure_session() self.session = report.SESSION def get_attachments_from_issue(self, issue): r = self.session.get( 'https://chirp.danplanet.com/issues/%i.json' % issue, params={'include': 'attachments'}) LOG.debug('Fetched attachments for issue %i (status %s)' % ( issue, r.status_code)) r.raise_for_status() data = r.json()['issue']['attachments'] return [a for a in data if a['filename'].endswith('.py') and a.get('content_type', '').startswith('text/') and a['filesize'] < (256 * 1024)] def get_user_is_developer(self, uid): r = self.session.get('https://chirp.danplanet.com/users/%i.json' % uid, params={'include': 'memberships'}) LOG.debug('Fetched info for user %i (status %s)', uid, r.status_code) r.raise_for_status() data = r.json() try: membership = data['user']['memberships'][0] except IndexError: LOG.debug('User %s(%i) has no roles', data['user']['login'], uid) return False roles = [r['name'] for r in membership['roles']] return 'Developer' in roles or 'Manager' in roles def get_attachment_from_user(self, issue, attachments): attachment_strings = { '%s from %s (%s)' % (a['filename'], a['author']['name'], a['created_on']): a for a in sorted(attachments, key=lambda a: a['created_on']) } choices = list(attachment_strings.keys()) choice = wx.GetSingleChoice( _('Choose the module to load from issue %i:' % issue), _('Available modules'), choices, len(choices) - 1, parent=self._parent) if choice: isdev = self.get_user_is_developer( attachment_strings[choice]['author']['id']) if not isdev: r = wx.MessageBox( _('The author of this module is not a recognized ' 'CHIRP developer. It is recommended that you not ' 'load this module as it could pose a security risk. ' 'Proceed anyway?'), _('Security Risk'), wx.YES_NO | wx.NO_DEFAULT) if r != wx.YES: return return attachment_strings[choice] def run(self): msg = _('This will load a module from a website issue') issue = wx.GetNumberFromUser(msg, _('Issue number:'), _('Load module from issue'), 0, 0, 999999, parent=self._parent) if issue < 0: return try: attachments = self.get_attachments_from_issue(issue) except Exception as e: LOG.exception('Failed to load attachments from %i: %s' % ( issue, e)) raise Exception('Unable to load modules from that issue') LOG.debug('Found %i valid module attachments from issue %i' % ( len(attachments), issue)) if not attachments: wx.MessageBox(_('No modules found in issue %i') % issue, _('No modules found'), wx.ICON_WARNING) return attachment = self.get_attachment_from_user(issue, attachments) if not attachment: return LOG.debug('User chose attachment %s' % attachment) LOG.debug('Fetching attachment URL %s' % attachment['content_url']) r = requests.get(attachment['content_url']) modfile = tempfile.mktemp('.py', 'loaded-%i-' % attachment['id']) trailer = ('\n\n# Loaded from issue %i attachment %i: %s\n' % ( issue, attachment['id'], attachment['content_url'])) with open(modfile, 'wb') as f: f.write(r.content) f.write(trailer.encode()) LOG.debug('Wrote attachment to %s' % modfile) return modfile chirp-20240224/chirp/wxui/__main__.py0000755000175000017500000000014314430171343016230 0ustar hibbyhibbyimport sys from chirp.wxui import chirpmain if __name__ == '__main__': sys.exit(chirpmain()) chirp-20240224/chirp/wxui/query_sources.py0000644000175000017500000007611614564102745017442 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import queue import tempfile import threading import urllib import wx import wx.adv from chirp import bandplan from chirp.sources import base from chirp.sources import dmrmarc from chirp.sources import radioreference from chirp.sources import repeaterbook from chirp.sources import przemienniki from chirp.wxui import common from chirp.wxui import config _ = wx.GetTranslation CONF = config.get() LOG = logging.getLogger(__name__) QueryThreadEvent, EVT_QUERY_THREAD = wx.lib.newevent.NewCommandEvent() class NumberValidator(wx.Validator): THING = _('Number') MIN = 0 MAX = 1 OPTIONAL = True def Validate(self, window): textctrl = self.GetWindow() strvalue = textctrl.GetValue() if not strvalue and self.OPTIONAL: return True try: v = float(strvalue) assert v >= self.MIN and v <= self.MAX textctrl.SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)) return True except ValueError: msg = _('Invalid %(value)s (use decimal degrees)') except AssertionError: msg = _('%(value)s must be between %(min)i and %(max)i') textctrl.SetFocus() textctrl.SetBackgroundColour('pink') catalog = {'value': self.THING, 'min': self.MIN, 'max': self.MAX} wx.MessageBox(msg % catalog, _('Invalid Entry')) return False def Clone(self): return self.__class__() def TransferToWindow(self): return True def SetWindow(self, win): super().SetWindow(win) # Clear the validation failure background color as soon as the value # changes to avoid asking them to click OK on a dialog with a warning # sign. win.Bind(wx.EVT_TEXT, self._colorchange) def _colorchange(self, event): self.GetWindow().SetBackgroundColour( wx.SystemSettings.GetColour(wx.SYS_COLOUR_WINDOW)) class LatValidator(NumberValidator): THING = _('Latitude') MIN = -90 MAX = 90 class LonValidator(NumberValidator): THING = _('Longitude') MIN = -180 MAX = 180 class DistValidator(NumberValidator): THING = _('Distance') MIN = 0 MAX = 7000 class ZipValidator(wx.Validator): def Validate(self, window): textctrl = self.GetWindow() strvalue = textctrl.GetValue() if len(strvalue) == 5 and strvalue.isdigit(): return True wx.MessageBox(_('Invalid ZIP code'), 'Invalid Entry') return False def Clone(self): return self.__class__() def TransferToWindow(self): return True class QueryThread(threading.Thread, base.QueryStatus): END_SENTINEL = object() def __init__(self, *a, **k): self.query_dialog = a[0] self.radio = a[1] super(QueryThread, self).__init__(*a[2:], **k) self.status_queue = queue.Queue() def run(self): try: self.radio.do_fetch(self, self.query_dialog.get_params()) except Exception as e: LOG.exception('Failed to execute query: %s' % e) self.send_fail('Failed: %s' % str(e)) def send_status(self, status, percent): self.query_dialog.status(status, percent) def send_end(self): self.query_dialog.end() def send_fail(self, reason): self.query_dialog.fail(reason) class QuerySourceDialog(wx.Dialog): NAME = 'NetworkSource' def __init__(self, *a, **k): super(QuerySourceDialog, self).__init__(*a, **k) self.result_radio = None vbox = self.build() self.Center() self.statusmsg = wx.StaticText( self, label='', style=(wx.ALIGN_CENTRE_HORIZONTAL | wx.ST_NO_AUTORESIZE | wx.ST_ELLIPSIZE_END)) vbox.Add(self.statusmsg, proportion=0, border=5, flag=wx.EXPAND | wx.BOTTOM) self.gauge = wx.Gauge(self) self.gauge.SetRange(100) vbox.Add(self.gauge, proportion=0, border=10, flag=wx.EXPAND | wx.LEFT | wx.RIGHT) link_label = urllib.parse.urlparse(self.get_link()).netloc link = wx.adv.HyperlinkCtrl(vbox.GetContainingWindow(), label=link_label, url=self.get_link(), style=wx.adv.HL_ALIGN_CENTRE) vbox.Insert(0, link, proportion=0, border=10, flag=(wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.ALIGN_CENTER_HORIZONTAL)) info = wx.StaticText(vbox.GetContainingWindow(), style=wx.ALIGN_CENTER_HORIZONTAL) info.SetLabelMarkup(self.get_info()) vbox.Insert(0, info, proportion=0, border=10, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.TOP) bs = self.CreateButtonSizer(wx.OK | wx.CANCEL) vbox.Add(bs, border=10, flag=wx.ALL) self.Bind(wx.EVT_BUTTON, self._button) self.Bind(EVT_QUERY_THREAD, self._got_status) self.SetMinSize((400, 200)) self.Fit() wx.CallAfter(self.Center) vbox.GetContainingWindow().InitDialog() self.result_file = tempfile.NamedTemporaryFile( prefix='%s-' % self.NAME, suffix='.csv').name def _call_validations(self, parent): for child in parent.GetChildren(): if not child.Validate(): return False self._call_validations(child) return True def _button(self, event): id = event.GetEventObject().GetId() if id == wx.ID_OK: if not self._call_validations(self): return self.FindWindowById(wx.ID_OK).Disable() self.do_query() return self.EndModal(id) def build(self): pass def do_query(self): LOG.info('Starting QueryThread for %s' % self.result_radio) LOG.debug('Query Parameters: %s' % self.get_params()) QueryThread(self, self.result_radio).start() def get_params(self): pass def get_info(self): return '' def get_link(self): return '' def status(self, status, percent): wx.PostEvent(self, QueryThreadEvent(self.GetId(), status=status, percent=percent)) def end(self): self.status(None, 100) def fail(self, reason): self.status(reason, 100) def _got_status(self, event): self.gauge.SetValue(int(event.percent)) if event.status is None: self.EndModal(wx.ID_OK) else: self.statusmsg.SetLabel(event.status) if event.percent == 100: self.FindWindowById(wx.ID_OK).Enable() class RepeaterBookQueryDialog(QuerySourceDialog): NAME = 'Repeaterbook' def get_info(self): return _( "RepeaterBook is Amateur Radio's most comprehensive,\n" "worldwide, FREE repeater directory.") def get_link(self): return 'https://repeaterbook.com' def build(self): vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) panel = wx.Panel(self) vbox.Add(panel, proportion=1, border=10, flag=wx.EXPAND | wx.BOTTOM) grid = wx.FlexGridSizer(2, 5, 0) grid.AddGrowableCol(1) panel.SetSizer(grid) self._country = wx.Choice(panel, choices=repeaterbook.COUNTRIES) prev = CONF.get('country', 'repeaterbook') if prev and prev in repeaterbook.COUNTRIES: self._country.SetStringSelection(prev) else: self._country.SetStringSelection(repeaterbook.NA_COUNTRIES[0]) self._country.Bind(wx.EVT_CHOICE, self._state_selected) self._add_grid(grid, _('Country'), self._country) self._service = wx.Choice(panel, choices=[_('Amateur'), _('GMRS')]) self._service.Bind(wx.EVT_CHOICE, self._service_selected) self._add_grid(grid, _('Service'), self._service) self._state = wx.Choice(panel, choices=[]) self._add_grid(grid, _('State/Province'), self._state) self._lat = wx.TextCtrl(panel, value=CONF.get('lat', 'repeaterbook') or '', validator=LatValidator()) self._lat.SetHint(_('Optional: 45.0000')) self._lat.SetToolTip(_('If set, sort results by distance from ' 'these coordinates')) self._lon = wx.TextCtrl(panel, value=CONF.get('lon', 'repeaterbook') or '', validator=LonValidator()) self._lon.SetHint(_('Optional: -122.0000')) self._lon.SetToolTip(_('If set, sort results by distance from ' 'these coordinates')) self._add_grid(grid, _('Latitude'), self._lat) self._add_grid(grid, _('Longitude'), self._lon) self._dist = wx.TextCtrl(panel, value=CONF.get('dist', 'repeaterbook') or '', validator=DistValidator()) self._dist.SetHint(_('Optional: 100')) self._dist.SetToolTip(_('Limit results to this distance (km) from ' 'coordinates')) self._add_grid(grid, _('Distance'), self._dist) self._search = wx.TextCtrl(panel) self._search.SetHint(_('Optional: County, Hospital, etc.')) self._search.SetToolTip(_('Filter results with location matching ' 'this string')) self._add_grid(grid, _('Filter'), self._search) self._bands = bandplan.BandPlans(CONF).get_repeater_bands() self._limit_bands = [] self._bandfilter = wx.CheckBox(panel, label=_('Only certain bands')) self.Bind(wx.EVT_CHECKBOX, self._select_bands, self._bandfilter) self._add_grid(grid, _('Limit Bands'), self._bandfilter) self._limit_modes = list(repeaterbook.MODES) self._modefilter = wx.CheckBox(panel, label=_('Only certain modes')) self.Bind(wx.EVT_CHECKBOX, self._select_modes, self._modefilter) self._add_grid(grid, _('Limit Modes'), self._modefilter) self._fmconv = wx.CheckBox(panel, label=_('Convert to FM')) self._fmconv.SetValue(CONF.get_bool('fmconv', 'repeaterbook')) self._fmconv.SetToolTip(_('Dual-mode digital repeaters that support ' 'analog will be shown as FM')) self._add_grid(grid, _('Digital Modes'), self._fmconv) self._state_selected(None) self._service_selected(None) self.Layout() return vbox def _service_selected(self, event): is_gmrs = _('GMRS') in self._service.GetStringSelection() self._bandfilter.Enable(not is_gmrs) self._modefilter.Enable(not is_gmrs) def _state_selected(self, event): country = self._country.GetStringSelection() if country == 'United States': self._service.Enable(True) self._service.SetStringSelection( CONF.get('service', 'repeaterbook') or _('Amateur')) else: self._service.Enable(False) self._service.SetSelection(0) try: states = repeaterbook.STATES[country] except KeyError: self._state.SetItems([_('All')]) self._state.Enable(False) return self._state.SetItems(states) self._state.Enable(True) prev = CONF.get('state', 'repeaterbook') if prev and prev in states: self._state.SetStringSelection(prev) else: self._state.SetStringSelection(states[0]) def _add_grid(self, grid, label, widget): grid.Add(wx.StaticText(widget.GetParent(), label=label), border=20, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) grid.Add(widget, 1, border=20, flag=wx.EXPAND | wx.RIGHT | wx.LEFT) def _select_bands(self, event): if not self._bandfilter.IsChecked(): self._limit_bands = [] return band_names = [x.name for x in self._bands] d = wx.MultiChoiceDialog(self, _('Select Bands'), _('Bands'), choices=band_names) prev = CONF.get('bands', 'repeaterbook') or '' d.SetSelections([i for i, band in enumerate(self._bands) if band.name in prev.split(',')]) r = d.ShowModal() if r == wx.ID_CANCEL or not d.GetSelections(): self._bandfilter.SetValue(False) self._limit_bands = [] else: self._limit_bands = [self._bands[i].limits for i in d.GetSelections()] CONF.set('bands', ','.join(self._bands[i].name for i in d.GetSelections()), 'repeaterbook') def _select_modes(self, event): if not self._modefilter.IsChecked(): self._limit_modes = [] return d = wx.MultiChoiceDialog(self, _('Select Modes'), _('Modes'), choices=repeaterbook.MODES) r = d.ShowModal() if r == wx.ID_CANCEL or not d.GetSelections(): self._modefilter.SetValue(False) self._limit_modes = [] else: self._limit_modes = [repeaterbook.MODES[i] for i in d.GetSelections()] def do_query(self): CONF.set('lat', self._lat.GetValue(), 'repeaterbook') CONF.set('lon', self._lon.GetValue(), 'repeaterbook') CONF.set('dist', self._dist.GetValue(), 'repeaterbook') CONF.set('state', self._state.GetStringSelection(), 'repeaterbook') CONF.set('country', self._country.GetStringSelection(), 'repeaterbook') CONF.set('service', self._service.GetStringSelection(), 'repeaterbook') CONF.set_bool('fmconv', self._fmconv.IsChecked(), 'repeaterbook') self.result_radio = repeaterbook.RepeaterBook() super().do_query() def get_params(self): service = self._service.GetStringSelection() return { 'country': self._country.GetStringSelection(), 'state': self._state.GetStringSelection(), 'lat': self._lat.GetValue(), 'lon': self._lon.GetValue(), 'dist': self._dist.GetValue(), 'filter': self._search.GetValue(), 'bands': self._limit_bands, 'modes': self._limit_modes, 'service': 'gmrs' if service == _('GMRS') else '', 'service_display': self._service.GetStringSelection(), 'fmconv': self._fmconv.IsChecked(), } class DMRMARCQueryDialog(QuerySourceDialog): NAME = 'DMR-MARC' def _add_grid(self, grid, label, widget): grid.Add(wx.StaticText(widget.GetParent(), label=label), border=20, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) grid.Add(widget, 1, border=20, flag=wx.EXPAND | wx.RIGHT | wx.LEFT) def build(self): vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) panel = wx.Panel(self) vbox.Add(panel, 1, flag=wx.EXPAND | wx.ALL, border=20) grid = wx.FlexGridSizer(2, 5, 0) grid.AddGrowableCol(1) panel.SetSizer(grid) self._city = wx.TextCtrl(panel, value=CONF.get('city', 'dmrmarc') or '') self._add_grid(grid, _('City'), self._city) self._state = wx.TextCtrl(panel, value=CONF.get('state', 'dmrmarc') or '') self._add_grid(grid, _('State'), self._state) self._country = wx.TextCtrl(panel, value=CONF.get('country', 'dmrmarc') or '') self._add_grid(grid, _('Country'), self._country) return vbox def get_info(self): return _('The DMR-MARC Worldwide Network') def get_link(self): return 'https://www.dmr-marc.net' def do_query(self): CONF.set('city', self._city.GetValue(), 'dmrmarc') CONF.set('state', self._state.GetValue(), 'dmrmarc') CONF.set('country', self._country.GetValue(), 'dmrmarc') self.result_radio = dmrmarc.DMRMARCRadio() super().do_query() def get_params(self): return {'city': CONF.get('city', 'dmrmarc'), 'state': CONF.get('state', 'dmrmarc'), 'country': CONF.get('country', 'dmrmarc')} class PrzemiennikiQueryDialog(QuerySourceDialog): NAME = 'przemienniki.net' _section = 'przemienniki' _countries = sorted( ['at', 'bg', 'by', 'ch', 'cz', 'de', 'dk', 'es', 'fi', 'fr', 'hu', 'is', 'it', 'lt', 'lv', 'no', 'nl', 'pl', 'ro', 'ru', 'se', 'si', 'sk', 'ua', 'uk']) _bands = ['10m', '4m', '6m', '2m', '70cm', '23cm', '13cm', '3cm'] _modes = ['FM', 'MOTOTRBO', 'DSTAR', 'C4FM', 'ECHOLINK', 'FMLINK', 'APCO25', 'ATV'] def _add_grid(self, grid, label, widget): grid.Add(wx.StaticText(widget.GetParent(), label=label), border=20, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) grid.Add(widget, 1, border=20, flag=wx.EXPAND | wx.RIGHT | wx.LEFT) def build(self): vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) panel = wx.Panel(self) vbox.Add(panel, 1, flag=wx.EXPAND | wx.ALL, border=20) grid = wx.FlexGridSizer(2, 5, 0) grid.AddGrowableCol(1) panel.SetSizer(grid) # Mode self._mode = wx.Choice(panel, choices=self._modes) prev = CONF.get('mode', self._section) if prev and prev in self._modes: self._mode.SetStringSelection(prev) else: self._mode.SetStringSelection(self._modes[0]) self._add_grid(grid, _('Mode'), self._mode) # Band selection if CONF.is_defined('band', self._section): CONF.remove_option('band', self._section) self._bandfilter = wx.CheckBox(panel, label=_('Only certain bands')) self.Bind(wx.EVT_CHECKBOX, self._select_bands, self._bandfilter) self._add_grid(grid, _('Limit Bands'), self._bandfilter) # Only working if CONF.is_defined('workingstatus', self._section): self._limit_onlyworking = CONF.get_bool('workingstatus', self._section) else: self._limit_onlyworking = True self._onlyworkingfilter = wx.CheckBox(panel, label=_('Only working repeaters') ) self._onlyworkingfilter.SetValue(self._limit_onlyworking) CONF.set_bool('workingstatus', self._limit_onlyworking, self._section) self.Bind(wx.EVT_CHECKBOX, self._select_workingstatus, self._onlyworkingfilter) self._add_grid(grid, _('Limit Status'), self._onlyworkingfilter) # Country self._country = wx.Choice(panel, choices=self._countries) prev = CONF.get('country', self._section) if prev and prev in self._countries: self._country.SetStringSelection(prev) else: self._country.SetStringSelection('pl') self._add_grid(grid, _('Country'), self._country) # Coordinates self._lat = wx.TextCtrl(panel, value=CONF.get('lat', 'repeaterbook') or '', validator=LatValidator()) self._lat.SetHint(_('Optional: 45.0000')) self._lat.SetToolTip(_('If set, sort results by distance from ' 'these coordinates')) self._lon = wx.TextCtrl(panel, value=CONF.get('lon', 'repeaterbook') or '', validator=LonValidator()) self._lon.SetHint(_('Optional: -122.0000')) self._lon.SetToolTip(_('If set, sort results by distance from ' 'these coordinates')) self._add_grid(grid, _('Latitude'), self._lat) self._add_grid(grid, _('Longitude'), self._lon) self._dist = wx.TextCtrl(panel, value=CONF.get('dist', 'repeaterbook') or '', validator=DistValidator()) self._dist.SetHint(_('Optional: 100')) self._dist.SetToolTip(_('Limit results to this distance (km) from ' 'coordinates')) self._add_grid(grid, _('Distance'), self._dist) return vbox def _select_workingstatus(self, event): if not self._onlyworkingfilter.IsChecked(): self._limit_onlyworking = False else: self._limit_onlyworking = True CONF.set_bool('workingstatus', self._limit_onlyworking, self._section) return def _select_bands(self, event): if not self._bandfilter.IsChecked(): CONF.set('band', '', self._section) return band_names = [x for x in self._bands] d = wx.MultiChoiceDialog(self, _('Select Bands'), _('Bands'), choices=band_names) d.SetSelections([i for i, band in enumerate(self._bands) if band in ['2m', '70cm']]) r = d.ShowModal() if r == wx.ID_CANCEL or not d.GetSelections(): self._bandfilter.SetValue(False) else: CONF.set('band', ','.join(self._bands[i] for i in d.GetSelections()), self._section) def get_info(self): return _('FREE repeater database, which provides most up-to-date\n' 'information about repeaters in Europe. No account is\n' 'required.') def get_link(self): return 'https://przemienniki.net' def do_query(self): CONF.set('country', self._country.GetStringSelection(), self._section) CONF.set('mode', self._mode.GetStringSelection(), self._section) CONF.set('lat', self._lat.GetValue(), 'repeaterbook') CONF.set('lon', self._lon.GetValue(), 'repeaterbook') CONF.set('dist', self._dist.GetValue(), 'repeaterbook') self.result_radio = przemienniki.Przemienniki() super().do_query() def get_params(self): params = { 'country': CONF.get('country', self._section), 'band': CONF.get('band', self._section), 'mode': CONF.get('mode', self._section).lower(), 'latitude': CONF.get('lat', 'repeaterbook'), 'longitude': CONF.get('lon', 'repeaterbook'), 'range': CONF.get('dist', 'repeaterbook'), } if CONF.get_bool('workingstatus', self._section): params['onlyworking'] = 'Yes' return params class RRQueryDialog(QuerySourceDialog): NAME = 'RadioReference' def get_info(self): return _( "RadioReference.com is the world's largest\n" "radio communications data provider\n" "Premium account required") def get_link(self): return ( 'https://support.radioreference.com/hc/en-us/articles/' '18860633200276-Programming-Using-the-RadioReference-Web-Service') def _add_grid(self, grid, label, widget): grid.Add(wx.StaticText(widget.GetParent(), label=label), border=20, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) grid.Add(widget, 1, border=20, flag=wx.EXPAND | wx.RIGHT | wx.LEFT) def build(self): self.result_radio = radioreference.RadioReferenceRadio() self.tabs = wx.Notebook(self) vbox = wx.BoxSizer(wx.VERTICAL) self.SetSizer(vbox) panel = wx.Panel(self) grid = wx.FlexGridSizer(3, 5, 0) grid.AddGrowableCol(1) panel.SetSizer(grid) vbox.Add(panel, proportion=0, flag=wx.EXPAND) # build the login elements self._rrusername = wx.TextCtrl( panel, value=CONF.get('username', 'radioreference') or '') self._add_grid(grid, 'Username', self._rrusername) grid.Add(wx.StaticText(panel, label=''), border=20, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) self._rrpassword = wx.TextCtrl( panel, style=wx.TE_PASSWORD, value=CONF.get_password('password', 'radioreference') or '') self._add_grid(grid, 'Password', self._rrpassword) vbox.Add(self.tabs, proportion=1, border=10, flag=wx.EXPAND | wx.BOTTOM | wx.TOP) self.tabs.InsertPage(0, self.build_us(self.tabs), _('United States')) self.tabs.InsertPage(1, self.build_ca(self.tabs), _('Canada')) return vbox def _call_validations(self, parent): if parent == self: # If we're calling validations at the top-level, redirect that to # the start of our country-specific widgets, based on whatever tab # is selected. This avoids trying to validate US things when # Canada is selected and so on. parent = self.tabs.GetPage(self.tabs.GetSelection()) return super()._call_validations(parent) def build_ca(self, parent): panel = wx.Panel(parent) grid = wx.FlexGridSizer(3, 5, 0) grid.AddGrowableCol(1) # build a new login button self._loginbutton = wx.Button(panel, label='Log In') grid.Add(self._loginbutton) self._loginbutton.Bind(wx.EVT_BUTTON, self._populateca) # build a prov/county selector grid & add selectors self._provchoice = wx.Choice(panel, choices=['Log in First']) self.Bind(wx.EVT_CHOICE, self.selected_province, self._provchoice) self._add_grid(grid, 'Province', self._provchoice) grid.Add(wx.StaticText(panel, label=''), border=20, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) self._countychoice = wx.Choice(panel, choices=['Log in First']) self._add_grid(grid, 'County', self._countychoice) self.Bind(wx.EVT_CHOICE, self.selected_county, self._countychoice) grid.Add(wx.StaticText(panel, label=''), border=20, flag=wx.ALIGN_CENTER | wx.RIGHT | wx.LEFT) if radioreference.CA_PROVINCES: self.populateprov() panel.SetSizer(grid) return panel def build_us(self, parent): panel = wx.Panel(parent) grid = wx.FlexGridSizer(2, 5, 0) grid.AddGrowableCol(1) panel.SetSizer(grid) self._uszip = wx.TextCtrl( panel, value=CONF.get('zipcode', 'radioreference') or '', validator=ZipValidator()) self._add_grid(grid, 'ZIP Code', self._uszip) return panel def _populateca(self, event): button = event.GetEventObject() button.Disable() okay = self.FindWindowById(wx.ID_OK) okay.Disable() def cb(result): wx.CallAfter(okay.Enable) if isinstance(result, Exception): self.status('Failed: %s' % result, 0) wx.CallAfter(button.Enable) else: self.status('Logged in', 0) wx.CallAfter(self.populateprov) self.status('Attempting login...', 0) radioreference.RadioReferenceCAData( cb, self._rrusername.GetValue(), self._rrpassword.GetValue()).start() def populateprov(self): self._provchoice.SetItems([str(x) for x in radioreference.CA_PROVINCES.keys()]) self.getconfdefaults() self._provchoice.SetStringSelection(self.default_prov) self._selected_province(self.default_prov) self._countychoice.SetStringSelection(self.default_county) self._selected_county(self.default_county) self._loginbutton.Enable(False) def getconfdefaults(self): code = CONF.get("province", "radioreference") for k, v in radioreference.CA_PROVINCES.items(): if code == str(v): self.default_prov = k break else: self.default_prov = "BC" code = CONF.get("county", "radioreference") for row in radioreference.CA_COUNTIES: if code == str(row[2]): self.default_county = row[3] break else: self.default_county = 0 LOG.debug('Default province=%r county=%r' % (self.default_prov, self.default_county)) def selected_province(self, event): self._selected_province(event.GetEventObject().GetStringSelection()) def _selected_province(self, chosenprov): # if user alters the province dropdown, load the new counties into # the county dropdown choice for name, id in radioreference.CA_PROVINCES.items(): if name == chosenprov: CONF.set_int('province', id, 'radioreference') LOG.debug('Province id %s for %s' % (id, name)) break self._countychoice.Clear() for x in radioreference.CA_COUNTIES: if x[1] == chosenprov: self._countychoice.Append(x[3]) self._selected_county(self._countychoice.GetItems()[0]) def selected_county(self, event): self._selected_county(self._countychoice.GetStringSelection()) def _selected_county(self, chosencounty): self._ca_county_id = 0 for _u, _prov, cid, county in radioreference.CA_COUNTIES: if county == chosencounty: self._ca_county_id = cid break CONF.set_int('county', self._ca_county_id, 'radioreference') LOG.debug('County id %s for %s' % (self._ca_county_id, chosencounty)) @common.error_proof() def do_query(self): CONF.set('username', self._rrusername.GetValue(), 'radioreference') CONF.set_password('password', self._rrpassword.GetValue(), 'radioreference') CONF.set('zipcode', self._uszip.GetValue(), 'radioreference') self.result_radio.set_auth( CONF.get('username', 'radioreference'), CONF.get_password('password', 'radioreference')) if self.tabs.GetSelection() == 1: # CA if not radioreference.CA_PROVINCES: raise Exception(_('RadioReference Canada requires a login ' 'before you can query')) super().do_query() def get_params(self): if self.tabs.GetSelection() == 0: # US return {'zipcounty': self._uszip.GetValue(), 'country': 'US'} else: # CA return {'zipcounty': '%s' % self._ca_county_id, 'country': 'CA'} chirp-20240224/chirp/wxui/__init__.py0000644000175000017500000001740114551723752016264 0ustar hibbyhibbyimport argparse import builtins import logging import os import sys if sys.version_info < (3, 10): import importlib_resources else: import importlib.resources as importlib_resources from chirp import directory from chirp import logger LOG = logging.getLogger(__name__) CONF = None def maybe_install_desktop(): local = os.path.join(os.path.expanduser('~'), '.local') desktop_path = os.path.join(local, 'share', 'applications', 'chirp.desktop') with importlib_resources.as_file( importlib_resources.files('chirp.share') .joinpath('chirp.desktop')) as desktop_src: with open(desktop_src) as f: desktop_content = f.readlines() with importlib_resources.as_file( importlib_resources.files('chirp.share') .joinpath('chirp.ico')) as p: icon_path = str(p) if os.path.exists(desktop_path): return import wx r = wx.MessageBox( _('Would you like CHIRP to install a desktop icon for you?'), _('Install desktop icon?'), style=wx.YES_NO) if r != wx.YES: CONF.set_bool('offered_desktop', True, 'state') return os.makedirs(os.path.dirname(desktop_path), exist_ok=True) # Try to run chirp by name from ~/.local/bin exec_path = os.path.join(local, 'bin', 'chirp') if not os.path.exists(exec_path): # If that doesn't work, then just run it with our python via # module, which should always work exec_path = '%s -mchirp.wxui' % sys.executable with open(desktop_path, 'w') as f: for line in desktop_content: if line.startswith('Exec'): f.write('Exec=%s\n' % exec_path) elif line.startswith('Icon'): f.write('Icon=%s\n' % icon_path) else: f.write(line) LOG.debug('Wrote %s with exec=%r icon=%r' % ( f.name, exec_path, icon_path)) def chirpmain(): global CONF import wx # This must be imported before wx.App() to squelch warnings on startup # about duplicate "Windows bitmap file" handlers import wx.richtext from chirp.wxui import config CONF = config.get() actions = ['upload', 'download', 'query_rr', 'query_mg', 'query_rb', 'query_dm', 'new'] parser = argparse.ArgumentParser() parser.add_argument("files", metavar="file", nargs='*', help="File to open") parser.add_argument("--module", metavar="module", help="Load module on startup") logger.add_version_argument(parser) parser.add_argument("--profile", action="store_true", help="Enable profiling") parser.add_argument("--onlydriver", nargs="+", help="Include this driver while loading") parser.add_argument("--inspect", action="store_true", help="Show wxPython inspector") parser.add_argument('--page', default=None, help='Select this page of the default editor at start') parser.add_argument('--action', default=None, choices=actions, help='Start UI action immediately') parser.add_argument('--restore', default=None, action='store_true', help="Restore previous tabs") parser.add_argument('--force-language', default=None, help='Force locale to this ISO language code') if sys.platform == 'linux': parser.add_argument('--no-linux-gdk-backend', action='store_true', help='Do not force GDK_BACKEND=x11') parser.add_argument('--install-desktop-app', action='store_true', default=not CONF.get_bool('offered_desktop', 'state'), help='Prompt to install a desktop icon') logger.add_arguments(parser) args = parser.parse_args() logger.handle_options(args) app = wx.App() if args.force_language: force_lang = wx.Locale.FindLanguageInfo(args.force_language) if force_lang is None: print('Failed to find language %r' % args.force_language) return 1 LOG.info('Forcing locale to %r (%s)' % ( args.force_language, force_lang.Description)) lang = force_lang.Language elif CONF.is_defined('force_language', 'prefs'): prefs_lang = CONF.get('force_language', 'prefs') force_lang = wx.Locale.FindLanguageInfo(prefs_lang) if force_lang is None: LOG.warning('Config prefs.force_language specifies unknown ' 'language %r', prefs_lang) lang = wx.Locale.GetSystemLanguage() else: LOG.info('Forcing locale to %r (%s) via config', prefs_lang, force_lang.Description) lang = force_lang.Language else: lang = wx.Locale.GetSystemLanguage() localedir = str(os.path.join(importlib_resources.files('chirp'), 'locale')) app._lc = wx.Locale() if localedir and os.path.isdir(localedir): wx.Locale.AddCatalogLookupPathPrefix(localedir) else: LOG.warning('Did not find localedir: %s' % localedir) if lang != wx.LANGUAGE_UNKNOWN: app._lc.Init(lang) else: LOG.warning('Initializing locale without known language') app._lc.Init() app._lc.AddCatalog('CHIRP') builtins._ = wx.GetTranslation builtins.ngettext = wx.GetTranslation LOG.debug('Using locale: %s (%i)', app._lc.GetCanonicalName(), lang) LOG.debug('Translation loaded=%s for CHIRP: %s (%s) from %s', app._lc.IsLoaded('CHIRP'), wx.Translations.Get().GetBestTranslation('CHIRP'), ','.join( wx.Translations.Get().GetAvailableTranslations('CHIRP')), localedir) LOG.debug('Translation loaded=%s for wxstd: %s (%s)', app._lc.IsLoaded('wxstd'), wx.Translations.Get().GetBestTranslation('wxstd'), ','.join( wx.Translations.Get().GetAvailableTranslations('wxstd'))) from chirp.wxui import main from chirp.wxui import report logging.getLogger('main').info(report.get_environment()) directory.import_drivers(limit=args.onlydriver) if CONF.get_bool('developer', 'state'): from chirp.drivers import fake fake.register_fakes() # wxGTK on Wayland seems to have problems. Override GDK_BACKEND to # use X11, unless we were asked not to if sys.platform == 'linux' and not args.no_linux_gdk_backend: os.putenv('GDK_BACKEND', 'x11') app.SetAppName('CHIRP') mainwindow = main.ChirpMain(None, title='CHIRP') mainwindow.Show() if args.module: mainwindow.load_module(args.module) if args.restore or CONF.get_bool('restore_tabs', 'prefs'): restored = mainwindow.restore_tabs(None) else: restored = [] for fn in args.files: if os.path.abspath(fn) in restored: LOG.info('File %s on the command line is already being restored', fn) continue mainwindow.open_file(fn, select=False) if args.page: mainwindow.current_editorset.select_editor(name=args.page) if args.inspect: from wx.lib import inspection inspection.InspectionTool().Show() if args.action: wx.CallAfter(getattr(mainwindow, '_menu_%s' % args.action), None) report.check_for_updates( lambda ver: wx.CallAfter(main.display_update_notice, ver)) if sys.platform == 'linux' and args.install_desktop_app: try: maybe_install_desktop() except Exception as e: LOG.exception('Failed to run linux desktop installer: %s', e) app.MainLoop() chirp-20240224/chirp/drivers/0000755000175000017500000000000014566340177014634 5ustar hibbyhibbychirp-20240224/chirp/drivers/fake.py0000644000175000017500000001522014564102745016107 0ustar hibbyhibbyimport importlib import logging import os import struct import time from chirp import chirp_common from chirp import directory from chirp import errors from chirp import settings from chirp import util LOG = logging.getLogger(__name__) class FakeLiveRadio(chirp_common.LiveRadio): VENDOR = 'CHIRP' MODEL = 'Fake Live Radio' def __init__(self, *a, **k): super().__init__(*a, **k) self.settings = {'knob': 5} self.memories = [] for i in range(1, 12): m = chirp_common.Memory(i, empty=i > 5, name='channel %i' % i) m.freq = 146520000 self.memories.append(m) self.memories[-1].extd_number = 'Special' def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 10) rf.has_settings = True # We don't even implement this interface, but the point of this # is to make sure the GUI doesn't choke on live radios. rf.has_bank = True rf.valid_name_length = 8 rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_special_chans = ['Special'] return rf def get_memory(self, number): if number == 'Special': number = len(self.memories) m = self.memories[number - 1] if isinstance(m, chirp_common.Memory) and m.number != number: LOG.error('fake driver found %i instead of %i', m.number, number) return m def set_memory(self, mem): LOG.info('Set memory %s' % mem) self.memories[mem.number - 1] = mem.dupe() def get_settings(self): g = settings.RadioSettingGroup('top', 'Some Settings') g.append( settings.RadioSetting( 'knob', 'A knob', settings.RadioSettingValueInteger(0, 10, self.settings['knob']))) return settings.RadioSettings(g) def set_settings(self, rs): for e in rs: if isinstance(e, settings.RadioSetting): self.settings[e.name] = e.value else: self.set_settings(e) class FakeLiveSlowRadio(FakeLiveRadio): VARIANT = 'Slow' def get_memory(self, number): time.sleep(0.5) return super().get_memory(number) def set_memory(self, mem): time.sleep(5) return super().set_memory(mem) def get_settings(self): time.sleep(1) return super().get_settings() def set_settings(self, settings): time.sleep(2) return super().set_settings(settings) class FakeLiveRadioWithErrors(FakeLiveRadio): VARIANT = 'Errors' def __init__(self, *a, **k): super().__init__(*a, **k) self.memories[2] = errors.RadioError self.memories[3] = Exception def get_memory(self, number): m = super().get_memory(number) if isinstance(m, type): raise m('Error getting %i' % number) else: return m def set_memory(self, mem): if not mem.empty and mem.freq < 145000000: raise errors.RadioError('Out of range') else: return super().set_memory(mem) class FakeCloneFail(chirp_common.CloneModeRadio): VENDOR = 'CHIRP' MODEL = 'Fake Clone Radio' VARIANT = 'Errors' def sync_in(self): s = chirp_common.Status() s.max = 100 s.cur = 10 s.msg = 'Gonna fail...' self.status_fn(s) raise errors.RadioError('This always fails') class FakeKenwoodSerial: def __init__(self, *a, **k): self._rbuf = b'' def write(self, buffer): LOG.debug('Write: %r' % buffer) if buffer.startswith(b'ID'): self._rbuf += b'ID TH-F7\r' elif buffer.startswith(b'MR 0,001'): self._rbuf += \ b'MR 0,001,00146520000,0,0,0,0,0,0,00,00,000,000000000,0,0\r' elif buffer.startswith(b'MNA 001\r'): self._rbuf += b'MNA 001,Foo\r' elif buffer.startswith(b'MNA 0'): self._rbuf += buffer elif buffer.startswith(b'MW 0'): self._rbuf += b'MW\r' else: self._rbuf += b'N\r' def read(self, n): ret = self._rbuf[:n] self._rbuf = self._rbuf[n:] return ret # NOTE: This is not complete, it's just enough to do the ident dance with # these radios class FakeUV17Serial: def get_radio(self): baofeng_uv17 = importlib.import_module('chirp.drivers.baofeng_uv17') self.rclass = baofeng_uv17.UV17 def __init__(self, *a, **k): self._sbuf = b'' self.get_radio() imgfn = os.path.join(os.path.dirname(__file__), '..', '..', 'tests', 'images', '%s_%s.img' % (self.rclass.VENDOR, self.rclass.MODEL)) LOG.debug('Opening %s' % imgfn) try: with open(imgfn, 'rb') as f: self._img = f.read() LOG.debug('Loaded image size 0x%x', len(self._img)) except FileNotFoundError: LOG.error('Unable to open image, fixture will not work') self._img = b'' def write(self, buffer): baofeng_uv17Pro = importlib.import_module( 'chirp.drivers.baofeng_uv17Pro') if buffer == self.rclass._magic: LOG.debug('Sent first magic') self._sbuf += self.rclass._fingerprint elif buffer.startswith(b'R'): LOG.debug('Got: %s' % util.hexprint(buffer)) cmd, addr, blen = struct.unpack('>cHb', buffer) resp = struct.pack('>cHb', b'W', addr, blen) block = self._img[addr:addr + blen] or (b'\x00' * blen) LOG.debug('Sending block length 0x%x', len(block)) self._sbuf += resp + baofeng_uv17Pro._crypt(1, block) else: for magic, rlen in self.rclass._magics: if buffer == magic: LOG.debug('Sent magic %r' % magic) self._sbuf += b' ' * rlen return LOG.debug('Unrecognized ident string %r' % buffer) self._sbuf += b'\x15' * 32 def read(self, length): chunk = self._sbuf[:length] self._sbuf = self._sbuf[length:] return chunk def close(self): pass class FakeUV17ProSerial(FakeUV17Serial): def get_radio(self): baofeng_uv17Pro = importlib.import_module( 'chirp.drivers.baofeng_uv17Pro') self.rclass = baofeng_uv17Pro.UV17Pro def register_fakes(): directory.register(FakeLiveRadio) directory.register(FakeLiveSlowRadio) directory.register(FakeLiveRadioWithErrors) directory.register(FakeCloneFail) chirp-20240224/chirp/drivers/retevis_rt22.py0000644000175000017500000005375414566340166017554 0ustar hibbyhibby# Copyright 2016-2020 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings, \ RadioSettingValueString LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rx_tone; ul16 tx_tone; u8 unknown1; u8 unknown3:2, highpower:1, // Power Level wide:1, // Bandwidth unknown4:2, signal:1, // Signal bcl:1; // BCL u8 unknown5[2]; } memory[16]; #seekto 0x012F; struct { u8 voice; // Voice Annunciation u8 tot; // Time-out Timer u8 unknown1[3]; u8 squelch; // Squelch Level u8 save; // Battery Saver u8 beep; // Beep u8 unknown2[2]; u8 vox; // VOX u8 voxgain; // VOX Gain u8 voxdelay; // VOX Delay u8 unknown3[2]; u8 pf2key; // PF2 Key } settings; #seekto 0x017E; u8 skipflags[2]; // SCAN_ADD #seekto 0x0200; struct { char id_0x200[8]; // Radio ID @ 0x0200 } radio; #seekto 0x0300; struct { char line1[32]; char line2[32]; } embedded_msg; """ CMD_ACK = b"\x06" RT22_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=2.00), chirp_common.PowerLevel("High", watts=5.00)] RT22_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) PF2KEY_LIST = ["Scan", "Local Alarm", "Remote Alarm"] TIMEOUTTIMER_LIST = ["Off"] + ["%s seconds" % x for x in range(15, 615, 15)] VOICE_LIST = ["Off", "Chinese", "English"] VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 17)] VOXDELAY_LIST = ["0.5 | Off", "1.0 | 0", "1.5 | 1", "2.0 | 2", "2.5 | 3", "3.0 | 4", "--- | 5"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`{|}!\"#$%&'()*+,-./:;<=>?@[]^_" def _ident_from_data(data): return data[0x1B8:0x1C0] def _ident_from_image(radio): return _ident_from_data(radio.get_mmap()) def _get_radio_model(radio): block = _rt22_read_block(radio, 0x360, 0x10) block = _rt22_read_block(radio, 0x1B8, 0x10) version = block[0:8] return version def _rt22_enter_programming_mode(radio): serial = radio.pipe magic = b"PROGRGS" exito = False for i in range(0, 5): for j in range(0, len(magic)): time.sleep(0.005) serial.write(magic[j:j + 1]) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) try: serial.write(b"\x02") ident = serial.read(8) except: _rt22_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") # check if ident is OK itis = False for fp in radio._fileid: if fp in ident: # got it! itis = True break if itis is False: LOG.debug("Incorrect model ID, got this:\n\n" + util.hexprint(ident)) raise errors.RadioError("Radio identification failed.") try: serial.write(CMD_ACK) ack = serial.read(1) except: _rt22_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: _rt22_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") try: serial.write(b"\x07") ack = serial.read(1) except: _rt22_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != b"\x4E": _rt22_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") return ident def _rt22_exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _rt22_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: for j in range(0, len(cmd)): time.sleep(0.005) serial.write(cmd[j:j + 1]) response = serial.read(4 + block_size) if response[:4] != expectedresponse: _rt22_exit_programming_mode(radio) raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] time.sleep(0.005) serial.write(CMD_ACK) ack = serial.read(1) except: _rt22_exit_programming_mode(radio) raise errors.RadioError("Failed to read block at %04x" % block_addr) if ack != CMD_ACK: _rt22_exit_programming_mode(radio) raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _rt22_write_block(radio, block_addr, block_size, _requires_patch=False, _radio_id=""): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) if _requires_patch: mmap = radio.get_mmap() data = mmap[block_addr:block_addr + block_size] # For some radios (RT-622 & RT22FRS) memory at 0x1b8 reads as 0, but # radio ID should be written instead if block_addr == 0x1b8: for fp in _radio_id: if fp in mmap[0:len(_radio_id)]: data = mmap[0:len(_radio_id)] + data[len(_radio_id):] else: data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: for j in range(0, len(cmd)): time.sleep(0.005) serial.write(cmd[j:j + 1]) for j in range(0, len(data)): time.sleep(0.005) serial.write(data[j:j + 1]) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: _rt22_exit_programming_mode(radio) raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") radio_ident = _rt22_enter_programming_mode(radio) LOG.info("Radio Ident is %s" % repr(radio_ident)) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio._block_size): status.cur = addr + radio._block_size radio.status_fn(status) block = _rt22_read_block(radio, addr, radio._block_size) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _rt22_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" radio_ident = _rt22_enter_programming_mode(radio) LOG.info("Radio Ident is %s" % repr(radio_ident)) image_ident = _ident_from_image(radio) LOG.info("Image Ident is %s" % repr(image_ident)) # Determine if upload requires patching if image_ident == b"\x00\x00\x00\x00\x00\x00\xFF\xFF": patch_block = True else: patch_block = False status.cur = 0 status.max = radio._memsize for start_addr, end_addr, block_size in radio._ranges: for addr in range(start_addr, end_addr, block_size): status.cur = addr + block_size radio.status_fn(status) _rt22_write_block(radio, addr, block_size, patch_block, radio_ident) _rt22_exit_programming_mode(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" if len(data) == 0x0408: rid = data[0x0400:0x0408] return rid.startswith(cls.MODEL.encode()) else: return False @directory.register class RT22Radio(chirp_common.CloneModeRadio): """Retevis RT22""" VENDOR = "Retevis" MODEL = "RT22" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _ranges = [ (0x0000, 0x0180, 0x10), (0x01B8, 0x01F8, 0x10), (0x01F8, 0x0200, 0x08), (0x0200, 0x0340, 0x10), ] _memsize = 0x0400 _block_size = 0x40 _fileid = [b"P32073", b"P3" + b"\x00\x00\x00" + b"3", b"P3207!", b"\x00\x00\x00\x00\x00\x00\xF8\xFF"] def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = RT22_POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["NFM", "FM"] # 12.5 kHz, 25 kHz. rf.valid_dtcs_codes = RT22_DTCS rf.memory_bounds = (1, 16) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] rf.valid_bands = [(400000000, 520000000)] return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2800: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" elif _mem.tx_tone != 0xFFFF: mem.rtone = _mem.tx_tone / 10.0 txmode = "Tone" else: txmode = "" if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2800: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rx_tone != 0xFFFF: mem.ctone = _mem.rx_tone / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) if mem.tmode == "DTCS": mem.dtcs_polarity = "%s%s" % (tpol, rpol) LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.tx_tone, rxmode, _mem.rx_tone)) def get_memory(self, number): bitpos = (1 << ((number - 1) % 8)) bytepos = ((number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) _mem = self._memobj.memory[number - 1] _skp = self._memobj.skipflags[bytepos] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = _mem.wide and "FM" or "NFM" self._get_tone(_mem, mem) mem.power = RT22_POWER_LEVELS[_mem.highpower] mem.skip = "" if (_skp & bitpos) else "S" LOG.debug("mem.skip %s" % mem.skip) mem.extra = RadioSettingGroup("Extra", "extra") if self.MODEL == "RT22FRS" or self.MODEL == "RT622": rs = RadioSettingValueBoolean(_mem.bcl) rset = RadioSetting("bcl", "Busy Channel Lockout", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(_mem.signal) rset = RadioSetting("signal", "Signal", rs) mem.extra.append(rset) return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0x8000 return val rx_mode = tx_mode = None rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None tx_tone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = int(mem.rtone * 10) if rx_mode == "DTCS": rx_tone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = int(mem.ctone * 10) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.tx_tone, rx_mode, _mem.rx_tone)) def set_memory(self, mem): bitpos = (1 << ((mem.number - 1) % 8)) bytepos = ((mem.number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) _mem = self._memobj.memory[mem.number - 1] _skp = self._memobj.skipflags[bytepos] if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) return _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq.fill_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.wide = mem.mode == "FM" self._set_tone(mem, _mem) _mem.highpower = mem.power == RT22_POWER_LEVELS[1] if mem.skip != "S": _skp |= bitpos else: _skp &= ~bitpos LOG.debug("_skp %s" % _skp) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings _message = self._memobj.embedded_msg basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("tot", "Time-out timer", RadioSettingValueList( TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[_settings.tot])) basic.append(rs) rs = RadioSetting("voice", "Voice Prompts", RadioSettingValueList( VOICE_LIST, VOICE_LIST[_settings.voice])) basic.append(rs) rs = RadioSetting("pf2key", "PF2 Key", RadioSettingValueList( PF2KEY_LIST, PF2KEY_LIST[_settings.pf2key])) basic.append(rs) rs = RadioSetting("vox", "Vox", RadioSettingValueBoolean(_settings.vox)) basic.append(rs) rs = RadioSetting("voxgain", "VOX Level", RadioSettingValueList( VOX_LIST, VOX_LIST[_settings.voxgain])) basic.append(rs) rs = RadioSetting("voxdelay", "VOX Delay Time (Old | New)", RadioSettingValueList( VOXDELAY_LIST, VOXDELAY_LIST[_settings.voxdelay])) basic.append(rs) rs = RadioSetting("save", "Battery Save", RadioSettingValueBoolean(_settings.save)) basic.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) if self.MODEL != "W31E": def _filter(name): filtered = "" for char in str(name): if char in VALID_CHARS: filtered += char else: filtered += " " return filtered val = str(self._memobj.radio.id_0x200) if val == "\xFF" * 8: rs = RadioSetting("embedded_msg.line1", "Embedded Message 1", RadioSettingValueString(0, 32, _filter( _message.line1))) basic.append(rs) rs = RadioSetting("embedded_msg.line2", "Embedded Message 2", RadioSettingValueString(0, 32, _filter( _message.line2))) basic.append(rs) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) in [0x0408, ]: match_size = True # testing the model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False @directory.register class KDC1(RT22Radio): """WLN KD-C1""" VENDOR = "WLN" MODEL = "KD-C1" @directory.register class ZTX6(RT22Radio): """Zastone ZT-X6""" VENDOR = "Zastone" MODEL = "ZT-X6" @directory.register class LT316(RT22Radio): """Luiton LT-316""" VENDOR = "LUITON" MODEL = "LT-316" @directory.register class TDM8(RT22Radio): VENDOR = "TID" MODEL = "TD-M8" @directory.register class RT22FRS(RT22Radio): VENDOR = "Retevis" MODEL = "RT22FRS" @directory.register class RT622(RT22Radio): VENDOR = "Retevis" MODEL = "RT622" @directory.register class W31E(RT22Radio): """Baofeng W31E""" VENDOR = "Baofeng" MODEL = "W31E" _ranges = [ (0x0000, 0x0200, 0x10), ] _memsize = 0x0200 _block_size = 0x40 @directory.register class BFT20(RT22Radio): """Baofeng BF-T20""" VENDOR = "Baofeng" MODEL = "BF-T20" _fileid = [b"P330h33", ] chirp-20240224/chirp/drivers/ga510.py0000644000175000017500000010113314547737342016025 0ustar hibbyhibby# Copyright 2011 Dan Smith # Portions copyright 2023 Dave Liske # Portions copyright 2020 by Jiauxn Yang # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import struct from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp import errors from chirp import memmap from chirp.settings import RadioSetting, RadioSettingGroup, RadioSettings from chirp.settings import RadioSettingValueBoolean, RadioSettingValueList from chirp.settings import RadioSettingValueInteger, RadioSettingValueString LOG = logging.getLogger(__name__) try: from builtins import bytes has_future = True except ImportError: has_future = False LOG.debug('python-future package is not available; ' '%s requires it' % __name__) # GA510 and SHX8800 also have DTCS code 645 DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) DTMFCHARS = '0123456789ABCD*#' def reset(radio): try: radio.pipe.write(b'E') except Exception as e: LOG.error('Failed to reset radio: %s' % e) def start_program(radio): reset(radio) radio.pipe.read(256) radio.pipe.write(radio._magic) ack = radio.pipe.read(256) if not ack.endswith(b'\x06'): LOG.debug('Ack was %r' % ack) raise errors.RadioError('Radio did not respond to clone request') radio.pipe.write(b'F') ident = radio.pipe.read(8) LOG.debug('Radio ident string is %r' % ident) return ident def do_download(radio): ident = start_program(radio) s = chirp_common.Status() s.msg = 'Downloading' s.max = 0x1C00 data = bytes() for addr in range(0, 0x1C40, 0x40): cmd = struct.pack('>cHB', b'R', addr, 0x40) LOG.debug('Reading block at %04x: %r' % (addr, cmd)) radio.pipe.write(cmd) block = radio.pipe.read(0x44) header = block[:4] rcmd, raddr, rlen = struct.unpack('>BHB', header) block = block[4:] if raddr != addr: raise errors.RadioError('Radio send address %04x, expected %04x' % (raddr, addr)) if rlen != 0x40 or len(block) != 0x40: raise errors.RadioError('Radio sent %02x (%02x) bytes, ' 'expected %02x' % (rlen, len(block), 0x40)) data += block s.cur = addr radio.status_fn(s) return data def do_upload(radio): ident = start_program(radio) s = chirp_common.Status() s.msg = 'Uploading' s.max = 0x1C00 # The factory software downloads 0x40 for the block # at 0x1C00, but only uploads 0x20 there. Mimic that # here. for addr in range(0, 0x1C20, 0x20): cmd = struct.pack('>cHB', b'W', addr, 0x20) LOG.debug('Writing block at %04x: %r' % (addr, cmd)) block = radio._mmap[addr:addr + 0x20] radio.pipe.write(cmd) radio.pipe.write(block) ack = radio.pipe.read(1) if ack != b'\x06': raise errors.RadioError('Radio refused block at addr %04x' % addr) s.cur = addr radio.status_fn(s) BASE_FORMAT = """ struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 signal; u8 unknown1:6, pttid:2; u8 unknown2:6, power:2; u8 unknown3_0:1, narrow:1, unknown3_1:2, bcl:1, scan:1, allow_tx:1, // SHX8800 FAMILY ONLY (unknown3_2 for GA-510) fhss:1; } memories[128]; #seekto 0x0C00; struct { char name[10]; u8 pad[6]; } names[128]; """ MODEL_GA510_FORMAT = """ #seekto 0x1A00; struct { // 0x1A00 u8 squelch; u8 savemode; // [off, mode1, mode2, mode3] u8 vox; // off=0 u8 backlight; u8 tdr; // bool u8 timeout; // n*15 = seconds u8 beep; // bool u8 voice; // 0x1A08 u8 language; // [eng, chin] u8 dtmfst; u8 scanmode; // [TO, CO, SE] u8 pttid; // [off, BOT, EOT, Both] u8 pttdelay; // 0-30 u8 cha_disp; // [ch-name, ch-freq] // [ch, ch-name]; retevis u8 chb_disp; u8 bcl; // bool // 0x1A10 u8 autolock; // bool u8 alarm_mode; // [site, tone, code] u8 alarmsound; // bool u8 txundertdr; // [off, bandA, bandB] u8 tailnoiseclear; // [off, on] u8 rptnoiseclr; // 10*ms, 0-1000 u8 rptnoisedet; u8 roger; // bool // 0x1A18 u8 unknown1a10; u8 fmradio; // boolean, inverted u8 workmode; // [vfo, chan]; 1A30-1A31 related? u8 kblock; // boolean } settings; #seekto 0x1A80; struct { u8 skey1sp; // [off, lamp, sos, fm, noaa, moni, search] u8 skey1lp; // [off, lamp, sos, fm, noaa, moni, search] u8 skey2sp; // [off, lamp, sos, fm, noaa, moni, search] u8 skey2lp; // [off, lamp, sos, fm, noaa, moni, search] } skey; struct dtmfcode { u8 code[5]; u8 ffpad[11]; // always 0xFF }; #seekto 0x1B00; struct dtmfcode dtmfgroup[15]; struct { u8 code[5]; u8 groupcode; // 0->D, *, # u8 nothing:6, releasetosend:1, presstosend:1; u8 dtmfspeedon; // 80 + n*10, up to [194] u8 dtmfspeedoff; } anicode; //dtmf on -> 90ms //dtmf off-> 120ms //group code *->0 //press 0->1 //release 1->0 """ MODEL_SHX8800_FORMAT = """ #seekto 0x1A00; struct { // 0x1A00 u8 squelch; u8 savemode; // [off, mode1, mode2, mode3] u8 vox; // off=0 u8 backlight; u8 tdr; // bool u8 timeout; // n*15 = seconds u8 beep; // bool u8 voice; // 0x1A08 u8 language; // [inop in 8800] u8 dtmfst; u8 scanmode; // [TO, CO, SE] u8 pttid; // [off, BOT, EOT, Both] u8 pttdelay; // 0-30 u8 cha_disp; // [ch-name, ch-freq] // [ch, ch-name]; retevis u8 chb_disp; u8 bcl; // bool // 0x1A10 u8 autolock; // bool u8 alarm_mode; // [site, tone, code] u8 alarmsound; // bool u8 txundertdr; // [off, bandA, bandB] u8 tailnoiseclear; // [off, on] u8 rptnoiseclr; // 10*ms, 0-1000 u8 rptnoisedet; u8 roger; // bool // 0x1A18 u8 unknown1a10; u8 fmradio; // boolean, inverted u8 workmodeb:4, workmodea:4; u8 kblock; u8 unknown2[4]; u8 voxdelay; u8 menu_timeout; u8 micgain; } settings; #seekto 0x1a40; struct { u8 freq[8]; ul16 rxtone; ul16 txtone; u8 unknown[2]; u8 unused2:2, sftd:2, scode:4; u8 unknown1; u8 txpower; u8 widenarr:1, unknown2:4, fhss:1, unknown3:2; u8 band; u8 unknown4:5, step:3; u8 unknown5; u8 offset[6]; } vfoa; // displays in Browser tab #seekto 0x1a60; struct { u8 freq[8]; ul16 rxtone; ul16 txtone; u8 unknown[2]; u8 unused2:2, sftd:2, scode:4; u8 unknown1; u8 txpower; u8 widenarr:1, unknown2:4, fhss:1, unknown3:2; u8 band; u8 unknown4:5, step:3; u8 unknown5; u8 offset[6]; } vfob; // displays in Browser tab #seekto 0x1a80; struct { u8 sidekey; u8 sidekeyl; } keymaps; #seekto 0x1b00; struct { u8 code[5]; u8 unused[11]; } dtmfgroup[15]; struct { u8 code[5]; u8 groupcode; u8 aniid; u8 dtmfspeedon; u8 dtmfspeedoff; } anicode; """ PTTID = ['Off', 'BOT', 'EOT', 'Both'] SIGNAL = [str(i) for i in range(1, 16)] WORKMODE_LIST = ["VFO", "CH"] SHIFTD_LIST = ["Off", "+", "-"] PTTIDCODE_LIST = ["%s" % x for x in range(1, 128)] STEPS = [6.25, 10.0, 12.5, 20.0, 25.0, 50.0] STEP_LIST = [str(x) for x in STEPS] TXPOWER_LIST = ["High (5W)", "Low (1W)"] BANDWIDTH_LIST = ["Wide", "Narrow"] @directory.register class RadioddityGA510Radio(chirp_common.CloneModeRadio): VENDOR = 'Radioddity' MODEL = 'GA-510' BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False POWER_LEVELS = [ chirp_common.PowerLevel('H', watts=10), chirp_common.PowerLevel('L', watts=1), chirp_common.PowerLevel('M', watts=5)] _mem_format = MODEL_GA510_FORMAT _magic = (b'PROGROMBFHU') _gmrs = False def sync_in(self): try: data = do_download(self) self._mmap = memmap.MemoryMapBytes(data) except errors.RadioError: raise except Exception as e: LOG.exception('General failure') raise errors.RadioError('Failed to download from radio: %s' % e) finally: reset(self) self.process_mmap() def sync_out(self): try: do_upload(self) except errors.RadioError: raise except Exception as e: LOG.exception('General failure') raise errors.RadioError('Failed to upload to radio: %s' % e) finally: reset(self) def process_mmap(self): self._memobj = bitwise.parse(BASE_FORMAT + self._mem_format, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 127) rf.has_ctone = True rf.has_cross = True rf.has_tuning_step = False rf.has_settings = True rf.has_bank = False rf.has_sub_devices = False rf.has_dtcs_polarity = True rf.has_rx_dtcs = True rf.can_odd_split = True rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ['Tone->Tone', 'DTCS->', '->DTCS', 'Tone->DTCS', 'DTCS->Tone', '->Tone', 'DTCS->DTCS'] rf.valid_modes = ['FM', 'NFM'] rf.valid_tuning_steps = [2.5, 5.0, 6.25, 12.5, 10.0, 15.0, 20.0, 25.0, 50.0, 100.0] rf.valid_dtcs_codes = DTCS_CODES rf.valid_duplexes = ['', '-', '+', 'split', 'off'] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 10 rf.valid_characters = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' '0123456789' '!"#$%&\'()~+-,./:;<=>?@[\\]^`{}*| ') rf.valid_bands = [(136000000, 174000000), (400000000, 480000000)] return rf def get_raw_memory(self, num): return repr(self._memobj.memories[num]) + repr(self._memobj.names[num]) @staticmethod def _decode_tone(toneval): if toneval in (0, 0xFFFF): LOG.debug('no tone value: %s' % toneval) return '', None, None elif toneval < 670: toneval = toneval - 1 index = toneval % len(DTCS_CODES) if index != int(toneval): pol = 'R' # index -= 1 else: pol = 'N' return 'DTCS', DTCS_CODES[index], pol else: return 'Tone', toneval / 10.0, 'N' @staticmethod def _encode_tone(mode, val, pol): if not mode: return 0x0000 elif mode == 'Tone': return int(val * 10) elif mode == 'DTCS': index = DTCS_CODES.index(val) if pol == 'R': index += len(DTCS_CODES) index += 1 LOG.debug('Encoded dtcs %s/%s to %04x' % (val, pol, index)) return index else: raise errors.RadioError('Unsupported tone mode %r' % mode) def _get_extra(self, _mem): group = RadioSettingGroup('extra', 'Extra') s = RadioSetting('bcl', 'Busy Channel Lockout', RadioSettingValueBoolean(_mem.bcl)) group.append(s) s = RadioSetting('fhss', 'FHSS', RadioSettingValueBoolean(_mem.fhss)) group.append(s) # pttid, signal cur = PTTID[int(_mem.pttid)] s = RadioSetting('pttid', 'PTTID', RadioSettingValueList(PTTID, cur)) group.append(s) cur = SIGNAL[int(_mem.signal)] s = RadioSetting('signal', 'Signal', RadioSettingValueList(SIGNAL, cur)) group.append(s) return group def _set_extra(self, _mem, mem): _mem.bcl = int(mem.extra['bcl'].value) _mem.fhss = int(mem.extra['fhss'].value) _mem.pttid = int(mem.extra['pttid'].value) _mem.signal = int(mem.extra['signal'].value) def _is_txinh(self, _mem): raw_tx = "" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw(asbytes=False) return raw_tx == "\xFF\xFF\xFF\xFF" def _get_mem(self, num): return self._memobj.memories[num] def _get_nam(self, num): return self._memobj.names[num] def get_memory(self, num): _mem = self._get_mem(num) _nam = self._get_nam(num) mem = chirp_common.Memory() mem.number = num if int(_mem.rxfreq) == 166666665: mem.empty = True return mem mem.name = ''.join([str(c) for c in _nam.name if ord(str(c)) < 127]).rstrip() mem.freq = int(_mem.rxfreq) * 10 offset = (int(_mem.txfreq) - int(_mem.rxfreq)) * 10 if self._is_txinh(_mem): mem.duplex = 'off' mem.offset = 0 elif offset == 0: mem.duplex = '' elif abs(offset) < 100000000: mem.duplex = offset < 0 and '-' or '+' mem.offset = abs(offset) else: mem.duplex = 'split' mem.offset = int(_mem.txfreq) * 10 mem.power = self.POWER_LEVELS[_mem.power] mem.mode = 'NFM' if _mem.narrow else 'FM' mem.skip = '' if _mem.scan else 'S' LOG.debug('got txtone: %s' % repr(self._decode_tone(_mem.txtone))) LOG.debug('got rxtone: %s' % repr(self._decode_tone(_mem.rxtone))) chirp_common.split_tone_decode(mem, self._decode_tone(_mem.txtone), self._decode_tone(_mem.rxtone)) try: mem.extra = self._get_extra(_mem) except: LOG.exception('Failed to get extra for %i' % num) return mem def _set_mem(self, number): return self._memobj.memories[number] def _set_nam(self, number): return self._memobj.names[number] def set_memory(self, mem): _mem = self._set_mem(mem.number) _nam = self._set_nam(mem.number) if mem.empty: _mem.set_raw(b'\xff' * 16) _nam.set_raw(b'\xff' * 16) return if int(_mem.rxfreq) == 166666665: LOG.debug('Initializing new memory %i' % mem.number) _mem.set_raw(b'\x00' * 16) _nam.name = mem.name.ljust(10) if isinstance(self, Senhaix8800Radio): _mem.allow_tx = True _mem.rxfreq = mem.freq // 10 if mem.duplex == '': if isinstance(self, Senhaix8800Radio): _mem.allow_tx = False _mem.txfreq = mem.freq // 10 elif mem.duplex == 'split': _mem.txfreq = mem.offset // 10 elif mem.duplex == 'off': for i in range(0, 4): _mem.txfreq[i].set_raw(b'\xFF') elif mem.duplex == '-': _mem.txfreq = (mem.freq - mem.offset) // 10 elif mem.duplex == '+': _mem.txfreq = (mem.freq + mem.offset) // 10 else: raise errors.RadioError('Unsupported duplex mode %r' % mem.duplex) txtone, rxtone = chirp_common.split_tone_encode(mem) LOG.debug('tx tone is %s' % repr(txtone)) LOG.debug('rx tone is %s' % repr(rxtone)) _mem.txtone = self._encode_tone(*txtone) _mem.rxtone = self._encode_tone(*rxtone) try: _mem.power = self.POWER_LEVELS.index(mem.power) except ValueError: _mem.power = 0 _mem.narrow = mem.mode == 'NFM' _mem.scan = mem.skip != 'S' if mem.extra: self._set_extra(_mem, mem) def get_settings(self): _set = self._memobj.settings basic = RadioSettingGroup('basic', 'Basic') adv = RadioSettingGroup('advanced', 'Advanced') dtmf = RadioSettingGroup('dtmf', 'DTMF') radioddity_settings = { 'savemode': ['Off', 'Mode 1', 'Mode 2', 'Mode 3'], 'cha_disp': ['CH+Name', 'CH+Freq'], 'chb_disp': ['CH+Name', 'CH+Freq'], 'txundertdr': ['Off', 'Band A', 'Band B'], 'rptnoiseclr': ['Off'] + ['%i' % i for i in range(100, 1001, 100)], 'rptnoisedet': ['Off'] + ['%i' % i for i in range(100, 1001, 100)], } retevis_settings = { 'savemode': ['Off', 'On'], 'cha_disp': ['CH', 'CH+Name'], 'chb_disp': ['CH', 'CH+Name'], } language_setting = { 'language': ['English', 'Chinese'], } ga_workmode = { 'workmode': ['VFO', 'Chan'], } shx_workmode = { 'workmodea': ['VFO', 'Chan'], 'workmodeb': ['VFO', 'Chan'], } choice_settings = { 'vox': ['Off'] + ['%i' % i for i in range(1, 11)], 'backlight': ['Off'] + ['%i' % i for i in range(1, 11)], 'timeout': ['Off'] + ['%i' % i for i in range(15, 615, 15)], 'dtmfst': ['OFF', 'KB Side Tone', 'ANI Side Tone', 'KB ST+ANI ST', 'Both'], 'scanmode': ['TO', 'CO', 'SE'], 'pttid': ['Off', 'BOT', 'EOT', 'Both'], 'alarm_mode': ['Site', 'Tone', 'Code'], } if isinstance(self, Senhaix8800Radio): choice_settings.update(shx_workmode) else: choice_settings.update(language_setting) choice_settings.update(ga_workmode) if self.VENDOR == "Retevis": choice_settings.update(retevis_settings) else: choice_settings.update(radioddity_settings) if isinstance(self, Senhaix8800Radio): basic_settings = ['timeout', 'vox', 'backlight', 'cha_disp', 'chb_disp', 'workmodea', 'workmodeb'] else: basic_settings = ['timeout', 'vox', 'backlight', 'language', 'cha_disp', 'chb_disp', 'workmode'] titles = { 'savemode': 'Save Mode', 'vox': 'VOX', 'backlight': 'Auto Backlight', 'timeout': 'Time Out Timer (s)', 'language': 'Language', 'dtmfst': 'DTMF-ST', 'scanmode': 'Scan Mode', 'pttid': 'PTT-ID', 'cha_disp': 'Channel A Display', 'chb_disp': 'Channel B Display', 'alarm_mode': 'Alarm Mode', 'txundertdr': 'TX Under TDR', 'rptnoiseclr': 'RPT Noise Clear (ms)', 'rptnoisedet': 'RPT Noise Detect (ms)', 'workmode': 'Work Mode', 'workmodea': 'Work Mode A', 'workmodeb': 'Work Mode B', } basic.append( RadioSetting('squelch', 'Squelch Level', RadioSettingValueInteger(0, 9, int(_set.squelch)))) adv.append( RadioSetting('pttdelay', 'PTT Delay', RadioSettingValueInteger(0, 30, int(_set.pttdelay)))) adv.append( RadioSetting('tdr', 'TDR', RadioSettingValueBoolean( int(_set.tdr)))) adv.append( RadioSetting('beep', 'Beep', RadioSettingValueBoolean( int(_set.beep)))) basic.append( RadioSetting('voice', 'Voice Enable', RadioSettingValueBoolean( int(_set.voice)))) adv.append( RadioSetting('bcl', 'BCL', RadioSettingValueBoolean( int(_set.bcl)))) adv.append( RadioSetting('autolock', 'Auto Lock', RadioSettingValueBoolean( int(_set.autolock)))) adv.append( RadioSetting('alarmsound', 'Alarm Sound', RadioSettingValueBoolean( int(_set.alarmsound)))) adv.append( RadioSetting('tailnoiseclear', 'Tail Noise Clear', RadioSettingValueBoolean( int(_set.tailnoiseclear)))) adv.append( RadioSetting('roger', 'Roger', RadioSettingValueBoolean( int(_set.roger)))) adv.append( RadioSetting('fmradio', 'FM Radio Disabled', RadioSettingValueBoolean( int(_set.fmradio)))) adv.append( RadioSetting('kblock', 'KB Lock', RadioSettingValueBoolean( int(_set.kblock)))) for key in sorted(choice_settings): choices = choice_settings[key] title = titles[key] if key in basic_settings: group = basic else: group = adv val = int(getattr(_set, key)) try: cur = choices[val] except IndexError: LOG.error('Value %i for %s out of range for list (%i): %s' % ( val, key, len(choices), choices)) raise group.append( RadioSetting(key, title, RadioSettingValueList( choices, choices[val]))) if self.VENDOR == "Retevis": # Side Keys _skey = self._memobj.skey SK_CHOICES = ['OFF', 'LAMP', 'SOS', 'FM', 'NOAA', 'MONI', 'SEARCH'] SK_VALUES = [0xFF, 0x08, 0x03, 0x07, 0x0C, 0x05, 0x1D] def apply_sk_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = SK_CHOICES.index(val) val = SK_VALUES[index] obj.set_value(val) # Side Key 1 - Short Press if _skey.skey1sp in SK_VALUES: idx = SK_VALUES.index(_skey.skey1sp) else: idx = SK_VALUES.index(0xFF) rs = RadioSetting('skey.skey1sp', 'Side Key 1 - Short Press', RadioSettingValueList(SK_CHOICES, SK_CHOICES[idx])) rs.set_apply_callback(apply_sk_listvalue, _skey.skey1sp) adv.append(rs) # Side Key 1 - Long Press if _skey.skey1lp in SK_VALUES: idx = SK_VALUES.index(_skey.skey1lp) else: idx = SK_VALUES.index(0xFF) rs = RadioSetting('skey.skey1lp', 'Side Key 1 - Long Press', RadioSettingValueList(SK_CHOICES, SK_CHOICES[idx])) rs.set_apply_callback(apply_sk_listvalue, _skey.skey1lp) adv.append(rs) # Side Key 2 - Short Press if _skey.skey2sp in SK_VALUES: idx = SK_VALUES.index(_skey.skey2sp) else: idx = SK_VALUES.index(0xFF) rs = RadioSetting('skey.skey2sp', 'Side Key 2 - Short Press', RadioSettingValueList(SK_CHOICES, SK_CHOICES[idx])) rs.set_apply_callback(apply_sk_listvalue, _skey.skey2sp) adv.append(rs) # Side Key 1 - Long Press if _skey.skey2lp in SK_VALUES: idx = SK_VALUES.index(_skey.skey2lp) else: idx = SK_VALUES.index(0xFF) rs = RadioSetting('skey.skey2lp', 'Side Key 2 - Long Press', RadioSettingValueList(SK_CHOICES, SK_CHOICES[idx])) rs.set_apply_callback(apply_sk_listvalue, _skey.skey2lp) adv.append(rs) for i in range(1, 16): cur = ''.join( DTMFCHARS[i] for i in self._memobj.dtmfgroup[i - 1].code if int(i) < 0xF) dtmf.append( RadioSetting( 'dtmf.code@%i' % i, 'DTMF Group %i' % i, RadioSettingValueString(0, 5, cur, autopad=False, charset=DTMFCHARS))) cur = ''.join( '%X' % i for i in self._memobj.anicode.code if int(i) < 0xE) anicode = self._memobj.anicode if isinstance(self, Senhaix8800Radio): _codeobj = self._memobj.anicode.code _code = "".join([DTMFCHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMFCHARS) rs = RadioSetting("anicode.code", "ANI Code", val) def apply_code(setting, obj): code = [] for j in range(0, 5): try: code.append(DTMFCHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, anicode) dtmf.append(rs) dtmf.append( RadioSetting( "anicode.groupcode", "Group Code", RadioSettingValueList(list(DTMFCHARS), DTMFCHARS[int(anicode.groupcode)]))) else: dtmf.append( RadioSetting( 'anicode.code', 'ANI Code', RadioSettingValueString(0, 5, cur, autopad=False, charset=DTMFCHARS))) dtmf.append( RadioSetting( 'anicode.groupcode', 'Group Code', RadioSettingValueList( list(DTMFCHARS), DTMFCHARS[int(anicode.groupcode)]))) dtmf.append( RadioSetting( 'anicode.releasetosend', 'Release To Send', RadioSettingValueBoolean( int(anicode.releasetosend)))) dtmf.append( RadioSetting( 'anicode.presstosend', 'Press To Send', RadioSettingValueBoolean( int(anicode.presstosend)))) cur = int(anicode.dtmfspeedon) * 10 + 80 dtmf.append( RadioSetting( 'anicode.dtmfspeedon', 'DTMF Speed (on time in ms)', RadioSettingValueInteger(60, 2000, cur, 10))) cur = int(anicode.dtmfspeedoff) * 10 + 80 dtmf.append( RadioSetting( 'anicode.dtmfspeedoff', 'DTMF Speed (off time in ms)', RadioSettingValueInteger(60, 2000, cur, 10))) top = RadioSettings(basic, adv, dtmf) return top def set_settings(self, settings): for element in settings: if element.get_name().startswith('anicode.'): self._set_anicode(element) elif element.get_name().startswith('dtmf.code'): self._set_dtmfcode(element) elif element.get_name().startswith('skey.'): self._set_skey(element) elif not isinstance(element, RadioSetting): self.set_settings(element) continue else: self._set_setting(element) def _set_setting(self, setting): key = setting.get_name() val = setting.value setattr(self._memobj.settings, key, int(val)) def _set_anicode(self, setting): name = setting.get_name().split('.', 1)[1] if name == 'code': val = [DTMFCHARS.index(c) for c in str(setting.value)] for i in range(0, 5): try: value = val[i] except IndexError: value = 0xFF self._memobj.anicode.code[i] = value elif name.startswith('dtmfspeed'): setattr(self._memobj.anicode, name, (int(setting.value) - 80) // 10) else: setattr(self._memobj.anicode, name, int(setting.value)) def _set_dtmfcode(self, setting): index = int(setting.get_name().split('@', 1)[1]) - 1 val = [DTMFCHARS.index(c) for c in str(setting.value)] for i in range(0, 5): try: value = val[i] except IndexError: value = 0xFF self._memobj.dtmfgroup[index].code[i] = value def _set_skey(self, setting): if setting.has_apply_callback(): LOG.debug("Using apply callback") setting.run_apply_callback() @directory.register class RetevisRA685Radio(RadioddityGA510Radio): VENDOR = 'Retevis' MODEL = 'RA685' POWER_LEVELS = [ chirp_common.PowerLevel('H', watts=5), chirp_common.PowerLevel('L', watts=1), chirp_common.PowerLevel('M', watts=3)] _magic = b'PROGROMWLTU' def get_features(self): rf = RadioddityGA510Radio.get_features(self) rf.memory_bounds = (1, 128) rf.valid_bands = [(136000000, 174000000), (400000000, 520000000)] return rf def _get_mem(self, num): return self._memobj.memories[num - 1] def _get_nam(self, number): return self._memobj.names[number - 1] def _set_mem(self, num): return self._memobj.memories[num - 1] def _set_nam(self, number): return self._memobj.names[number - 1] vhftx = [144000000, 146000000] uhftx = [430000000, 440000000] @directory.register class RetevisRA85Radio(RadioddityGA510Radio): VENDOR = 'Retevis' MODEL = 'RA85' POWER_LEVELS = [ chirp_common.PowerLevel('H', watts=5), chirp_common.PowerLevel('L', watts=0.5), chirp_common.PowerLevel('M', watts=0.6)] _magic = b'PROGROMWLTU' def get_features(self): rf = RadioddityGA510Radio.get_features(self) rf.memory_bounds = (1, 128) rf.valid_bands = [(136000000, 174000000), (400000000, 520000000)] return rf def _get_mem(self, num): return self._memobj.memories[num - 1] def _get_nam(self, number): return self._memobj.names[number - 1] def _set_mem(self, num): return self._memobj.memories[num - 1] def _set_nam(self, number): return self._memobj.names[number - 1] @directory.register class TDH6Radio(RadioddityGA510Radio): VENDOR = "TIDRADIO" MODEL = "TD-H6" def get_features(self): rf = super().get_features() rf.valid_bands = [(136000000, 174000000), (400000000, 520000000)] return rf @directory.register class Senhaix8800Radio(RadioddityGA510Radio): """Senhaix 8800""" VENDOR = "SenhaiX" MODEL = "8800" POWER_LEVELS = [ chirp_common.PowerLevel('H', watts=5), chirp_common.PowerLevel('L', watts=1)] _mem_format = MODEL_SHX8800_FORMAT _magic = b'PROGROMSHXU' @directory.register class RadioddityGS5BRadio(Senhaix8800Radio): """Radioddity GS-5B""" VENDOR = "Radioddity" MODEL = "GS-5B" # NOTE: This was added as Signus originally in 18295675 @directory.register class CignusXTR5Radio(Senhaix8800Radio): """Cignus XTR-5""" VENDOR = "Cignus" MODEL = "XTR-5" @directory.register class AnysecuAC580Radio(Senhaix8800Radio): """Anysecu AC-580""" VENDOR = "Anysecu" MODEL = "AC-580" @directory.register class AbbreeARF5Radio(RadioddityGA510Radio): VENDOR = 'Abbree' MODEL = 'AR-F5' POWER_LEVELS = [ chirp_common.PowerLevel('H', watts=5), chirp_common.PowerLevel('L', watts=1), chirp_common.PowerLevel('M', watts=2)] _magic = b'PROGROMWLTU' def get_features(self): rf = RadioddityGA510Radio.get_features(self) rf.memory_bounds = (1, 128) rf.valid_bands = [(136000000, 174000000), (200000000, 300000000), (300000000, 400000000), (400000000, 520000000)] return rf def _get_mem(self, num): return self._memobj.memories[num - 1] def _get_nam(self, number): return self._memobj.names[number - 1] def _set_mem(self, num): return self._memobj.memories[num - 1] def _set_nam(self, number): return self._memobj.names[number - 1] chirp-20240224/chirp/drivers/kyd_IP620.py0000644000175000017500000005366414566340166016631 0ustar hibbyhibby# Copyright 2015 Lepik.stv # based on modification of Dan Smith's and Jim Unroe original work # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """KYD IP-620 radios management module""" # TODO: Power on message # TODO: Channel name # TODO: Tuning step import struct import time import logging from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettings LOG = logging.getLogger(__name__) IP620_MEM_FORMAT = """ #seekto 0x0000; struct { // Channel memory structure lbcd rx_freq[4]; // RX frequency lbcd tx_freq[4]; // TX frequency ul16 rx_tone; // RX tone ul16 tx_tone; // TX tone u8 unknown_1:4, // n-a busy_loc:2, // NO-00, Carrier wave-01, SM-10 n_a:2; // n-a u8 unknown_2:1, // n-a scan_add:1, // Scan add n_a2:1, // n-a w_n:1, // Narrow-0 Wide-1 lout:1, // LOCKOUT OFF-0 ON-1 n_a_:1, // n-a power:2; // Power low-00 middle-01 high-10 u8 unknown_3; // n-a u8 unknown_4; // n-a } memory[200]; #seekto 0x1000; struct { u8 chan_name[6]; //Channel name u8 unknown_1[10]; } chan_names[200]; #seekto 0x0C80; struct { // Settings memory structure ( A-Frequency mode ) lbcd freq_a_rx[4]; lbcd freq_a_tx[4]; ul16 freq_a_rx_tone; // RX tone ul16 freq_a_tx_tone; // TX tone u8 unknown_1_5:4, freq_a_busy_loc:2, n_a:2; u8 unknown_1_6:3, freq_a_w_n:1, n_a2:1, na:1, freq_a_power:2; u8 unknown_1_7; u8 unknown_1_8; } settings_freq_a; #seekto 0x0E20; struct { u8 chan_disp_way; // Channel display way u8 step_freq; // Step frequency kHz u8 rf_sql; // Squelch level u8 bat_save; // Battery Saver u8 chan_pri; // Channel PRI u8 end_beep; // End beep u8 tot; // Time-out timer u8 vox; // VOX Gain u8 chan_pri_num; // Channel PRI time Sec u8 n_a_2; u8 ch_mode; // CH mode u8 n_a_3; u8 call_tone; // Call tone u8 beep; // Beep u8 unknown_1_1[2]; u8 unknown_1_2[8]; u8 scan_rev; // Scan rev u8 unknown_1_3[2]; u8 enc; // Frequency lock u8 vox_dly; // VOX Delay u8 wait_back_light;// Wait back light u8 unknown_1_4[2]; } settings; #seekto 0x0E40; struct { u8 fm_radio; // FM radio u8 auto_lock; // Auto lock u8 unknown_1[8]; u8 pon_msg[6]; //Power on msg } settings_misc; #seekto 0x1C80; struct { u8 unknown_1[16]; u8 unknown_2[16]; } settings_radio_3; """ CMD_ACK = "\x06" WRITE_BLOCK_SIZE = 0x10 READ_BLOCK_SIZE = 0x40 CHAR_LENGTH_MAX = 6 OFF_ON_LIST = ["OFF", "ON"] ON_OFF_LIST = ["ON", "OFF"] NO_YES_LIST = ["NO", "YES"] STEP_LIST = ["5.0", "6.25", "10.0", "12.5", "25.0"] BAT_SAVE_LIST = ["OFF", "0.2 Sec", "0.4 Sec", "0.6 Sec", "0.8 Sec", "1.0 Sec"] SHIFT_LIST = ["", "-", "+"] SCANM_LIST = ["Time", "Carrier wave", "Search"] ENDBEEP_LIST = ["OFF", "Begin", "End", "Begin/End"] POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("Medium", watts=2.50), chirp_common.PowerLevel("High", watts=5.00)] TIMEOUT_LIST = ["OFF", "1 Min", "3 Min", "10 Min"] TOTALERT_LIST = ["", "OFF"] + ["%s seconds" % x for x in range(1, 11)] VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 17)] VOXDELAY_LIST = ["0.3 Sec", "0.5 Sec", "1.0 Sec", "1.5 Sec", "2.0 Sec", "3.0 Sec", "4.0 Sec", "5.0 Sec"] PRI_NUM = [3, 5, 8, 10] PRI_NUM_LIST = [str(x) for x in PRI_NUM] CH_FLAG_LIST = ["Channel+Freq", "Channel+Name"] BACKLIGHT_LIST = ["Always Off", "Auto", "Always On"] BUSYLOCK_LIST = ["NO", "Carrier", "SM"] KEYBLOCK_LIST = ["Manual", "Auto"] CALLTONE_LIST = ["OFF", "1", "2", "3", "4", "5", "6", "7", "8", "1750"] RFSQL_LIST = ["OFF", "S-1", "S-2", "S-3", "S-4", "S-5", "S-6", "S-7", "S-8", "S-FULL"] IP620_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ?+-* " IP620_BANDS = [ (136000000, 174000000), (200000000, 260000000), (300000000, 340000000), # <--- this band supports only Russian model (ARGUT A-36) (350000000, 390000000), (400000000, 480000000), (420000000, 510000000), (450000000, 520000000), ] @directory.register class IP620Radio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """KYD IP-620""" VENDOR = "KYD" MODEL = "IP-620" BAUD_RATE = 9600 _ranges = [ (0x0000, 0x2000), ] _memsize = 0x2000 @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0xF7E:0xF80] == b"\x01\xE2" def _ip620_exit_programming_mode(self): try: self.pipe.write("\x06") except errors.RadioError: raise except Exception as e: raise errors.RadioError("Radio refused to exit programming mode: %s" % e) def _ip620_enter_programming_mode(self): try: self.pipe.write("iUHOUXUN") self.pipe.write("\x02") time.sleep(0.2) _ack = self.pipe.read(1) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Error communicating with radio: %s" % e) if not _ack: raise errors.RadioError("No response from radio") elif _ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") try: self.pipe.write("\x02") _ident = self.pipe.read(8) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Error communicating with radio: %s" % e) if not _ident.startswith("\x06\x4B\x47\x36\x37\x01\x56\xF8"): print(util.hexprint(_ident)) raise errors.RadioError("Radio returned unknown identification string") try: self.pipe.write(CMD_ACK) _ack = self.pipe.read(1) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Error communicating with radio: %s" % e) if _ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _ip620_write_block(self, block_addr): _cmd = struct.pack(">cHb", 'W', block_addr, WRITE_BLOCK_SIZE) _data = self.get_mmap()[block_addr:block_addr + WRITE_BLOCK_SIZE] LOG.debug("Writing Data:") LOG.debug(util.hexprint(_cmd + _data)) try: self.pipe.write(_cmd + _data) if self.pipe.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def _ip620_read_block(self, block_addr): _cmd = struct.pack(">cHb", 'R', block_addr, READ_BLOCK_SIZE) _expectedresponse = "W" + _cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: self.pipe.write(_cmd) _response = self.pipe.read(4 + READ_BLOCK_SIZE) if _response[:4] != _expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) _block_data = _response[4:] self.pipe.write(CMD_ACK) _ack = self.pipe.read(1) except: raise errors.RadioError("Failed to read block at %04x" % block_addr) if _ack != CMD_ACK: raise Exception("No ACK reading block %04x." % (block_addr)) return _block_data def _do_download(self): self._ip620_enter_programming_mode() _data = "" _status = chirp_common.Status() _status.msg = "Cloning from radio" _status.cur = 0 _status.max = self._memsize for _addr in range(0, self._memsize, READ_BLOCK_SIZE): _status.cur = _addr + READ_BLOCK_SIZE self.status_fn(_status) _block = self._ip620_read_block(_addr) _data += _block LOG.debug("Address: %04x" % _addr) LOG.debug(util.hexprint(_block)) self._ip620_exit_programming_mode() return memmap.MemoryMap(_data) def _do_upload(self): _status = chirp_common.Status() _status.msg = "Uploading to radio" self._ip620_enter_programming_mode() _status.cur = 0 _status.max = self._memsize for _start_addr, _end_addr in self._ranges: for _addr in range(_start_addr, _end_addr, WRITE_BLOCK_SIZE): _status.cur = _addr + WRITE_BLOCK_SIZE self.status_fn(_status) self._ip620_write_block(_addr) self._ip620_exit_programming_mode() @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is currently under development. " "There are no known issues with it, but you should " "proceed with caution. However, proceed at your own risk!") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = False rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = False rf.has_name = False rf.valid_skips = [] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_duplexes = SHIFT_LIST rf.valid_modes = ["FM", "NFM"] rf.memory_bounds = (1, 200) rf.valid_bands = IP620_BANDS rf.valid_characters = ''.join(set(IP620_CHARSET)) rf.valid_name_length = CHAR_LENGTH_MAX return rf def process_mmap(self): self._memobj = bitwise.parse(IP620_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._do_download() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): self._do_upload() def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2800: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" elif _mem.tx_tone != 0xFFFF: mem.rtone = _mem.tx_tone / 10.0 txmode = "Tone" else: txmode = "" if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2800: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rx_tone != 0xFFFF: mem.ctone = _mem.rx_tone / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) if mem.tmode == "DTCS": mem.dtcs_polarity = "%s%s" % (tpol, rpol) LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.tx_tone, rxmode, _mem.rx_tone)) def get_memory(self, number): _mem = self._memobj.memory[number - 1] _nam = self._memobj.chan_names[number - 1] def _is_empty(): if _mem.rx_freq.get_raw() != b"\xFF\xFF\xFF\xFF": return False return True mem = chirp_common.Memory() mem.number = number if _is_empty(): mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 if int(_mem.rx_freq) == int(_mem.tx_freq): mem.duplex = "" mem.offset = 0 elif _mem.tx_freq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" else: mem.duplex = int(_mem.rx_freq) > int(_mem.tx_freq) and "-" or "+" mem.offset = abs(int(_mem.rx_freq) - int(_mem.tx_freq)) * 10 mem.mode = _mem.w_n and "FM" or "NFM" self._get_tone(_mem, mem) mem.power = POWER_LEVELS[_mem.power] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("lout", "Lock out", RadioSettingValueList(OFF_ON_LIST, OFF_ON_LIST[_mem.lout])) mem.extra.append(rs) rs = RadioSetting("busy_loc", "Busy lock", RadioSettingValueList(BUSYLOCK_LIST, BUSYLOCK_LIST[_mem.busy_loc])) mem.extra.append(rs) rs = RadioSetting("scan_add", "Scan add", RadioSettingValueList(NO_YES_LIST, NO_YES_LIST[_mem.scan_add])) mem.extra.append(rs) # TODO: Show name channel # count = 0 # for i in _nam.chan_name: # if i == 0xFF: # break # try: # mem.name += IP620_CHARSET[i] # except Exception: # LOG.error("Unknown name char %i: 0x%02x (mem %i)" % # (count, i, number - 1)) # mem.name += " " # count += 1 # mem.name = mem.name.rstrip() return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0x8000 return val rx_mode = tx_mode = None rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None tx_tone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = int(mem.rtone * 10) if rx_mode == "DTCS": rx_tone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = int(mem.ctone * 10) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.tx_tone, rx_mode, _mem.rx_tone)) def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.fill_raw(b"\xFF") return _mem.rx_freq = mem.freq / 10 if mem.duplex == "off": _mem.tx_freq.fill_raw(b"\xFF") elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 else: _mem.tx_freq = mem.freq / 10 _mem.w_n = mem.mode == "FM" self._set_tone(mem, _mem) _mem.power = mem.power == POWER_LEVELS[1] for setting in ('lout', 'busy_loc', 'scan_add'): setattr(_mem, setting, 0) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings _settings_misc = self._memobj.settings_misc basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) rs = RadioSetting("rf_sql", "Squelch level (SQL)", RadioSettingValueList(RFSQL_LIST, RFSQL_LIST[_settings.rf_sql])) basic.append(rs) rs = RadioSetting("step_freq", "Step frequency kHz (STP)", RadioSettingValueList(STEP_LIST, STEP_LIST[_settings.step_freq])) basic.append(rs) rs = RadioSetting("fm_radio", "FM radio (DW)", RadioSettingValueList(OFF_ON_LIST, OFF_ON_LIST[_settings_misc.fm_radio])) basic.append(rs) rs = RadioSetting("call_tone", "Call tone (CK)", RadioSettingValueList(CALLTONE_LIST, CALLTONE_LIST[_settings.call_tone])) basic.append(rs) rs = RadioSetting("tot", "Time-out timer (TOT)", RadioSettingValueList(TIMEOUT_LIST, TIMEOUT_LIST[_settings.tot])) basic.append(rs) rs = RadioSetting("chan_disp_way", "Channel display way", RadioSettingValueList(CH_FLAG_LIST, CH_FLAG_LIST[_settings.chan_disp_way])) basic.append(rs) rs = RadioSetting("vox", "VOX Gain (VOX)", RadioSettingValueList(VOX_LIST, VOX_LIST[_settings.vox])) basic.append(rs) rs = RadioSetting("vox_dly", "VOX Delay", RadioSettingValueList(VOXDELAY_LIST, VOXDELAY_LIST[_settings.vox_dly])) basic.append(rs) rs = RadioSetting("beep", "Beep (BP)", RadioSettingValueList(OFF_ON_LIST, OFF_ON_LIST[_settings.beep])) basic.append(rs) rs = RadioSetting("auto_lock", "Auto lock (KY)", RadioSettingValueList(NO_YES_LIST, NO_YES_LIST[_settings_misc.auto_lock])) basic.append(rs) rs = RadioSetting("bat_save", "Battery Saver (SAV)", RadioSettingValueList(BAT_SAVE_LIST, BAT_SAVE_LIST[_settings.bat_save])) basic.append(rs) rs = RadioSetting("chan_pri", "Channel PRI (PRI)", RadioSettingValueList(OFF_ON_LIST, OFF_ON_LIST[_settings.chan_pri])) basic.append(rs) rs = RadioSetting("chan_pri_num", "Channel PRI time Sec (PRI)", RadioSettingValueList(PRI_NUM_LIST, PRI_NUM_LIST[_settings.chan_pri_num])) basic.append(rs) rs = RadioSetting("end_beep", "End beep (ET)", RadioSettingValueList(ENDBEEP_LIST, ENDBEEP_LIST[_settings.end_beep])) basic.append(rs) rs = RadioSetting("ch_mode", "CH mode", RadioSettingValueList(ON_OFF_LIST, ON_OFF_LIST[_settings.ch_mode])) basic.append(rs) rs = RadioSetting("scan_rev", "Scan rev (SCAN)", RadioSettingValueList(SCANM_LIST, SCANM_LIST[_settings.scan_rev])) basic.append(rs) rs = RadioSetting("enc", "Frequency lock (ENC)", RadioSettingValueList(OFF_ON_LIST, OFF_ON_LIST[_settings.enc])) basic.append(rs) rs = RadioSetting("wait_back_light", "Wait back light (LED)", RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.wait_back_light])) basic.append(rs) return top def _set_misc_settings(self, settings): for element in settings: try: setattr(self._memobj.settings_misc, element.get_name(), element.value) except Exception: LOG.debug(element.get_name()) raise def set_settings(self, settings): _settings = self._memobj.settings _settings_misc = self._memobj.settings_misc for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() if setting in ["auto_lock", "fm_radio"]: oldval = getattr(_settings_misc, setting) else: oldval = getattr(_settings, setting) newval = element.value LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) if setting in ["auto_lock", "fm_radio"]: setattr(_settings_misc, setting, newval) else: setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/template.py0000644000175000017500000001127014466370044017015 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, memmap from chirp import bitwise # Here is where we define the memory map for the radio. Since # We often just know small bits of it, we can use #seekto to skip # around as needed. # # Our fake radio includes just a single array of ten memory objects, # With some very basic settings, a 32-bit unsigned integer for the # frequency (in Hertz) and an eight-character alpha tag # MEM_FORMAT = """ #seekto 0x0000; struct { u32 freq; char name[8]; } memory[10]; """ def do_download(radio): """This is your download function""" # NOTE: Remove this in your real implementation! return memmap.MemoryMapBytes(b"\x00" * 1000) # Get the serial port connection serial = radio.pipe # Our fake radio is just a simple download of 1000 bytes # from the serial port. Do that one byte at a time and # store them in the memory map data = b"" for _i in range(0, 1000): data += serial.read(1) return memmap.MemoryMapBytes(data) def do_upload(radio): """This is your upload function""" # NOTE: Remove this in your real implementation! raise Exception("This template driver does not really work!") # Get the serial port connection serial = radio.pipe # Our fake radio is just a simple upload of 1000 bytes # to the serial port. Do that one byte at a time, reading # from our memory map for i in range(0, 1000): serial.write(radio.get_mmap()[i]) # Uncomment this to actually register this radio in CHIRP # @directory.register class TemplateRadio(chirp_common.CloneModeRadio): """Acme Template""" VENDOR = "Acme" # Replace this with your vendor MODEL = "Template" # Replace this with your model BAUD_RATE = 9600 # Replace this with your baud rate # All new drivers should be "Byte Clean" so leave this in place. NEEDS_COMPAT_SERIAL = False # Return information about this radio's features, including # how many memories it has, what bands it supports, etc def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.memory_bounds = (0, 9) # This radio supports memories 0-9 rf.valid_bands = [(144000000, 148000000), # Supports 2-meters (440000000, 450000000), # Supports 70-centimeters ] return rf # Do a download of the radio from the serial port def sync_in(self): self._mmap = do_download(self) self.process_mmap() # Do an upload of the radio to the serial port def sync_out(self): do_upload(self) # Convert the raw byte array into a memory object structure def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # Return a raw representation of the memory object, which # is very helpful for development def get_raw_memory(self, number): return repr(self._memobj.memory[number]) # Extract a high-level memory object from the low-level memory map # This is called to populate a memory in the UI def get_memory(self, number): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[number] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() mem.number = number # Set the memory number # Convert your low-level frequency to Hertz mem.freq = int(_mem.freq) mem.name = str(_mem.name).rstrip() # Set the alpha tag # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem # Store details about a high-level memory to the memory map # This is called when a user edits a memory in the UI def set_memory(self, mem): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number] # Convert to low-level frequency representation _mem.freq = mem.freq _mem.name = mem.name.ljust(8)[:8] # Store the alpha tag chirp-20240224/chirp/drivers/ic208.py0000644000175000017500000001727014430171343016025 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, directory, bitwise MEM_FORMAT = """ struct memory { u24 freq; u16 offset; u8 power:2, rtone:6; u8 duplex:2, ctone:6; u8 unknown1:1, dtcs:7; u8 tuning_step:4, unknown2:4; u8 unknown3; u8 alt_mult:1, unknown4:1, is_fm:1, is_wide:1, unknown5:2, tmode:2; u16 dtcs_polarity:2, usealpha:1, empty:1, name1:6, name2:6; u24 name3:6, name4:6, name5:6, name6:6; }; struct memory memory[510]; struct { u8 unknown1:1, empty:1, pskip:1, skip:1, bank:4; } flags[512]; struct memory call[2]; """ MODES = ["AM", "FM", "NFM", "NAM"] TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "", "-", "+"] DTCS_POL = ["NN", "NR", "RN", "RR"] STEPS = [5.0, 10.0, 12.5, 15, 20.0, 25.0, 30.0, 50.0, 100.0, 200.0] POWER = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=15), ] IC208_SPECIAL = [] for i in range(1, 6): IC208_SPECIAL.append("%iA" % i) IC208_SPECIAL.append("%iB" % i) CHARSET = dict(list(zip([0x00, 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0f], " ()*+-/")) + list(zip(list(range(0x10, 0x1a)), "0123456789")) + [(0x1c, '|'), (0x1d, '=')] + list(zip(list(range(0x21, 0x3b)), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"))) CHARSET_REV = dict(list(zip(list(CHARSET.values()), list(CHARSET.keys())))) def get_name(_mem): """Decode the name from @_mem""" def _get_char(val): try: return CHARSET[int(val)] except KeyError: return "*" name_bytes = [_mem.name1, _mem.name2, _mem.name3, _mem.name4, _mem.name5, _mem.name6] name = "" for val in name_bytes: name += _get_char(val) return name.rstrip() def set_name(_mem, name): """Encode @name in @_mem""" def _get_index(char): try: return CHARSET_REV[char] except KeyError: return CHARSET_REV["*"] name = name.ljust(6)[:6] _mem.usealpha = bool(name.strip()) # The element override calling convention makes this harder to automate. # It's just six, so do it manually _mem.name1 = _get_index(name[0]) _mem.name2 = _get_index(name[1]) _mem.name3 = _get_index(name[2]) _mem.name4 = _get_index(name[3]) _mem.name5 = _get_index(name[4]) _mem.name6 = _get_index(name[5]) @directory.register class IC208Radio(icf.IcomCloneModeRadio): """Icom IC800""" VENDOR = "Icom" MODEL = "IC-208H" _model = "\x26\x32\x00\x01" _memsize = 0x2600 _endframe = "Icom Inc\x2e30" _can_hispeed = True _memories = [] _ranges = [(0x0000, 0x2600, 32)] def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 500) rf.has_bank = True rf.valid_tuning_steps = list(STEPS) rf.valid_tmodes = list(TMODES) rf.valid_modes = list(MODES) rf.valid_duplexes = list(DUPLEX) rf.valid_power_levels = list(POWER) rf.valid_skips = ["", "S", "P"] rf.valid_bands = [(118000000, 174000000), (230000000, 550000000), (810000000, 999995000)] rf.valid_special_chans = ["C1", "C2"] + sorted(IC208_SPECIAL) rf.valid_characters = "".join(list(CHARSET.values())) return rf def get_raw_memory(self, number): _mem, _flg, index = self._get_memory(number) return repr(_mem) + repr(_flg) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def _get_bank(self, loc): _flg = self._memobj.flags[loc-1] if _flg.bank >= 0x0A: return None else: return _flg.bank def _set_bank(self, loc, bank): _flg = self._memobj.flags[loc-1] if bank is None: _flg.bank = 0x0A else: _flg.bank = bank def _get_memory(self, number): if isinstance(number, str): if "A" in number or "B" in number: index = 501 + IC208_SPECIAL.index(number) _mem = self._memobj.memory[index - 1] _flg = self._memobj.flags[index - 1] else: index = int(number[1]) - 1 _mem = self._memobj.call[index] _flg = self._memobj.flags[510 + index] index = index + -10 elif number <= 0: index = 10 - abs(number) _mem = self._memobj.call[index] _flg = self._memobj.flags[index + 510] else: index = number _mem = self._memobj.memory[number - 1] _flg = self._memobj.flags[number - 1] return _mem, _flg, index def get_memory(self, number): _mem, _flg, index = self._get_memory(number) mem = chirp_common.Memory() mem.number = index if isinstance(number, str): mem.extd_number = number else: mem.skip = _flg.pskip and "P" or _flg.skip and "S" or "" if _flg.empty: mem.empty = True return mem mult = _mem.alt_mult and 6250 or 5000 mem.freq = int(_mem.freq) * mult mem.offset = int(_mem.offset) * 5000 mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POL[_mem.dtcs_polarity] mem.duplex = DUPLEX[_mem.duplex] mem.tmode = TMODES[_mem.tmode] mem.mode = ((not _mem.is_wide and "N" or "") + (_mem.is_fm and "FM" or "AM")) mem.tuning_step = STEPS[_mem.tuning_step] mem.name = get_name(_mem) mem.power = POWER[_mem.power] return mem def set_memory(self, mem): _mem, _flg, index = self._get_memory(mem.number) if mem.empty: _flg.empty = True self._set_bank(mem.number, None) return if _flg.empty: _mem.set_raw("\x00" * 16) _flg.empty = False _mem.alt_mult = chirp_common.is_fractional_step(mem.freq) _mem.freq = mem.freq / (_mem.alt_mult and 6250 or 5000) _mem.offset = mem.offset / 5000 _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = DTCS_POL.index(mem.dtcs_polarity) _mem.duplex = DUPLEX.index(mem.duplex) _mem.tmode = TMODES.index(mem.tmode) _mem.is_fm = "FM" in mem.mode _mem.is_wide = mem.mode[0] != "N" _mem.tuning_step = STEPS.index(mem.tuning_step) set_name(_mem, mem.name) try: _mem.power = POWER.index(mem.power) except Exception: pass if not isinstance(mem.number, str): _flg.skip = mem.skip == "S" _flg.pskip = mem.skip == "P" chirp-20240224/chirp/drivers/tg_uv2p.py0000644000175000017500000006652514522657251016606 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # This driver was derived from the: # Quansheng TG-UV2 Utility by Mike Nix # (So thanks Mike!) import struct import logging import serial from chirp import chirp_common, directory, bitwise, memmap, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueFloat, \ RadioSettingValueMap, RadioSettings LOG = logging.getLogger(__name__) mem_format = """ struct memory { bbcd freq[4]; bbcd offset[4]; u8 rxtone; u8 txtone; u8 unknown1:2, txtmode:2, unknown2:2, rxtmode:2; u8 duplex; u8 unknown3:3, isnarrow:1, unknown4:2, not_scramble:1, not_revfreq:1; u8 flag3; u8 step; u8 power; }; struct bandflag { u8 scanadd:1, unknown1:3, band:4; }; struct tguv2_config { u8 unknown1; u8 squelch; u8 time_out_timer; u8 priority_channel; u8 unknown2:7, keyunlocked:1; u8 busy_lockout; u8 vox; u8 unknown3; u8 beep_tone_disabled; u8 display; u8 step; u8 unknown4; u8 unknown5; u8 rxmode; u8 unknown6:7, not_end_tone_elim:1; u8 vfo_mode; }; struct vfo { u8 current; u8 chan; u8 memno; }; struct name { u8 name[6]; u8 unknown1[10]; }; #seekto 0x0000; char ident[32]; u8 blank[16]; struct memory channels[200]; struct memory bands[5]; #seekto 0x0D30; struct bandflag bandflags[200]; #seekto 0x0E30; struct tguv2_config settings; struct vfo vfos[2]; u8 unk5; u8 reserved2[9]; u8 band_restrict; u8 txen350390; #seekto 0x0F30; struct name names[200]; """ def do_program_mode(radio): radio.pipe.write(b"\x02PnOGdAM") for x in range(10): ack = radio.pipe.read(1) if ack == b'\x06': break else: raise errors.RadioError("Radio did not ack programming mode") def do_ident(radio): radio.pipe.timeout = 3 radio.pipe.stopbits = serial.STOPBITS_TWO do_program_mode(radio) radio.pipe.write(b"\x4D\x02") ident = radio.pipe.read(8) LOG.debug(util.hexprint(ident)) if not ident.startswith(b'P5555'): LOG.debug("First ident attempt (x4D, x02) failed trying 0x40,x02") do_program_mode(radio) radio.pipe.write(b"\x40\x02") ident = radio.pipe.read(8) LOG.debug(util.hexprint(ident)) if not ident.startswith(b'P5555'): raise errors.RadioError("Unsupported model") radio.pipe.write(b"\x06") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio did not ack ident") def do_status(radio, direction, addr): status = chirp_common.Status() status.msg = "Cloning %s radio" % direction status.cur = addr status.max = 0x2000 radio.status_fn(status) def do_download(radio): do_ident(radio) data = b"TG-UV2+ Radio Program Data v1.0\x00" data += (b"\x00" * 16) firstack = None for i in range(0, 0x2000, 8): frame = struct.pack(">cHB", b"R", i, 8) radio.pipe.write(frame) result = radio.pipe.read(12) if not (result[0:1] == b"W" and frame[1:4] == result[1:4]): LOG.debug(util.hexprint(result)) raise errors.RadioError("Invalid response for address 0x%04x" % i) radio.pipe.write(b"\x06") ack = radio.pipe.read(1) if not firstack: firstack = ack else: if not ack == firstack: LOG.debug("first ack: %s ack received: %s", util.hexprint(firstack), util.hexprint(ack)) raise errors.RadioError("Unexpected response") data += result[4:] do_status(radio, "from", i) return memmap.MemoryMapBytes(data) def do_upload(radio): do_ident(radio) data = radio._mmap[0x0030:] for i in range(0, 0x2000, 8): frame = struct.pack(">cHB", b"W", i, 8) frame += data[i:i + 8] radio.pipe.write(frame) ack = radio.pipe.read(1) if ack != b"\x06": LOG.debug("Radio NAK'd block at address 0x%04x" % i) raise errors.RadioError( "Radio NAK'd block at address 0x%04x" % i) LOG.debug("Radio ACK'd block at address 0x%04x" % i) do_status(radio, "to", i) DUPLEX = ["", "+", "-"] TGUV2P_STEPS = [5, 6.25, 10, 12.5, 15, 20, 25, 30, 50, 100] CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_|* +-" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=10), chirp_common.PowerLevel("Med", watts=5), chirp_common.PowerLevel("Low", watts=1)] POWER_LEVELS_STR = ["High", "Med", "Low"] VALID_BANDS = [(88000000, 108000000), (136000000, 174000000), (350000000, 390000000), (400000000, 470000000), (470000000, 520000000)] @directory.register class QuanshengTGUV2P(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Quansheng TG-UV2+""" VENDOR = "Quansheng" MODEL = "TG-UV2+" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _memsize = 0x2000 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('Experimental version for TG-UV2/2+ radios ' 'Proceed at your own risk!') rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on.\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to download image from device.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on.\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to upload image to device.\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_duplexes = DUPLEX rf.can_odd_split = False rf.valid_skips = ["", "S"] rf.valid_characters = CHARSET rf.valid_name_length = 6 rf.valid_tuning_steps = TGUV2P_STEPS rf.valid_bands = VALID_BANDS rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = POWER_LEVELS rf.has_ctone = True rf.has_bank = False rf.has_tuning_step = True rf.memory_bounds = (0, 199) return rf def sync_in(self): try: self._mmap = do_download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: do_upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.channels[number]) def _decode_tone(self, _mem, which): def _get(field): return getattr(_mem, "%s%s" % (which, field)) value = _get('tone') tmode = _get('tmode') if (value <= 104) and (tmode <= 3): if tmode == 0: mode = val = pol = None elif tmode == 1: mode = 'Tone' val = chirp_common.TONES[value] pol = None else: mode = 'DTCS' val = chirp_common.DTCS_CODES[value] pol = "N" if (tmode == 2) else "R" else: mode = val = pol = None return mode, val, pol def _encode_tone(self, _mem, which, mode, val, pol): def _set(field, value): setattr(_mem, "%s%s" % (which, field), value) if (mode == "Tone"): _set("tone", chirp_common.TONES.index(val)) _set("tmode", 0x01) elif mode == "DTCS": _set("tone", chirp_common.DTCS_CODES.index(val)) if pol == "N": _set("tmode", 0x02) else: _set("tmode", 0x03) else: _set("tone", 0) _set("tmode", 0) def _get_memobjs(self, number): if isinstance(number, str): return (getattr(self._memobj, number.lower()), None) else: return (self._memobj.channels[number], self._memobj.bandflags[number], self._memobj.names[number].name) def get_memory(self, number): _mem, _bf, _nam = self._get_memobjs(number) mem = chirp_common.Memory() if isinstance(number, str): mem.extd_number = number else: mem.number = number if ((_mem.freq.get_raw(asbytes=False)[0] == "\xFF") or (_bf.band == "\x0F")): mem.empty = True return mem mem.freq = int(_mem.freq) * 10 if _mem.offset.get_raw(asbytes=False)[0] == "\xFF": mem.offset = 0 else: mem.offset = int(_mem.offset) * 10 chirp_common.split_tone_decode( mem, self._decode_tone(_mem, "tx"), self._decode_tone(_mem, "rx")) if 'step' in _mem and _mem.step > len(TGUV2P_STEPS): _mem.step = 0x00 mem.tuning_step = TGUV2P_STEPS[_mem.step] mem.duplex = DUPLEX[_mem.duplex] mem.mode = _mem.isnarrow and "NFM" or "FM" mem.skip = "" if bool(_bf.scanadd) else "S" mem.power = POWER_LEVELS[_mem.power] if _nam: for char in _nam: try: mem.name += CHARSET[char] except IndexError: break mem.name = mem.name.rstrip() mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("not_scramble", "(not)SCRAMBLE", RadioSettingValueBoolean(_mem.not_scramble)) mem.extra.append(rs) rs = RadioSetting("not_revfreq", "(not)Reverse Duplex", RadioSettingValueBoolean(_mem.not_revfreq)) mem.extra.append(rs) return mem def set_memory(self, mem): _mem, _bf, _nam = self._get_memobjs(mem.number) _bf.set_raw("\xFF") if mem.empty: _mem.set_raw("\xFF" * 16) return _mem.set_raw("\x00" * 12 + "\xFF" * 2 + "\x00"*2) _bf.scanadd = int(mem.skip != "S") _bf.band = 0x0F for idx, ele in enumerate(VALID_BANDS): if mem.freq >= ele[0] and mem.freq <= ele[1]: _bf.band = idx _mem.freq = mem.freq / 10 _mem.offset = mem.offset / 10 tx, rx = chirp_common.split_tone_encode(mem) self._encode_tone(_mem, 'tx', *tx) self._encode_tone(_mem, 'rx', *rx) _mem.duplex = DUPLEX.index(mem.duplex) _mem.isnarrow = mem.mode == "NFM" _mem.step = TGUV2P_STEPS.index(mem.tuning_step) if mem.power is None: _mem.power = 0 else: _mem.power = POWER_LEVELS.index(mem.power) if _nam: for i in range(0, 6): try: _nam[i] = CHARSET.index(mem.name[i]) except IndexError: _nam[i] = 0xFF for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings _vfoa = self._memobj.vfos[0] _vfob = self._memobj.vfos[1] _bandsettings = self._memobj.bands cfg_grp = RadioSettingGroup("cfg_grp", "Configuration") vfoa_grp = RadioSettingGroup( "vfoa_grp", "VFO A Settings\n (Current Status, Read Only)") vfob_grp = RadioSettingGroup( "vfob_grp", "VFO B Settings\n (Current Status, Read Only)") group = RadioSettings(cfg_grp, vfoa_grp, vfob_grp) # # Configuration Settings # # TX time out timer: options = ["Off"] + ["%s min" % x for x in range(1, 10)] rs = RadioSetting("time_out_timer", "TX Time Out Timer", RadioSettingValueList( options, options[_settings.time_out_timer])) cfg_grp.append(rs) # Display mode options = ["Frequency", "Channel", "Name"] rs = RadioSetting("display", "Channel Display Mode", RadioSettingValueList( options, options[_settings.display])) cfg_grp.append(rs) # Squelch level rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) cfg_grp.append(rs) # Vox level mem_vals = list(range(10)) user_options = [str(x) for x in mem_vals] user_options[0] = "Off" options_map = list(zip(user_options, mem_vals)) rs = RadioSetting("vox", "VOX Level", RadioSettingValueMap(options_map, _settings.vox)) cfg_grp.append(rs) # Keypad beep rs = RadioSetting("beep_tone_disabled", "Beep Prompt", RadioSettingValueBoolean( not _settings.beep_tone_disabled)) cfg_grp.append(rs) # Dual watch/crossband options = ["Dual Watch", "CrossBand", "Normal"] if _settings.rxmode >= 2: _rxmode = 2 else: _rxmode = _settings.rxmode rs = RadioSetting("rxmode", "Dual Watch/CrossBand Monitor", RadioSettingValueList( options, options[_rxmode])) cfg_grp.append(rs) # Busy channel lock rs = RadioSetting("busy_lockout", "Busy Channel Lock", RadioSettingValueBoolean( not _settings.busy_lockout)) cfg_grp.append(rs) # Keypad lock rs = RadioSetting("keyunlocked", "Keypad Lock", RadioSettingValueBoolean( not _settings.keyunlocked)) cfg_grp.append(rs) # Priority channel mem_vals = list(range(200)) user_options = [str(x) for x in mem_vals] mem_vals.insert(0, 0xFF) user_options.insert(0, "Not Set") options_map = list(zip(user_options, mem_vals)) if _settings.priority_channel >= 200: _priority_ch = 0xFF else: _priority_ch = _settings.priority_channel rs = RadioSetting( "priority_channel", "Priority Channel \n" "Note: Unused channels,\nor channels " "in the\nbroadcast FM band,\nwill not be set", RadioSettingValueMap(options_map, _priority_ch)) cfg_grp.append(rs) # Step mem_vals = list(range(0, len(TGUV2P_STEPS))) mem_vals.append(0xFF) user_options = [(str(x) + " kHz") for x in TGUV2P_STEPS] user_options.append("Unknown") options_map = list(zip(user_options, mem_vals)) rs = RadioSetting("step", "Current (VFO?) step size", RadioSettingValueMap(options_map, _settings.step)) cfg_grp.append(rs) # End (Tail) tone elimination mem_vals = [0, 1] user_options = ["Tone Elimination On", "Tone Elimination Off"] options_map = list(zip(user_options, mem_vals)) rs = RadioSetting("not_end_tone_elim", "Tx End Tone Elimination", RadioSettingValueMap(options_map, _settings.not_end_tone_elim)) cfg_grp.append(rs) # VFO mode if _settings.vfo_mode >= 1: _vfo_mode = 0xFF else: _vfo_mode = _settings.vfo_mode mem_vals = [0xFF, 0] user_options = ["VFO Mode Enabled", "VFO Mode Disabled"] options_map = list(zip(user_options, mem_vals)) rs = RadioSetting("vfo_mode", "VFO (CH only) mode", RadioSettingValueMap(options_map, _vfo_mode)) cfg_grp.append(rs) # # VFO Settings # vfo_groups = [vfoa_grp, vfob_grp] vfo_mem = [_vfoa, _vfob] vfo_lower = ["vfoa", "vfob"] vfo_upper = ["VFOA", "VFOB"] for idx, vfo_group in enumerate(vfo_groups): options = ["Channel", "Frequency"] tempvar = 0 if (vfo_mem[idx].current < 200) else 1 rs = RadioSetting(vfo_lower[idx] + "_mode", vfo_upper[idx]+" Mode", RadioSettingValueList( options, options[tempvar])) vfo_group.append(rs) if tempvar == 0: rs = RadioSetting(vfo_lower[idx] + "_ch", vfo_upper[idx] + " Channel", RadioSettingValueInteger( 0, 199, vfo_mem[idx].current)) vfo_group.append(rs) else: band_num = vfo_mem[idx].current - 200 freq = int(_bandsettings[band_num].freq) * 10 offset = int(_bandsettings[band_num].offset) * 10 txtmode = _bandsettings[band_num].txtmode rxtmode = _bandsettings[band_num].rxtmode rs = RadioSetting(vfo_lower[idx] + "_freq", vfo_upper[idx] + " Frequency", RadioSettingValueFloat( 0.0, 520.0, freq / 1000000.0, precision=6)) vfo_group.append(rs) if offset > 70e6: offset = 0 rs = RadioSetting(vfo_lower[idx] + "_offset", vfo_upper[idx] + " Offset", RadioSettingValueFloat( 0.0, 69.995, offset / 100000.0, resolution=0.005)) vfo_group.append(rs) rs = RadioSetting(vfo_lower[idx] + "_duplex", vfo_upper[idx] + " Shift", RadioSettingValueList( DUPLEX, DUPLEX[_bandsettings[band_num].duplex])) vfo_group.append(rs) rs = RadioSetting( vfo_lower[idx] + "_step", vfo_upper[idx] + " Step", RadioSettingValueFloat( 0.0, 1000.0, TGUV2P_STEPS[_bandsettings[band_num].step], resolution=0.25)) vfo_group.append(rs) rs = RadioSetting( vfo_lower[idx] + "_pwr", vfo_upper[idx] + " Power", RadioSettingValueList( POWER_LEVELS_STR, POWER_LEVELS_STR[_bandsettings[band_num].power])) vfo_group.append(rs) options = ["None", "Tone", "DTCS-N", "DTCS-I"] rs = RadioSetting(vfo_lower[idx] + "_ttmode", vfo_upper[idx]+" TX tone mode", RadioSettingValueList( options, options[txtmode])) vfo_group.append(rs) if txtmode == 1: rs = RadioSetting( vfo_lower[idx] + "_ttone", vfo_upper[idx] + " TX tone", RadioSettingValueFloat( 0.0, 1000.0, chirp_common.TONES[_bandsettings[band_num].txtone], resolution=0.1)) vfo_group.append(rs) elif txtmode >= 2: txtone = _bandsettings[band_num].txtone rs = RadioSetting( vfo_lower[idx] + "_tdtcs", vfo_upper[idx] + " TX DTCS", RadioSettingValueInteger( 0, 1000, chirp_common.DTCS_CODES[txtone])) vfo_group.append(rs) options = ["None", "Tone", "DTCS-N", "DTCS-I"] rs = RadioSetting(vfo_lower[idx] + "_rtmode", vfo_upper[idx] + " RX tone mode", RadioSettingValueList(options, options[rxtmode])) vfo_group.append(rs) if rxtmode == 1: rs = RadioSetting( vfo_lower[idx] + "_rtone", vfo_upper[idx] + " RX tone", RadioSettingValueFloat( 0.0, 1000.0, chirp_common.TONES[_bandsettings[band_num].rxtone], resolution=0.1)) vfo_group.append(rs) elif rxtmode >= 2: rxtone = _bandsettings[band_num].rxtone rs = RadioSetting(vfo_lower[idx] + "_rdtcs", vfo_upper[idx] + " TX rTCS", RadioSettingValueInteger( 0, 1000, chirp_common.DTCS_CODES[rxtone])) vfo_group.append(rs) options = ["FM", "NFM"] rs = RadioSetting( vfo_lower[idx] + "_fm", vfo_upper[idx] + " FM BW ", RadioSettingValueList( options, options[_bandsettings[band_num].isnarrow])) vfo_group.append(rs) return group def _validate_priority_ch(self, ch_num): if ch_num == 0xFF: return True _mem, _bf, _nam = self._get_memobjs(ch_num) if ((_mem.freq.get_raw(asbytes=False)[0] == "\xFF") or (_bf.band == "\x0F")): return False elif _bf.band == 0x00: return False else: return True def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "vfoa" in element.get_name(): continue if "vfob" in element.get_name(): continue elif "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("using apply callback") element.run_apply_callback() elif setting == "beep_tone_disabled": LOG.debug("Setting %s = %s" % (setting, not int(element.value))) setattr(obj, setting, not int(element.value)) elif setting == "busy_lockout": LOG.debug("Setting %s = %s" % (setting, not int(element.value))) setattr(obj, setting, not int(element.value)) elif setting == "keyunlocked": # keypad currently unlocked being set to locked # and rx_mode is currently not "Normal": if getattr(obj, "keyunlocked") and int(element.value) \ and (getattr(obj, "rxmode") != 0x02): raise errors.InvalidValueError( "Keypad lock not allowed in " "Dual-Watch or CrossBand") LOG.debug("Setting %s = %s" % (setting, not int(element.value))) setattr(obj, setting, not int(element.value)) elif setting == "rxmode": # rx_mode was normal, now being set otherwise # and keypad is locked: if (getattr(obj, "rxmode") == 0x02) \ and (int(element.value) != 2) \ and not (getattr(obj, "keyunlocked")): raise errors.InvalidValueError( "Dual-Watch or CrossBand can not be set " "when keypad is locked") LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) elif setting == "priority_channel": _check = self._validate_priority_ch(int(element.value)) if _check: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) else: raise errors.InvalidValueError( "Please select a valid priority channel:\n" "A used memory channel which is not " "in the Broadcast FM band (88-108 MHz),\n" "Or select 'Not Used'") elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): return (filedata.startswith(b"TG-UV2+ Radio Program Data") and len(filedata) == (cls._memsize + 0x30)) chirp-20240224/chirp/drivers/ft7800.py0000644000175000017500000007457714522135005016142 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging import re from chirp.drivers import yaesu_clone from chirp import chirp_common, memmap, directory, bitwise, errors from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettings from collections import defaultdict LOG = logging.getLogger(__name__) ACK = b'\x06' MEM_FORMAT = """ struct mem_struct { u8 used:1, unknown1:1, mode:2, unknown2:1, duplex:3; bbcd freq[3]; u8 clockshift:1, tune_step:3, unknown5:1, // TODO: tmode has extended settings, at least 4 bits tmode:3; bbcd split[3]; u8 power:2, tone:6; u8 unknown6:1, dtcs:7; u8 unknown7[2]; u8 offset; u8 unknown9[3]; }; #seekto 0x002A; u8 banks_unk2; u8 current_channel; u8 unk3; u8 unk4; u8 current_menu; #seekto 0x003A; struct { u8 apo; u8 tot; u8 lock:3, arts_interval:1, unk1a:1, prog_panel_acc:3; u8 prog_p1; u8 prog_p2; u8 prog_p3; u8 prog_p4; u8 rf_sql; u8 inet_dtmf_mem:4, inet_dtmf_digit:4; u8 arts_cwid_enable:1, prog_tone_vm:1, unk2a:1, hyper_write:2, memory_only:1, dimmer:2; u8 beep_scan:1, beep_edge:1, beep_key:1, unk3a:1, inet_mode:1, unk3b:1, dtmf_speed:2; u8 dcs_polarity:2, smart_search:1, priority_revert:1, unk4a:1, dtmf_delay:3; u8 unk5a:3, microphone_type:1, scan_resume:1, unk5b:1, arts_mode:2; u8 unk6; } settings; #seekto 0x0048; struct mem_struct vfos[5]; #seekto 0x00C8; struct { u8 memory[16]; } dtmf[16]; #seekto 0x01C8; struct mem_struct homes[5]; #seekto 0x0218; u8 arts_cwid[6]; #seekto 0x04C8; struct mem_struct memory[1000]; #seekto 0x4988; struct { char name[6]; u8 enabled:1, unknown1:7; u8 used:1, unknown2:7; } names[1000]; #seekto 0x6c48; struct { u32 bitmap[32]; } bank_channels[20]; #seekto 0x7648; struct { u8 skip0:2, skip1:2, skip2:2, skip3:2; } flags[250]; #seekto 0x7B48; u8 checksum; """ MODES = ["FM", "AM", "NFM"] DUPLEX = ["", "", "-", "+", "split"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] SKIPS = ["", "S", "P", ""] CHARSET = ["%i" % int(x) for x in range(0, 10)] + \ [chr(x) for x in range(ord("A"), ord("Z")+1)] + \ list(" " * 10) + \ list("*+,- /| [ ] _") + \ list("\x00" * 100) DTMFCHARSET = list("0123456789ABCD*#") def _send(ser, data): for i in data: ser.write(bytes([i])) time.sleep(0.002) echo = ser.read(len(data)) if echo != data: raise errors.RadioError("Error reading echo (Bad cable?)") def _download(radio): data = bytes(b"") chunk = bytes(b"") for i in range(0, 30): chunk += radio.pipe.read(radio._block_lengths[0]) if chunk: break if len(chunk) != radio._block_lengths[0]: raise Exception("Failed to read header (%i)" % len(chunk)) data += chunk _send(radio.pipe, ACK) for i in range(0, radio._block_lengths[1], radio._block_size): chunk = radio.pipe.read(radio._block_size) data += chunk if len(chunk) != radio._block_size: break time.sleep(0.01) _send(radio.pipe, ACK) if radio.status_fn: status = chirp_common.Status() status.max = radio.get_memsize() status.cur = i+len(chunk) status.msg = "Cloning from radio" radio.status_fn(status) data += radio.pipe.read(1) _send(radio.pipe, ACK) return memmap.MemoryMapBytes(data) def _upload(radio): cur = 0 mmap = radio.get_mmap().get_byte_compatible() for block in radio._block_lengths: for _i in range(0, block, radio._block_size): length = min(radio._block_size, block) # LOG.debug("i=%i length=%i range: %i-%i" % # (i, length, cur, cur+length)) _send(radio.pipe, mmap[cur:cur+length]) if radio.pipe.read(1) != ACK: raise errors.RadioError("Radio did not ack block at %i" % cur) cur += length time.sleep(0.05) if radio.status_fn: status = chirp_common.Status() status.cur = cur status.max = radio.get_memsize() status.msg = "Cloning to radio" radio.status_fn(status) def get_freq(rawfreq): """Decode a frequency that may include a fractional step flag""" # Ugh. The 0x80 and 0x40 indicate values to add to get the # real frequency. Gross. if rawfreq > 8000000000: rawfreq = (rawfreq - 8000000000) + 5000 if rawfreq > 4000000000: rawfreq = (rawfreq - 4000000000) + 2500 return rawfreq def set_freq(freq, obj, field): """Encode a frequency with any necessary fractional step flags""" obj[field] = freq / 10000 if (freq % 1000) == 500: obj[field][0].set_bits(0x40) if (freq % 10000) >= 5000: obj[field][0].set_bits(0x80) return freq class FTx800Radio(yaesu_clone.YaesuCloneModeRadio): """Base class for FT-7800,7900,8800,8900 radios""" BAUD_RATE = 9600 VENDOR = "Yaesu" MODES = list(MODES) NEEDS_COMPAT_SERIAL = False _block_size = 64 POWER_LEVELS_VHF = [chirp_common.PowerLevel("Hi", watts=50), chirp_common.PowerLevel("Mid1", watts=20), chirp_common.PowerLevel("Mid2", watts=10), chirp_common.PowerLevel("Low", watts=5)] POWER_LEVELS_UHF = [chirp_common.PowerLevel("Hi", watts=35), chirp_common.PowerLevel("Mid1", watts=20), chirp_common.PowerLevel("Mid2", watts=10), chirp_common.PowerLevel("Low", watts=5)] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to DATA jack.\n" "3. Press and hold in the [MHz(PRI)] key while turning the\n" " radio on.\n" "4. Rotate the DIAL job to select \"F-7 CLONE\".\n" "5. Press and hold in the [BAND(SET)] key. The display\n" " will disappear for a moment, then the \"CLONE\" notation\n" " will appear.\n" "6. After clicking OK, press the [V/M(MW)] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to DATA jack.\n" "3. Press and hold in the [MHz(PRI)] key while turning the\n" " radio on.\n" "4. Rotate the DIAL job to select \"F-7 CLONE\".\n" "5. Press and hold in the [BAND(SET)] key. The display\n" " will disappear for a moment, then the \"CLONE\" notation\n" " will appear.\n" "6. Press the [LOW(ACC)] key (\"--RX--\" will appear on the" " display).\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 999) rf.has_bank = False rf.has_ctone = False rf.has_dtcs_polarity = False rf.valid_modes = MODES rf.valid_tmodes = self.TMODES rf.valid_duplexes = ["", "-", "+", "split"] rf.valid_tuning_steps = STEPS rf.valid_bands = [(108000000, 520000000), (700000000, 990000000)] rf.valid_skips = ["", "S", "P"] rf.valid_power_levels = self.POWER_LEVELS_VHF rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 6 rf.can_odd_split = True return rf def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x7B47)] def sync_in(self): start = time.time() try: self._mmap = _download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Download finished in %i seconds" % (time.time() - start)) self.check_checksums() self.process_mmap() def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_out(self): self.update_checksums() start = time.time() try: _upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Upload finished in %i seconds" % (time.time() - start)) def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def _get_mem_offset(self, mem, _mem): if mem.duplex == "split": return get_freq(int(_mem.split) * 10000) else: return (_mem.offset * 5) * 10000 def _set_mem_offset(self, mem, _mem): if mem.duplex == "split": set_freq(mem.offset, _mem, "split") else: _mem.offset = (int(mem.offset / 10000) / 5) def _get_mem_name(self, mem, _mem): _nam = self._memobj.names[mem.number - 1] name = "" if _nam.used: for i in str(_nam.name): name += CHARSET[ord(i)] return name.rstrip() def _set_mem_name(self, mem, _mem): _nam = self._memobj.names[mem.number - 1] if mem.name.rstrip(): name = [chr(CHARSET.index(x)) for x in mem.name.ljust(6)[:6]] _nam.name = "".join(name) _nam.used = 1 _nam.enabled = 1 else: _nam.used = 0 _nam.enabled = 0 def _get_mem_skip(self, mem, _mem): _flg = self._memobj.flags[(mem.number - 1) / 4] flgidx = (mem.number - 1) % 4 return SKIPS[_flg["skip%i" % flgidx]] def _set_mem_skip(self, mem, _mem): _flg = self._memobj.flags[(mem.number - 1) / 4] flgidx = (mem.number - 1) % 4 _flg["skip%i" % flgidx] = SKIPS.index(mem.skip) def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.empty = not _mem.used if mem.empty: return mem mem.freq = get_freq(int(_mem.freq) * 10000) mem.rtone = chirp_common.TONES[_mem.tone] mem.tmode = self.TMODES[_mem.tmode] mem.mode = self.MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] if self.get_features().has_tuning_step: mem.tuning_step = STEPS[_mem.tune_step] mem.duplex = DUPLEX[_mem.duplex] mem.offset = self._get_mem_offset(mem, _mem) mem.name = self._get_mem_name(mem, _mem) if int(mem.freq / 100) == 4: mem.power = self.POWER_LEVELS_UHF[_mem.power] else: mem.power = self.POWER_LEVELS_VHF[_mem.power] mem.skip = self._get_mem_skip(mem, _mem) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _mem.used = int(not mem.empty) if mem.empty: return set_freq(mem.freq, _mem, "freq") _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.tmode = self.TMODES.index(mem.tmode) _mem.mode = self.MODES.index(mem.mode) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) if self.get_features().has_tuning_step: _mem.tune_step = STEPS.index(mem.tuning_step) _mem.duplex = DUPLEX.index(mem.duplex) _mem.split = mem.duplex == "split" and int(mem.offset / 10000) or 0 if mem.power: _mem.power = self.POWER_LEVELS_VHF.index(mem.power) else: _mem.power = 0 _mem.unknown5 = 0 # Make sure we don't leave garbage here # NB: Leave offset after mem name for the 8800! self._set_mem_name(mem, _mem) self._set_mem_offset(mem, _mem) self._set_mem_skip(mem, _mem) class FT7800BankModel(chirp_common.BankModel): """Yaesu FT-7800/7900 bank model""" def __init__(self, radio): super(FT7800BankModel, self).__init__(radio) self.__b2m_cache = defaultdict(list) self.__m2b_cache = defaultdict(list) def __precache(self): if self.__b2m_cache: return for bank in self.get_mappings(): self.__b2m_cache[bank.index] = self._get_bank_memories(bank) for memnum in self.__b2m_cache[bank.index]: self.__m2b_cache[memnum].append(bank.index) def get_num_mappings(self): return 20 def get_mappings(self): banks = [] for i in range(0, self.get_num_mappings()): bank = chirp_common.Bank(self, "%i" % i, "BANK-%i" % (i + 1)) bank.index = i banks.append(bank) return banks def add_memory_to_mapping(self, memory, bank): self.__precache() index = memory.number - 1 _bitmap = self._radio._memobj.bank_channels[bank.index] ishft = 31 - (index % 32) _bitmap.bitmap[index // 32] |= (1 << ishft) self.__m2b_cache[memory.number].append(bank.index) self.__b2m_cache[bank.index].append(memory.number) def remove_memory_from_mapping(self, memory, bank): self.__precache() index = memory.number - 1 _bitmap = self._radio._memobj.bank_channels[bank.index] ishft = 31 - (index % 32) if not (_bitmap.bitmap[index // 32] & (1 << ishft)): raise Exception("Memory {num} is not in bank {bank}".format( num=memory.number, bank=bank)) _bitmap.bitmap[index // 32] &= ~(1 << ishft) self.__b2m_cache[bank.index].remove(memory.number) self.__m2b_cache[memory.number].remove(bank.index) def _get_bank_memories(self, bank): memories = [] upper = self._radio.get_features().memory_bounds[1] c = self._radio._memobj.bank_channels[bank.index] for i in range(0, upper): _bitmap = c.bitmap[i // 32] ishft = 31 - (i % 32) if _bitmap & (1 << ishft): memories.append(i + 1) return memories def get_mapping_memories(self, bank): self.__precache() return [self._radio.get_memory(n) for n in self.__b2m_cache[bank.index]] def get_memory_mappings(self, memory): self.__precache() _banks = self.get_mappings() return [_banks[b] for b in self.__m2b_cache[memory.number]] @directory.register class FT7800Radio(FTx800Radio): """Yaesu FT-7800""" MODEL = "FT-7800/7900" _model = b"AH016" _memsize = 31561 _block_lengths = [8, 31552, 1] TMODES = ["", "Tone", "TSQL", "TSQL-R", "DTCS"] def get_bank_model(self): if not hasattr(self, '_banks'): self._banks = FT7800BankModel(self) return self._banks def get_features(self): rf = FTx800Radio.get_features(self) rf.has_bank = True rf.has_settings = True return rf def set_memory(self, memory): if memory.empty: self._wipe_memory_banks(memory) FTx800Radio.set_memory(self, memory) def _decode_chars(self, inarr): LOG.debug("@_decode_chars, type: %s" % type(inarr)) LOG.debug(inarr) outstr = "" for i in inarr: if i == 0xFF: break outstr += CHARSET[i & 0x7F] return outstr.rstrip() def _encode_chars(self, instr, length=16): LOG.debug("@_encode_chars, type: %s" % type(instr)) LOG.debug(instr) outarr = [] instr = str(instr) for i in range(length): if i < len(instr): outarr.append(CHARSET.index(instr[i])) else: outarr.append(0xFF) return outarr def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") dtmf = RadioSettingGroup("dtmf", "DTMF") arts = RadioSettingGroup("arts", "ARTS") prog = RadioSettingGroup("prog", "Programmable Buttons") top = RadioSettings(basic, dtmf, arts, prog) basic.append(RadioSetting( "priority_revert", "Priority Revert", RadioSettingValueBoolean(_settings.priority_revert))) basic.append(RadioSetting( "memory_only", "Memory Only mode", RadioSettingValueBoolean(_settings.memory_only))) opts = ["off"] + ["%0.1f" % (t / 60.0) for t in range(30, 750, 30)] basic.append(RadioSetting( "apo", "APO time (hrs)", RadioSettingValueList(opts, opts[_settings.apo]))) basic.append(RadioSetting( "beep_scan", "Beep: Scan", RadioSettingValueBoolean(_settings.beep_scan))) basic.append(RadioSetting( "beep_edge", "Beep: Edge", RadioSettingValueBoolean(_settings.beep_edge))) basic.append(RadioSetting( "beep_key", "Beep: Key", RadioSettingValueBoolean(_settings.beep_key))) opts = ["T/RX Normal", "RX Reverse", "TX Reverse", "T/RX Reverse"] basic.append(RadioSetting( "dcs_polarity", "DCS polarity", RadioSettingValueList(opts, opts[_settings.dcs_polarity]))) opts = ["off", "dim 1", "dim 2", "dim 3"] basic.append(RadioSetting( "dimmer", "Dimmer", RadioSettingValueList(opts, opts[_settings.dimmer]))) opts = ["manual", "auto", "1-auto"] basic.append(RadioSetting( "hyper_write", "Hyper Write", RadioSettingValueList(opts, opts[_settings.hyper_write]))) opts = ["", "key", "dial", "key+dial", "ptt", "ptt+key", "ptt+dial", "all"] basic.append(RadioSetting( "lock", "Lock mode", RadioSettingValueList(opts, opts[_settings.lock]))) opts = ["MH-42", "MH-48"] basic.append(RadioSetting( "microphone_type", "Microphone Type", RadioSettingValueList(opts, opts[_settings.microphone_type]))) opts = ["off"] + ["S-%d" % n for n in range(2, 10)] + ["S-Full"] basic.append(RadioSetting( "rf_sql", "RF Squelch", RadioSettingValueList(opts, opts[_settings.rf_sql]))) opts = ["time", "hold", "busy"] basic.append(RadioSetting( "scan_resume", "Scan Resume", RadioSettingValueList(opts, opts[_settings.scan_resume]))) opts = ["single", "continuous"] basic.append(RadioSetting( "smart_search", "Smart Search", RadioSettingValueList(opts, opts[_settings.smart_search]))) opts = ["off"] + ["%d" % t for t in range(1, 31)] basic.append(RadioSetting( "tot", "Time-out timer (mins)", RadioSettingValueList(opts, opts[_settings.tot]))) # dtmf tab opts = ["50", "100", "250", "450", "750", "1000"] dtmf.append(RadioSetting( "dtmf_delay", "DTMF delay (ms)", RadioSettingValueList(opts, opts[_settings.dtmf_delay]))) opts = ["50", "75", "100"] dtmf.append(RadioSetting( "dtmf_speed", "DTMF speed (ms)", RadioSettingValueList(opts, opts[_settings.dtmf_speed]))) for i in range(16): name = "dtmf%02d" % i dtmfsetting = self._memobj.dtmf[i] dtmfstr = "" for c in dtmfsetting.memory: if c == 0xFF: break if c < len(DTMFCHARSET): dtmfstr += DTMFCHARSET[c] LOG.debug(dtmfstr) dtmfentry = RadioSettingValueString(0, 16, dtmfstr) dtmfentry.set_charset(DTMFCHARSET + list(" ")) rs = RadioSetting(name, name.upper(), dtmfentry) dtmf.append(rs) # arts tab opts = ["off", "in range", "always"] arts.append(RadioSetting( "arts_mode", "ARTS beep", RadioSettingValueList(opts, opts[_settings.arts_mode]))) opts = ["15", "25"] arts.append(RadioSetting( "arts_interval", "ARTS interval", RadioSettingValueList(opts, opts[_settings.arts_interval]))) arts.append(RadioSetting( "arts_cwid_enable", "CW ID", RadioSettingValueBoolean(_settings.arts_cwid_enable))) _arts_cwid = self._memobj.arts_cwid cwid = RadioSettingValueString( 0, 16, self._decode_chars(_arts_cwid.get_value())) cwid.set_charset(CHARSET) arts.append(RadioSetting("arts_cwid", "CW ID", cwid)) # prog buttons opts = ["WX", "Reverse", "Repeater", "SQL Off", "Lock", "Dimmer"] prog.append(RadioSetting( "prog_panel_acc", "Prog Panel - Low(ACC)", RadioSettingValueList(opts, opts[_settings.prog_panel_acc]))) opts = ["Reverse", "Home"] prog.append(RadioSetting( "prog_tone_vm", "TONE | V/M", RadioSettingValueList(opts, opts[_settings.prog_tone_vm]))) opts = ["" for n in range(26)] + \ ["Priority", "Low", "Tone", "MHz", "Reverse", "Home", "Band", "VFO/MR", "Scan", "Sql Off", "TCall", "SSCH", "ARTS", "Tone Freq", "DCSC", "WX", "Repeater"] prog.append(RadioSetting( "prog_p1", "P1", RadioSettingValueList(opts, opts[_settings.prog_p1]))) prog.append(RadioSetting( "prog_p2", "P2", RadioSettingValueList(opts, opts[_settings.prog_p2]))) prog.append(RadioSetting( "prog_p3", "P3", RadioSettingValueList(opts, opts[_settings.prog_p3]))) prog.append(RadioSetting( "prog_p4", "P4", RadioSettingValueList(opts, opts[_settings.prog_p4]))) return top def set_settings(self, uisettings): for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: _settings = self._memobj.settings setting = element.get_name() if re.match(r'dtmf\d', setting): # set dtmf fields dtmfstr = str(element.value).strip() newval = [] for i in range(0, 16): if i < len(dtmfstr): newval.append(DTMFCHARSET.index(dtmfstr[i])) else: newval.append(0xFF) LOG.debug(newval) idx = int(setting[-2:]) _settings = self._memobj.dtmf[idx] _settings.memory = newval continue if setting == "arts_cwid": oldval = self._memobj.arts_cwid newval = self._encode_chars(newval.get_value(), 6) self._memobj.arts_cwid = newval continue # normal settings newval = element.value oldval = getattr(_settings, setting) LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise MEM_FORMAT_8800 = """ #seekto 0x%X; struct { u8 used:1, unknown1:1, mode:2, unknown2:1, duplex:3; bbcd freq[3]; u8 unknown3:1, tune_step:3, power:2, tmode:2; bbcd split[3]; u8 nameused:1, unknown5:1, tone:6; u8 namevalid:1, dtcs:7; u8 name[6]; } memory[500]; #seekto 0x%X; struct { u32 bitmap[16]; } bank_channels[10]; #seekto 0x51C8; struct { u8 skip0:2, skip1:2, skip2:2, skip3:2; } flags[250]; #seekto 0x7B48; u8 checksum; """ class FT8800BankModel(FT7800BankModel): def get_num_mappings(self): return 10 @directory.register class FT8800Radio(FTx800Radio): """Base class for Yaesu FT-8800""" MODEL = "FT-8800" _model = b"AH018" _memsize = 22217 _block_lengths = [8, 22208, 1] _memstart = 0x0000 TMODES = ["", "Tone", "TSQL", "DTCS"] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to DATA jack.\n" "3. Press and hold in the \"left\" [V/M] key while turning the\n" " radio on.\n" "4. Rotate the \"right\" DIAL knob to select \"CLONE START\".\n" "5. Press the [SET] key. The display will disappear\n" " for a moment, then the \"CLONE\" notation will appear.\n" "6. After clicking OK, press the \"left\" [V/M] key to\n" " send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to DATA jack.\n" "3. Press and hold in the \"left\" [V/M] key while turning the\n" " radio on.\n" "4. Rotate the \"right\" DIAL knob to select \"CLONE START\".\n" "5. Press the [SET] key. The display will disappear\n" " for a moment, then the \"CLONE\" notation will appear.\n" "6. Press the \"left\" [LOW] key (\"CLONE -RX-\" will appear" " on\n" " the display).\n") return rp def get_features(self): rf = FTx800Radio.get_features(self) rf.has_sub_devices = self.VARIANT == "" rf.has_bank = True rf.memory_bounds = (1, 500) return rf def get_sub_devices(self): return [FT8800RadioLeft(self._mmap), FT8800RadioRight(self._mmap)] def get_bank_model(self): if not hasattr(self, '_banks'): self._banks = FT8800BankModel(self) return self._banks def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x56C7)] def process_mmap(self): if not self._memstart: return self._memobj = bitwise.parse(MEM_FORMAT_8800 % (self._memstart, self._bankstart), self._mmap) def _get_mem_offset(self, mem, _mem): if mem.duplex == "split": return get_freq(int(_mem.split) * 10000) # The offset is packed into the upper two bits of the last four # bytes of the name (?!) val = 0 for i in _mem.name[2:6]: val <<= 2 val |= ((i & 0xC0) >> 6) return (val * 5) * 10000 def _set_mem_offset(self, mem, _mem): if mem.duplex == "split": set_freq(mem.offset, _mem, "split") return val = int(mem.offset / 10000) // 5 for i in reversed(list(range(2, 6))): _mem.name[i] = (_mem.name[i] & 0x3F) | ((val & 0x03) << 6) val >>= 2 def _get_mem_name(self, mem, _mem): name = "" if _mem.namevalid: for i in _mem.name: index = int(i) & 0x3F if index < len(CHARSET): name += CHARSET[index] return name.rstrip() def _set_mem_name(self, mem, _mem): _mem.name = [CHARSET.index(x) for x in mem.name.ljust(6)[:6]] _mem.namevalid = 1 _mem.nameused = bool(mem.name.rstrip()) class FT8800RadioLeft(FT8800Radio): """Yaesu FT-8800 Left VFO subdevice""" VARIANT = "Left" _memstart = 0x0948 _bankstart = 0x4BC8 class FT8800RadioRight(FT8800Radio): """Yaesu FT-8800 Right VFO subdevice""" VARIANT = "Right" _memstart = 0x2948 _bankstart = 0x4BC8 MEM_FORMAT_8900 = """ #seekto 0x0708; struct { u8 used:1, skip:2, sub_used:1, unknown2:1, duplex:3; bbcd freq[3]; u8 mode:2, nameused:1, unknown4:1, power:2, tmode:2; bbcd split[3]; u8 unknown5:2, tone:6; u8 namevalid:1, dtcs:7; u8 name[6]; } memory[799]; #seekto 0x51C8; struct { u8 skip0:2, skip1:2, skip2:2, skip3:2; } flags[400]; #seekto 0x7B48; u8 checksum; """ @directory.register class FT8900Radio(FT8800Radio): """Yaesu FT-8900""" MODEL = "FT-8900" _model = b"AH008" _memsize = 14793 _block_lengths = [8, 14784, 1] MODES = ["FM", "NFM", "AM"] def get_bank_model(self): return def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_8900, self._mmap) def get_features(self): rf = FT8800Radio.get_features(self) rf.has_sub_devices = False rf.has_bank = False rf.valid_modes = self.MODES rf.valid_bands = [(28000000, 29700000), (50000000, 54000000), (108000000, 180000000), (320000000, 480000000), (700000000, 985000000)] rf.memory_bounds = (1, 799) rf.has_tuning_step = False return rf def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x39C7)] def _get_mem_skip(self, mem, _mem): return SKIPS[_mem.skip] def _set_mem_skip(self, mem, _mem): _mem.skip = SKIPS.index(mem.skip) def get_memory(self, number): mem = super().get_memory(number) _mem = self._memobj.memory[number - 1] return mem def set_memory(self, mem): FT8800Radio.set_memory(self, mem) # The 8900 has a bit flag that tells the radio whether or not # the memory should show up on the sub (right) band _mem = self._memobj.memory[mem.number - 1] if mem.freq < 108000000 or mem.freq > 480000000: _mem.sub_used = 0 else: _mem.sub_used = 1 chirp-20240224/chirp/drivers/puxing.py0000644000175000017500000003726714522657251016533 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Puxing radios management module""" import time import logging from chirp import util, chirp_common, bitwise, errors, directory from chirp.drivers.wouxun import wipe_memory, do_download, do_upload LOG = logging.getLogger(__name__) def _puxing_prep(radio): radio.pipe.write(b"\x02PROGRA") ack = radio.pipe.read(1) if ack != b"\x06": raise Exception("Radio did not ACK first command") radio.pipe.write(b"M\x02") ident = radio.pipe.read(8) if len(ident) != 8: LOG.debug(util.hexprint(ident)) raise Exception("Radio did not send identification") radio.pipe.write(b"\x06") if radio.pipe.read(1) != b"\x06": raise Exception("Radio did not ACK ident") def puxing_prep(radio): """Do the Puxing PX-777 identification dance""" ex = None for _i in range(0, 10): try: return _puxing_prep(radio) except Exception as e: time.sleep(1) ex = e raise ex def puxing_download(radio): """Talk to a Puxing PX-777 and do a download""" try: puxing_prep(radio) return do_download(radio, 0x0000, 0x0C60, 0x0008) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def puxing_upload(radio): """Talk to a Puxing PX-777 and do an upload""" try: puxing_prep(radio) return do_upload(radio, 0x0000, 0x0C40, 0x0008) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] PUXING_CHARSET = list("0123456789") + \ [chr(x + ord("A")) for x in range(0, 26)] + \ list("- ") PUXING_MEM_FORMAT = """ #seekto 0x0000; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 _3_unknown_1; u8 _2_unknown_1:2, power_high:1, iswide:1, skip:1, bclo:2, _2_unknown_2:1; u8 _4_unknown1:7, pttid:1; u8 unknown; } memory[128]; #seekto 0x080A; struct { u8 limits; u8 model; } model[1]; #seekto 0x0850; struct { u8 name[6]; u8 pad[2]; } names[128]; """ # Limits # 67- 72: 0xEE # 136-174: 0xEF # 240-260: 0xF0 # 350-390: 0xF1 # 400-430: 0xF2 # 430-450: 0xF3 # 450-470: 0xF4 # 470-490: 0xF5 # 400-470: 0xF6 # 460-520: 0xF7 PUXING_MODELS = { 328: 0x38, 338: 0x39, 777: 0x3A, } PUXING_777_BANDS = [ (67000000, 72000000), (136000000, 174000000), (240000000, 260000000), (350000000, 390000000), (400000000, 430000000), (430000000, 450000000), (450000000, 470000000), (470000000, 490000000), (400000000, 470000000), (460000000, 520000000), ] @directory.register class Puxing777Radio(chirp_common.CloneModeRadio): """Puxing PX-777""" VENDOR = "Puxing" MODEL = "PX-777" NEEDS_COMPAT_SERIAL = False def sync_in(self): self._mmap = puxing_download(self) self.process_mmap() def sync_out(self): puxing_upload(self) def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = POWER_LEVELS rf.valid_characters = ''.join(set(PUXING_CHARSET)) rf.valid_name_length = 6 rf.valid_tuning_steps = [2.5, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] rf.has_ctone = False rf.has_tuning_step = False rf.has_bank = False rf.memory_bounds = (1, 128) if not hasattr(self, "_memobj") or self._memobj is None: rf.valid_bands = [PUXING_777_BANDS[1]] elif self._memobj.model.model == PUXING_MODELS[777]: limit_idx = self._memobj.model.limits - 0xEE try: rf.valid_bands = [PUXING_777_BANDS[limit_idx]] except IndexError: LOG.error("Invalid band index %i (0x%02x)" % (limit_idx, self._memobj.model.limits)) rf.valid_bands = [PUXING_777_BANDS[1]] elif self._memobj.model.model == PUXING_MODELS[328]: # There are PX-777 that says to be model 328 ... # for them we only know this freq limits till now if self._memobj.model.limits == 0xEE: rf.valid_bands = [PUXING_777_BANDS[1]] else: raise Exception("Unsupported band limits 0x%02x for PX-777" % (self._memobj.model.limits) + " submodel 328" " - PLEASE REPORT THIS ERROR TO DEVELOPERS!!") return rf def process_mmap(self): self._memobj = bitwise.parse(PUXING_MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) + "\r\n" + \ repr(self._memobj.names[number - 1]) @classmethod def match_model(cls, filedata, filename): # There are PX-777 that says to be model 328 ... return (len(filedata) == 3168 and (util.byte_to_int(filedata[0x080B]) == PUXING_MODELS[777] or (util.byte_to_int(filedata[0x080B]) == PUXING_MODELS[328] and util.byte_to_int(filedata[0x080A]) == 0xEE))) def get_memory(self, number): _mem = self._memobj.memory[number - 1] _nam = self._memobj.names[number - 1] def _is_empty(): for i in range(0, 4): if _mem.rx_freq[i].get_raw(asbytes=False) != "\xFF": return False return True def _is_no_tone(field): return field.get_raw(asbytes=False) in ["\x00\x00", "\xFF\xFF"] def _get_dtcs(value): # Upper nibble 0x80 -> DCS, 0xC0 -> Inv. DCS if value > 12000: return "R", value - 12000 elif value > 8000: return "N", value - 8000 else: raise Exception("Unable to convert DCS value") def _do_dtcs(mem, txfield, rxfield): if int(txfield) < 8000 or int(rxfield) < 8000: raise Exception("Split tone not supported") if txfield[0].get_raw(asbytes=False) == "\xFF": tp, tx = "N", None else: tp, tx = _get_dtcs(int(txfield)) if rxfield[0].get_raw(asbytes=False) == "\xFF": rp, rx = "N", None else: rp, rx = _get_dtcs(int(rxfield)) if not rx: rx = tx if not tx: tx = rx if tx != rx: raise Exception("Different RX and TX DCS codes not supported") mem.dtcs = tx mem.dtcs_polarity = "%s%s" % (tp, rp) mem = chirp_common.Memory() mem.number = number if _is_empty(): mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 mem.offset = (int(_mem.tx_freq) * 10) - mem.freq if mem.offset < 0: mem.duplex = "-" elif mem.offset: mem.duplex = "+" mem.offset = abs(mem.offset) if not _mem.skip: mem.skip = "S" if not _mem.iswide: mem.mode = "NFM" if _is_no_tone(_mem.tx_tone): pass # No tone elif int(_mem.tx_tone) > 8000 or \ (not _is_no_tone(_mem.rx_tone) and int(_mem.rx_tone) > 8000): mem.tmode = "DTCS" _do_dtcs(mem, _mem.tx_tone, _mem.rx_tone) else: mem.rtone = int(_mem.tx_tone) / 10.0 mem.tmode = _is_no_tone(_mem.rx_tone) and "Tone" or "TSQL" mem.power = POWER_LEVELS[not _mem.power_high] for i in _nam.name: if i == 0xFF: break mem.name += PUXING_CHARSET[i] mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _nam = self._memobj.names[mem.number - 1] if mem.empty: wipe_memory(_mem, "\xFF") return _mem.rx_freq = mem.freq / 10 if mem.duplex == "+": _mem.tx_freq = (mem.freq / 10) + (mem.offset / 10) elif mem.duplex == "-": _mem.tx_freq = (mem.freq / 10) - (mem.offset / 10) else: _mem.tx_freq = (mem.freq / 10) _mem.skip = mem.skip != "S" _mem.iswide = mem.mode != "NFM" _mem.rx_tone[0].set_raw("\xFF") _mem.rx_tone[1].set_raw("\xFF") _mem.tx_tone[0].set_raw("\xFF") _mem.tx_tone[1].set_raw("\xFF") if mem.tmode == "DTCS": _mem.tx_tone = int("%x" % int("%i" % (mem.dtcs), 16)) _mem.rx_tone = int("%x" % int("%i" % (mem.dtcs), 16)) # Argh. Set the high order two bits to signal DCS or Inv. DCS txm = mem.dtcs_polarity[0] == "N" and 0x80 or 0xC0 rxm = mem.dtcs_polarity[1] == "N" and 0x80 or 0xC0 _mem.tx_tone[1].set_raw( chr(ord(_mem.tx_tone[1].get_raw(asbytes=False)) | txm)) _mem.rx_tone[1].set_raw( chr(ord(_mem.rx_tone[1].get_raw(asbytes=False)) | rxm)) elif mem.tmode: _mem.tx_tone = int(mem.rtone * 10) if mem.tmode == "TSQL": _mem.rx_tone = int(_mem.tx_tone) if mem.power: _mem.power_high = not POWER_LEVELS.index(mem.power) else: _mem.power_high = True # Default to disabling the busy channel lockout # 00 == Close # 01 == Carrier # 10 == QT/DQT _mem.bclo = 0 _nam.name = [0xFF] * 6 for i in range(0, len(mem.name)): try: _nam.name[i] = PUXING_CHARSET.index(mem.name[i]) except IndexError: raise Exception("Character `%s' not supported") def puxing_2r_prep(radio): """Do the Puxing 2R identification dance""" radio.pipe.timeout = 0.2 radio.pipe.write(b"PROGRAM\x02") ack = radio.pipe.read(1) if ack != b"\x06": raise Exception("Radio is not responding") radio.pipe.write(ack) ident = radio.pipe.read(16) LOG.info("Radio ident: %s (%i)" % (repr(ident), len(ident))) def puxing_2r_download(radio): """Talk to a Puxing 2R and do a download""" try: puxing_2r_prep(radio) return do_download(radio, 0x0000, 0x0FE0, 0x0010) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def puxing_2r_upload(radio): """Talk to a Puxing 2R and do an upload""" try: puxing_2r_prep(radio) return do_upload(radio, 0x0000, 0x0FE0, 0x0010) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) PUXING_2R_MEM_FORMAT = """ #seekto 0x0010; struct { lbcd freq[4]; lbcd offset[4]; u8 rx_tone; u8 tx_tone; u8 duplex:2, txdtcsinv:1, rxdtcsinv:1, simplex:1, unknown2:1, iswide:1, ishigh:1; u8 name[5]; } memory[128]; """ PX2R_DUPLEX = ["", "+", "-", ""] PX2R_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.0), chirp_common.PowerLevel("High", watts=2.0)] PX2R_CHARSET = "0123456789- ABCDEFGHIJKLMNOPQRSTUVWXYZ +" @directory.register class Puxing2RRadio(chirp_common.CloneModeRadio): """Puxing PX-2R""" VENDOR = "Puxing" MODEL = "PX-2R" _memsize = 0x0FE0 def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = PX2R_POWER_LEVELS rf.valid_bands = [(400000000, 500000000)] rf.valid_characters = PX2R_CHARSET rf.valid_name_length = 5 rf.valid_duplexes = ["", "+", "-"] rf.valid_skips = [] rf.has_ctone = False rf.has_tuning_step = False rf.has_bank = False rf.memory_bounds = (1, 128) rf.can_odd_split = False return rf @classmethod def match_model(cls, filedata, filename): return (len(filedata) == cls._memsize) and \ filedata[-16:] not in ("IcomCloneFormat3", b'IcomCloneFormat3') def sync_in(self): self._mmap = puxing_2r_download(self) self.process_mmap() def sync_out(self): puxing_2r_upload(self) def process_mmap(self): self._memobj = bitwise.parse(PUXING_2R_MEM_FORMAT, self._mmap) def get_memory(self, number): _mem = self._memobj.memory[number-1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0:4] == "\xff\xff\xff\xff": mem.empty = True return mem mem.freq = int(_mem.freq) * 10 mem.offset = int(_mem.offset) * 10 mem.mode = _mem.iswide and "FM" or "NFM" mem.duplex = PX2R_DUPLEX[_mem.duplex] mem.power = PX2R_POWER_LEVELS[_mem.ishigh] if _mem.tx_tone >= 0x33: mem.dtcs = chirp_common.DTCS_CODES[_mem.tx_tone - 0x33] mem.tmode = "DTCS" mem.dtcs_polarity = \ (_mem.txdtcsinv and "R" or "N") + \ (_mem.rxdtcsinv and "R" or "N") elif _mem.tx_tone: mem.rtone = chirp_common.TONES[_mem.tx_tone - 1] mem.tmode = _mem.rx_tone and "TSQL" or "Tone" count = 0 for i in _mem.name: if i == 0xFF: break try: mem.name += PX2R_CHARSET[i] except Exception: LOG.error("Unknown name char %i: 0x%02x (mem %i)" % (count, i, number)) mem.name += " " count += 1 mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] if mem.empty: _mem.set_raw("\xff" * 16) return _mem.freq = mem.freq / 10 _mem.offset = mem.offset / 10 _mem.iswide = mem.mode == "FM" _mem.duplex = PX2R_DUPLEX.index(mem.duplex) _mem.ishigh = mem.power == PX2R_POWER_LEVELS[1] if mem.tmode == "DTCS": _mem.tx_tone = chirp_common.DTCS_CODES.index(mem.dtcs) + 0x33 _mem.rx_tone = chirp_common.DTCS_CODES.index(mem.dtcs) + 0x33 _mem.txdtcsinv = mem.dtcs_polarity[0] == "R" _mem.rxdtcsinv = mem.dtcs_polarity[1] == "R" elif mem.tmode in ["Tone", "TSQL"]: _mem.tx_tone = chirp_common.TONES.index(mem.rtone) + 1 _mem.rx_tone = mem.tmode == "TSQL" and int(_mem.tx_tone) or 0 else: _mem.tx_tone = 0 _mem.rx_tone = 0 for i in range(0, 5): try: _mem.name[i] = PX2R_CHARSET.index(mem.name[i]) except IndexError: _mem.name[i] = 0xFF def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) chirp-20240224/chirp/drivers/idrp.py0000644000175000017500000001110114430171343016121 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import serial import logging from chirp import chirp_common, errors, util LOG = logging.getLogger(__name__) def parse_frames(buf): """Parse frames from the radio""" frames = [] while "\xfe\xfe" in buf: try: start = buf.index("\xfe\xfe") end = buf[start:].index("\xfd") + start + 1 except Exception: LOG.error("Unable to parse frames") break frames.append(buf[start:end]) buf = buf[end:] return frames def send(pipe, buf): """Send data in @buf to @pipe""" pipe.write("\xfe\xfe%s\xfd" % buf) pipe.flush() data = "" while True: buf = pipe.read(4096) if not buf: break data += buf LOG.debug("Got: \n%s" % util.hexprint(buf)) return parse_frames(data) def send_magic(pipe): """Send the magic wakeup call to @pipe""" send(pipe, ("\xfe" * 15) + "\x01\x7f\x19") def drain(pipe): """Chew up any data waiting on @pipe""" while True: buf = pipe.read(4096) if not buf: break def set_freq(pipe, freq): """Set the frequency of the radio on @pipe to @freq""" freqbcd = util.bcd_encode(freq, bigendian=False, width=9) buf = "\x01\x7f\x05" + freqbcd drain(pipe) send_magic(pipe) resp = send(pipe, buf) for frame in resp: if len(frame) == 6: if frame[4] == "\xfb": return True raise errors.InvalidDataError("Repeater reported error") def get_freq(pipe): """Get the frequency of the radio attached to @pipe""" buf = "\x01\x7f\x1a\x09" drain(pipe) send_magic(pipe) resp = send(pipe, buf) for frame in resp: if frame[4] == "\x03": els = frame[5:10] freq = int("%02x%02x%02x%02x%02x" % (ord(els[4]), ord(els[3]), ord(els[2]), ord(els[1]), ord(els[0]))) LOG.debug("Freq: %f" % freq) return freq raise errors.InvalidDataError("No frequency frame received") RP_IMMUTABLE = ["number", "skip", "bank", "extd_number", "name", "rtone", "ctone", "dtcs", "tmode", "dtcs_polarity", "skip", "duplex", "offset", "mode", "tuning_step", "bank_index"] class IDRPx000V(chirp_common.LiveRadio): """Icom IDRP-*""" BAUD_RATE = 19200 VENDOR = "Icom" MODEL = "ID-2000V/4000V/2D/2V" _model = "0000" # Unknown mem_upper_limit = 0 def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_modes = ["DV"] rf.valid_tmodes = [] rf.valid_characters = "" rf.valid_duplexes = [""] rf.valid_name_length = 0 rf.valid_skips = [] rf.valid_tuning_steps = [] rf.has_bank = False rf.has_ctone = False rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_mode = False rf.has_name = False rf.has_offset = False rf.has_tuning_step = False rf.memory_bounds = (0, 0) return rf def get_memory(self, number): if number != 0: raise errors.InvalidMemoryLocation("Repeaters have only one slot") mem = chirp_common.Memory() mem.number = 0 mem.freq = get_freq(self.pipe) mem.name = "TX/RX" mem.mode = "DV" mem.offset = 0.0 mem.immutable = RP_IMMUTABLE return mem def set_memory(self, mem): if mem.number != 0: raise errors.InvalidMemoryLocation("Repeaters have only one slot") set_freq(self.pipe, mem.freq) def do_test(): """Get the frequency of /dev/icom""" ser = serial.Serial(port="/dev/icom", baudrate=19200, timeout=0.5) # set_freq(pipe, 439.920) get_freq(ser) if __name__ == "__main__": do_test() chirp-20240224/chirp/drivers/anytone778uv.py0000644000175000017500000020533114466370044017503 0ustar hibbyhibby# Copyright 2020 Joe Milbourn # Copyright 2021 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # TODO use the band field from ver_response # TODO handle radio settings # # Supported features # * Read and write memory access for 200 normal memories # * CTCSS and DTCS for transmit and receive # * Scan list # * Tx off # * Duplex (+ve, -ve, odd, and off splits) # * Transmit power # * Channel width (25 kHz and 12.5 kHz) # * Retevis RT95, CRT Micron UV, and Midland DBR2500 radios # * Full range of frequencies for tx and rx, supported band read from radio # during download, not verified on upload. Radio will refuse to TX if out of # band. # * Busy channel lock out (for each memory) # # Unsupported features # * VFO1, VFO2, and TRF memories # * custom CTCSS tones # * Any non-memory radio settings # * Reverse, talkaround, scramble # * probably other things too - like things encoded by the unknown bits in the # memory struct from chirp import chirp_common, directory, memmap, errors, util from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettings import struct import time import logging LOG = logging.getLogger(__name__) # Gross hack to handle missing future module on un-updatable # platforms like MacOS. Just avoid registering these radio # classes for now. try: from builtins import bytes has_future = True except ImportError: has_future = False LOG.debug('python-future package is not ' 'available; %s requires it' % __name__) # Here is where we define the memory map for the radio. Since # We often just know small bits of it, we can use #seekto to skip # around as needed. MEM_FORMAT = ''' #seekto 0x0000; struct { bbcd freq[4]; bbcd offset[4]; u8 unknown1; u8 talkaround:1, scramble:1, unknown:2, txpower:2, duplex:2; u8 unknown_bits1:4, channel_width:2, reverse:1, tx_off:1; u8 unknown_bits2:4, dtcs_decode_en:1, ctcss_decode_en:1, dtcs_encode_en:1, ctcss_encode_en:1; u8 ctcss_dec_tone; u8 ctcss_enc_tone; u8 dtcs_decode_code; u8 unknown_bits6:6, dtcs_decode_invert:1, dtcs_decode_code_highbit:1; u8 dtcs_encode_code; u8 unknown_bits7:6, dtcs_encode_invert:1, dtcs_encode_code_highbit:1; u8 unknown_bits4:6, busy_channel_lockout:2; u8 unknown6; u8 unknown_bits5:7, tone_squelch_en:1; u8 unknown7; u8 unknown8; u8 unknown9; char name[6]; // the VOX models have 6-character names // the original models only have 5-character names // the 1st byte is not used and will always be 0x00 ul16 customctcss; } memory[200]; #seekto 0x1940; struct { u8 occupied_bitfield[32]; u8 scan_enabled_bitfield[32]; } memory_status; #seekto 0x1980; struct { char line[7]; // starting display } starting_display; #seekto 0x1990; struct { u8 code[16]; // DTMF Encode M1-M16 } pttid[16]; #seekto 0x1A90; struct { u8 pttIdStart[16]; // 0x1A90 ptt id starting u8 pttIdEnd[16]; // 0x1AA0 ptt id ending u8 remoteStun[16]; // 0x1AB0 remotely stun u8 remoteKill[16]; // 0x1AC0 remotely kill u8 intervalChar; // 0x1AD0 dtmf interval character u8 groupCode; // 0x1AD1 group code u8 unk1ad2:6, // 0x1AD2 decodingResponse:2; // decoding response u8 pretime; // 0x1AD3 pretime u8 firstDigitTime; // 0x1AD4 first digit time u8 autoResetTime; // 0x1AD5 auto reset time u8 selfID[3]; // 0x1AD6 dtmf self id u8 unk1ad9:7, // 0x1AD9 sideTone:1; // side tone u8 timeLapse; // 0x1ADA time-lapse after encode u8 pauseTime; // 0x1ADB ptt id pause time } dtmf; #seekto 0x3200; struct { u8 unk3200:5, // 0x3200 beepVolume:3; // beep volume u8 unk3201:4, // 0x3201 frequencyStep:4; // frequency step u8 unk3202:6, // 0x3202 displayMode:2; // display mode u8 unk0x3203; u8 unk3204:4, // 0x3204 squelchLevelA:4; // squelch level a u8 unk3205:4, // 0x3205 squelchLevelB:4; // squelch level b u8 unk3206:2, // 0x3206 speakerVol:6; // speaker volume u8 unk3207:7, // 0x3207 powerOnPasswd:1; // power-on password u8 unk3208:6, // 0x3208 scanType:2; // scan type u8 unk3209:6, // 0x3209 scanRecoveryT:2; // scan recovery time u8 unk320a:7, // 0x320A autoPowerOn:1; // auto power on u8 unk320b:7, // 0x320B main:1; // main u8 unk320c:7, // 0x320C dualWatch:1; // dual watch (rx way select) u8 unk320d:5, // 0x320D backlightBr:3; // backlight brightness u8 unk320e:3, // 0x320E timeOutTimer:5; // time out timer u8 unk320f:6, // 0x320F autoPowerOff:2; // auto power off u8 unk3210:6, // 0x3210 tbstFrequency:2; // tbst frequency u8 unk3211:7, // 0x3211 screenDir:1; // screen direction u8 unk3212:2, // 0x3212 micKeyBrite:6; // hand mic key brightness u8 unk3213:6, // 0x3213 speakerSwitch:2; // speaker switch u8 keyPA; // 0x3214 key pa u8 keyPB; // 0x3215 key pb u8 keyPC; // 0x3216 key pc u8 keyPD; // 0x3217 key pd u8 unk3218:5, // 0x3218 steType:3; // ste type u8 unk3219:6, // 0x3219 steFrequency:2; // ste frequency u8 unk321a:5, // 0x321A dtmfTxTime:3; // dtmf transmitting time u8 unk_bit7_6:2, // 0x321B monKeyFunction:1, // mon key function channelLocked:1, // channel locked saveChParameter:1, // save channel parameter powerOnReset:1, // power on reset trfEnable:1, // trf enable knobMode:1; // knob mode u8 unk321c:7, // 0x321C voxOnOff:1; // vox on/off u8 voxLevel; // 0x321D vox level u8 voxDelay; // 0x321E vox delay } settings; #seekto 0x3240; struct { char digits[6]; // password } password; #seekto 0x3250; struct { u8 keyMode1P1; // 0x3250 key mode 1 p1 u8 keyMode1P2; // 0x3251 key mode 1 p2 u8 keyMode1P3; // 0x3252 key mode 1 p3 u8 keyMode1P4; // 0x3253 key mode 1 p4 u8 keyMode1P5; // 0x3254 key mode 1 p5 u8 keyMode1P6; // 0x3255 key mode 1 p6 u8 keyMode2P1; // 0x3256 key mode 2 p1 u8 keyMode2P2; // 0x3257 key mode 2 p2 u8 keyMode2P3; // 0x3258 key mode 2 p3 u8 keyMode2P4; // 0x3259 key mode 2 p4 u8 keyMode2P5; // 0x325A key mode 2 p5 u8 keyMode2P6; // 0x325B key mode 2 p6 } pfkeys; #seekto 0x3260; struct { u8 mrChanA; // 0x3260 mr channel a u8 unknown1_0:7, // 0x3261 vfomrA:1; // vfo/mr mode a u8 unknown2; u8 unknown3; u8 unknown4; u8 unknown5; u8 unknown6; u8 mrChanB; // 0x3267 mr channel b u8 unknown8_0:4, // 0x3268 scan_active:1, unknown8_1:2, vfomrB:1; // vfo/mr mode b u8 unknown9; u8 unknowna; u8 unknownb; u8 unknownc; u8 bandlimit; // 0x326D mode u8 unknownd; u8 unknowne; u8 unknownf; } radio_settings; ''' # Format for the version messages returned by the radio VER_FORMAT = ''' u8 hdr; char model[7]; u8 bandlimit; char version[6]; u8 ack; ''' TXPOWER_LOW = 0x00 TXPOWER_MED = 0x01 TXPOWER_HIGH = 0x02 DUPLEX_NOSPLIT = 0x00 DUPLEX_POSSPLIT = 0x01 DUPLEX_NEGSPLIT = 0x02 DUPLEX_ODDSPLIT = 0x03 CHANNEL_WIDTH_25kHz = 0x02 CHANNEL_WIDTH_20kHz = 0x01 CHANNEL_WIDTH_12d5kHz = 0x00 BUSY_CHANNEL_LOCKOUT_OFF = 0x00 BUSY_CHANNEL_LOCKOUT_REPEATER = 0x01 BUSY_CHANNEL_LOCKOUT_BUSY = 0x02 MEMORY_ADDRESS_RANGE = (0x0000, 0x3290) MEMORY_RW_BLOCK_SIZE = 0x10 MEMORY_RW_BLOCK_CMD_SIZE = 0x16 POWER_LEVELS = [chirp_common.PowerLevel('Low', dBm=37), chirp_common.PowerLevel('Medium', dBm=40), chirp_common.PowerLevel('High', dBm=44)] # CTCSS Tone definitions TONE_CUSTOM_CTCSS = 0x33 TONE_MAP_VAL_TO_TONE = {0x00: 62.5, 0x01: 67.0, 0x02: 69.3, 0x03: 71.9, 0x04: 74.4, 0x05: 77.0, 0x06: 79.7, 0x07: 82.5, 0x08: 85.4, 0x09: 88.5, 0x0a: 91.5, 0x0b: 94.8, 0x0c: 97.4, 0x0d: 100.0, 0x0e: 103.5, 0x0f: 107.2, 0x10: 110.9, 0x11: 114.8, 0x12: 118.8, 0x13: 123.0, 0x14: 127.3, 0x15: 131.8, 0x16: 136.5, 0x17: 141.3, 0x18: 146.2, 0x19: 151.4, 0x1a: 156.7, 0x1b: 159.8, 0x1c: 162.2, 0x1d: 165.5, 0x1e: 167.9, 0x1f: 171.3, 0x20: 173.8, 0x21: 177.3, 0x22: 179.9, 0x23: 183.5, 0x24: 186.2, 0x25: 189.9, 0x26: 192.8, 0x27: 196.6, 0x28: 199.5, 0x29: 203.5, 0x2a: 206.5, 0x2b: 210.7, 0x2c: 218.1, 0x2d: 225.7, 0x2e: 229.1, 0x2f: 233.6, 0x30: 241.8, 0x31: 250.3, 0x32: 254.1} TONE_MAP_TONE_TO_VAL = {TONE_MAP_VAL_TO_TONE[val]: val for val in TONE_MAP_VAL_TO_TONE} TONES_EN_TXTONE = (1 << 3) TONES_EN_RXTONE = (1 << 2) TONES_EN_TXCODE = (1 << 1) TONES_EN_RXCODE = (1 << 0) TONES_EN_NO_TONE = 0 # Radio supports upper case and symbols CHARSET_ASCII_PLUS = chirp_common.CHARSET_UPPER_NUMERIC + '- ' # Band limits as defined by the band byte in ver_response, defined in Hz, for # VHF and UHF, used for RX and TX. BAND_LIMITS = {0x00: [(144000000, 148000000), (430000000, 440000000)], 0x01: [(136000000, 174000000), (400000000, 490000000)], 0x02: [(144000000, 146000000), (430000000, 440000000)]} # Get band limits from a band limit value def get_band_limits_Hz(limit_value): if limit_value not in BAND_LIMITS: limit_value = 0x01 LOG.warning('Unknown band limit value 0x%02x, default to 0x01') bandlimitfrequencies = BAND_LIMITS[limit_value] return bandlimitfrequencies # Calculate the checksum used in serial packets def checksum(message_bytes): mask = 0xFF checksum = 0 for b in message_bytes: checksum = (checksum + b) & mask return checksum # Send a command to the radio, return any reply stripping the echo of the # command (tx and rx share a single pin in this radio) def send_serial_command(serial, command, expectedlen=None): ''' send a command to the radio, and return any response. set expectedlen to return as soon as that many bytes are read. ''' serial.write(command) serial.flush() response = b'' tout = time.time() + 0.5 while time.time() < tout: if serial.inWaiting(): response += serial.read() # remember everything gets echo'd back if len(response) - len(command) == expectedlen: break # cut off what got echo'd back, we don't need to see it again if response.startswith(command): response = response[len(command):] return response # strip trailing 0x00 to convert a string returned by bitwise.parse into a # python string def cstring_to_py_string(cstring): return "".join(c for c in cstring if c != '\x00') # Check the radio version reported to see if it's one we support, # returns bool version supported, and the band index def check_ver(ver_response, allowed_types): ''' Check the returned radio version is one we approve of ''' LOG.debug('ver_response = ') LOG.debug(util.hexprint(ver_response)) global HAS_VOX resp = bitwise.parse(VER_FORMAT, ver_response) verok = False if resp.hdr == 0x49 and resp.ack == 0x06: model, version = [cstring_to_py_string(bitwise.get_string(s)).strip() for s in (resp.model, resp.version)] LOG.debug('radio model: \'%s\' version: \'%s\'' % (model, version)) LOG.debug('allowed_types = %s' % allowed_types) HAS_VOX = "P" == model[-1:] if model in allowed_types: LOG.debug('model in allowed_types') if version in allowed_types[model]: LOG.debug('version in allowed_types[model]') verok = True else: raise errors.RadioError('Failed to parse version response') return verok, int(resp.bandlimit) # Put the radio in programming mode, sending the initial command and checking # the response. raise RadioError if there is no response (500ms timeout), and # if the returned version isn't matched by check_ver def enter_program_mode(radio): serial = radio.pipe # place the radio in program mode, and confirm program_response = send_serial_command(serial, b'PROGRAM') if program_response != b'QX\x06': raise errors.RadioError('No initial response from radio.') LOG.debug('entered program mode') # read the radio ID string, make sure it matches one we know about ver_response = send_serial_command(serial, b'\x02') verok, bandlimit = check_ver(ver_response, radio.ALLOWED_RADIO_TYPES) if not verok: exit_program_mode(radio) ver = "V2" if radio.VENDOR == "CRT" else "VOX" if HAS_VOX and ("V2" and "VOX") not in radio.MODEL: raise errors.RadioError( 'Radio identified as model with VOX\n' 'Try %s-%s %s' % (radio.VENDOR, radio.MODEL, ver)) else: raise errors.RadioError( 'Radio version not in allowed list for %s-%s:\n' '%s' % (radio.VENDOR, radio.MODEL, util.hexprint(ver_response))) return bandlimit # Exit programming mode def exit_program_mode(radio): send_serial_command(radio.pipe, b'END') # Parse a packet from the radio returning the header (R/W, address, data, and # checksum valid def parse_read_response(resp): addr = resp[:4] data = bytes(resp[4:-2]) cs = checksum(d for d in resp[1:-2]) valid = cs == resp[-2] if not valid: LOG.error('checksumfail: %02x, expected %02x' % (cs, resp[-2])) LOG.error('msg data: %s' % util.hexprint(resp)) return addr, data, valid # Download data from the radio and populate the memory map def do_download(radio): '''Download memories from the radio''' # Get the serial port connection serial = radio.pipe try: enter_program_mode(radio) memory_data = bytes() # status info for the UI status = chirp_common.Status() status.cur = 0 status.max = (MEMORY_ADDRESS_RANGE[1] - MEMORY_ADDRESS_RANGE[0]) // MEMORY_RW_BLOCK_SIZE status.msg = 'Cloning from radio...' radio.status_fn(status) for addr in range(MEMORY_ADDRESS_RANGE[0], MEMORY_ADDRESS_RANGE[1] + MEMORY_RW_BLOCK_SIZE, MEMORY_RW_BLOCK_SIZE): read_command = struct.pack('>BHB', 0x52, addr, MEMORY_RW_BLOCK_SIZE) read_response = send_serial_command(serial, read_command, MEMORY_RW_BLOCK_CMD_SIZE) # LOG.debug('read response:\n%s' % util.hexprint(read_response)) address, data, valid = parse_read_response(read_response) memory_data += data # update UI status.cur = (addr - MEMORY_ADDRESS_RANGE[0])\ // MEMORY_RW_BLOCK_SIZE radio.status_fn(status) exit_program_mode(radio) except errors.RadioError as e: raise e except Exception as e: raise errors.RadioError('Failed to download from radio: %s' % e) return memmap.MemoryMapBytes(memory_data) # Build a write data command to send to the radio def make_write_data_cmd(addr, data, datalen): cmd = struct.pack('>BHB', 0x57, addr, datalen) cmd += data cs = checksum(c for c in cmd[1:]) cmd += struct.pack('>BB', cs, 0x06) return cmd # Upload a memory map to the radio def do_upload(radio): try: bandlimit = enter_program_mode(radio) if bandlimit != radio._memobj.radio_settings.bandlimit: LOG.warning('radio and image bandlimits differ' ' some channels many not work' ' (img:0x%02x radio:0x%02x)' % (int(bandlimit), int(radio._memobj.radio_settings.bandlimit))) LOG.warning('radio bands: %s' % get_band_limits_Hz( int(radio._memobj.radio_settings.bandlimit))) LOG.warning('img bands: %s' % get_band_limits_Hz(bandlimit)) serial = radio.pipe # send the initial message, radio responds with something that looks a # bit like a bitfield, but I don't know what it is yet. read_command = struct.pack('>BHB', 0x52, 0x3b10, MEMORY_RW_BLOCK_SIZE) read_response = send_serial_command(serial, read_command, MEMORY_RW_BLOCK_CMD_SIZE) address, data, valid = parse_read_response(read_response) LOG.debug('Got initial response from radio: %s' % util.hexprint(read_response)) bptr = 0 memory_addrs = list(range(MEMORY_ADDRESS_RANGE[0], MEMORY_ADDRESS_RANGE[1] + MEMORY_RW_BLOCK_SIZE, MEMORY_RW_BLOCK_SIZE)) # status info for the UI status = chirp_common.Status() status.cur = 0 status.max = len(memory_addrs) status.msg = 'Cloning to radio...' radio.status_fn(status) for idx, addr in enumerate(memory_addrs): write_command = make_write_data_cmd( addr, radio._mmap[bptr:bptr+MEMORY_RW_BLOCK_SIZE], MEMORY_RW_BLOCK_SIZE) # LOG.debug('write data:\n%s' % util.hexprint(write_command)) write_response = send_serial_command(serial, write_command, 0x01) bptr += MEMORY_RW_BLOCK_SIZE if write_response == '\x0a': # NACK from radio, e.g. checksum wrong LOG.debug('Radio returned 0x0a - NACK:') LOG.debug(' * write cmd:\n%s' % util.hexprint(write_command)) LOG.debug(' * write response:\n%s' % util.hexprint(write_response)) exit_program_mode(radio) raise errors.RadioError('Radio NACK\'d write command') # update UI status.cur = idx radio.status_fn(status) exit_program_mode(radio) except errors.RadioError: raise except Exception as e: raise errors.RadioError('Failed to download from radio: %s' % e) # Get the value of @bitfield @number of bits in from 0 def get_bitfield(bitfield, number): ''' Get the value of @bitfield @number of bits in ''' byteidx = number//8 bitidx = number - (byteidx * 8) return bitfield[byteidx] & (1 << bitidx) # Set the @value of @bitfield @number of bits in from 0 def set_bitfield(bitfield, number, value): ''' Set the @value of @bitfield @number of bits in ''' byteidx = number//8 bitidx = number - (byteidx * 8) if value is True: bitfield[byteidx] |= (1 << bitidx) else: bitfield[byteidx] &= ~(1 << bitidx) return bitfield # Translate the radio's version of a code as stored to a real code def dtcs_code_bits_to_val(highbit, lowbyte): return chirp_common.ALL_DTCS_CODES[highbit*256 + lowbyte] # Translate the radio's version of a tone as stored to a real tone def ctcss_tone_bits_to_val(tone_byte): # TODO use the custom setting 0x33 and ref the custom ctcss # field tone_byte = int(tone_byte) if tone_byte in TONE_MAP_VAL_TO_TONE: return TONE_MAP_VAL_TO_TONE[tone_byte] elif tone_byte == TONE_CUSTOM_CTCSS: LOG.info('custom ctcss not implemented (yet?).') else: raise errors.UnsupportedToneError('unknown ctcss tone value: %02x' % tone_byte) # Translate a real tone to the radio's version as stored def ctcss_code_val_to_bits(tone_value): if tone_value in TONE_MAP_TONE_TO_VAL: return TONE_MAP_TONE_TO_VAL[tone_value] else: raise errors.UnsupportedToneError('Tone %f not supported' % tone_value) # Translate a real code to the radio's version as stored def dtcs_code_val_to_bits(code): val = chirp_common.ALL_DTCS_CODES.index(code) return (val & 0xFF), ((val >> 8) & 0x01) class AnyTone778UVBase(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): '''AnyTone 778UV and probably Retevis RT95 and others''' BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False NAME_LENGTH = 5 HAS_VOX = False @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This is experimental support for the %s %s. ' 'Please send in bug and enhancement requests!' % (cls.VENDOR, cls.MODEL)) return rp # Return information about this radio's features, including # how many memories it has, what bands it supports, etc def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_settings = True rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.valid_name_length = self.NAME_LENGTH rf.valid_duplexes = ['', '+', '-', 'split', 'off'] rf.valid_characters = CHARSET_ASCII_PLUS rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.valid_dtcs_codes = chirp_common.ALL_DTCS_CODES rf.has_ctone = True rf.has_cross = True rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ['Tone->Tone', 'Tone->DTCS', 'DTCS->Tone', 'DTCS->DTCS', 'DTCS->', '->DTCS', '->Tone'] rf.memory_bounds = (1, 200) # This radio supports memories 1-200 try: rf.valid_bands = get_band_limits_Hz( int(self._memobj.radio_settings.bandlimit)) except AttributeError: # If we're asked without memory loaded, assume the most permissive rf.valid_bands = get_band_limits_Hz(1) except Exception as e: LOG.exception( 'Failed to get band limits for anytone778uv: %s' % e) rf.valid_bands = get_band_limits_Hz(1) rf.valid_modes = ['FM', 'NFM'] rf.valid_power_levels = POWER_LEVELS rf.valid_tuning_steps = [2.5, 5, 6.25, 10, 12.5, 20, 25, 30, 50] rf.has_tuning_step = False return rf # Do a download of the radio from the serial port def sync_in(self): self._mmap = do_download(self) self.process_mmap() # Do an upload of the radio to the serial port def sync_out(self): do_upload(self) # Convert the raw byte array into a memory object structure def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # Return a raw representation of the memory object, which # is very helpful for development def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) # Extract a high-level memory object from the low-level memory map # This is called to populate a memory in the UI def get_memory(self, number): number -= 1 # Get a low-level memory object mapped to the image _mem = self._memobj.memory[number] _mem_status = self._memobj.memory_status # Create a high-level memory object to return to the UI mem = chirp_common.Memory() mem.number = number + 1 # Set the memory number # Check if this memory is present in the occupied list mem.empty = get_bitfield(_mem_status.occupied_bitfield, number) == 0 if not mem.empty: # Check if this memory is in the scan enabled list mem.skip = '' if get_bitfield(_mem_status.scan_enabled_bitfield, number) == 0: mem.skip = 'S' # set the name if self.NAME_LENGTH == 5: # original models with 5-character name length temp_name = str(_mem.name) # Strip the first character and set the alpha tag mem.name = str(temp_name[1:6]).rstrip() else: # new VOX models with 6-character name length mem.name = str(_mem.name).rstrip() # Set the alpha tag # Convert your low-level frequency and offset to Hertz mem.freq = int(_mem.freq) * 10 mem.offset = int(_mem.offset) * 10 # Set the duplex flags if _mem.duplex == DUPLEX_POSSPLIT: mem.duplex = '+' elif _mem.duplex == DUPLEX_NEGSPLIT: mem.duplex = '-' elif _mem.duplex == DUPLEX_NOSPLIT: mem.duplex = '' elif _mem.duplex == DUPLEX_ODDSPLIT: mem.duplex = 'split' else: LOG.error('%s: get_mem: unhandled duplex: %02x' % (mem.name, _mem.duplex)) # handle tx off if _mem.tx_off: mem.duplex = 'off' # Set the channel width if _mem.channel_width == CHANNEL_WIDTH_25kHz: mem.mode = 'FM' elif _mem.channel_width == CHANNEL_WIDTH_20kHz: LOG.info( '%s: get_mem: promoting 20 kHz channel width to 25 kHz' % mem.name) mem.mode = 'FM' elif _mem.channel_width == CHANNEL_WIDTH_12d5kHz: mem.mode = 'NFM' else: LOG.error('%s: get_mem: unhandled channel width: 0x%02x' % (mem.name, _mem.channel_width)) # set the power level if _mem.txpower == TXPOWER_LOW: mem.power = POWER_LEVELS[0] elif _mem.txpower == TXPOWER_MED: mem.power = POWER_LEVELS[1] elif _mem.txpower == TXPOWER_HIGH: mem.power = POWER_LEVELS[2] else: LOG.error('%s: get_mem: unhandled power level: 0x%02x' % (mem.name, _mem.txpower)) # CTCSS Tones # TODO support custom ctcss tones here txtone = None rxtone = None rxcode = None txcode = None # check if dtcs tx is enabled if _mem.dtcs_encode_en: txcode = dtcs_code_bits_to_val(_mem.dtcs_encode_code_highbit, _mem.dtcs_encode_code) # check if dtcs rx is enabled if _mem.dtcs_decode_en: rxcode = dtcs_code_bits_to_val(_mem.dtcs_decode_code_highbit, _mem.dtcs_decode_code) if txcode is not None: LOG.debug('%s: get_mem dtcs_enc: %d' % (mem.name, txcode)) if rxcode is not None: LOG.debug('%s: get_mem dtcs_dec: %d' % (mem.name, rxcode)) # tsql set if radio squelches on tone tsql = _mem.tone_squelch_en # check if ctcss tx is enabled if _mem.ctcss_encode_en: txtone = ctcss_tone_bits_to_val(_mem.ctcss_enc_tone) # check if ctcss rx is enabled if _mem.ctcss_decode_en: rxtone = ctcss_tone_bits_to_val(_mem.ctcss_dec_tone) # Define this here to allow a readable if-else tree enabling tone # options enabled = 0 enabled |= (txtone is not None) * TONES_EN_TXTONE enabled |= (rxtone is not None) * TONES_EN_RXTONE enabled |= (txcode is not None) * TONES_EN_TXCODE enabled |= (rxcode is not None) * TONES_EN_RXCODE # Add some debugging output for the tone bitmap enstr = [] if enabled & TONES_EN_TXTONE: enstr += ['TONES_EN_TXTONE'] if enabled & TONES_EN_RXTONE: enstr += ['TONES_EN_RXTONE'] if enabled & TONES_EN_TXCODE: enstr += ['TONES_EN_TXCODE'] if enabled & TONES_EN_RXCODE: enstr += ['TONES_EN_RXCODE'] if enabled == 0: enstr = ['TONES_EN_NOTONE'] LOG.debug('%s: enabled = %s' % ( mem.name, '|'.join(enstr))) mem.tmode = '' if enabled == TONES_EN_NO_TONE: mem.tmode = '' elif enabled == TONES_EN_TXTONE: mem.tmode = 'Tone' mem.rtone = txtone elif enabled == TONES_EN_RXTONE and tsql: mem.tmode = 'Cross' mem.cross_mode = '->Tone' mem.ctone = rxtone elif enabled == (TONES_EN_TXTONE | TONES_EN_RXTONE) and tsql: if txtone == rxtone: # TSQL mem.tmode = 'TSQL' mem.ctone = txtone else: # Tone->Tone mem.tmode = 'Cross' mem.cross_mode = 'Tone->Tone' mem.ctone = rxtone mem.rtone = txtone elif enabled == TONES_EN_TXCODE: mem.tmode = 'Cross' mem.cross_mode = 'DTCS->' mem.dtcs = txcode elif enabled == TONES_EN_RXCODE and tsql: mem.tmode = 'Cross' mem.cross_mode = '->DTCS' mem.rx_dtcs = rxcode elif enabled == (TONES_EN_TXCODE | TONES_EN_RXCODE) and tsql: if rxcode == txcode: mem.tmode = 'DTCS' mem.rx_dtcs = rxcode # #8327 Not sure this is the correct interpretation of # DevelopersToneModes, but it seems to make it work round # tripping with the Anytone software. DTM implies that we # might not need to set mem.dtcs, but if we do it only DTCS # rx works (as if we were Cross:None->DTCS). mem.dtcs = rxcode else: mem.tmode = 'Cross' mem.cross_mode = 'DTCS->DTCS' mem.rx_dtcs = rxcode mem.dtcs = txcode elif enabled == (TONES_EN_TXCODE | TONES_EN_RXTONE) and tsql: mem.tmode = 'Cross' mem.cross_mode = 'DTCS->Tone' mem.dtcs = txcode mem.ctone = rxtone elif enabled == (TONES_EN_TXTONE | TONES_EN_RXCODE) and tsql: mem.tmode = 'Cross' mem.cross_mode = 'Tone->DTCS' mem.rx_dtcs = rxcode mem.rtone = txtone else: LOG.error('%s: Unhandled tmode enabled = %d.' % ( mem.name, enabled)) # Can get here if e.g. TONE_EN_RXCODE is set and tsql isn't # In that case should we perhaps store the tone and code values # if they're present and then setup tmode and cross_mode as # appropriate later? # set the dtcs polarity dtcs_pol_bit_to_str = {0: 'N', 1: 'R'} mem.dtcs_polarity = '%s%s' %\ (dtcs_pol_bit_to_str[_mem.dtcs_encode_invert == 1], dtcs_pol_bit_to_str[_mem.dtcs_decode_invert == 1]) # Extra mem.extra = RadioSettingGroup("Extra", "extra") # Busy channel lockout bcl_options = ['Off', 'Repeater', 'Busy'] bcl_option = bcl_options[_mem.busy_channel_lockout] rs = RadioSetting("busy_channel_lockout", "Busy Channel Lockout", RadioSettingValueList(bcl_options, bcl_option)) mem.extra.append(rs) return mem # Store details about a high-level memory to the memory map # This is called when a user edits a memory in the UI def set_memory(self, mem): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] _mem_status = self._memobj.memory_status # set the occupied bitfield _mem_status.occupied_bitfield = \ set_bitfield(_mem_status.occupied_bitfield, mem.number - 1, not mem.empty) # set the scan add bitfield _mem_status.scan_enabled_bitfield = \ set_bitfield(_mem_status.scan_enabled_bitfield, mem.number - 1, (not mem.empty) and (mem.skip != 'S')) if mem.empty: # Set the whole memory to 0xff _mem.set_raw('\xff' * (_mem.size() // 8)) else: _mem.set_raw('\x00' * (_mem.size() // 8)) _mem.freq = int(mem.freq / 10) _mem.offset = int(mem.offset / 10) # Store the alpha tag if self.NAME_LENGTH == 5: # original models with 5-character name length temp_name = mem.name.ljust(self.NAME_LENGTH)[:self.NAME_LENGTH] # prefix the 5-character name with 0x00 to fit structure _mem.name = temp_name.rjust(6, chr(00)) else: # new VOX models with 6-character name length _mem.name = mem.name.ljust(self.NAME_LENGTH)[:self.NAME_LENGTH] # Set duplex bitfields if mem.duplex == '+': _mem.duplex = DUPLEX_POSSPLIT elif mem.duplex == '-': _mem.duplex = DUPLEX_NEGSPLIT elif mem.duplex == '': _mem.duplex = DUPLEX_NOSPLIT elif mem.duplex == 'split': # TODO: this is an unverified punt! _mem.duplex = DUPLEX_ODDSPLIT else: LOG.error('%s: set_mem: unhandled duplex: %s' % (mem.name, mem.duplex)) # handle tx off _mem.tx_off = 0 if mem.duplex == 'off': _mem.tx_off = 1 # Set the channel width - remember we promote 20 kHz channels to FM # on import # , so don't handle them here if mem.mode == 'FM': _mem.channel_width = CHANNEL_WIDTH_25kHz elif mem.mode == 'NFM': _mem.channel_width = CHANNEL_WIDTH_12d5kHz else: LOG.error('%s: set_mem: unhandled mode: %s' % ( mem.name, mem.mode)) # set the power level if mem.power == POWER_LEVELS[0]: _mem.txpower = TXPOWER_LOW elif mem.power == POWER_LEVELS[1]: _mem.txpower = TXPOWER_MED elif mem.power == POWER_LEVELS[2]: _mem.txpower = TXPOWER_HIGH else: LOG.error('%s: set_mem: unhandled power level: %s' % (mem.name, mem.power)) # TODO set the CTCSS values # TODO support custom ctcss tones here # Default - tones off, carrier sql _mem.ctcss_encode_en = 0 _mem.ctcss_decode_en = 0 _mem.tone_squelch_en = 0 _mem.ctcss_enc_tone = 0x00 _mem.ctcss_dec_tone = 0x00 _mem.customctcss = 0x00 _mem.dtcs_encode_en = 0 _mem.dtcs_encode_code_highbit = 0 _mem.dtcs_encode_code = 0 _mem.dtcs_encode_invert = 0 _mem.dtcs_decode_en = 0 _mem.dtcs_decode_code_highbit = 0 _mem.dtcs_decode_code = 0 _mem.dtcs_decode_invert = 0 dtcs_pol_str_to_bit = {'N': 0, 'R': 1} _mem.dtcs_encode_invert = dtcs_pol_str_to_bit[mem.dtcs_polarity[0]] _mem.dtcs_decode_invert = dtcs_pol_str_to_bit[mem.dtcs_polarity[1]] if mem.tmode == 'Tone': _mem.ctcss_encode_en = 1 _mem.ctcss_enc_tone = ctcss_code_val_to_bits(mem.rtone) elif mem.tmode == 'TSQL': _mem.ctcss_encode_en = 1 _mem.ctcss_enc_tone = ctcss_code_val_to_bits(mem.ctone) _mem.ctcss_decode_en = 1 _mem.tone_squelch_en = 1 _mem.ctcss_dec_tone = ctcss_code_val_to_bits(mem.ctone) elif mem.tmode == 'DTCS': _mem.dtcs_encode_en = 1 _mem.dtcs_encode_code, _mem.dtcs_encode_code_highbit = \ dtcs_code_val_to_bits(mem.rx_dtcs) _mem.dtcs_decode_en = 1 _mem.dtcs_decode_code, _mem.dtcs_decode_code_highbit = \ dtcs_code_val_to_bits(mem.rx_dtcs) _mem.tone_squelch_en = 1 elif mem.tmode == 'Cross': txmode, rxmode = mem.cross_mode.split('->') if txmode == 'Tone': _mem.ctcss_encode_en = 1 _mem.ctcss_enc_tone = ctcss_code_val_to_bits(mem.rtone) elif txmode == '': pass elif txmode == 'DTCS': _mem.dtcs_encode_en = 1 _mem.dtcs_encode_code, _mem.dtcs_encode_code_highbit = \ dtcs_code_val_to_bits(mem.dtcs) else: LOG.error('%s: unhandled cross TX mode: %s' % ( mem.name, mem.cross_mode)) if rxmode == 'Tone': _mem.ctcss_decode_en = 1 _mem.tone_squelch_en = 1 _mem.ctcss_dec_tone = ctcss_code_val_to_bits(mem.ctone) elif rxmode == '': pass elif rxmode == 'DTCS': _mem.dtcs_decode_en = 1 _mem.dtcs_decode_code, _mem.dtcs_decode_code_highbit = \ dtcs_code_val_to_bits(mem.rx_dtcs) _mem.tone_squelch_en = 1 else: LOG.error('%s: unhandled cross RX mode: %s' % ( mem.name, mem.cross_mode)) else: LOG.error('%s: Unhandled tmode/cross %s/%s.' % (mem.name, mem.tmode, mem.cross_mode)) LOG.debug('%s: tmode=%s, cross=%s, rtone=%f, ctone=%f' % ( mem.name, mem.tmode, mem.cross_mode, mem.rtone, mem.ctone)) LOG.debug('%s: CENC=%d, CDEC=%d, t(enc)=%02x, t(dec)=%02x' % ( mem.name, _mem.ctcss_encode_en, _mem.ctcss_decode_en, ctcss_code_val_to_bits(mem.rtone), ctcss_code_val_to_bits(mem.ctone))) # set unknown defaults, based on reading memory set by vendor tool _mem.unknown1 = 0x00 _mem.unknown6 = 0x00 _mem.unknown7 = 0x00 _mem.unknown8 = 0x00 _mem.unknown9 = 0x00 # Extra settings (eg. Busy channel lockout) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): """Translate the MEM_FORMAT structs into setstuf in the UI""" _settings = self._memobj.settings _radio_settings = self._memobj.radio_settings _password = self._memobj.password _pfkeys = self._memobj.pfkeys _dtmf = self._memobj.dtmf # Function Setup function = RadioSettingGroup("function", "Function Setup") group = RadioSettings(function) # MODE SET # Channel Locked rs = RadioSettingValueBoolean(_settings.channelLocked) rset = RadioSetting("settings.channelLocked", "Channel locked", rs) function.append(rset) # Menu 3 - Display Mode options = ["Frequency", "Channel", "Name"] rs = RadioSettingValueList(options, options[_settings.displayMode]) rset = RadioSetting("settings.displayMode", "Display Mode", rs) function.append(rset) # VFO/MR A options = ["MR", "VFO"] rs = RadioSettingValueList(options, options[_radio_settings.vfomrA]) rset = RadioSetting("radio_settings.vfomrA", "VFO/MR mode A", rs) function.append(rset) # MR Channel A options = ["%s" % x for x in range(1, 201)] rs = RadioSettingValueList(options, options[_radio_settings.mrChanA]) rset = RadioSetting("radio_settings.mrChanA", "MR channel A", rs) function.append(rset) # VFO/MR B options = ["MR", "VFO"] rs = RadioSettingValueList(options, options[_radio_settings.vfomrB]) rset = RadioSetting("radio_settings.vfomrB", "VFO/MR mode B", rs) function.append(rset) # MR Channel B options = ["%s" % x for x in range(1, 201)] rs = RadioSettingValueList(options, options[_radio_settings.mrChanB]) rset = RadioSetting("radio_settings.mrChanB", "MR channel B", rs) function.append(rset) # DISPLAY SET # Starting Display name = "" for i in range(7): # 0 - 7 name += chr(int(self._memobj.starting_display.line[i])) name = name.upper().rstrip() # remove trailing spaces rs = RadioSettingValueString(0, 7, name) rs.set_charset(chirp_common.CHARSET_ALPHANUMERIC) rset = RadioSetting("starting_display.line", "Starting display", rs) function.append(rset) # Menu 11 - Backlight Brightness options = ["%s" % x for x in range(1, 4)] rs = RadioSettingValueList(options, options[_settings.backlightBr - 1]) rset = RadioSetting("settings.backlightBr", "Backlight brightness", rs) function.append(rset) # Menu 15 - Screen Direction options = ["Positive", "Inverted"] rs = RadioSettingValueList(options, options[_settings.screenDir]) rset = RadioSetting("settings.screenDir", "Screen direction", rs) function.append(rset) # Hand Mic Key Brightness options = ["%s" % x for x in range(1, 32)] rs = RadioSettingValueList(options, options[_settings.micKeyBrite - 1]) rset = RadioSetting("settings.micKeyBrite", "Hand mic key brightness", rs) function.append(rset) # VOL SET # Menu 1 - Beep Volume options = ["OFF"] + ["%s" % x for x in range(1, 6)] rs = RadioSettingValueList(options, options[_settings.beepVolume]) rset = RadioSetting("settings.beepVolume", "Beep volume", rs) function.append(rset) # Menu 5 - Volume level Setup options = ["%s" % x for x in range(1, 37)] rs = RadioSettingValueList(options, options[_settings.speakerVol - 1]) rset = RadioSetting("settings.speakerVol", "Speaker volume", rs) function.append(rset) # Menu 16 - Speaker Switch options = ["Host on | Hand mic off", "Host on | Hand mic on", "Host off | Hand mic on"] rs = RadioSettingValueList(options, options[_settings.speakerSwitch]) rset = RadioSetting("settings.speakerSwitch", "Speaker switch", rs) function.append(rset) # STE SET # STE Frequency options = ["Off", "55.2 Hz", "259.2 Hz"] rs = RadioSettingValueList(options, options[_settings.steFrequency]) rset = RadioSetting("settings.steFrequency", "STE frequency", rs) function.append(rset) # STE Type options = ["Off", "Silent", "120 degrees", "180 degrees", "240 degrees"] rs = RadioSettingValueList(options, options[_settings.steType]) rset = RadioSetting("settings.steType", "STE type", rs) function.append(rset) # ON/OFF SET # The Power-on Password feature is not available on models with VOX if not self.HAS_VOX: # Power-on Password rs = RadioSettingValueBoolean(_settings.powerOnPasswd) rset = RadioSetting("settings.powerOnPasswd", "Power-on Password", rs) function.append(rset) # Password def _char_to_str(chrx): """ Remove ff pads from char array """ # chrx is char array str1 = "" for sx in chrx: if int(sx) > 31 and int(sx) < 127: str1 += chr(int(sx)) return str1 def _pswd_vfy(setting, obj, atrb): """ Verify password is 1-6 chars, numbers 1-5 """ str1 = str(setting.value).strip() # initial # valid chars str2 = ''.join([c for c in str1 if c in '0123456789']) if str1 != str2: # Two lines due to python 73 char limit sx = "Bad characters in Password" raise errors.RadioError(sx) str2 = str1.ljust(6, chr(00)) # pad to 6 with 00's setattr(obj, atrb, str2) return sx = _char_to_str(_password.digits).strip() rx = RadioSettingValueString(0, 6, sx) sx = "Password (numerals 0-9)" rset = RadioSetting("password.digits", sx, rx) rset.set_apply_callback(_pswd_vfy, _password, "digits") function.append(rset) # Menu 9 - Auto Power On rs = RadioSettingValueBoolean(_settings.autoPowerOn) rset = RadioSetting("settings.autoPowerOn", "Auto power on", rs) function.append(rset) # Menu 13 - Auto Power Off options = ["Off", "30 minutes", "60 minutes", "120 minutes"] rs = RadioSettingValueList(options, options[_settings.autoPowerOff]) rset = RadioSetting("settings.autoPowerOff", "Auto power off", rs) function.append(rset) # Power On Reset Enable rs = RadioSettingValueBoolean(_settings.powerOnReset) rset = RadioSetting("settings.powerOnReset", "Power on reset", rs) function.append(rset) # FUNCTION SET # Menu 4 - Squelch Level A options = ["OFF"] + ["%s" % x for x in range(1, 10)] rs = RadioSettingValueList(options, options[_settings.squelchLevelA]) rset = RadioSetting("settings.squelchLevelA", "Squelch level A", rs) function.append(rset) # Squelch Level B options = ["OFF"] + ["%s" % x for x in range(1, 10)] rs = RadioSettingValueList(options, options[_settings.squelchLevelB]) rset = RadioSetting("settings.squelchLevelB", "Squelch level B", rs) function.append(rset) # Menu 7 - Scan Type options = ["Time operated (TO)", "Carrier operated (CO)", "Search (SE)"] rs = RadioSettingValueList(options, options[_settings.scanType]) rset = RadioSetting("settings.scanType", "Scan mode", rs) function.append(rset) # Menu 8 - Scan Recovery Time options = ["%s seconds" % x for x in range(5, 20, 5)] rs = RadioSettingValueList(options, options[_settings.scanRecoveryT]) rset = RadioSetting("settings.scanRecoveryT", "Scan recovery time", rs) function.append(rset) # Main options = ["A", "B"] rs = RadioSettingValueList(options, options[_settings.main]) rset = RadioSetting("settings.main", "Main", rs) function.append(rset) # Menu 10 - Dual Watch (RX Way Select) rs = RadioSettingValueBoolean(_settings.dualWatch) rset = RadioSetting("settings.dualWatch", "Dual watch", rs) function.append(rset) # Menu 12 - Time Out Timer options = ["OFF"] + ["%s minutes" % x for x in range(1, 31)] rs = RadioSettingValueList(options, options[_settings.timeOutTimer]) rset = RadioSetting("settings.timeOutTimer", "Time out timer", rs) function.append(rset) # TBST Frequency options = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] rs = RadioSettingValueList(options, options[_settings.tbstFrequency]) rset = RadioSetting("settings.tbstFrequency", "TBST frequency", rs) function.append(rset) # Save Channel Parameter rs = RadioSettingValueBoolean(_settings.saveChParameter) rset = RadioSetting("settings.saveChParameter", "Save channel parameter", rs) function.append(rset) # MON Key Function options = ["Squelch off momentary", "Squelch off"] rs = RadioSettingValueList(options, options[_settings.monKeyFunction]) rset = RadioSetting("settings.monKeyFunction", "MON key function", rs) function.append(rset) # Frequency Step options = ["2.5 kHz", "5 kHz", "6.25 kHz", "10 kHz", "12.5 kHz", "20 kHz", "25 kHz", "30 kHz", "50 kHz"] rs = RadioSettingValueList(options, options[_settings.frequencyStep]) rset = RadioSetting("settings.frequencyStep", "Frequency step", rs) function.append(rset) # Knob Mode options = ["Volume", "Channel"] rs = RadioSettingValueList(options, options[_settings.knobMode]) rset = RadioSetting("settings.knobMode", "Knob mode", rs) function.append(rset) # TRF Enable rs = RadioSettingValueBoolean(_settings.trfEnable) rset = RadioSetting("settings.trfEnable", "TRF enable", rs) function.append(rset) if self.HAS_VOX: # VOX On/Off rs = RadioSettingValueBoolean(_settings.voxOnOff) rset = RadioSetting("settings.voxOnOff", "VOX", rs) function.append(rset) # VOX Delay options = ["0.5 S", "1.0 S", "1.5 S", "2.0 S", "2.5 S", "3.0 S", "3.5 S", "4.0 S", "4.5 S"] rs = RadioSettingValueList(options, options[_settings.voxDelay]) rset = RadioSetting("settings.voxDelay", "VOX delay", rs) function.append(rset) # VOX Level options = ["%s" % x for x in range(1, 10)] rs = RadioSettingValueList(options, options[_settings.voxLevel]) rset = RadioSetting("settings.voxLevel", "VOX Level", rs) function.append(rset) # Key Assignment pfkeys = RadioSettingGroup("pfkeys", "Key Assignment") group.append(pfkeys) options = ["A/B", "V/M", "SQL", "VOL", "POW", "CDT", "REV", "SCN", "CAL", "TALK", "BND", "SFT", "MON", "DIR", "TRF", "RDW", "NULL"] if self.HAS_VOX: options.insert(16, "VOX") # Key Mode 1 # P1 rs = RadioSettingValueList(options, options[_pfkeys.keyMode1P1 - 1]) rset = RadioSetting("pfkeys.keyMode1P1", "Key mode 1 P1", rs) pfkeys.append(rset) # P2 rs = RadioSettingValueList(options, options[_pfkeys.keyMode1P2 - 1]) rset = RadioSetting("pfkeys.keyMode1P2", "Key mode 1 P2", rs) pfkeys.append(rset) # P3 rs = RadioSettingValueList(options, options[_pfkeys.keyMode1P3 - 1]) rset = RadioSetting("pfkeys.keyMode1P3", "Key mode 1 P3", rs) pfkeys.append(rset) # P4 rs = RadioSettingValueList(options, options[_pfkeys.keyMode1P4 - 1]) rset = RadioSetting("pfkeys.keyMode1P4", "Key mode 1 P4", rs) pfkeys.append(rset) # P5 rs = RadioSettingValueList(options, options[_pfkeys.keyMode1P5 - 1]) rset = RadioSetting("pfkeys.keyMode1P5", "Key mode 1 P5", rs) pfkeys.append(rset) # P6 rs = RadioSettingValueList(options, options[_pfkeys.keyMode1P6 - 1]) rset = RadioSetting("pfkeys.keyMode1P6", "Key mode 1 P6", rs) pfkeys.append(rset) # Key Mode 2 # P1 rs = RadioSettingValueList(options, options[_pfkeys.keyMode2P1 - 1]) rset = RadioSetting("pfkeys.keyMode2P1", "Key mode 2 P1", rs) pfkeys.append(rset) # P2 rs = RadioSettingValueList(options, options[_pfkeys.keyMode2P2 - 1]) rset = RadioSetting("pfkeys.keyMode2P2", "Key mode 2 P2", rs) pfkeys.append(rset) # P3 rs = RadioSettingValueList(options, options[_pfkeys.keyMode2P3 - 1]) rset = RadioSetting("pfkeys.keyMode2P3", "Key mode 2 P3", rs) pfkeys.append(rset) # P4 rs = RadioSettingValueList(options, options[_pfkeys.keyMode2P4 - 1]) rset = RadioSetting("pfkeys.keyMode2P4", "Key mode 2 P4", rs) pfkeys.append(rset) # P5 rs = RadioSettingValueList(options, options[_pfkeys.keyMode2P5 - 1]) rset = RadioSetting("pfkeys.keyMode2P5", "Key mode 2 P5", rs) pfkeys.append(rset) # P6 rs = RadioSettingValueList(options, options[_pfkeys.keyMode2P6 - 1]) rset = RadioSetting("pfkeys.keyMode2P6", "Key mode 2 P6", rs) pfkeys.append(rset) options = ["V/M", "SQL", "VOL", "POW", "CDT", "REV", "SCN", "CAL", "TALK", "BND", "SFT", "MON", "DIR", "TRF", "RDW"] if self.HAS_VOX: options.insert(15, "VOX") # PA rs = RadioSettingValueList(options, options[_settings.keyPA - 2]) rset = RadioSetting("settings.keyPA", "Key PA", rs) pfkeys.append(rset) # PB rs = RadioSettingValueList(options, options[_settings.keyPB - 2]) rset = RadioSetting("settings.keyPB", "Key PB", rs) pfkeys.append(rset) # PC rs = RadioSettingValueList(options, options[_settings.keyPC - 2]) rset = RadioSetting("settings.keyPC", "Key PC", rs) pfkeys.append(rset) # PD rs = RadioSettingValueList(options, options[_settings.keyPD - 2]) rset = RadioSetting("settings.keyPD", "Key PD", rs) pfkeys.append(rset) # DTMF dtmf = RadioSettingGroup("dtmf", "DTMF") group.append(dtmf) # DTMF Transmitting Time options = ["50 milliseconds", "100 milliseconds", "200 milliseconds", "300 milliseconds", "500 milliseconds"] rs = RadioSettingValueList(options, options[_settings.dtmfTxTime]) rset = RadioSetting("settings.dtmfTxTime", "DTMF transmitting time", rs) dtmf.append(rset) # DTMF Self ID # DTMF Interval Character IC_CHOICES = ["A", "B", "C", "D", "*", "#"] IC_VALUES = [0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F] def apply_ic_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = IC_CHOICES.index(val) val = IC_VALUES[index] obj.set_value(val) if _dtmf.intervalChar in IC_VALUES: idx = IC_VALUES.index(_dtmf.intervalChar) else: idx = IC_VALUES.index(0x0E) rs = RadioSetting("dtmf.intervalChar", "DTMF interval character", RadioSettingValueList(IC_CHOICES, IC_CHOICES[idx])) rs.set_apply_callback(apply_ic_listvalue, _dtmf.intervalChar) dtmf.append(rs) # Group Code GC_CHOICES = ["Off", "A", "B", "C", "D", "*", "#"] GC_VALUES = [0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F] def apply_gc_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = GC_CHOICES.index(val) val = GC_VALUES[index] obj.set_value(val) if _dtmf.groupCode in GC_VALUES: idx = GC_VALUES.index(_dtmf.groupCode) else: idx = GC_VALUES.index(0x0A) rs = RadioSetting("dtmf.groupCode", "DTMF interval character", RadioSettingValueList(GC_CHOICES, GC_CHOICES[idx])) rs.set_apply_callback(apply_gc_listvalue, _dtmf.groupCode) dtmf.append(rs) # Decoding Response options = ["None", "Beep tone", "Beep tone & respond"] rs = RadioSettingValueList(options, options[_dtmf.decodingResponse]) rset = RadioSetting("dtmf.decodingResponse", "Decoding response", rs) dtmf.append(rset) # First Digit Time options = ["%s" % x for x in range(0, 2510, 10)] rs = RadioSettingValueList(options, options[_dtmf.firstDigitTime]) rset = RadioSetting("dtmf.firstDigitTime", "First Digit Time(ms)", rs) dtmf.append(rset) # First Digit Time options = ["%s" % x for x in range(10, 2510, 10)] rs = RadioSettingValueList(options, options[_dtmf.pretime - 1]) rset = RadioSetting("dtmf.pretime", "Pretime(ms)", rs) dtmf.append(rset) # Auto Reset Time options = ["%s" % x for x in range(0, 25100, 100)] rs = RadioSettingValueList(options, options[_dtmf.autoResetTime]) rset = RadioSetting("dtmf.autoResetTime", "Auto Reset time(ms)", rs) dtmf.append(rset) # Time-Lapse After Encode options = ["%s" % x for x in range(10, 2510, 10)] rs = RadioSettingValueList(options, options[_dtmf.timeLapse - 1]) rset = RadioSetting("dtmf.timeLapse", "Time-lapse after encode(ms)", rs) dtmf.append(rset) # PTT ID Pause Time options = ["Off", "-", "-", "-", "-"] + [ "%s" % x for x in range(5, 76)] rs = RadioSettingValueList(options, options[_dtmf.pauseTime]) rset = RadioSetting("dtmf.pauseTime", "PTT ID pause time(s)", rs) dtmf.append(rset) # Side Tone rs = RadioSettingValueBoolean(_dtmf.sideTone) rset = RadioSetting("dtmf.sideTone", "Side tone", rs) dtmf.append(rset) # PTT ID Starting DTMF_CHARS = "0123456789ABCD*# " _codeobj = _dtmf.pttIdStart _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 16, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("dtmf.pttIdStart", "PTT ID starting", val) def apply_code(setting, obj): code = [] for j in range(0, 16): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.pttIdStart = code rs.set_apply_callback(apply_code, _dtmf) dtmf.append(rs) # PTT ID Ending _codeobj = _dtmf.pttIdEnd _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 16, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("dtmf.pttIdEnd", "PTT ID ending", val) def apply_code(setting, obj): code = [] for j in range(0, 16): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.pttIdEnd = code rs.set_apply_callback(apply_code, _dtmf) dtmf.append(rs) # Remotely Kill _codeobj = _dtmf.remoteKill _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 16, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("dtmf.remoteKill", "Remotely kill", val) def apply_code(setting, obj): code = [] for j in range(0, 16): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.remoteKill = code rs.set_apply_callback(apply_code, _dtmf) dtmf.append(rs) # Remotely Stun _codeobj = _dtmf.remoteStun _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 16, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("dtmf.remoteStun", "Remotely stun", val) def apply_code(setting, obj): code = [] for j in range(0, 16): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.remoteStun = code rs.set_apply_callback(apply_code, _dtmf) dtmf.append(rs) # DTMF Encode # M1 - M16 for i in range(0, 16): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 16, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("pttid/%i.code" % i, "DTMF encode M%i" % (i + 1), val) def apply_code(setting, obj): code = [] for j in range(0, 16): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.pttid[i]) dtmf.append(rs) return group def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "timeLapse": setattr(obj, setting, int(element.value) + 1) elif setting == "pretime": setattr(obj, setting, int(element.value) + 1) elif setting == "backlightBr": setattr(obj, setting, int(element.value) + 1) elif setting == "micKeyBrite": setattr(obj, setting, int(element.value) + 1) elif setting == "speakerVol": setattr(obj, setting, int(element.value) + 1) elif "keyMode" in setting: setattr(obj, setting, int(element.value) + 1) elif "keyP" in setting: setattr(obj, setting, int(element.value) + 2) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise # Original non-VOX models if has_future: @directory.register class AnyTone778UV(AnyTone778UVBase): VENDOR = "AnyTone" MODEL = "778UV" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'AT778UV': ['V100', 'V200']} @directory.register class RetevisRT95(AnyTone778UVBase): VENDOR = "Retevis" MODEL = "RT95" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'RT95': ['V100']} @directory.register class CRTMicronUV(AnyTone778UVBase): VENDOR = "CRT" MODEL = "Micron UV" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'MICRON': ['V100']} @directory.register class MidlandDBR2500(AnyTone778UVBase): VENDOR = "Midland" MODEL = "DBR2500" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'DBR2500': ['V100']} @directory.register class YedroYCM04vus(AnyTone778UVBase): VENDOR = "Yedro" MODEL = "YC-M04VUS" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'YCM04UV': ['V100']} class AnyTone778UVvoxBase(AnyTone778UVBase): '''AnyTone 778UV VOX, Retevis RT95 VOX and others''' NAME_LENGTH = 6 HAS_VOX = True # New VOX models if has_future: @directory.register class AnyTone778UVvox(AnyTone778UVvoxBase): VENDOR = "AnyTone" MODEL = "778UV VOX" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'778UV-P': ['V100']} @directory.register class RetevisRT95vox(AnyTone778UVvoxBase): VENDOR = "Retevis" MODEL = "RT95 VOX" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'RT95-P': ['V100']} @directory.register class CRTMicronUVvox(AnyTone778UVvoxBase): VENDOR = "CRT" MODEL = "Micron UV V2" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'MICRONP': ['V100']} chirp-20240224/chirp/drivers/vx5.py0000644000175000017500000002614014430171343015716 0ustar hibbyhibby# Copyright 2011 Dan Smith # Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, errors, bitwise MEM_FORMAT = """ struct mem_struct { u8 unknown1:2, half_deviation:1, cpu_shift:1, unknown2:1, sp_rx1:1, unknown3:1, sp_rx2:1; u8 unknown4:4, tuning_step:4; bbcd freq[3]; u8 icon:6, mode:2; char name[8]; bbcd offset[3]; u8 tmode:4, power:2, duplex:2; u8 unknown5:2, tone:6; u8 unknown6:1, dtcs:7; u8 unknown7; u8 unknown8; }; struct flag_struct { u8 zeros:4, pskip:1, skip:1, visible:1, used:1; }; #seekto 0x002A; struct { u8 current_member; } bank_used[5]; #seekto 0x0032; struct { struct { u8 status; u8 channel; } members[24]; } bank_groups[5]; #seekto 0x012A; struct flag_struct flag[220]; struct flag_struct specialflag[20]; #seekto 0x026A; struct mem_struct memory[220]; struct mem_struct special[50]; #seekto 0x1D03; u8 current_bank; """ TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+", "split"] MODES = ["FM", "AM", "WFM"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00), chirp_common.PowerLevel("L3", watts=2.50), chirp_common.PowerLevel("L2", watts=1.00), chirp_common.PowerLevel("L1", watts=0.05)] SPECIALS = ["%s%d" % (c, i + 1) for i in range(0, 10) for c in ('L', 'U')] class VX5BankModel(chirp_common.BankModel): def get_num_mappings(self): return 5 def get_mappings(self): banks = [] for i in range(0, self.get_num_mappings()): bank = chirp_common.Bank(self, "%i" % (i+1), "MG%i" % (i+1)) bank.index = i banks.append(bank) return banks def add_memory_to_mapping(self, memory, bank): _members = self._radio._memobj.bank_groups[bank.index].members _bank_used = self._radio._memobj.bank_used[bank.index] for i in range(0, len(_members)): if _members[i].status == 0xFF: # LOG.debug("empty found, inserting %d at %d" % # (memory.number, i)) if self._radio._memobj.current_bank == 0xFF: self._radio._memobj.current_bank = bank.index _members[i].status = 0x00 _members[i].channel = memory.number - 1 _bank_used.current_member = i return True raise Exception(_("{bank} is full").format(bank=bank)) def remove_memory_from_mapping(self, memory, bank): _members = self._radio._memobj.bank_groups[bank.index].members _bank_used = self._radio._memobj.bank_used[bank.index] found = False remaining_members = 0 for i in range(0, len(_members)): if _members[i].status == 0x00: if _members[i].channel == (memory.number - 1): _members[i].status = 0xFF found = True else: remaining_members += 1 if not found: raise Exception(_("Memory {num} not in " "bank {bank}").format(num=memory.number, bank=bank)) if not remaining_members: _bank_used.current_member = 0xFF def get_mapping_memories(self, bank): memories = [] _members = self._radio._memobj.bank_groups[bank.index].members _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.current_member == 0xFF: return memories for member in _members: if member.status == 0xFF: continue memories.append(self._radio.get_memory(member.channel+1)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in [x.number for x in self.get_mapping_memories(bank)]: banks.append(bank) return banks @directory.register class VX5Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu VX-5""" BAUD_RATE = 9600 VENDOR = "Yaesu" MODEL = "VX-5" _model = "" _memsize = 8123 _block_lengths = [10, 16, 8097] _block_size = 8 def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x1FB9, 0x1FBA)] def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = True rf.has_bank = True rf.has_ctone = False rf.has_dtcs_polarity = False rf.valid_modes = MODES + ["NFM"] rf.valid_tmodes = TMODES rf.valid_tuning_steps = STEPS rf.valid_duplexes = DUPLEX rf.memory_bounds = (1, 220) rf.valid_bands = [(500000, 16000000), (48000000, 729000000), (800000000, 999000000)] rf.valid_skips = ["", "S", "P"] rf.valid_power_levels = POWER_LEVELS rf.valid_name_length = 8 rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_special_chans = SPECIALS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def get_memory(self, number): mem = chirp_common.Memory() if isinstance(number, str): mem.number = len(self._memobj.memory) + SPECIALS.index(number) + 1 mem.extd_number = number _mem = self._memobj.special[mem.number - len(self._memobj.memory) - 1] _flg = self._memobj.specialflag[mem.number - len(self._memobj.memory) - 1] elif number > len(self._memobj.memory): mem.number = number mem.extd_number = SPECIALS[number - len(self._memobj.memory) - 1] _mem = self._memobj.special[mem.number - len(self._memobj.memory) - 1] _flg = self._memobj.specialflag[mem.number - len(self._memobj.memory) - 1] else: mem.number = number _mem = self._memobj.memory[mem.number - 1] _flg = self._memobj.flag[mem.number - 1] if not _flg.visible: mem.empty = True if not _flg.used: mem.empty = True return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.duplex = DUPLEX[_mem.duplex] mem.name = self.filter_name(str(_mem.name).rstrip()) mem.mode = MODES[_mem.mode] if mem.mode == "FM" and _mem.half_deviation: mem.mode = "NFM" mem.tuning_step = STEPS[_mem.tuning_step] mem.offset = int(_mem.offset) * 1000 mem.power = POWER_LEVELS[3 - _mem.power] mem.tmode = TMODES[_mem.tmode & 0x3] # masked so bad mems can be read if mem.duplex == "split": mem.offset = chirp_common.fix_rounded_step(mem.offset) mem.rtone = mem.ctone = chirp_common.OLD_TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.skip = _flg.pskip and "P" or _flg.skip and "S" or "" return mem def set_memory(self, mem): if mem.number > len(self._memobj.memory): _mem = self._memobj.special[mem.number - len(self._memobj.memory) - 1] _flg = self._memobj.specialflag[mem.number - len(self._memobj.memory) - 1] else: _mem = self._memobj.memory[mem.number - 1] _flg = self._memobj.flag[mem.number - 1] # initialize new channel to safe defaults if not mem.empty and not _flg.used: _flg.used = True _mem.unknown1 = 0x00 _mem.unknown2 = 0x0 _mem.unknown3 = 0x0 _mem.unknown4 = 0x0000 _mem.unknown5 = 0x0 _mem.unknown6 = 0x0 _mem.unknown7 = 0x00 _mem.unknown8 = 0x00 _mem.cpu_shift = 0x0 _mem.sp_rx1 = 0x0 _mem.sp_rx2 = 0x0 _mem.icon = 12 # file cabinet icon if mem.empty and _flg.used and not _flg.visible: _flg.used = False return _flg.visible = not mem.empty if mem.empty: self._wipe_memory_banks(mem) return _mem.freq = int(mem.freq / 1000) _mem.duplex = DUPLEX.index(mem.duplex) _mem.name = mem.name.ljust(8) if mem.mode == "NFM": _mem.mode = MODES.index("FM") _mem.half_deviation = 1 else: _mem.mode = MODES.index(mem.mode) _mem.half_deviation = 0 _mem.tuning_step = STEPS.index(mem.tuning_step) _mem.offset = int(mem.offset / 1000) if mem.power: _mem.power = 3 - POWER_LEVELS.index(mem.power) else: _mem.power = 0 _mem.tmode = TMODES.index(mem.tmode) try: _mem.tone = chirp_common.OLD_TONES.index(mem.rtone) except ValueError: raise errors.UnsupportedToneError( ("This radio does not support tone %s" % mem.rtone)) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _flg.skip = mem.skip == "S" _flg.pskip = mem.skip == "P" @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to MIC/EAR jack.\n" "3. Press and hold in the [F/W] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. After clicking OK, press the [VFO(DW)SC] key to" " receive\n" " the image from the radio.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to MIC/EAR jack.\n" "3. Press and hold in the [F/W] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. Press the [MR(SKP)SC] key (\"CLONE WAIT\" will appear\n" " on the LCD).\n" "5. Click OK to send image to radio.\n") return rp @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize def get_bank_model(self): return VX5BankModel(self) chirp-20240224/chirp/drivers/uvb5.py0000644000175000017500000006403514522657251016073 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from __future__ import division import struct import logging from chirp import chirp_common, directory, bitwise, memmap, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) mem_format = """ struct memory { lbcd freq[4]; lbcd offset[4]; u8 unknown1:2, txpol:1, rxpol:1, compander:1, unknown2:3; u8 rxtone; u8 txtone; u8 pttid:1, scanadd:1, isnarrow:1, bcl:1, highpower:1, revfreq:1, duplex:2; u8 step; u8 unknown[3]; }; #seekto 0x0000; char ident[32]; u8 blank[16]; struct memory vfo1; struct memory channels[99]; #seekto 0x0850; struct memory vfo2; #seekto 0x09D0; u16 fm_presets[16]; #seekto 0x0A30; struct { u8 name[5]; } names[99]; #seekto 0x0D30; struct { u8 squelch; u8 freqmode_ab:1, save_funct:1, backlight:1, beep_tone_disabled:1, roger:1, tdr:1, scantype:2; u8 language:1, workmode_b:1, workmode_a:1, workmode_fm:1, voice_prompt:1, fm:1, pttid:2; u8 unknown_0:5, timeout:3; u8 mdf_b:2, mdf_a:2, unknown_1:2, txtdr:2; u8 unknown_2:4, ste_disabled:1, unknown_3:2, sidetone:1; u8 vox; u8 unk1; u8 mem_chan_a; u16 fm_vfo; u8 unk4; u8 unk5; u8 mem_chan_b; u8 unk6; u8 last_menu; // number of last menu item accessed } settings; #seekto 0x0D50; struct { u8 code[6]; } pttid; #seekto 0x0F30; struct { lbcd lower_vhf[2]; lbcd upper_vhf[2]; lbcd lower_uhf[2]; lbcd upper_uhf[2]; } limits; #seekto 0x0FF0; struct { u8 vhfsquelch0; u8 vhfsquelch1; u8 vhfsquelch2; u8 vhfsquelch3; u8 vhfsquelch4; u8 vhfsquelch5; u8 vhfsquelch6; u8 vhfsquelch7; u8 vhfsquelch8; u8 vhfsquelch9; u8 unknown1[6]; u8 uhfsquelch0; u8 uhfsquelch1; u8 uhfsquelch2; u8 uhfsquelch3; u8 uhfsquelch4; u8 uhfsquelch5; u8 uhfsquelch6; u8 uhfsquelch7; u8 uhfsquelch8; u8 uhfsquelch9; u8 unknown2[6]; u8 vhfhipwr0; u8 vhfhipwr1; u8 vhfhipwr2; u8 vhfhipwr3; u8 vhfhipwr4; u8 vhfhipwr5; u8 vhfhipwr6; u8 vhfhipwr7; u8 vhflopwr0; u8 vhflopwr1; u8 vhflopwr2; u8 vhflopwr3; u8 vhflopwr4; u8 vhflopwr5; u8 vhflopwr6; u8 vhflopwr7; u8 uhfhipwr0; u8 uhfhipwr1; u8 uhfhipwr2; u8 uhfhipwr3; u8 uhfhipwr4; u8 uhfhipwr5; u8 uhfhipwr6; u8 uhfhipwr7; u8 uhflopwr0; u8 uhflopwr1; u8 uhflopwr2; u8 uhflopwr3; u8 uhflopwr4; u8 uhflopwr5; u8 uhflopwr6; u8 uhflopwr7; } test; """ def do_ident(radio): radio.pipe.timeout = 3 radio.pipe.write(b"\x05PROGRAM") for x in range(10): ack = radio.pipe.read(1) if ack == b'\x06': break else: raise errors.RadioError("Radio did not ack programming mode") radio.pipe.write(b"\x02") ident = radio.pipe.read(8) LOG.debug(util.hexprint(ident)) if not ident.startswith(b'HKT511'): raise errors.RadioError("Unsupported model") radio.pipe.write(b"\x06") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio did not ack ident") def do_status(radio, direction, addr): status = chirp_common.Status() status.msg = "Cloning %s radio" % direction status.cur = addr status.max = 0x1000 radio.status_fn(status) def do_download(radio): do_ident(radio) data = b"KT511 Radio Program data v1.08\x00\x00" data += (b"\x00" * 16) firstack = None for i in range(0, 0x1000, 16): frame = struct.pack(">cHB", b"R", i, 16) radio.pipe.write(frame) result = radio.pipe.read(20) if frame[1:4] != result[1:4]: LOG.debug(util.hexprint(result)) raise errors.RadioError("Invalid response for address 0x%04x" % i) radio.pipe.write(b"\x06") ack = radio.pipe.read(1) if not firstack: firstack = ack else: if not ack == firstack: LOG.debug("first ack: %s ack received: %s", util.hexprint(firstack), util.hexprint(ack)) raise errors.RadioError("Unexpected response") data += result[4:] do_status(radio, "from", i) return memmap.MemoryMapBytes(data) def do_upload(radio): do_ident(radio) data = radio._mmap.get_byte_compatible()[0x0030:] for i in range(0, 0x1000, 16): frame = struct.pack(">cHB", b"W", i, 16) frame += data[i:i + 16] radio.pipe.write(frame) ack = radio.pipe.read(1) if ack != b"\x06": # UV-B5/UV-B6 radios with 27 menus do not support service settings # and will stop ACKing when the upload reaches 0x0F10 if i == 0x0F10: # must be a radio with 27 menus detected - stop upload break else: LOG.debug("Radio NAK'd block at address 0x%04x" % i) raise errors.RadioError( "Radio NAK'd block at address 0x%04x" % i) LOG.debug("Radio ACK'd block at address 0x%04x" % i) do_status(radio, "to", i) DUPLEX = ["", "-", "+"] UVB5_STEPS = [5.00, 6.25, 10.0, 12.5, 20.0, 25.0] CHARSET = "0123456789- ABCDEFGHIJKLMNOPQRSTUVWXYZ/_+*" POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1), chirp_common.PowerLevel("High", watts=5)] @directory.register class BaofengUVB5(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Baofeng UV-B5""" VENDOR = "Baofeng" MODEL = "UV-B5" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False SPECIALS = { "VFO1": -2, "VFO2": -1, } _memsize = 0x1000 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This version of the UV-B5 driver allows you to ' 'modify the Test Mode settings of your radio. This has been ' 'tested and reports from other users indicate that it is a ' 'safe thing to do. However, modifications to these values may ' 'have unintended consequences, including damage to your ' 'device. You have been warned. Proceed at your own risk!') rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on.\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to download image from device.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on.\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to upload image to device.\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_cross = True rf.has_rx_dtcs = True rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_duplexes = DUPLEX + ["split"] rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_characters = CHARSET rf.valid_name_length = 5 rf.valid_tuning_steps = UVB5_STEPS rf.valid_bands = [(130000000, 175000000), (220000000, 269000000), (400000000, 520000000)] rf.valid_modes = ["FM", "NFM"] rf.valid_special_chans = list(self.SPECIALS.keys()) rf.valid_power_levels = POWER_LEVELS rf.has_ctone = True rf.has_bank = False rf.has_tuning_step = False rf.memory_bounds = (1, 99) return rf def sync_in(self): try: self._mmap = do_download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: do_upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.channels[number - 1]) def _decode_tone(self, _mem, which): def _get(field): return getattr(_mem, "%s%s" % (which, field)) value = _get('tone') flag = _get('pol') if value > 155: mode = val = pol = None elif value > 50: mode = 'DTCS' val = chirp_common.DTCS_CODES[value - 51] pol = flag and 'R' or 'N' elif value: mode = 'Tone' val = chirp_common.TONES[value - 1] pol = None else: mode = val = pol = None return mode, val, pol def _encode_tone(self, _mem, which, mode, val, pol): def _set(field, value): setattr(_mem, "%s%s" % (which, field), value) _set("pol", 0) if mode == "Tone": _set("tone", chirp_common.TONES.index(val) + 1) elif mode == "DTCS": _set("tone", chirp_common.DTCS_CODES.index(val) + 51) _set("pol", pol == "R") else: _set("tone", 0) def _get_memobjs(self, number): if isinstance(number, str): return (getattr(self._memobj, number.lower()), None) elif number < 0: for k, v in list(self.SPECIALS.items()): if number == v: return (getattr(self._memobj, k.lower()), None) else: return (self._memobj.channels[number - 1], self._memobj.names[number - 1].name) def get_memory(self, number): _mem, _nam = self._get_memobjs(number) mem = chirp_common.Memory() if isinstance(number, str): mem.number = self.SPECIALS[number] mem.extd_number = number else: mem.number = number if _mem.freq.get_raw()[0] == 0xff: mem.empty = True return mem mem.freq = int(_mem.freq) * 10 mem.offset = int(_mem.offset) * 10 chirp_common.split_tone_decode( mem, self._decode_tone(_mem, "tx"), self._decode_tone(_mem, "rx")) if 'step' in _mem and _mem.step > 0x05: _mem.step = 0x00 mem.duplex = DUPLEX[_mem.duplex] mem.mode = _mem.isnarrow and "NFM" or "FM" mem.skip = "" if _mem.scanadd else "S" mem.power = POWER_LEVELS[_mem.highpower] if _nam: for char in _nam: try: mem.name += CHARSET[char] except IndexError: break mem.name = mem.name.rstrip() mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("revfreq", "Reverse Duplex", RadioSettingValueBoolean(_mem.revfreq)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueBoolean(_mem.pttid)) mem.extra.append(rs) rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(_mem.compander)) mem.extra.append(rs) return mem def set_memory(self, mem): _mem, _nam = self._get_memobjs(mem.number) if mem.empty: if _nam is None: raise errors.InvalidValueError("VFO channels can not be empty") _mem.set_raw("\xFF" * 16) return if _mem.get_raw(asbytes=False) == ("\xFF" * 16): _mem.set_raw("\x00" * 13 + "\xFF" * 3) _mem.freq = mem.freq / 10 if mem.duplex == "split": diff = mem.offset - mem.freq _mem.duplex = DUPLEX.index("-") if diff < 0 else DUPLEX.index("+") _mem.offset = abs(diff) / 10 else: _mem.offset = mem.offset / 10 _mem.duplex = DUPLEX.index(mem.duplex) tx, rx = chirp_common.split_tone_encode(mem) self._encode_tone(_mem, 'tx', *tx) self._encode_tone(_mem, 'rx', *rx) _mem.isnarrow = mem.mode == "NFM" _mem.scanadd = mem.skip == "" _mem.highpower = mem.power == POWER_LEVELS[1] if _nam: for i in range(0, 5): try: _nam[i] = CHARSET.index(mem.name[i]) except IndexError: _nam[i] = 0xFF for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) options = ["Time", "Carrier", "Search"] rs = RadioSetting("scantype", "Scan Type", RadioSettingValueList(options, options[_settings.scantype])) basic.append(rs) options = ["Off"] + ["%s min" % x for x in range(1, 8)] rs = RadioSetting("timeout", "Time Out Timer", RadioSettingValueList( options, options[_settings.timeout])) basic.append(rs) options = ["A", "B"] rs = RadioSetting("freqmode_ab", "Frequency Mode", RadioSettingValueList( options, options[_settings.freqmode_ab])) basic.append(rs) options = ["Frequency Mode", "Channel Mode"] rs = RadioSetting("workmode_a", "Radio Work Mode(A)", RadioSettingValueList( options, options[_settings.workmode_a])) basic.append(rs) rs = RadioSetting("workmode_b", "Radio Work Mode(B)", RadioSettingValueList( options, options[_settings.workmode_b])) basic.append(rs) options = ["Frequency", "Name", "Channel"] rs = RadioSetting("mdf_a", "Display Format(F1)", RadioSettingValueList( options, options[_settings.mdf_a])) basic.append(rs) rs = RadioSetting("mdf_b", "Display Format(F2)", RadioSettingValueList( options, options[_settings.mdf_b])) basic.append(rs) rs = RadioSetting("mem_chan_a", "Mem Channel (A)", RadioSettingValueInteger( 1, 99, _settings.mem_chan_a)) basic.append(rs) rs = RadioSetting("mem_chan_b", "Mem Channel (B)", RadioSettingValueInteger( 1, 99, _settings.mem_chan_b)) basic.append(rs) options = ["Off", "BOT", "EOT", "Both"] rs = RadioSetting("pttid", "PTT-ID", RadioSettingValueList( options, options[_settings.pttid])) basic.append(rs) dtmfchars = "0123456789ABCD*#" _codeobj = self._memobj.pttid.code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("pttid.code", "PTT-ID Code", val) def apply_code(setting, obj): code = [] for j in range(0, 6): try: code.append(dtmfchars.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.pttid) basic.append(rs) rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("vox", "VOX Level", RadioSettingValueInteger(0, 9, _settings.vox)) basic.append(rs) options = ["Frequency Mode", "Channel Mode"] rs = RadioSetting("workmode_fm", "FM Work Mode", RadioSettingValueList( options, options[_settings.workmode_fm])) basic.append(rs) options = ["Current Frequency", "F1 Frequency", "F2 Frequency"] rs = RadioSetting("txtdr", "Dual Standby TX Priority", RadioSettingValueList(options, options[_settings.txtdr])) basic.append(rs) options = ["English", "Chinese"] rs = RadioSetting("language", "Language", RadioSettingValueList(options, options[_settings.language])) basic.append(rs) rs = RadioSetting("tdr", "Dual Standby", RadioSettingValueBoolean(_settings.tdr)) basic.append(rs) rs = RadioSetting("roger", "Roger Beep", RadioSettingValueBoolean(_settings.roger)) basic.append(rs) rs = RadioSetting("backlight", "Backlight", RadioSettingValueBoolean(_settings.backlight)) basic.append(rs) rs = RadioSetting("save_funct", "Save Mode", RadioSettingValueBoolean(_settings.save_funct)) basic.append(rs) rs = RadioSetting("fm", "FM Function", RadioSettingValueBoolean(_settings.fm)) basic.append(rs) rs = RadioSetting("beep_tone_disabled", "Beep Prompt", RadioSettingValueBoolean( not _settings.beep_tone_disabled)) basic.append(rs) rs = RadioSetting("voice_prompt", "Voice Prompt", RadioSettingValueBoolean(_settings.voice_prompt)) basic.append(rs) rs = RadioSetting("sidetone", "DTMF Side Tone", RadioSettingValueBoolean(_settings.sidetone)) basic.append(rs) rs = RadioSetting("ste_disabled", "Squelch Tail Eliminate", RadioSettingValueBoolean(not _settings.ste_disabled)) basic.append(rs) _limit = int(self._memobj.limits.lower_vhf) // 10 rs = RadioSetting("limits.lower_vhf", "VHF Lower Limit (MHz)", RadioSettingValueInteger(128, 270, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.lower_vhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) _limit = int(self._memobj.limits.upper_vhf) // 10 rs = RadioSetting("limits.upper_vhf", "VHF Upper Limit (MHz)", RadioSettingValueInteger(128, 270, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.upper_vhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) _limit = int(self._memobj.limits.lower_uhf) // 10 rs = RadioSetting("limits.lower_uhf", "UHF Lower Limit (MHz)", RadioSettingValueInteger(400, 520, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.lower_uhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) _limit = int(self._memobj.limits.upper_uhf) // 10 rs = RadioSetting("limits.upper_uhf", "UHF Upper Limit (MHz)", RadioSettingValueInteger(400, 520, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.upper_uhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) fm_preset = RadioSettingGroup("fm_preset", "FM Radio Presets") group.append(fm_preset) for i in range(0, 16): if self._memobj.fm_presets[i] < 0x01AF: used = True preset = self._memobj.fm_presets[i] / 10.0 + 65 else: used = False preset = 65 rs = RadioSetting("fm_presets_%1i" % i, "FM Preset %i" % (i + 1), RadioSettingValueBoolean(used), RadioSettingValueFloat(65, 108, preset, 0.1, 1)) fm_preset.append(rs) testmode = RadioSettingGroup("testmode", "Test Mode Settings") group.append(testmode) vhfdata = ["136-139", "140-144", "145-149", "150-154", "155-159", "160-164", "165-169", "170-174"] uhfdata = ["400-409", "410-419", "420-429", "430-439", "440-449", "450-459", "460-469", "470-479"] powernamedata = ["Hi", "Lo"] powerkeydata = ["hipwr", "lopwr"] for power in range(0, 2): for index in range(0, 8): key = "test.vhf%s%i" % (powerkeydata[power], index) name = "%s MHz %s Power" % (vhfdata[index], powernamedata[power]) rs = RadioSetting( key, name, RadioSettingValueInteger( 0, 255, getattr( self._memobj.test, "vhf%s%i" % (powerkeydata[power], index)))) testmode.append(rs) for power in range(0, 2): for index in range(0, 8): key = "test.uhf%s%i" % (powerkeydata[power], index) name = "%s MHz %s Power" % (uhfdata[index], powernamedata[power]) rs = RadioSetting( key, name, RadioSettingValueInteger( 0, 255, getattr( self._memobj.test, "uhf%s%i" % (powerkeydata[power], index)))) testmode.append(rs) for band in ["vhf", "uhf"]: for index in range(0, 10): key = "test.%ssquelch%i" % (band, index) name = "%s Squelch %i" % (band.upper(), index) rs = RadioSetting( key, name, RadioSettingValueInteger( 0, 255, getattr( self._memobj.test, "%ssquelch%i" % (band, index)))) testmode.append(rs) return group def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "beep_tone_disabled": setattr(obj, setting, not int(element.value)) elif setting == "ste_disabled": setattr(obj, setting, not int(element.value)) else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _set_fm_preset(self, settings): for element in settings: try: index = (int(element.get_name().split("_")[-1])) val = element.value if list(val)[0].get_value(): value = int(list(val)[1].get_value() * 10 - 650) else: value = 0x01AF LOG.debug("Setting fm_presets[%1i] = %s" % (index, value)) setting = self._memobj.fm_presets setting[index] = value except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): return (filedata.startswith(b"KT511 Radio Program data") and len(filedata) == (cls._memsize + 0x30)) chirp-20240224/chirp/drivers/vgc.py0000644000175000017500000014346714522657251016000 0ustar hibbyhibby# Copyright 2016: # * Jim Unroe KC9HI, # * Pavel Milanes CO7WT # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging import re from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct mem { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unknown0:2, txp:2, wn:2, unknown1:1, bcl:1; u8 unknown2:2, revert:1, dname:1, unknown3:4; u8 unknown4[2]; }; struct nam { char name[6]; u8 unknown1[2]; }; #seekto 0x0000; struct mem left_memory[500]; #seekto 0x2000; struct mem right_memory[500]; #seekto 0x4000; struct nam left_names[500]; #seekto 0x5000; struct nam right_names[500]; #seekto 0x6000; u8 left_usedflags[64]; #seekto 0x6040; u8 left_scanflags[64]; #seekto 0x6080; u8 right_usedflags[64]; #seekto 0x60C0; u8 right_scanflags[64]; #seekto 0x6160; struct { char line32[32]; } embedded_msg; #seekto 0x6180; struct { u8 sbmute:2, // sub band mute unknown1:1, workmodb:1, // work mode (right side) dw:1, // dual watch audio:1, // audio output mode (stereo/mono) unknown2:1, workmoda:1; // work mode (left side) u8 scansb:1, // scan stop beep aftone:3, // af tone control scand:1, // scan direction scanr:3; // scan resume u8 rxexp:1, // rx expansion ptt:1, // ptt mode display:1, // display select (frequency/clock) omode:1, // operation mode beep:2, // beep volume spkr:2; // speaker u8 cpuclk:1, // operating mode(cpu clock) fkey:3, // fkey function mrscan:1, // memory scan type color:3; // lcd backlight color u8 vox:2, // vox voxs:3, // vox sensitivity mgain:3; // mic gain u8 wbandb:4, // work band (right side) wbanda:4; // work band (left side) u8 sqlb:4, // squelch level (right side) sqla:4; // squelch level (left side) u8 apo:4, // auto power off ars:1, // automatic repeater shift tot:3; // time out timer u8 stepb:4, // auto step (right side) stepa:4; // auto step (left side) u8 rxcoverm:1, // rx coverage-memory lcdc:3, // lcd contrast rxcoverv:1, // rx coverage-vfo lcdb:3; // lcd brightness u8 smode:1, // smart function mode timefmt:1, // time format datefmt:2, // date format timesig:1, // time signal keyb:3; // key/led brightness u8 dwstop:1, // dual watch stop unknown3:1, sqlexp:1, // sql expansion decbandsel:1, // decoding band select dtmfmodenc:1, // dtmf mode encode bell:3; // bell ringer u8 unknown4:2, btime:6; // lcd backlight time u8 unknown5:2, tz:6; // time zone u8 unknown618E; u8 unknown618F; ul16 offseta; // work offset (left side) ul16 offsetb; // work offset (right side) ul16 mrcha; // selected memory channel (left) ul16 mrchb; // selected memory channel (right) ul16 wpricha; // work priority channel (left) ul16 wprichb; // work priority channel (right) u8 unknown6:3, datasql:2, // data squelch dataspd:1, // data speed databnd:2; // data band select u8 unknown7:1, pfkey2:3, // mic p2 key unknown8:1, pfkey1:3; // mic p1 key u8 unknown9:1, pfkey4:3, // mic p4 key unknowna:1, pfkey3:3; // mic p3 key u8 unknownb:7, dtmfmoddec:1; // dtmf mode decode } settings; #seekto 0x61B0; struct { char line16[16]; } poweron_msg; #seekto 0x6300; struct { u8 unknown1:3, ttdgt:5; // dtmf digit time u8 unknown2:3, ttint:5; // dtmf interval time u8 unknown3:3, tt1stdgt:5; // dtmf 1st digit time u8 unknown4:3, tt1stdly:5; // dtmf 1st digit delay u8 unknown5:3, ttdlyqt:5; // dtmf delay when use qt u8 unknown6:3, ttdkey:5; // dtmf d key function u8 unknown7; u8 unknown8:4, ttautod:4; // dtmf auto dial group } dtmf; #seekto 0x6330; struct { u8 unknown1:7, ttsig:1; // dtmf signal u8 unknown2:4, ttintcode:4; // dtmf interval code u8 unknown3:5, ttgrpcode:3; // dtmf group code u8 unknown4:4, ttautorst:4; // dtmf auto reset time u8 unknown5:5, ttalert:3; // dtmf alert tone/transpond } dtmf2; #seekto 0x6360; struct { u8 code1[8]; // dtmf code u8 code1_len; // dtmf code length u8 unknown1[7]; u8 code2[8]; // dtmf code u8 code2_len; // dtmf code length u8 unknown2[7]; u8 code3[8]; // dtmf code u8 code3_len; // dtmf code length u8 unknown3[7]; u8 code4[8]; // dtmf code u8 code4_len; // dtmf code length u8 unknown4[7]; u8 code5[8]; // dtmf code u8 code5_len; // dtmf code length u8 unknown5[7]; u8 code6[8]; // dtmf code u8 code6_len; // dtmf code length u8 unknown6[7]; u8 code7[8]; // dtmf code u8 code7_len; // dtmf code length u8 unknown7[7]; u8 code8[8]; // dtmf code u8 code8_len; // dtmf code length u8 unknown8[7]; u8 code9[8]; // dtmf code u8 code9_len; // dtmf code length u8 unknown9[7]; } dtmfcode; """ MEM_SIZE = 0x8000 BLOCK_SIZE = 0x40 MODES = ["FM", "Auto", "NFM", "AM"] SKIP_VALUES = ["", "S"] TONES = chirp_common.TONES DTCS_CODES = chirp_common.DTCS_CODES NAME_LENGTH = 6 DTMF_CHARS = list("0123456789ABCD*#") STIMEOUT = 1 # Basic settings lists LIST_AFTONE = ["Low-3", "Low-2", "Low-1", "Normal", "High-1", "High-2"] LIST_SPKR = ["Off", "Front", "Rear", "Front + Rear"] LIST_AUDIO = ["Monaural", "Stereo"] LIST_SBMUTE = ["Off", "TX", "RX", "Both"] LIST_MLNHM = ["Min", "Low", "Normal", "High", "Max"] LIST_PTT = ["Momentary", "Toggle"] LIST_RXEXP = ["General", "Wide coverage"] LIST_VOX = ["Off", "Internal mic", "Front hand-mic", "Rear hand-mic"] LIST_DISPLAY = ["Frequency", "Timer/Clock"] LIST_MINMAX = ["Min"] + ["%s" % x for x in range(2, 8)] + ["Max"] LIST_COLOR = ["White-Blue", "Sky-Blue", "Marine-Blue", "Green", "Yellow-Green", "Orange", "Amber", "White"] LIST_BTIME = ["Continuous"] + ["%s" % x for x in range(1, 61)] LIST_MRSCAN = ["All", "Selected"] LIST_DWSTOP = ["Auto", "Hold"] LIST_SCAND = ["Down", "Up"] LIST_SCANR = ["Busy", "Hold", "1 sec", "3 sec", "5 sec"] LIST_APO = ["Off", ".5", "1", "1.5"] + ["%s" % x for x in range(2, 13)] LIST_BEEP = ["Off", "Low", "High"] LIST_FKEY = ["MHz/AD-F", "AF Dual 1(line-in)", "AF Dual 2(AM)", "AF Dual 3(FM)", "PA", "SQL off", "T-call", "WX"] LIST_PFKEY = ["Off", "SQL off", "TX power", "Scan", "RPT shift", "Reverse", "T-Call"] LIST_AB = ["A", "B"] LIST_COVERAGE = ["In band", "All"] LIST_TOT = ["Off"] + ["%s" % x for x in range(5, 25, 5)] + ["30"] LIST_DATEFMT = ["yyyy/mm/dd", "yyyy/dd/mm", "mm/dd/yyyy", "dd/mm/yyyy"] LIST_TIMEFMT = ["24H", "12H"] LIST_TZ = ["-12 INT DL W", "-11 MIDWAY", "-10 HAST", "-9 AKST", "-8 PST", "-7 MST", "-6 CST", "-5 EST", "-4:30 CARACAS", "-4 AST", "-3:30 NST", "-3 BRASILIA", "-2 MATLANTIC", "-1 AZORES", "-0 LONDON", "+0 LONDON", "+1 ROME", "+2 ATHENS", "+3 MOSCOW", "+3:30 REHRW", "+4 ABUDNABI", "+4:30 KABUL", "+5 ISLMABAD", "+5:30 NEWDELHI", "+6 DHAKA", "+6:30 YANGON", "+7 BANKOK", "+8 BEIJING", "+9 TOKYO", "+10 ADELAIDE", "+10 SYDNET", "+11 NWCLDNIA", "+12 FIJI", "+13 NUKALOFA" ] LIST_BELL = ["Off", "1 time", "3 times", "5 times", "8 times", "Continuous"] LIST_DATABND = ["Main band", "Sub band", "Left band-fixed", "Right band-fixed"] LIST_DATASPD = ["1200 bps", "9600 bps"] LIST_DATASQL = ["Busy/TX", "Busy", "TX"] # Other settings lists LIST_CPUCLK = ["Clock frequency 1", "Clock frequency 2"] # Work mode settings lists LIST_WORK = ["VFO", "Memory System"] LIST_WBANDB = ["Air", "H-V", "GR1-V", "GR1-U", "H-U", "GR2"] LIST_WBANDA = ["Line-in", "AM", "FM"] + LIST_WBANDB LIST_SQL = ["Open"] + ["%s" % x for x in range(1, 10)] _STEP_LIST = [2.5, 5., 6.25, 8.33, 9., 10., 12.5, 15., 20., 25., 50., 100., 200.] LIST_STEP = ["Auto"] + ["{0:.2f} kHz".format(x) for x in _STEP_LIST] LIST_SMODE = ["F-1", "F-2"] # DTMF settings lists LIST_TTDKEY = ["D code"] + ["Send delay %s s" % x for x in range(1, 17)] LIST_TT200 = ["%s ms" % x for x in range(50, 210, 10)] LIST_TT1000 = ["%s ms" % x for x in range(100, 1050, 50)] LIST_TTSIG = ["Code squelch", "Select call"] LIST_TTAUTORST = ["Off"] + ["%s s" % x for x in range(1, 16)] LIST_TTGRPCODE = ["Off"] + list("ABCD*#") LIST_TTINTCODE = DTMF_CHARS LIST_TTALERT = ["Off", "Alert tone", "Transpond", "Transpond-ID code", "Transpond-transpond code"] LIST_TTAUTOD = ["%s" % x for x in range(1, 10)] # valid chars on the LCD VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`{|}!\"#$%&'()*+,-./:;<=>?@[]^_" # Power Levels POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=20), chirp_common.PowerLevel("High", watts=50)] # B-TECH UV-50X3 id string UV50X3_id = b"VGC6600MD" def _clean_buffer(radio): radio.pipe.timeout = 0.005 junk = radio.pipe.read(256) radio.pipe.timeout = STIMEOUT if junk: LOG.debug("Got %i bytes of junk before starting" % len(junk)) def _check_for_double_ack(radio): radio.pipe.timeout = 0.005 c = radio.pipe.read(1) radio.pipe.timeout = STIMEOUT if c and c != b'\x06': _exit_program_mode(radio) raise errors.RadioError('Expected nothing or ACK, got %r' % c) def _rawrecv(radio, amount): """Raw read from the radio device""" data = b"" try: data = radio.pipe.read(amount) except: _exit_program_mode(radio) msg = "Generic error reading data from radio; check your cable." raise errors.RadioError(msg) if len(data) != amount: _exit_program_mode(radio) msg = "Error reading data from radio: not the amount of data we want." raise errors.RadioError(msg) return data def _rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) except: raise errors.RadioError("Error sending data to radio") def _make_frame(cmd, addr, length, data=""): """Pack the info in the header format""" frame = struct.pack(">BHB", ord(cmd), addr, length) # add the data if set if len(data) != 0: frame += data # return the data return frame def _recv(radio, addr, length=BLOCK_SIZE): """Get data from the radio """ # read 4 bytes of header hdr = _rawrecv(radio, 4) # check for unexpected extra command byte c, a, l = struct.unpack(">BHB", hdr) if hdr[0:2] == b"WW" and a != addr: # extra command byte detected # throw away the 1st byte and add the next byte in the buffer hdr = hdr[1:] + _rawrecv(radio, 1) # read 64 bytes (0x40) of data data = _rawrecv(radio, (BLOCK_SIZE)) # DEBUG LOG.info("Response:") LOG.debug(util.hexprint(hdr + data)) c, a, l = struct.unpack(">BHB", hdr) if a != addr or l != length or c != ord(b"W"): _exit_program_mode(radio) LOG.error("Invalid answer for block 0x%04x:" % addr) LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (c, a, l)) raise errors.RadioError("Unknown response from the radio") return data def _do_ident(radio): """Put the radio in PROGRAM mode & identify it""" # set the serial discipline radio.pipe.baudrate = 115200 radio.pipe.parity = "N" radio.pipe.timeout = STIMEOUT # flush input buffer _clean_buffer(radio) magic = b"V66LINK" _rawsend(radio, magic) # Ok, get the ident string ident = _rawrecv(radio, 9) # check if ident is OK if ident != radio.IDENT: # bad ident msg = "Incorrect model ID, got this:" msg += util.hexprint(ident) LOG.debug(msg) raise errors.RadioError("Radio identification failed.") # DEBUG LOG.info("Positive ident, got this:") LOG.debug(util.hexprint(ident)) return True def _exit_program_mode(radio): endframe = b"\x45" _rawsend(radio, endframe) def _download(radio): """Get the memory map""" # put radio in program mode and identify it _do_ident(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data = b"" for addr in range(0, MEM_SIZE, BLOCK_SIZE): frame = _make_frame(b"R", addr, BLOCK_SIZE) # DEBUG LOG.info("Request sent:") LOG.debug(util.hexprint(frame)) # sending the read request _rawsend(radio, frame) # now we read d = _recv(radio, addr) # aggregate the data data += d # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) _exit_program_mode(radio) return data def _upload(radio): """Upload procedure""" MEM_SIZE = 0x7000 # put radio in program mode and identify it _do_ident(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) # the fun start here for addr in range(0, MEM_SIZE, BLOCK_SIZE): # sending the data data = radio.get_mmap()[addr:addr + BLOCK_SIZE] frame = _make_frame(b"W", addr, BLOCK_SIZE, data) _rawsend(radio, frame) # receiving the response ack = _rawrecv(radio, 1) if ack != b"\x06": _exit_program_mode(radio) msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) _check_for_double_ack(radio) # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) _exit_program_mode(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0x6140:0x6148] if rid in cls.IDENT: return True return False def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True class VGCStyleRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """BTECH's UV-50X3""" VENDOR = "BTECH" NEEDS_COMPAT_SERIAL = False _air_range = (108000000, 136000000) _vhf_range = (136000000, 174000000) _vhf2_range = (174000000, 250000000) _220_range = (222000000, 225000000) _gen1_range = (300000000, 400000000) _uhf_range = (400000000, 480000000) _gen2_range = (480000000, 520000000) _upper = 499 MODEL = "" IDENT = "" @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('The UV-50X3 driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow this instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.has_sub_devices = self.VARIANT == "" rf.valid_modes = MODES rf.valid_characters = VALID_CHARS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_skips = SKIP_VALUES rf.valid_name_length = NAME_LENGTH rf.valid_dtcs_codes = DTCS_CODES rf.valid_tuning_steps = _STEP_LIST rf.valid_bands = [self._air_range, self._vhf_range, self._vhf2_range, self._220_range, self._gen1_range, self._uhf_range, self._gen2_range] rf.memory_bounds = (0, self._upper) return rf def get_sub_devices(self): return [UV50X3Left(self._mmap), UV50X3Right(self._mmap)] def sync_in(self): """Download from radio""" try: data = _download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def _memory_obj(self, suffix=""): return getattr(self._memobj, "%s_memory%s" % (self._vfo, suffix)) def _name_obj(self, suffix=""): return getattr(self._memobj, "%s_names%s" % (self._vfo, suffix)) def _scan_obj(self, suffix=""): return getattr(self._memobj, "%s_scanflags%s" % (self._vfo, suffix)) def _used_obj(self, suffix=""): return getattr(self._memobj, "%s_usedflags%s" % (self._vfo, suffix)) def get_memory(self, number): """Get the mem representation from the radio image""" bitpos = (1 << (number % 8)) bytepos = (number / 8) _mem = self._memory_obj()[number] _names = self._name_obj()[number] _scn = self._scan_obj()[bytepos] _usd = self._used_obj()[bytepos] isused = bitpos & int(_usd) isscan = bitpos & int(_scn) # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Memory number mem.number = number if not isused: mem.empty = True return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if _mem.get_raw(asbytes=False)[4] == "\xFF": # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX feq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 # skip if not isscan: mem.skip = "S" # name TAG of the channel mem.name = str(_names.name).strip("\xFF") # power mem.power = POWER_LEVELS[int(_mem.txp)] # wide/narrow mem.mode = MODES[int(_mem.wn)] # tone data rxtone = txtone = None txtone = self.decode_tone(_mem.txtone) rxtone = self.decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) # Extra mem.extra = RadioSettingGroup("extra", "Extra") bcl = RadioSetting("bcl", "Busy channel lockout", RadioSettingValueBoolean(bool(_mem.bcl))) mem.extra.append(bcl) revert = RadioSetting("revert", "Revert", RadioSettingValueBoolean(bool(_mem.revert))) mem.extra.append(revert) dname = RadioSetting("dname", "Display name", RadioSettingValueBoolean(bool(_mem.dname))) mem.extra.append(dname) return mem def set_memory(self, mem): """Set the memory data in the eeprom img from the UI""" bitpos = (1 << (mem.number % 8)) bytepos = (mem.number / 8) _mem = self._memory_obj()[mem.number] _names = self._name_obj()[mem.number] _scn = self._scan_obj()[bytepos] _usd = self._used_obj()[bytepos] if mem.empty: _usd &= ~bitpos _scn &= ~bitpos _mem.set_raw("\xFF" * 16) _names.name = ("\xFF" * 6) return else: _usd |= bitpos # frequency _mem.rxfreq = mem.freq / 10 # duplex if mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 elif mem.duplex == "off": for i in _mem.txfreq: i.set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 else: _mem.txfreq = mem.freq / 10 # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_mem.txtone, txmode, txtone, txpol) self.encode_tone(_mem.rxtone, rxmode, rxtone, rxpol) # name TAG of the channel _names.name = mem.name.rstrip().ljust(6, "\xFF") # power level, # default power level is low _mem.txp = 0 if mem.power is None else POWER_LEVELS.index(mem.power) # wide/narrow _mem.wn = MODES.index(mem.mode) if mem.skip == "S": _scn &= ~bitpos else: _scn |= bitpos # autoset display to display name if filled if mem.extra: # mem.extra only seems to be populated when called from edit panel dname = mem.extra["dname"] else: dname = None if mem.name: _mem.dname = True if dname and not dname.changed(): dname.value = True else: _mem.dname = False if dname and not dname.changed(): dname.value = False # resetting unknowns, this has to be set by hand _mem.unknown0 = 0 _mem.unknown1 = 0 _mem.unknown2 = 0 _mem.unknown3 = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) else: # there are no extra settings, load defaults _mem.bcl = 0 _mem.revert = 0 _mem.dname = 1 def _bbcd2dtmf(self, bcdarr, strlen=16): # doing bbcd, but with support for ABCD*# LOG.debug(bcdarr.get_value()) string = ''.join("%02X" % b for b in bcdarr) LOG.debug("@_bbcd2dtmf, received: %s" % string) string = string.replace('E', '*').replace('F', '#') if strlen <= 16: string = string[:strlen] return string def _dtmf2bbcd(self, value): dtmfstr = value.get_value() dtmfstr = dtmfstr.replace('*', 'E').replace('#', 'F') dtmfstr = str.ljust(dtmfstr.strip(), 16, "F") bcdarr = list(bytearray.fromhex(dtmfstr)) LOG.debug("@_dtmf2bbcd, sending: %s" % bcdarr) return bcdarr def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") top = RadioSettings(basic, other, work, dtmf) # Basic # Audio: A01-A04 aftone = RadioSetting("settings.aftone", "AF tone control", RadioSettingValueList(LIST_AFTONE, LIST_AFTONE[ _mem.settings.aftone])) basic.append(aftone) spkr = RadioSetting("settings.spkr", "Speaker", RadioSettingValueList(LIST_SPKR, LIST_SPKR[ _mem.settings.spkr])) basic.append(spkr) audio = RadioSetting("settings.audio", "Stereo/Mono", RadioSettingValueList(LIST_AUDIO, LIST_AUDIO[ _mem.settings.audio])) basic.append(audio) sbmute = RadioSetting("settings.sbmute", "Sub band mute", RadioSettingValueList(LIST_SBMUTE, LIST_SBMUTE[ _mem.settings.sbmute])) basic.append(sbmute) # TX/RX: B01-B08 mgain = RadioSetting("settings.mgain", "Mic gain", RadioSettingValueList(LIST_MLNHM, LIST_MLNHM[ _mem.settings.mgain])) basic.append(mgain) ptt = RadioSetting("settings.ptt", "PTT mode", RadioSettingValueList(LIST_PTT, LIST_PTT[ _mem.settings.ptt])) basic.append(ptt) # B03 (per channel) # B04 (per channel) rxexp = RadioSetting("settings.rxexp", "RX expansion", RadioSettingValueList(LIST_RXEXP, LIST_RXEXP[ _mem.settings.rxexp])) basic.append(rxexp) vox = RadioSetting("settings.vox", "Vox", RadioSettingValueList(LIST_VOX, LIST_VOX[ _mem.settings.vox])) basic.append(vox) voxs = RadioSetting("settings.voxs", "Vox sensitivity", RadioSettingValueList(LIST_MLNHM, LIST_MLNHM[ _mem.settings.voxs])) basic.append(voxs) # B08 (per channel) # Display: C01-C06 display = RadioSetting("settings.display", "Display select", RadioSettingValueList( LIST_DISPLAY, LIST_DISPLAY[ _mem.settings.display])) basic.append(display) lcdb = RadioSetting("settings.lcdb", "LCD brightness", RadioSettingValueList(LIST_MINMAX, LIST_MINMAX[ _mem.settings.lcdb])) basic.append(lcdb) color = RadioSetting("settings.color", "LCD color", RadioSettingValueList(LIST_COLOR, LIST_COLOR[ _mem.settings.color])) basic.append(color) lcdc = RadioSetting("settings.lcdc", "LCD contrast", RadioSettingValueList(LIST_MINMAX, LIST_MINMAX[ _mem.settings.lcdc])) basic.append(lcdc) btime = RadioSetting("settings.btime", "LCD backlight time", RadioSettingValueList(LIST_BTIME, LIST_BTIME[ _mem.settings.btime])) basic.append(btime) keyb = RadioSetting("settings.keyb", "Key brightness", RadioSettingValueList(LIST_MINMAX, LIST_MINMAX[ _mem.settings.keyb])) basic.append(keyb) # Memory: D01-D04 # D01 (per channel) # D02 (per channel) mrscan = RadioSetting("settings.mrscan", "Memory scan type", RadioSettingValueList(LIST_MRSCAN, LIST_MRSCAN[ _mem.settings.mrscan])) basic.append(mrscan) # D04 (per channel) # Scan: E01-E04 dwstop = RadioSetting("settings.dwstop", "Dual watch stop", RadioSettingValueList(LIST_DWSTOP, LIST_DWSTOP[ _mem.settings.dwstop])) basic.append(dwstop) scand = RadioSetting("settings.scand", "Scan direction", RadioSettingValueList(LIST_SCAND, LIST_SCAND[ _mem.settings.scand])) basic.append(scand) scanr = RadioSetting("settings.scanr", "Scan resume", RadioSettingValueList(LIST_SCANR, LIST_SCANR[ _mem.settings.scanr])) basic.append(scanr) scansb = RadioSetting("settings.scansb", "Scan stop beep", RadioSettingValueBoolean(_mem.settings.scansb)) basic.append(scansb) # System: F01-F09 apo = RadioSetting("settings.apo", "Automatic power off [hours]", RadioSettingValueList(LIST_APO, LIST_APO[ _mem.settings.apo])) basic.append(apo) ars = RadioSetting("settings.ars", "Automatic repeater shift", RadioSettingValueBoolean(_mem.settings.ars)) basic.append(ars) beep = RadioSetting("settings.beep", "Beep volume", RadioSettingValueList(LIST_BEEP, LIST_BEEP[ _mem.settings.beep])) basic.append(beep) fkey = RadioSetting("settings.fkey", "F key", RadioSettingValueList(LIST_FKEY, LIST_FKEY[ _mem.settings.fkey])) basic.append(fkey) pfkey1 = RadioSetting("settings.pfkey1", "Mic P1 key", RadioSettingValueList(LIST_PFKEY, LIST_PFKEY[ _mem.settings.pfkey1])) basic.append(pfkey1) pfkey2 = RadioSetting("settings.pfkey2", "Mic P2 key", RadioSettingValueList(LIST_PFKEY, LIST_PFKEY[ _mem.settings.pfkey2])) basic.append(pfkey2) pfkey3 = RadioSetting("settings.pfkey3", "Mic P3 key", RadioSettingValueList(LIST_PFKEY, LIST_PFKEY[ _mem.settings.pfkey3])) basic.append(pfkey3) pfkey4 = RadioSetting("settings.pfkey4", "Mic P4 key", RadioSettingValueList(LIST_PFKEY, LIST_PFKEY[ _mem.settings.pfkey4])) basic.append(pfkey4) omode = RadioSetting("settings.omode", "Operation mode", RadioSettingValueList(LIST_AB, LIST_AB[ _mem.settings.omode])) basic.append(omode) rxcoverm = RadioSetting("settings.rxcoverm", "RX coverage - memory", RadioSettingValueList( LIST_COVERAGE, LIST_COVERAGE[ _mem.settings.rxcoverm])) basic.append(rxcoverm) rxcoverv = RadioSetting("settings.rxcoverv", "RX coverage - VFO", RadioSettingValueList( LIST_COVERAGE, LIST_COVERAGE[ _mem.settings.rxcoverv])) basic.append(rxcoverv) tot = RadioSetting("settings.tot", "Time out timer [min]", RadioSettingValueList(LIST_TOT, LIST_TOT[ _mem.settings.tot])) basic.append(tot) # Timer/Clock: G01-G04 # G01 datefmt = RadioSetting("settings.datefmt", "Date format", RadioSettingValueList( LIST_DATEFMT, LIST_DATEFMT[ _mem.settings.datefmt])) basic.append(datefmt) timefmt = RadioSetting("settings.timefmt", "Time format", RadioSettingValueList( LIST_TIMEFMT, LIST_TIMEFMT[ _mem.settings.timefmt])) basic.append(timefmt) timesig = RadioSetting("settings.timesig", "Time signal", RadioSettingValueBoolean(_mem.settings.timesig)) basic.append(timesig) tz = RadioSetting("settings.tz", "Time zone", RadioSettingValueList(LIST_TZ, LIST_TZ[ _mem.settings.tz])) basic.append(tz) # Signaling: H01-H06 bell = RadioSetting("settings.bell", "Bell ringer", RadioSettingValueList(LIST_BELL, LIST_BELL[ _mem.settings.bell])) basic.append(bell) # H02 (per channel) dtmfmodenc = RadioSetting("settings.dtmfmodenc", "DTMF mode encode", RadioSettingValueBoolean( _mem.settings.dtmfmodenc)) basic.append(dtmfmodenc) dtmfmoddec = RadioSetting("settings.dtmfmoddec", "DTMF mode decode", RadioSettingValueBoolean( _mem.settings.dtmfmoddec)) basic.append(dtmfmoddec) # H04 (per channel) decbandsel = RadioSetting("settings.decbandsel", "DTMF band select", RadioSettingValueList(LIST_AB, LIST_AB[ _mem.settings.decbandsel])) basic.append(decbandsel) sqlexp = RadioSetting("settings.sqlexp", "SQL expansion", RadioSettingValueBoolean(_mem.settings.sqlexp)) basic.append(sqlexp) # Pkt: I01-I03 databnd = RadioSetting("settings.databnd", "Packet data band", RadioSettingValueList( LIST_DATABND, LIST_DATABND[ _mem.settings.databnd])) basic.append(databnd) dataspd = RadioSetting("settings.dataspd", "Packet data speed", RadioSettingValueList( LIST_DATASPD, LIST_DATASPD[ _mem.settings.dataspd])) basic.append(dataspd) datasql = RadioSetting("settings.datasql", "Packet data squelch", RadioSettingValueList( LIST_DATASQL, LIST_DATASQL[ _mem.settings.datasql])) basic.append(datasql) # Other dw = RadioSetting("settings.dw", "Dual watch", RadioSettingValueBoolean(_mem.settings.dw)) other.append(dw) cpuclk = RadioSetting("settings.cpuclk", "CPU clock frequency", RadioSettingValueList(LIST_CPUCLK, LIST_CPUCLK[ _mem.settings.cpuclk])) other.append(cpuclk) def _filter(name): filtered = "" for char in str(name): if char in VALID_CHARS: filtered += char else: filtered += " " return filtered line16 = RadioSetting("poweron_msg.line16", "Power-on message", RadioSettingValueString(0, 16, _filter( _mem.poweron_msg.line16))) other.append(line16) line32 = RadioSetting("embedded_msg.line32", "Embedded message", RadioSettingValueString(0, 32, _filter( _mem.embedded_msg.line32))) other.append(line32) # Work workmoda = RadioSetting("settings.workmoda", "Work mode A", RadioSettingValueList(LIST_WORK, LIST_WORK[ _mem.settings.workmoda])) work.append(workmoda) workmodb = RadioSetting("settings.workmodb", "Work mode B", RadioSettingValueList(LIST_WORK, LIST_WORK[ _mem.settings.workmodb])) work.append(workmodb) wbanda = RadioSetting("settings.wbanda", "Work band A", RadioSettingValueList(LIST_WBANDA, LIST_WBANDA[ (_mem.settings.wbanda) - 1])) work.append(wbanda) wbandb = RadioSetting("settings.wbandb", "Work band B", RadioSettingValueList(LIST_WBANDB, LIST_WBANDB[ (_mem.settings.wbandb) - 4])) work.append(wbandb) sqla = RadioSetting("settings.sqla", "Squelch A", RadioSettingValueList(LIST_SQL, LIST_SQL[ _mem.settings.sqla])) work.append(sqla) sqlb = RadioSetting("settings.sqlb", "Squelch B", RadioSettingValueList(LIST_SQL, LIST_SQL[ _mem.settings.sqlb])) work.append(sqlb) stepa = RadioSetting("settings.stepa", "Auto step A", RadioSettingValueList(LIST_STEP, LIST_STEP[ _mem.settings.stepa])) work.append(stepa) stepb = RadioSetting("settings.stepb", "Auto step B", RadioSettingValueList(LIST_STEP, LIST_STEP[ _mem.settings.stepb])) work.append(stepb) mrcha = RadioSetting("settings.mrcha", "Current channel A", RadioSettingValueInteger(0, 499, _mem.settings.mrcha)) work.append(mrcha) mrchb = RadioSetting("settings.mrchb", "Current channel B", RadioSettingValueInteger(0, 499, _mem.settings.mrchb)) work.append(mrchb) val = _mem.settings.offseta / 100.00 offseta = RadioSetting("settings.offseta", "Offset A (0-37.95)", RadioSettingValueFloat(0, 38.00, val, 0.05, 2)) work.append(offseta) val = _mem.settings.offsetb / 100.00 offsetb = RadioSetting("settings.offsetb", "Offset B (0-79.95)", RadioSettingValueFloat(0, 80.00, val, 0.05, 2)) work.append(offsetb) wpricha = RadioSetting("settings.wpricha", "Priority channel A", RadioSettingValueInteger(0, 499, _mem.settings.wpricha)) work.append(wpricha) wprichb = RadioSetting("settings.wprichb", "Priority channel B", RadioSettingValueInteger(0, 499, _mem.settings.wprichb)) work.append(wprichb) smode = RadioSetting("settings.smode", "Smart function mode", RadioSettingValueList(LIST_SMODE, LIST_SMODE[ _mem.settings.smode])) work.append(smode) # dtmf ttdkey = RadioSetting("dtmf.ttdkey", "D key function", RadioSettingValueList(LIST_TTDKEY, LIST_TTDKEY[ _mem.dtmf.ttdkey])) dtmf.append(ttdkey) ttdgt = RadioSetting("dtmf.ttdgt", "Digit time", RadioSettingValueList(LIST_TT200, LIST_TT200[ (_mem.dtmf.ttdgt) - 5])) dtmf.append(ttdgt) ttint = RadioSetting("dtmf.ttint", "Interval time", RadioSettingValueList(LIST_TT200, LIST_TT200[ (_mem.dtmf.ttint) - 5])) dtmf.append(ttint) tt1stdgt = RadioSetting("dtmf.tt1stdgt", "1st digit time", RadioSettingValueList(LIST_TT200, LIST_TT200[ (_mem.dtmf.tt1stdgt) - 5])) dtmf.append(tt1stdgt) tt1stdly = RadioSetting("dtmf.tt1stdly", "1st digit delay time", RadioSettingValueList(LIST_TT1000, LIST_TT1000[ (_mem.dtmf.tt1stdly) - 2])) dtmf.append(tt1stdly) ttdlyqt = RadioSetting("dtmf.ttdlyqt", "Digit delay when use qt", RadioSettingValueList(LIST_TT1000, LIST_TT1000[ (_mem.dtmf.ttdlyqt) - 2])) dtmf.append(ttdlyqt) ttsig = RadioSetting("dtmf2.ttsig", "Signal", RadioSettingValueList(LIST_TTSIG, LIST_TTSIG[ _mem.dtmf2.ttsig])) dtmf.append(ttsig) ttautorst = RadioSetting("dtmf2.ttautorst", "Auto reset time", RadioSettingValueList( LIST_TTAUTORST, LIST_TTAUTORST[ _mem.dtmf2.ttautorst])) dtmf.append(ttautorst) if _mem.dtmf2.ttgrpcode > 0x06: val = 0x00 else: val = _mem.dtmf2.ttgrpcode ttgrpcode = RadioSetting("dtmf2.ttgrpcode", "Group code", RadioSettingValueList(LIST_TTGRPCODE, LIST_TTGRPCODE[val])) dtmf.append(ttgrpcode) ttintcode = RadioSetting("dtmf2.ttintcode", "Interval code", RadioSettingValueList( LIST_TTINTCODE, LIST_TTINTCODE[ _mem.dtmf2.ttintcode])) dtmf.append(ttintcode) if _mem.dtmf2.ttalert > 0x04: val = 0x00 else: val = _mem.dtmf2.ttalert ttalert = RadioSetting("dtmf2.ttalert", "Alert tone/transpond", RadioSettingValueList(LIST_TTALERT, LIST_TTALERT[val])) dtmf.append(ttalert) ttautod = RadioSetting("dtmf.ttautod", "Auto dial group", RadioSettingValueList( LIST_TTAUTOD, LIST_TTAUTOD[ _mem.dtmf.ttautod])) dtmf.append(ttautod) # setup 9 dtmf autodial entries for i in map(str, list(range(1, 10))): objname = "code" + i strname = "Code " + str(i) dtmfsetting = getattr(_mem.dtmfcode, objname) dtmflen = getattr(_mem.dtmfcode, objname + "_len") dtmfstr = self._bbcd2dtmf(dtmfsetting, dtmflen) code = RadioSettingValueString(0, 16, dtmfstr) code.set_charset(DTMF_CHARS + list(" ")) rs = RadioSetting("dtmfcode." + objname, strname, code) dtmf.append(rs) return top def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "line16": setattr(obj, setting, str(element.value).rstrip( " ").ljust(16, "\xFF")) elif setting == "line32": setattr(obj, setting, str(element.value).rstrip( " ").ljust(32, "\xFF")) elif setting == "wbanda": setattr(obj, setting, int(element.value) + 1) elif setting == "wbandb": setattr(obj, setting, int(element.value) + 4) elif setting in ["offseta", "offsetb"]: val = element.value value = int(val.get_value() * 100) setattr(obj, setting, value) elif setting in ["ttdgt", "ttint", "tt1stdgt"]: setattr(obj, setting, int(element.value) + 5) elif setting in ["tt1stdly", "ttdlyqt"]: setattr(obj, setting, int(element.value) + 2) elif re.match(r'code\d', setting): # set dtmf length field and then get bcd dtmf dtmfstrlen = len(str(element.value).strip()) setattr(_mem.dtmfcode, setting + "_len", dtmfstrlen) dtmfstr = self._dtmf2bbcd(element.value) setattr(_mem.dtmfcode, setting, dtmfstr) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == MEM_SIZE: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False @directory.register class UV50X3(VGCStyleRadio): """BTech UV-50X3""" MODEL = "UV-50X3" IDENT = UV50X3_id class UV50X3Left(UV50X3): VARIANT = "Left" _vfo = "left" class UV50X3Right(UV50X3): VARIANT = "Right" _vfo = "right" chirp-20240224/chirp/drivers/h777.py0000644000175000017500000005534714547737342015723 0ustar hibbyhibby# -*- coding: utf-8 -*- # Copyright 2013 Andrew Morgan # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import unittest import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unknown3:1, unknown2:1, unknown1:1, skip:1, highpower:1, narrow:1, beatshift:1, bcl:1; u8 unknown4[3]; } memory[16]; #seekto 0x02B0; struct { u8 voiceprompt; u8 voicelanguage; u8 scan; u8 vox; u8 voxlevel; u8 voxinhibitonrx; u8 lowvolinhibittx; u8 highvolinhibittx; u8 alarm; u8 fmradio; } settings; """ H777_SETTINGS2 = """ #seekto 0x03C0; struct { u8 unused:6, batterysaver:1, beep:1; u8 squelchlevel; u8 sidekeyfunction; u8 timeouttimer; u8 unused2[3]; u8 unused3:7, scanmode:1; } settings2; """ BF1900_SETTINGS2 = """ #seekto 0x03C0; struct { u8 unused:6, batterysaver:1, beep:1; u8 squelchlevel; u8 scanmode; u8 timeouttimer; u8 unused2[4]; } settings2; """ CMD_ACK = b"\x06" BLOCK_SIZE = 0x08 UPLOAD_BLOCKS = [list(range(0x0000, 0x0110, 8)), list(range(0x02b0, 0x02c0, 8)), list(range(0x0380, 0x03e0, 8))] VOICE_LIST = ["English", "Chinese"] TIMEOUTTIMER_LIST = ["Off", "30 seconds", "60 seconds", "90 seconds", "120 seconds", "150 seconds", "180 seconds", "210 seconds", "240 seconds", "270 seconds", "300 seconds"] def _h777_enter_programming_mode(radio): serial = radio.pipe # increase default timeout from .25 to .5 for all serial communications serial.timeout = 0.5 try: serial.write(b"\x02") time.sleep(0.1) serial.write(radio.PROGRAM_CMD) ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if not ack: raise errors.RadioError("No response from radio") elif ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") try: serial.write(b"\x02") # At least one version of the Baofeng BF-888S has a consistent # ~0.33s delay between sending the first five bytes of the # version data and the last three bytes. We need to raise the # timeout so that the read doesn't finish early. ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") if not ident.startswith(b"P3107"): LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _h777_exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _h777_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, BLOCK_SIZE) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + BLOCK_SIZE) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Failed to read block at %04x" % block_addr) if ack != CMD_ACK: raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _h777_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, BLOCK_SIZE) data = radio.get_mmap().get_byte_compatible()[block_addr:block_addr + 8] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) # Time required to write data blocks varies between individual # radios of the Baofeng BF-888S model. The longest seen is # ~0.31s. if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _h777_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, BLOCK_SIZE): status.cur = addr + BLOCK_SIZE radio.status_fn(status) block = _h777_read_block(radio, addr, BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _h777_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _h777_enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, BLOCK_SIZE): status.cur = addr + BLOCK_SIZE radio.status_fn(status) _h777_write_block(radio, addr, BLOCK_SIZE) _h777_exit_programming_mode(radio) class ArcshellAR5(chirp_common.Alias): VENDOR = 'Arcshell' MODEL = 'AR-5' class ArcshellAR6(chirp_common.Alias): VENDOR = 'Arcshell' MODEL = 'AR-6' class GV8SAlias(chirp_common.Alias): VENDOR = 'Greaval' MODEL = 'GV-8S' class GV9SAlias(chirp_common.Alias): VENDOR = 'Greaval' MODEL = 'GV-9S' class A8SAlias(chirp_common.Alias): VENDOR = 'Ansoko' MODEL = 'A-8S' class TenwayTW325Alias(chirp_common.Alias): VENDOR = 'Tenway' MODEL = 'TW-325' class RetevisH777Alias(chirp_common.Alias): VENDOR = 'Retevis' MODEL = 'H777' @directory.register class H777Radio(chirp_common.CloneModeRadio): """HST H-777""" # VENDOR = "Heng Shun Tong (ц’щЁКщ€š)" # MODEL = "H-777" VENDOR = "Baofeng" MODEL = "BF-888" PROGRAM_CMD = b'PROGRAM' BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False # TODO: Is it 1 watt? POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("High", watts=5.00)] VALID_BANDS = (400000000, 490000000) MAX_VOXLEVEL = 5 ALIASES = [ArcshellAR5, ArcshellAR6, GV8SAlias, GV9SAlias, A8SAlias, TenwayTW325Alias, RetevisH777Alias] SIDEKEYFUNCTION_LIST = ["Off", "Monitor", "Transmit Power", "Alarm"] SCANMODE_LIST = ["Carrier", "Time"] # This code currently requires that ranges start at 0x0000 # and are continuous. In the original program 0x0388 and 0x03C8 # are only written (all bytes 0xFF), not read. # _ranges = [ # (0x0000, 0x0110), # (0x02B0, 0x02C0), # (0x0380, 0x03E0) # ] # Memory starts looping at 0x1000... But not every 0x1000. _ranges = [ (0x0000, 0x0110), (0x0380, 0x03E0), (0x02B0, 0x02C0), ] _memsize = 0x03E0 _has_fm = True _has_sidekey = True _has_scanmodes = True _has_scramble = True def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.valid_modes = ["NFM", "FM"] # 12.5 kHz, 25 kHz. rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.can_odd_split = True rf.has_rx_dtcs = True rf.has_ctone = True rf.has_cross = True rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.has_tuning_step = False rf.has_bank = False rf.has_name = False rf.memory_bounds = (1, 16) rf.valid_bands = [self.VALID_BANDS] rf.valid_power_levels = self.POWER_LEVELS rf.valid_tuning_steps = [2.5, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT + H777_SETTINGS2, self._mmap) def sync_in(self): self._mmap = do_download(self) self.process_mmap() def sync_out(self): do_upload(self) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _decode_tone(self, val): val = int(val) if val == 16665: return '', None, None elif val >= 12000: return 'DTCS', val - 12000, 'R' elif val >= 8000: return 'DTCS', val - 8000, 'N' else: return 'Tone', val / 10.0, None def _encode_tone(self, memval, mode, value, pol): if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw(asbytes=False) == "\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if _mem.txfreq.get_raw(asbytes=False) == "\xFF\xFF\xFF\xFF": mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = not _mem.narrow and "FM" or "NFM" mem.power = self.POWER_LEVELS[_mem.highpower] mem.skip = _mem.skip and "S" or "" txtone = self._decode_tone(_mem.txtone) rxtone = self._decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueBoolean(not _mem.bcl)) mem.extra.append(rs) if self._has_scramble: rs = RadioSetting("beatshift", "Beat Shift(scramble)", RadioSettingValueBoolean(not _mem.beatshift)) mem.extra.append(rs) return mem def set_memory(self, mem): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) return _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 txtone, rxtone = chirp_common.split_tone_encode(mem) self._encode_tone(_mem.txtone, *txtone) self._encode_tone(_mem.rxtone, *rxtone) _mem.narrow = 'N' in mem.mode _mem.highpower = mem.power == self.POWER_LEVELS[1] _mem.skip = mem.skip == "S" for setting in mem.extra: # NOTE: Only two settings right now, both are inverted setattr(_mem, setting.get_name(), not int(setting.value)) # When set to one, official programming software (BF-480) shows always # "WFM", even if we choose "NFM". Therefore, for compatibility # purposes, we will set these to zero. _mem.unknown1 = 0 _mem.unknown2 = 0 _mem.unknown3 = 0 def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) # TODO: Check that all these settings actually do what they # say they do. rs = RadioSetting("voiceprompt", "Voice prompt", RadioSettingValueBoolean(_settings.voiceprompt)) basic.append(rs) rs = RadioSetting("voicelanguage", "Voice language", RadioSettingValueList( VOICE_LIST, VOICE_LIST[_settings.voicelanguage])) basic.append(rs) rs = RadioSetting("scan", "Scan", RadioSettingValueBoolean(_settings.scan)) basic.append(rs) if self._has_scanmodes: rs = RadioSetting("settings2.scanmode", "Scan mode", RadioSettingValueList( self.SCANMODE_LIST, self.SCANMODE_LIST[ self._memobj.settings2.scanmode])) basic.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueBoolean(_settings.vox)) basic.append(rs) rs = RadioSetting("voxlevel", "VOX level", RadioSettingValueInteger( 1, self.MAX_VOXLEVEL, _settings.voxlevel + 1)) basic.append(rs) rs = RadioSetting("voxinhibitonrx", "Inhibit VOX on receive", RadioSettingValueBoolean(_settings.voxinhibitonrx)) basic.append(rs) rs = RadioSetting("lowvolinhibittx", "Low voltage inhibit transmit", RadioSettingValueBoolean(_settings.lowvolinhibittx)) basic.append(rs) rs = RadioSetting("highvolinhibittx", "High voltage inhibit transmit", RadioSettingValueBoolean(_settings.highvolinhibittx)) basic.append(rs) if self.PROGRAM_CMD == b'PWPG970': # Baofeng 1900 series rs = RadioSetting("alarm", "Alarm", RadioSettingValueList( self.ALARM_LIST, self.ALARM_LIST[_settings.alarm])) else: rs = RadioSetting("alarm", "Alarm", RadioSettingValueBoolean(_settings.alarm)) basic.append(rs) # TODO: This should probably be called т€œFM Broadcast Band Radioт€ # or something. I'm not sure if the model actually has one though. if self._has_fm: rs = RadioSetting("fmradio", "FM function", RadioSettingValueBoolean(_settings.fmradio)) basic.append(rs) rs = RadioSetting("settings2.beep", "Beep", RadioSettingValueBoolean( self._memobj.settings2.beep)) basic.append(rs) rs = RadioSetting("settings2.batterysaver", "Battery saver", RadioSettingValueBoolean( self._memobj.settings2.batterysaver)) basic.append(rs) rs = RadioSetting("settings2.squelchlevel", "Squelch level", RadioSettingValueInteger( 0, 9, self._memobj.settings2.squelchlevel)) basic.append(rs) if self._has_sidekey: rs = RadioSetting("settings2.sidekeyfunction", "Side key function", RadioSettingValueList( self.SIDEKEYFUNCTION_LIST, self.SIDEKEYFUNCTION_LIST[ self._memobj.settings2.sidekeyfunction])) basic.append(rs) rs = RadioSetting("settings2.timeouttimer", "Timeout timer", RadioSettingValueList( TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[ self._memobj.settings2.timeouttimer])) basic.append(rs) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "voxlevel": setattr(obj, setting, int(element.value) - 1) else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise class H777TestCase(unittest.TestCase): def setUp(self): self.driver = H777Radio(None) self.testdata = bitwise.parse("lbcd foo[2];", memmap.MemoryMap("\x00\x00")) def test_decode_tone_dtcs_normal(self): mode, value, pol = self.driver._decode_tone(8023) self.assertEqual('DTCS', mode) self.assertEqual(23, value) self.assertEqual('N', pol) def test_decode_tone_dtcs_rev(self): mode, value, pol = self.driver._decode_tone(12023) self.assertEqual('DTCS', mode) self.assertEqual(23, value) self.assertEqual('R', pol) def test_decode_tone_tone(self): mode, value, pol = self.driver._decode_tone(885) self.assertEqual('Tone', mode) self.assertEqual(88.5, value) self.assertEqual(None, pol) def test_decode_tone_none(self): mode, value, pol = self.driver._decode_tone(16665) self.assertEqual('', mode) self.assertEqual(None, value) self.assertEqual(None, pol) def test_encode_tone_dtcs_normal(self): self.driver._encode_tone(self.testdata.foo, 'DTCS', 23, 'N') self.assertEqual(8023, int(self.testdata.foo)) def test_encode_tone_dtcs_rev(self): self.driver._encode_tone(self.testdata.foo, 'DTCS', 23, 'R') self.assertEqual(12023, int(self.testdata.foo)) def test_encode_tone(self): self.driver._encode_tone(self.testdata.foo, 'Tone', 88.5, 'N') self.assertEqual(885, int(self.testdata.foo)) def test_encode_tone_none(self): self.driver._encode_tone(self.testdata.foo, '', 67.0, 'N') self.assertEqual(16665, int(self.testdata.foo)) @directory.register class ROGA2SRadio(H777Radio): VENDOR = "Radioddity" MODEL = "GA-2S" ALIASES = [] _has_fm = False SIDEKEYFUNCTION_LIST = ["Off", "Monitor", "Unused", "Alarm"] @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class H777PlusRadio(H777Radio): VENDOR = "Retevis" MODEL = "H777 Plus" ALIASES = [] _has_fm = False _has_scanmodes = False @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class BFM4Radio(H777Radio): VENDOR = "Baofeng" MODEL = "BF-M4" ALIASES = [] _has_fm = False @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class BF1901Radio(H777Radio): VENDOR = "Baofeng" MODEL = "BF-1901" PROGRAM_CMD = b'PWPG970' ALIASES = [] VALID_BANDS = (400000000, 520000000) MAX_VOXLEVEL = 9 SCANMODE_LIST = ["Time", "Carrier", "Search"] ALARM_LIST = ["Local", "Remote"] _has_fm = True _has_sidekey = False _has_scanmodes = True _has_scramble = False def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT + BF1900_SETTINGS2, self._mmap) @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class BF1904Radio(BF1901Radio): VENDOR = "Baofeng" MODEL = "BF-1904" ALIASES = [] # TODO: Is it 1 watt? POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("High", watts=10.00)] @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class MAVERICKRA100Radio(BFM4Radio): VENDOR = "Maverick" MODEL = "RA-100" ALIASES = [] @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class MAVERICKRA425Radio(BF1904Radio): VENDOR = "Maverick" MODEL = "RA-425" ALIASES = [] _has_fm = False @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False chirp-20240224/chirp/drivers/hf90.py0000644000175000017500000004547514437323351015763 0ustar hibbyhibby# Copyright 2023 Finn Thain # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, bitwise, memmap, errors, directory, util from chirp.settings import RadioSettingGroup, RadioSetting from chirp.settings import RadioSettingValueList, RadioSettingValueBoolean from chirp.settings import RadioSettingValueInteger, RadioSettings import logging LOG = logging.getLogger(__name__) HF90_MEM_FORMAT = """ #seekto 0x1800; struct { u8 type:1, f_p_program:1, unknown1:1, auto_tune:1, tx_power:2, unknown2:1, mode_toggle:1; u8 unknown3; u24 pin; u16 selcall_id; u8 unknown4; } settings; struct { u8 unknown5:3, tx_equals_rx:1, usb:1, scan:1, selcall:1, alarm:1; ul16 rx0_15; u8 tx0_3:4, rx16_19:4; ul16 tx4_19; ul16 vnum; } memory[255]; """ HF90_CONFIG_ADDR = 0x1800 HF90_CONFIG_LEN = 0x800 def to_ihex(addr, kind, data): rec = [len(data) & 0xff, (addr >> 8) & 0xff, addr & 0xff, kind & 0xff] for d in data: rec.append(d) csum = 0 for n in rec: csum += n rec.append((-csum) & 0xff) return rec def reset_buffer(pipe): pipe.reset_input_buffer() timeout = pipe.timeout pipe.timeout = 0.05 junk = pipe.read(32) count = len(junk) if count > 0: LOG.debug("reset_buffer: discarded %d bytes" % count) LOG.debug(util.hexprint(junk)) junk = pipe.read(1) count = len(junk) pipe.timeout = timeout if count > 0: raise errors.RadioError("Unable to clean serial buffer. " "Please check your serial port selection.") class HF90StyleRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Base class for HF-90 radio variants""" VENDOR = "Q-MAC" MODEL = "HF-90" MODES = ["LSB", "USB"] DUPLEX = ["", "+", "-", "split", "off"] BAUD_RATE = 4800 NEEDS_COMPAT_SERIAL = False HF90_POWER_LEVELS = ["Low", "High"] _memsize = HF90_CONFIG_ADDR + HF90_CONFIG_LEN _lower = 1 _upper = 255 def _send(self, data): LOG.debug("PC->R: (%2i)\n%s" % (len(data), util.hexprint(data))) self.pipe.write(data) echo = self.pipe.read(len(data)) if echo != data: LOG.error("Bad echo: (%2i)\n%s" % (len(data), util.hexprint(data))) def _read(self, length): data = self.pipe.read(length) LOG.debug("R->PC: (%2i)\n%s" % (len(data), util.hexprint(data))) return data def _serial_prompt(self): reset_buffer(self.pipe) self._send(b'\r') return self._read(3) == b'\r\n#' def _download_chunk(self, addr): if addr % 16: raise Exception("Addr 0x%04x not on 16-byte boundary" % addr) # Response format: # 1. Four-digit address, followed by a space # 2. 16 pairs of hex digits, each pair followed by a space # 3. One additional space # 4. 16 char ASCII representation # 5. \r\n resp_len = 5 + 48 + 1 + 16 + 2 resp = self._read(resp_len).strip() if b' ' not in resp: raise errors.RadioError("Incorrect data received from radio") words = resp.split(b' ') if addr != int(words[0], 16): raise errors.RadioError("Incorrect address received from radio") data = [] for hh in words[1:17]: data.append(int(hh, 16)) if len(data) != 16: LOG.debug(data) raise errors.RadioError("Radio sent %d bytes" % len(data)) return bytes(data) def _download(self, limit): self.pipe.baudrate = self.BAUD_RATE if not self._serial_prompt(): raise errors.RadioError("Did not get initial prompt from radio") data = b'\x00' * HF90_CONFIG_ADDR cmd = b'D%04X%04X' % (HF90_CONFIG_ADDR, limit - HF90_CONFIG_ADDR) self._send(cmd) resp = self._read(2) if resp != b'\r\n': raise errors.RadioError("Incorrect separator received from radio") for addr in range(HF90_CONFIG_ADDR, limit, 16): data += self._download_chunk(addr) if self.status_fn: status = chirp_common.Status() status.cur = addr + 16 - HF90_CONFIG_ADDR status.max = limit - HF90_CONFIG_ADDR status.msg = "Downloading from radio" self.status_fn(status) resp = self._read(3) if resp != b'\r\n#': raise errors.RadioError("Incorrect response from radio") return memmap.MemoryMapBytes(data) def _upload_chunk(self, addr): if addr % 16: raise Exception("Addr 0x%04x not on 16-byte boundary" % addr) data = self._mmap.get_byte_compatible()[addr:addr + 16] ihex_rec = to_ihex(addr, 0, list(data[0:16])) cmd = b':' + b''.join(b'%02X' % b for b in ihex_rec) LOG.debug(cmd) self._send(cmd) resp = self._read(4) if resp != b'\x13\x11\r\n': LOG.debug(util.hexprint(resp)) raise errors.RadioError("Did not receive ack from radio") def _upload(self, limit): self.pipe.baudrate = self.BAUD_RATE if not self._serial_prompt(): raise errors.RadioError("Did not get initial prompt from radio") timeout = self.pipe.timeout self.pipe.timeout = 1 self._send(b'L0000') resp = self._read(4) if resp != b'\r\n\r\n': raise errors.RadioError("Did not get initial response from radio") for addr in range(HF90_CONFIG_ADDR, limit, 16): self._upload_chunk(addr) if self.status_fn: status = chirp_common.Status() status.cur = addr + 16 - HF90_CONFIG_ADDR status.max = limit - HF90_CONFIG_ADDR status.msg = "Uploading to radio" self.status_fn(status) self._send(b':00000001FF\r') resp = self._read(5) if resp != b'\r\n\r\n#': raise errors.RadioError("Did not get final response from radio") # Reset radio # self._send(b'E') self.pipe.timeout = timeout def process_mmap(self): self._memobj = bitwise.parse(HF90_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._download(self._memsize) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): if self._memobj is None: self.process_mmap() highest_nonempty = None lowest_empty = None for i in range(self._lower, self._upper + 1): m = self.get_memory(i) if m.empty: if lowest_empty is None: lowest_empty = i else: highest_nonempty = i msgs = self.validate_memory(m) if msgs: raise Exception("Memory %d failed validation: %s" % (i, ", ".join(msgs))) if highest_nonempty is None: raise Exception("Cannot upload with no channels defined") if isinstance(self, EarlyHF90Radio): if lowest_empty is not None and lowest_empty < highest_nonempty: raise Exception( "Cannot upload with gaps between defined channels") try: self._upload(self._memsize) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) @classmethod def match_model(cls, filedata, filename): return False @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is currently under development." "\nThere are no known issues with it, but you " "should proceed with caution.\n") rp.pre_download = ("Follow these instructions to down/upload:\n" "1. Turn off your radio.\n" "2. Connect the serial interface cable.\n" "3. Turn on your radio.\n" "4. Hold down 'CHAN UP' and 'CHAN DOWN' buttons " "until 'RS-232' is displayed.\n" "5. Click OK to proceed.\n" "6. After the process completes, cycle power on " "the radio to exit RS-232 mode.\n" "Please refer to the CHIRP wiki for information " "about HF-90 serial port compatibility issues.\n") rp.pre_upload = rp.pre_download return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = True rf.has_bank = False rf.has_ctone = False rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_name = False rf.has_nostep_tuning = True rf.has_settings = True rf.has_tuning_step = False rf.memory_bounds = (self._lower, self._upper) rf.valid_bands = self.BANDS rf.valid_cross_modes = [] rf.valid_duplexes = list(self.DUPLEX) rf.valid_modes = list(self.MODES) rf.valid_skips = [] rf.valid_tmodes = [] rf.valid_tones = [] # TODO how does one make the Tone column go away? return rf def apply_txpower(self, setting, obj): v = setting.value LOG.debug("apply_power: %s" % v) obj.tx_power = 3 * self.HF90_POWER_LEVELS.index(str(v)) def apply_type(self, setting, obj): v = setting.value LOG.debug("apply_type: %s %d" % (v, obj.type)) obj.type = self.HF90_TYPES.index(str(v)) def apply_selcall_id(self, setting, obj): v = setting.value LOG.debug("apply_selcall_id: %s %x" % (v, obj.selcall_id)) if isinstance(self, EarlyHF90Radio): # BCD, big endian, left aligned, "f" padded s = "%-4d" % int(v) s = s.replace(" ", "f") else: # BCD, big endian, right aligned, "0" padded s = "%04d" % int(v) obj.selcall_id = int(s[0:4], 16) def _get_selcall_id(self, _settings): s = "%04x" % _settings.selcall_id try: i = int(s.rstrip("f")) except ValueError: i = 9999 return i def get_settings(self): _settings = self._memobj.settings LOG.debug("get_settings: %s %s" % (type(self), self.MODEL)) grp = RadioSettingGroup("settings", "Settings") rs = RadioSetting("type", "Type", RadioSettingValueList( self.HF90_TYPES, self.HF90_TYPES[_settings.type])) rs.set_apply_callback(self.apply_type, _settings) grp.append(rs) if isinstance(self, EarlyHF90Radio): rs = RadioSetting("selcall_id", "Selcall ID (0 for standard type)", RadioSettingValueInteger( 0, 9999, self._get_selcall_id(_settings))) rs.set_apply_callback(self.apply_selcall_id, _settings) grp.append(rs) else: rs = RadioSetting("selcall_id", "Selcall ID", RadioSettingValueInteger( 1, 9999, self._get_selcall_id(_settings))) rs.set_apply_callback(self.apply_selcall_id, _settings) grp.append(rs) rs = RadioSetting("f_p_program", "Front panel programming", RadioSettingValueBoolean(_settings.f_p_program)) grp.append(rs) rs = RadioSetting("auto_tune", "Auto tuning", RadioSettingValueBoolean(_settings.auto_tune)) grp.append(rs) rs = RadioSetting("mode_toggle", "Mode toggling", RadioSettingValueBoolean(_settings.mode_toggle)) grp.append(rs) hp = int(_settings.tx_power == 3) rs = RadioSetting("tx_power", "Tx Power", RadioSettingValueList(self.HF90_POWER_LEVELS, self.HF90_POWER_LEVELS[hp])) rs.set_apply_callback(self.apply_txpower, _settings) grp.append(rs) return RadioSettings(grp) def set_settings(self, uisettings): _settings = self._memobj.settings for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: name = element.get_name() value = element.value if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: setattr(_settings, name, value) LOG.debug("Setting %s: %s" % (name, value)) except Exception: LOG.debug(element.get_name()) raise def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number _rx = _mem.rx0_15 | (_mem.rx16_19 << 16) _tx = _mem.tx0_3 | (_mem.tx4_19 << 4) mem.empty = _rx == 0 or _mem.vnum == 0 if not mem.empty: if (_tx == _rx) ^ _mem.tx_equals_rx: LOG.warn("get_memory(%d): tx_equals_rx incorrect" % number) if 0 < _rx * 100 < self._min_rx_freq: LOG.warn("get_memory(%d): rx frequency too low" % number) if _rx * 100 >= self._max_freq: LOG.warn("get_memory(%d): rx frequency too high" % number) if 0 < _tx * 100 < self._min_tx_freq: LOG.warn("get_memory(%d): tx frequency too low" % number) if _tx * 100 >= self._max_freq: LOG.warn("get_memory(%d): tx frequency too high" % number) mem.freq = int(_rx) * 100 if _tx == 0: mem.duplex = "off" mem.offset = 0 elif _tx > _rx: mem.duplex = "+" mem.offset = (int(_tx) - int(_rx)) * 100 elif _tx < _rx: mem.duplex = "-" mem.offset = (int(_rx) - int(_tx)) * 100 else: mem.duplex = "" mem.offset = 0 if _mem.usb: mem.mode = "USB" else: mem.mode = "LSB" n = _mem.vnum & 0xff if n == 0: n = number rsg = RadioSettingGroup("Extra", "extra") rs = RadioSetting("vnum", "Number", RadioSettingValueInteger(self._lower, self._upper, n)) rsg.append(rs) rs = RadioSetting("selcall", "Selcall", RadioSettingValueBoolean(_mem.selcall)) rsg.append(rs) rs = RadioSetting("scan", "Scan", RadioSettingValueBoolean(_mem.scan)) rsg.append(rs) mem.extra = rsg return mem def _get_tx_freq(self, mem): if mem.duplex == "": return mem.freq elif mem.duplex == "split": return mem.offset elif mem.duplex == "+": return mem.freq + mem.offset elif mem.duplex == "-": return mem.freq - mem.offset return 0 def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _mem.set_raw("\x00" * 8) if mem.empty: return rx = int(mem.freq / 100) tx = int(self._get_tx_freq(mem) / 100) _mem.tx_equals_rx = tx == rx _mem.rx0_15 = (rx >> 0) & 0xffff _mem.rx16_19 = (rx >> 16) & 0xf _mem.tx0_3 = (tx >> 0) & 0xf _mem.tx4_19 = (tx >> 4) & 0xffff _mem.usb = mem.mode == "USB" _mem.vnum = mem.number for setting in mem.extra: setattr(_mem, setting.get_name(), int(setting.value)) def validate_memory(self, mem): msgs = chirp_common.CloneModeRadio.validate_memory(self, mem) if 0 < self._get_tx_freq(mem) < self._min_tx_freq: msgs.append(chirp_common.ValidationWarning( "tx frequency too low")) if mem.extra and isinstance(self, EarlyHF90Radio): if self._memobj.settings.selcall_id == 0x0fff: if mem.extra["scan"].value or mem.extra["selcall"].value: msgs.append(chirp_common.ValidationWarning( "standard type but scan or selcall enabled")) else: if mem.extra["scan"].value and not mem.extra["selcall"].value: msgs.append(chirp_common.ValidationWarning( "scan enabled but selcall disabled")) return msgs # EarlyHF90Radio imitates version 2 of the dealer software whereas # LateHF90Radio imitates version 3. It seems both are needed because # version 3 warns that it is incompatible with firmware revisions below V301. # Unfortunately, the author does not have access to the technical information # required to better accommodate the quirks of the various firmware revisions. @directory.register class EarlyHF90Radio(HF90StyleRadio): """Base class for early HF-90 radios""" VARIANT = "v300 or earlier" _min_rx_freq = 2000000 _min_tx_freq = 2000000 _max_freq = 30000000 BANDS = [(_min_rx_freq, _max_freq)] HF90_TYPES = ["HF-90A (Australia)", "HF-90E (Export)"] @directory.register class LateHF90Radio(HF90StyleRadio): """Base class for late HF-90 radios""" VARIANT = "v301 or later" _min_rx_freq = 500000 _min_tx_freq = 1800000 _max_freq = 30000000 # band is split into two pieces to avoid unit test failures BANDS = [(_min_rx_freq, _min_tx_freq), (_min_tx_freq, _max_freq)] HF90_TYPES = ["Standard", "Advanced"] if __name__ == "__main__": import sys import serial s = serial.Serial(port=sys.argv[1], baudrate=4800, timeout=0.1) reset_buffer(s) s.write(b"\r") print(s.read(32)) print(s.out_waiting) chirp-20240224/chirp/drivers/ic9x_icf_ll.py0000644000175000017500000000733514411666130017367 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct from chirp import chirp_common from chirp.memmap import MemoryMap MEM_LOC_SIZE_A = 20 MEM_LOC_SIZE_B = MEM_LOC_SIZE_A + 1 + (3 * 8) POS_FREQ = 0 POS_OFFSET = 3 POS_TONE = 5 POS_MODE = 6 POS_DTCS = 7 POS_TS = 8 POS_DTCSPOL = 11 POS_DUPLEX = 11 POS_NAME = 12 def get_mem_offset(number): """Get the offset into the memory map for memory @number""" if number < 850: return MEM_LOC_SIZE_A * number else: return (MEM_LOC_SIZE_A * 850) + (MEM_LOC_SIZE_B * (number - 850)) def get_raw_memory(mmap, number): """Return a raw representation of memory @number""" offset = get_mem_offset(number) if number >= 850: size = MEM_LOC_SIZE_B else: size = MEM_LOC_SIZE_A return MemoryMap(mmap[offset:offset+size]) def get_freq(mmap): """Return the memory frequency""" if ord(mmap[10]) & 0x10: mult = 6250 else: mult = 5000 val, = struct.unpack(">I", "\x00" + mmap[POS_FREQ:POS_FREQ+3]) return val * mult def get_offset(mmap): """Return the memory offset""" val, = struct.unpack(">H", mmap[POS_OFFSET:POS_OFFSET+2]) return val * 5000 def get_rtone(mmap): """Return the memory rtone""" val = (ord(mmap[POS_TONE]) & 0xFC) >> 2 return chirp_common.TONES[val] def get_ctone(mmap): """Return the memory ctone""" val = (ord(mmap[POS_TONE]) & 0x03) | ((ord(mmap[POS_TONE+1]) & 0xF0) >> 4) return chirp_common.TONES[val] def get_dtcs(mmap): """Return the memory dtcs value""" val = ord(mmap[POS_DTCS]) >> 1 return chirp_common.DTCS_CODES[val] def get_mode(mmap): """Return the memory mode""" val = ord(mmap[POS_MODE]) & 0x07 modemap = ["FM", "NFM", "WFM", "AM", "DV", "FM"] return modemap[val] def get_ts(mmap): """Return the memory tuning step""" val = (ord(mmap[POS_TS]) & 0xF0) >> 4 if val == 14: return 5.0 # Coerce "Auto" to 5.0 icf_ts = list(chirp_common.TUNING_STEPS) icf_ts.insert(2, 8.33) icf_ts.insert(3, 9.00) icf_ts.append(100.0) icf_ts.append(125.0) icf_ts.append(200.0) return icf_ts[val] def get_dtcs_polarity(mmap): """Return the memory dtcs polarity""" val = (ord(mmap[POS_DTCSPOL]) & 0x03) pols = ["NN", "NR", "RN", "RR"] return pols[val] def get_duplex(mmap): """Return the memory duplex""" val = (ord(mmap[POS_DUPLEX]) & 0x0C) >> 2 dup = ["", "-", "+", ""] return dup[val] def get_name(mmap): """Return the memory name""" return mmap[POS_NAME:POS_NAME+8] def get_memory(_mmap, number): """Get memory @number from global memory map @_mmap""" mmap = get_raw_memory(_mmap, number) mem = chirp_common.Memory() mem.number = number mem.freq = get_freq(mmap) mem.offset = get_offset(mmap) mem.rtone = get_rtone(mmap) mem.ctone = get_ctone(mmap) mem.dtcs = get_dtcs(mmap) mem.mode = get_mode(mmap) mem.tuning_step = get_ts(mmap) mem.dtcs_polarity = get_dtcs_polarity(mmap) mem.duplex = get_duplex(mmap) mem.name = get_name(mmap) mem.empty = mem.freq == 0 return mem chirp-20240224/chirp/drivers/th9800.py0000644000175000017500000006665114522135005016140 0ustar hibbyhibby# Copyright 2014 Tom Hayward # Copyright 2014 Jens Jensen # Copyright 2014 James Lee N1DDK # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import bitwise, chirp_common, directory, errors, util, memmap import struct from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings from chirp.chirp_common import format_freq import logging from datetime import date LOG = logging.getLogger(__name__) TH9800_MEM_FORMAT = """ struct mem { lbcd rx_freq[4]; lbcd tx_freq[4]; lbcd ctcss[2]; lbcd dtcs[2]; u8 power:2, BeatShift:1, unknown0a:2, display:1, // freq=0, name=1 scan:2; u8 fmdev:2, // wide=00, mid=01, narrow=10 scramb:1, compand:1, emphasis:1, unknown1a:2, sqlmode:1; // carrier, tone u8 rptmod:2, // off, -, + reverse:1, talkaround:1, step:4; u8 dtcs_pol:2, bclo:2, unknown3:2, tmode:2; lbcd offset[4]; u8 hsdtype:2, // off, 2-tone, 5-tone, dtmf unknown5a:1, am:1, unknown5b:4; u8 unknown6[3]; char name[6]; u8 empty[2]; }; #seekto 0x%04X; struct mem memory[800]; #seekto 0x%04X; struct { struct mem lower; struct mem upper; } scanlimits[5]; #seekto 0x%04X; struct { u8 unk0xdc20:5, left_sql:3; u8 apo; u8 unk0xdc22:5, backlight:3; u8 unk0xdc23; u8 beep:1, keylock:1, pttlock:2, unk0xdc24_32:2, hyper_chan:1, right_func_key:1; u8 tbst_freq:2, ani_display:1, unk0xdc25_4:1, mute_mode:2, unk0xdc25_10:2; u8 auto_xfer:1, auto_contact:1, unk0xdc26_54:2, auto_am:1, unk0xdc26_210:3; u8 unk0xdc27_76543:5, scan_mode:1, unk0xdc27_1:1, scan_resume:1; u16 scramb_freq; u16 scramb_freq1; u8 exit_delay; u8 unk0xdc2d; u8 unk0xdc2e:5, right_sql:3; u8 unk0xdc2f:4, beep_vol:4; u8 tot; u8 tot_alert; u8 tot_rekey; u8 tot_reset; u8 unk0xdc34; u8 unk0xdc35; u8 unk0xdc36; u8 unk0xdc37; u8 p1; u8 p2; u8 p3; u8 p4; } settings; #seekto 0x%04X; u8 chan_active[128]; u8 scan_enable[128]; u8 priority[128]; #seekto 0x%04X; struct { char sn[8]; char model[8]; char code[16]; u8 empty[8]; lbcd prog_yr[2]; lbcd prog_mon; lbcd prog_day; u8 empty_10f2c[4]; } info; struct { lbcd lorx[4]; lbcd hirx[4]; lbcd lotx[4]; lbcd hitx[4]; } bandlimits[9]; """ BLANK_MEMORY = "\xFF" * 8 + "\x00\x10\x23\x00\xC0\x08\x06\x00" \ "\x00\x00\x76\x00\x00\x00" + "\xFF" * 10 DTCS_POLARITY = ["NN", "RN", "NR", "RR"] SCAN_MODES = ["", "S", "P"] MODES = ["WFM", "FM", "NFM"] TMODES = ["", "Tone", "TSQL", "DTCS"] POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5.00), chirp_common.PowerLevel("Mid2", watts=10.00), chirp_common.PowerLevel("Mid1", watts=20.00), chirp_common.PowerLevel("High", watts=50.00)] BUSY_LOCK = ["off", "Carrier", "2 tone"] MICKEYFUNC = ["None", "SCAN", "SQL.OFF", "TCALL", "PPTR", "PRI", "LOW", "TONE", "MHz", "REV", "HOME", "BAND", "VFO/MR"] SQLPRESET = ["Off", "2", "5", "9", "Full"] BANDS = ["30 MHz", "50 MHz", "60 MHz", "108 MHz", "150 MHz", "250 MHz", "350 MHz", "450 MHz", "850 MHz"] STEPS = [2.5, 5.0, 6.25, 7.5, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] def isValidDate(month, day, year): today = date.today() monthlist1 = [1, 3, 5, 7, 8, 10, 12] # monthlist for months with 31 days. monthlist2 = [4, 6, 9, 11] # monthlist for months with 30 days. monthlist3 = [2, ] # monthlist for month with 28 days. if month in monthlist1: max1 = 31 elif month in monthlist2: max1 = 30 elif month in monthlist3: if ((year % 4) == 0 and (year % 100) != 0 or (year % 400) == 0): max1 = 29 else: max1 = 28 if (month < 1 or month > 12): LOG.debug("Invalid 'Last Program Date: Month'") return False elif (day < 1 or day > max1): LOG.debug("Invalid 'Last Program Date: Day'") return False elif (year < 2014 or year > today.year): LOG.debug("Invalid 'Last Program Date: Year'") return False return True class TYTTH9800Base(chirp_common.Radio): """Base class for TYT TH-9800""" VENDOR = "TYT" NEEDS_COMPAT_SERIAL = False def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 800) rf.has_bank = False rf.has_tuning_step = True rf.valid_tuning_steps = STEPS rf.can_odd_split = True rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = TMODES rf.has_ctone = False rf.valid_power_levels = POWER_LEVELS rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "#*-+" rf.valid_bands = [(26000000, 33000000), (47000000, 54000000), (108000000, 180000000), (220000000, 260000000), (350000000, 399995000), (400000000, 512000000), (750000000, 950000000)] rf.valid_skips = SCAN_MODES rf.valid_modes = MODES + ["AM"] rf.valid_name_length = 6 rf.has_settings = True return rf def process_mmap(self): self._memobj = bitwise.parse( TH9800_MEM_FORMAT % (self._mmap_offset, self._scanlimits_offset, self._settings_offset, self._chan_active_offset, self._info_offset), self._mmap) def get_active(self, banktype, num): """get active flag for channel active, scan enable, or priority banks""" bank = getattr(self._memobj, banktype) index = (num - 1) // 8 bitpos = (num - 1) % 8 mask = 2**bitpos enabled = bank[index] & mask if enabled: return True else: return False def set_active(self, banktype, num, enable=True): """set active flag for channel active, scan enable, or priority banks""" bank = getattr(self._memobj, banktype) index = (num - 1) // 8 bitpos = (num - 1) % 8 mask = 2**bitpos if enable: bank[index] |= mask else: bank[index] &= ~mask def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.empty = not self.get_active("chan_active", number) if mem.empty: return mem mem.freq = int(_mem.rx_freq) * 10 txfreq = int(_mem.tx_freq) * 10 if txfreq == mem.freq: mem.duplex = "" elif txfreq == 0: mem.duplex = "off" mem.offset = 0 elif abs(txfreq - mem.freq) > 70000000: mem.duplex = "split" mem.offset = txfreq elif txfreq < mem.freq: mem.duplex = "-" mem.offset = mem.freq - txfreq elif txfreq > mem.freq: mem.duplex = "+" mem.offset = txfreq - mem.freq mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_pol] mem.tmode = TMODES[int(_mem.tmode)] mem.ctone = mem.rtone = int(_mem.ctcss) / 10.0 mem.dtcs = int(_mem.dtcs) mem.name = str(_mem.name) mem.name = mem.name.replace("\xFF", " ").rstrip() if not self.get_active("scan_enable", number): mem.skip = "S" elif self.get_active("priority", number): mem.skip = "P" else: mem.skip = "" mem.mode = _mem.am and "AM" or MODES[int(_mem.fmdev)] mem.power = POWER_LEVELS[_mem.power] mem.tuning_step = STEPS[_mem.step] mem.extra = RadioSettingGroup("extra", "Extra") opts = ["Frequency", "Name"] display = RadioSetting( "display", "Display", RadioSettingValueList(opts, opts[_mem.display])) mem.extra.append(display) bclo = RadioSetting( "bclo", "Busy Lockout", RadioSettingValueList(BUSY_LOCK, BUSY_LOCK[_mem.bclo])) bclo.set_doc("Busy Lockout") mem.extra.append(bclo) emphasis = RadioSetting( "emphasis", "Emphasis", RadioSettingValueBoolean(bool(_mem.emphasis))) emphasis.set_doc("Boosts 300 Hz to 2500 Hz mic response") mem.extra.append(emphasis) compand = RadioSetting( "compand", "Compand", RadioSettingValueBoolean(bool(_mem.compand))) compand.set_doc("Compress Audio") mem.extra.append(compand) BeatShift = RadioSetting( "BeatShift", "BeatShift", RadioSettingValueBoolean(bool(_mem.BeatShift))) BeatShift.set_doc("Beat Shift") mem.extra.append(BeatShift) TalkAround = RadioSetting( "talkaround", "Talk Around", RadioSettingValueBoolean(bool(_mem.talkaround))) TalkAround.set_doc("Simplex mode when out of range of repeater") mem.extra.append(TalkAround) scramb = RadioSetting( "scramb", "Scramble", RadioSettingValueBoolean(bool(_mem.scramb))) scramb.set_doc("Frequency inversion Scramble") mem.extra.append(scramb) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _prev_active = self.get_active("chan_active", mem.number) self.set_active("chan_active", mem.number, not mem.empty) if mem.empty or not _prev_active: LOG.debug("initializing memory channel %d" % mem.number) _mem.set_raw(BLANK_MEMORY) if mem.empty: return _mem.rx_freq = mem.freq / 10 if mem.duplex == "split": _mem.tx_freq = mem.offset / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "off": _mem.tx_freq = 0 _mem.offset = 0 else: _mem.tx_freq = mem.freq / 10 _mem.tmode = TMODES.index(mem.tmode) if mem.tmode == "TSQL" or mem.tmode == "DTCS": _mem.sqlmode = 1 else: _mem.sqlmode = 0 _mem.ctcss = mem.rtone * 10 _mem.dtcs = mem.dtcs _mem.dtcs_pol = DTCS_POLARITY.index(mem.dtcs_polarity) _mem.name = mem.name.ljust(6, "\xFF") # autoset display to name if filled, else show frequency if mem.extra: # mem.extra only seems to be populated when called from edit panel display = mem.extra["display"] else: display = None if mem.name: _mem.display = True else: _mem.display = False _mem.scan = SCAN_MODES.index(mem.skip) if mem.skip == "P": self.set_active("priority", mem.number, True) self.set_active("scan_enable", mem.number, True) elif mem.skip == "S": self.set_active("priority", mem.number, False) self.set_active("scan_enable", mem.number, False) elif mem.skip == "": self.set_active("priority", mem.number, False) self.set_active("scan_enable", mem.number, True) if mem.mode == "AM": _mem.am = True _mem.fmdev = 0 else: _mem.am = False _mem.fmdev = MODES.index(mem.mode) if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 # low _mem.step = STEPS.index(mem.tuning_step) for setting in mem.extra: LOG.debug("@set_mem: %s %s", setting.get_name(), setting.value) setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings _info = self._memobj.info _bandlimits = self._memobj.bandlimits basic = RadioSettingGroup("basic", "Basic") info = RadioSettingGroup("info", "Model Info") top = RadioSettings(basic, info) basic.append(RadioSetting( "beep", "Beep", RadioSettingValueBoolean(_settings.beep))) basic.append(RadioSetting( "beep_vol", "Beep Volume", RadioSettingValueInteger(0, 15, _settings.beep_vol))) basic.append(RadioSetting( "keylock", "Key Lock", RadioSettingValueBoolean(_settings.keylock))) basic.append(RadioSetting( "ani_display", "ANI Display", RadioSettingValueBoolean(_settings.ani_display))) basic.append(RadioSetting( "auto_xfer", "Auto Transfer", RadioSettingValueBoolean(_settings.auto_xfer))) basic.append(RadioSetting( "auto_contact", "Auto Contact Always Remind", RadioSettingValueBoolean(_settings.auto_contact))) basic.append(RadioSetting( "auto_am", "Auto AM", RadioSettingValueBoolean(_settings.auto_am))) basic.append(RadioSetting( "left_sql", "Left Squelch", RadioSettingValueList( SQLPRESET, SQLPRESET[_settings.left_sql]))) basic.append(RadioSetting( "right_sql", "Right Squelch", RadioSettingValueList( SQLPRESET, SQLPRESET[_settings.right_sql]))) # basic.append(RadioSetting("apo", "Auto Power off (0.1h)", # RadioSettingValueInteger(0, 20, _settings.apo))) opts = ["Off"] + ["%0.1f" % (t / 10.0) for t in range(1, 21, 1)] basic.append(RadioSetting( "apo", "Auto Power off (Hours)", RadioSettingValueList(opts, opts[_settings.apo]))) opts = ["Off", "1", "2", "3", "Full"] basic.append(RadioSetting( "backlight", "Display Backlight", RadioSettingValueList(opts, opts[_settings.backlight]))) opts = ["Off", "Right", "Left", "Both"] basic.append(RadioSetting( "pttlock", "PTT Lock", RadioSettingValueList(opts, opts[_settings.pttlock]))) opts = ["Manual", "Auto"] basic.append(RadioSetting( "hyper_chan", "Hyper Channel", RadioSettingValueList(opts, opts[_settings.hyper_chan]))) opts = ["Key 1", "Key 2"] basic.append(RadioSetting( "right_func_key", "Right Function Key", RadioSettingValueList(opts, opts[_settings.right_func_key]))) opts = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] basic.append(RadioSetting( "tbst_freq", "Tone Burst Frequency", RadioSettingValueList(opts, opts[_settings.tbst_freq]))) opts = ["Off", "TX", "RX", "TX RX"] basic.append(RadioSetting( "mute_mode", "Mute Mode", RadioSettingValueList(opts, opts[_settings.mute_mode]))) opts = ["MEM", "MSM"] scanmode = RadioSetting( "scan_mode", "Scan Mode", RadioSettingValueList(opts, opts[_settings.scan_mode])) scanmode.set_doc("MEM = Normal scan, bypass channels marked skip. " " MSM = Scan only channels marked priority.") basic.append(scanmode) opts = ["TO", "CO"] basic.append(RadioSetting( "scan_resume", "Scan Resume", RadioSettingValueList(opts, opts[_settings.scan_resume]))) opts = ["%0.1f" % (t / 10.0) for t in range(0, 51, 1)] basic.append(RadioSetting( "exit_delay", "Span Transit Exit Delay", RadioSettingValueList(opts, opts[_settings.exit_delay]))) basic.append(RadioSetting( "tot", "Time Out Timer (minutes)", RadioSettingValueInteger(0, 30, _settings.tot))) basic.append(RadioSetting( "tot_alert", "Time Out Timer Pre Alert(seconds)", RadioSettingValueInteger(0, 15, _settings.tot_alert))) basic.append(RadioSetting( "tot_rekey", "Time Out Rekey (seconds)", RadioSettingValueInteger(0, 15, _settings.tot_rekey))) basic.append(RadioSetting( "tot_reset", "Time Out Reset(seconds)", RadioSettingValueInteger(0, 15, _settings.tot_reset))) basic.append(RadioSetting( "p1", "P1 Function", RadioSettingValueList(MICKEYFUNC, MICKEYFUNC[_settings.p1]))) basic.append(RadioSetting( "p2", "P2 Function", RadioSettingValueList(MICKEYFUNC, MICKEYFUNC[_settings.p2]))) basic.append(RadioSetting( "p3", "P3 Function", RadioSettingValueList(MICKEYFUNC, MICKEYFUNC[_settings.p3]))) basic.append(RadioSetting( "p4", "P4 Function", RadioSettingValueList(MICKEYFUNC, MICKEYFUNC[_settings.p4]))) # opts = ["0", "1"] # basic.append(RadioSetting("x", "Desc", # RadioSettingValueList(opts, opts[_settings.x]))) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered rsvs = RadioSettingValueString(0, 8, _filter(_info.sn)) rsvs.set_mutable(False) rs = RadioSetting("sn", "Serial Number", rsvs) info.append(rs) rsvs = RadioSettingValueString(0, 8, _filter(_info.model)) rsvs.set_mutable(False) rs = RadioSetting("model", "Model Name", rsvs) info.append(rs) rsvs = RadioSettingValueString(0, 16, _filter(_info.code)) rsvs.set_mutable(False) rs = RadioSetting("code", "Model Code", rsvs) info.append(rs) mm = int(_info.prog_mon) dd = int(_info.prog_day) yy = int(_info.prog_yr) Valid_Date = isValidDate(mm, dd, yy) if Valid_Date: progdate = "%d/%d/%d" % (mm, dd, yy) else: progdate = "Invalid" rsvs = RadioSettingValueString(0, 10, progdate) rsvs.set_mutable(False) rs = RadioSetting("progdate", "Last Program Date", rsvs) info.append(rs) # 9 band limits for i in range(0, 9): objname = BANDS[i] + "lorx" objnamepp = BANDS[i] + " Rx Start" # rsv = RadioSettingValueInteger(0, 100000000, # int(_bandlimits[i].lorx)) rsv = RadioSettingValueString( 0, 10, format_freq(int(_bandlimits[i].lorx)*10)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) objname = BANDS[i] + "hirx" objnamepp = BANDS[i] + " Rx end" rsv = RadioSettingValueString( 0, 10, format_freq(int(_bandlimits[i].hirx)*10)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) objname = BANDS[i] + "lotx" objnamepp = BANDS[i] + " Tx Start" rsv = RadioSettingValueString( 0, 10, format_freq(int(_bandlimits[i].lotx)*10)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) objname = BANDS[i] + "hitx" objnamepp = BANDS[i] + " Tx end" rsv = RadioSettingValueString( 0, 10, format_freq(int(_bandlimits[i].hitx)*10)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) return top def set_settings(self, settings): _settings = self._memobj.settings _info = self._memobj.info _bandlimits = self._memobj.bandlimits for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() oldval = getattr(_settings, setting) newval = element.value LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise @directory.register class TYTTH9800File(TYTTH9800Base, chirp_common.FileBackedRadio): """TYT TH-9800 .dat file""" MODEL = "TH-9800 File" FILE_EXTENSION = "dat" _memsize = 69632 _mmap_offset = 0x1100 _scanlimits_offset = 0xC800 + _mmap_offset _settings_offset = 0xCB20 + _mmap_offset _chan_active_offset = 0xCB80 + _mmap_offset _info_offset = 0xfe00 + _mmap_offset def __init__(self, pipe): self.errors = [] self._mmap = None if isinstance(pipe, str): self.pipe = None self.load_mmap(pipe) else: chirp_common.FileBackedRadio.__init__(self, pipe) @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and filename.endswith('.dat') def _identify(radio): """Do identify handshake with TYT""" try: radio.pipe.write(b"\x02PROGRA") ack = radio.pipe.read(1) if ack != b"A": util.hexprint(ack) raise errors.RadioError("Radio did not ACK first command: %x" % ord(ack)) except: LOG.debug(util.hexprint(ack)) raise errors.RadioError("Unable to communicate with the radio") radio.pipe.write(b"M\x02") ident = radio.pipe.read(16) radio.pipe.write(b"A") r = radio.pipe.read(1) if r != b"A": raise errors.RadioError("Ack failed") return ident def _download(radio, memsize=0x10000, blocksize=0x80): """Download from TYT TH-9800""" data = _identify(radio) LOG.info("ident:\n%s", util.hexprint(data)) offset = 0x100 for addr in range(offset, memsize, blocksize): msg = struct.pack(">cHB", b"R", addr, blocksize) radio.pipe.write(msg) block = radio.pipe.read(blocksize + 4) if len(block) != (blocksize + 4): LOG.debug(util.hexprint(block)) raise errors.RadioError("Radio sent a short block") radio.pipe.write(b"A") ack = radio.pipe.read(1) if ack != b"A": LOG.debug(util.hexprint(ack)) raise errors.RadioError("Radio NAKed block") data += block[4:] if radio.status_fn: status = chirp_common.Status() status.cur = addr status.max = memsize status.msg = "Cloning from radio" radio.status_fn(status) radio.pipe.write(b"ENDR") return memmap.MemoryMapBytes(data) def _upload(radio, memsize=0xF400, blocksize=0x80): """Upload to TYT TH-9800""" data = _identify(radio) radio.pipe.timeout = 1 if data != radio._mmap[0:radio._mmap_offset]: raise errors.RadioError( "Model mismatch: \n%s\n%s" % (util.hexprint(data), util.hexprint(radio._mmap[:radio._mmap_offset]))) # in the factory software they update the last program date when # they upload, So let's do the same today = date.today() y = today.year m = today.month d = today.day _info = radio._memobj.info ly = int(_info.prog_yr) lm = int(_info.prog_mon) ld = int(_info.prog_day) Valid_Date = isValidDate(lm, ld, ly) if Valid_Date: LOG.debug("Updating last program date:%d/%d/%d" % (lm, ld, ly)) else: LOG.debug("Updating last program date: Invalid") LOG.debug(" to today:%d/%d/%d" % (m, d, y)) _info.prog_yr = y _info.prog_mon = m _info.prog_day = d offset = 0x0100 for addr in range(offset, memsize, blocksize): mapaddr = addr + radio._mmap_offset - offset LOG.debug("addr: 0x%04X, mmapaddr: 0x%04X" % (addr, mapaddr)) msg = struct.pack(">cHB", b"W", addr, blocksize) msg += radio._mmap[mapaddr:(mapaddr + blocksize)] LOG.debug(util.hexprint(msg)) radio.pipe.write(msg) ack = radio.pipe.read(1) if ack != b"A": LOG.debug(util.hexprint(ack)) raise errors.RadioError("Radio did not ack block 0x%04X" % addr) if radio.status_fn: status = chirp_common.Status() status.cur = addr status.max = memsize status.msg = "Cloning to radio" radio.status_fn(status) # End of clone radio.pipe.write(b"ENDW") # Checksum? final_data = radio.pipe.read(3) LOG.debug("final:\n%s" % util.hexprint(final_data)) @directory.register class TYTTH9800Radio(TYTTH9800Base, chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): VENDOR = "TYT" MODEL = "TH-9800" BAUD_RATE = 38400 _memsize = 65296 _mmap_offset = 0x0010 _scanlimits_offset = 0xC800 + _mmap_offset _settings_offset = 0xCB20 + _mmap_offset _chan_active_offset = 0xCB80 + _mmap_offset _info_offset = 0xfe00 + _mmap_offset @classmethod def match_model(cls, filedata, filename): if len(filedata) != cls._memsize: return False # TYT set this model for TH-7800 _AND_ TH-9800 if not filedata[0xfe18:0xfe1e] == b"TH9800": return False # TH-9800 bandlimits differ from TH-7800. First band is used # (non-zero). first_bandlimit = struct.unpack("BBBBBBBBBBBBBBBB", filedata[0xfe40:0xfe50]) if all(v == 0 for v in first_bandlimit): return False return True @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ( 'This is experimental support for TH-9800 ' 'which is still under development.\n' 'Please ensure you have a good backup with OEM software.\n' 'Also please send in bug and enhancement requests!\n' 'You have been warned. Proceed at your own risk!') return rp def sync_in(self): try: self._mmap = _download(self) except Exception as e: raise errors.RadioError( "Failed to communicate with the radio: %s" % e) self.process_mmap() def sync_out(self): try: _upload(self) except Exception as e: raise errors.RadioError( "Failed to communicate with the radio: %s" % e) chirp-20240224/chirp/drivers/ic2200.py0000644000175000017500000002063514411666130016100 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, util, directory, bitwise MEM_FORMAT = """ struct { ul16 freq; ul16 offset; char name[6]; u8 unknown1:2, rtone:6; u8 unknown2:2, ctone:6; u8 unknown3:1, dtcs:7; u8 unknown4:4, tuning_step:4; u8 unknown5[3]; u8 unknown6:4, urcall:4; u8 r1call:4, r2call:4; u8 unknown7:1, digital_code:7; u8 is_625:1, unknown8:1, mode_am:1, mode_narrow:1, power:2, tmode:2; u8 dtcs_polarity:2, duplex:2, unknown10:4; u8 unknown11; u8 mode_dv:1, unknown12:7; } memory[207]; #seekto 0x1370; struct { u8 unknown:2, empty:1, skip:1, bank:4; } flags[207]; #seekto 0x15F0; struct { char call[8]; } mycalls[6]; struct { char call[8]; } urcalls[6]; struct { char call[8]; } rptcalls[6]; """ TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+"] DTCSP = ["NN", "NR", "RN", "RR"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=65), chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("MidLow", watts=10), chirp_common.PowerLevel("Mid", watts=25)] def _get_special(): special = {"C": 206} for i in range(0, 3): ida = "%iA" % (i+1) idb = "%iB" % (i+1) num = 200 + i * 2 special[ida] = num special[idb] = num + 1 return special def _wipe_memory(mem, char): mem.set_raw(char * (mem.size() // 8)) @directory.register class IC2200Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): """Icom IC-2200""" VENDOR = "Icom" MODEL = "IC-2200H" _model = "\x26\x98\x00\x01" _memsize = 6848 _endframe = "Icom Inc\x2eD8" _can_hispeed = True _memories = [] _ranges = [(0x0000, 0x1340, 32), (0x1340, 0x1360, 16), (0x1360, 0x136B, 8), (0x1370, 0x1380, 16), (0x1380, 0x15E0, 32), (0x15E0, 0x1600, 16), (0x1600, 0x1640, 32), (0x1640, 0x1660, 16), (0x1660, 0x1680, 32), (0x16E0, 0x1860, 32), (0x1880, 0x1AB0, 32), (0x1AB8, 0x1AC0, 8), ] MYCALL_LIMIT = (0, 6) URCALL_LIMIT = (0, 6) RPTCALL_LIMIT = (0, 6) def _get_bank(self, loc): _flag = self._memobj.flags[loc] if _flag.bank == 0x0A: return None else: return _flag.bank def _set_bank(self, loc, bank): _flag = self._memobj.flags[loc] if bank is None: _flag.bank = 0x0A else: _flag.bank = bank def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.valid_modes = ["FM", "NFM", "AM", "NAM", "DV"] rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(118000000, 174000000)] rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS rf.valid_special_chans = sorted(_get_special().keys()) rf.has_settings = True return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_memory(self, number): if isinstance(number, str): number = _get_special()[number] _mem = self._memobj.memory[number] _flag = self._memobj.flags[number] if _mem.mode_dv and not _flag.empty: mem = chirp_common.DVMemory() mem.dv_urcall = \ str(self._memobj.urcalls[_mem.urcall].call).rstrip() mem.dv_rpt1call = \ str(self._memobj.rptcalls[_mem.r1call].call).rstrip() mem.dv_rpt2call = \ str(self._memobj.rptcalls[_mem.r2call].call).rstrip() else: mem = chirp_common.Memory() mem.number = number if number < 200: mem.skip = _flag.skip and "S" or "" else: mem.extd_number = util.get_dict_rev(_get_special(), number) mem.immutable = ["number", "skip", "bank", "bank_index", "extd_number"] if _flag.empty: mem.empty = True mem.power = POWER_LEVELS[0] return mem mult = _mem.is_625 and 6250 or 5000 mem.freq = (_mem.freq * mult) mem.offset = (_mem.offset * mult) mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.mode = _mem.mode_dv and "DV" or _mem.mode_am and "AM" or "FM" if _mem.mode_narrow: mem.mode = "N%s" % mem.mode mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCSP[_mem.dtcs_polarity] mem.tuning_step = STEPS[_mem.tuning_step] mem.name = str(_mem.name).replace("\x0E", "").rstrip() mem.power = POWER_LEVELS[_mem.power] return mem def get_memories(self, lo=0, hi=199): return [m for m in self._memories if m.number >= lo and m.number <= hi] def set_memory(self, mem): if isinstance(mem.number, str): number = _get_special()[mem.number] else: number = mem.number _mem = self._memobj.memory[number] _flag = self._memobj.flags[number] was_empty = int(_flag.empty) _flag.empty = mem.empty if mem.empty: _wipe_memory(_mem, "\xFF") return if was_empty: _wipe_memory(_mem, "\x00") _mem.unknown8 = 0 _mem.is_625 = chirp_common.is_fractional_step(mem.freq) mult = _mem.is_625 and 6250 or 5000 _mem.freq = mem.freq / mult _mem.offset = mem.offset / mult _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) _mem.mode_dv = mem.mode == "DV" _mem.mode_am = mem.mode.endswith("AM") _mem.mode_narrow = mem.mode.startswith("N") _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = DTCSP.index(mem.dtcs_polarity) _mem.tuning_step = STEPS.index(mem.tuning_step) _mem.name = mem.name.ljust(6) if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 if number < 200: _flag.skip = mem.skip != "" if isinstance(mem, chirp_common.DVMemory): urcalls = self.get_urcall_list() rptcalls = self.get_repeater_call_list() _mem.urcall = urcalls.index(mem.dv_urcall) _mem.r1call = rptcalls.index(mem.dv_rpt1call) _mem.r2call = rptcalls.index(mem.dv_rpt2call) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_urcall_list(self): return [str(x.call).rstrip() for x in self._memobj.urcalls] def get_repeater_call_list(self): return [str(x.call).rstrip() for x in self._memobj.rptcalls] def get_mycall_list(self): return [str(x.call).rstrip() for x in self._memobj.mycalls] def set_urcall_list(self, calls): for i in range(*self.URCALL_LIMIT): self._memobj.urcalls[i].call = calls[i].ljust(8) def set_repeater_call_list(self, calls): for i in range(*self.RPTCALL_LIMIT): self._memobj.rptcalls[i].call = calls[i].ljust(8) def set_mycall_list(self, calls): for i in range(*self.MYCALL_LIMIT): self._memobj.mycalls[i].call = calls[i].ljust(8) chirp-20240224/chirp/drivers/tk8180.py0000644000175000017500000012412014561124165016135 0ustar hibbyhibby# Copyright 2019 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import time import logging from collections import OrderedDict from chirp import chirp_common, directory, memmap, errors, util from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting from chirp.settings import RadioSettingValueBoolean, RadioSettingValueList from chirp.settings import RadioSettingValueString, RadioSettingValueInteger from chirp.settings import RadioSettings, RadioSettingSubGroup LOG = logging.getLogger(__name__) # Gross hack to handle missing future module on un-updatable # platforms like MacOS. Just avoid registering these radio # classes for now. try: from builtins import bytes has_future = True except ImportError: has_future = False LOG.debug('python-future package is not ' 'available; %s requires it' % __name__) HEADER_FORMAT = """ #seekto 0x0100; struct { char sw_name[7]; char sw_ver[5]; u8 unknown1[4]; char sw_key[12]; u8 unknown2[4]; char model[5]; u8 variant; u8 unknown3[10]; } header; #seekto 0x0140; struct { // 0x0140 u8 unknown1; u8 sublcd; u8 unknown2[30]; // 0x0160 char pon_msgtext[12]; u8 min_volume; u8 max_volume; u8 lo_volume; u8 hi_volume; // 0x0170 u8 tone_volume_offset; u8 poweron_tone; u8 control_tone; u8 warning_tone; u8 alert_tone; u8 sidetone; u8 locator_tone; u8 unknown3[2]; u8 ignition_mode; u8 ignition_time; // In tens of minutes (6 = 1h) u8 micsense; ul16 modereset; u8 min_vol_preset; u8 unknown4; // 0x0180 u8 unknown5[16]; // 0x0190 u8 unknown6[3]; u8 pon_msgtype; u8 unknown7[8]; u8 unknown8_1:2, ssi:1, busy_led:1, power_switch_memory:1, scrambler_memory:1, unknown8_2:1, off_hook_decode:1; u8 unknown9_1:5, clockfmt:1, datefmt:1, ignition_sense:1; u8 unknownA[2]; // 0x01A0 u8 unknownB[8]; u8 ptt_timer; u8 unknownB2[3]; u8 ptt_proceed:1, unknownC_1:3, tone_off:1, ost_memory:1, unknownC_2:1, ptt_release:1; u8 unknownD[3]; } settings; #seekto 0x01E0; struct { char name[12]; ul16 rxtone; ul16 txtone; } ost_tones[40]; #seekto 0x0A00; ul16 zone_starts[128]; struct zoneinfo { u8 number; u8 zonetype; u8 unknown1[2]; u8 count; char name[12]; u8 unknown2[2]; ul16 timeout; // 15-1200 ul16 tot_alert; // 10 ul16 tot_rekey; // 60 ul16 tot_reset; // 15 u8 unknown3[3]; u8 unknown21:2, bcl_override:1, unknown22:5; u8 unknown5; }; struct memory { u8 number; lbcd rx_freq[4]; lbcd tx_freq[4]; u8 unknown1[2]; ul16 rx_tone; ul16 tx_tone; char name[12]; u8 unknown2[19]; u8 unknown3_1:4, highpower:1, unknown3_2:1, wide:1, unknown3_3:1; u8 unknown4; }; #seekto 0xC570; // Fixme u8 skipflags[64]; """ SYSTEM_MEM_FORMAT = """ #seekto 0x%(addr)x; struct { struct zoneinfo zoneinfo; struct memory memories[%(count)i]; } zone%(index)i; """ STARTUP_MODES = ['Text', 'Clock'] VOLUMES = OrderedDict([(str(x), x) for x in range(0, 30)]) VOLUMES.update({'Selectable': 0x30, 'Current': 0xFF}) VOLUMES_REV = {v: k for k, v in VOLUMES.items()} MIN_VOL_PRESET = {'Preset': 0x30, 'Lowest Limit': 0x31} MIN_VOL_PRESET_REV = {v: k for k, v in MIN_VOL_PRESET.items()} SUBLCD = ['Zone Number', 'CH/GID Number', 'OSD List Number'] CLOCKFMT = ['12H', '24H'] DATEFMT = ['Day/Month', 'Month/Day'] MICSENSE = ['On'] ONLY_MOBILE_SETTINGS = ['power_switch_memory', 'off_hook_decode', 'ignition_sense', 'mvp', 'it', 'ignition_mode'] POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("High", watts=50)] def set_choice(setting, obj, key, choices, default='Off'): settingstr = str(setting.value) if settingstr == default: val = 0xFF else: val = choices.index(settingstr) + 0x30 setattr(obj, key, val) def get_choice(obj, key, choices, default='Off'): val = getattr(obj, key) if val == 0xFF: return default else: return choices[val - 0x30] def make_frame(cmd, addr, data=b""): return struct.pack(">BH", ord(cmd), addr) + data def send(radio, frame): # LOG.debug("%04i P>R:\n%s" % (len(frame), util.hexprint(frame))) radio.pipe.write(frame) def do_ident(radio): radio.pipe.baudrate = 9600 radio.pipe.stopbits = 2 radio.pipe.timeout = 1 send(radio, b'PROGRAM') ack = radio.pipe.read(1) LOG.debug('Read %r from radio' % ack) if ack != b'\x16': raise errors.RadioError('Radio refused hi-speed program mode') radio.pipe.baudrate = 19200 ack = radio.pipe.read(1) if ack != b'\x06': raise errors.RadioError('Radio refused program mode') radio.pipe.write(b'\x02') ident = radio.pipe.read(8) LOG.debug('Radio ident is %r' % ident) radio.pipe.write(b'\x06') ack = radio.pipe.read(1) if ack != b'\x06': raise errors.RadioError('Radio refused program mode') if ident[:6] not in (radio._model,): model = ident[:5].decode() variants = {b'\x06': 'K, K1, K3 (450-520 MHz)', b'\x07': 'K2, K4 (400-470 MHz)'} if model == 'P3180': model += ' ' + variants.get(ident[5], '(Unknown)') raise errors.RadioError('Unsupported radio model %s' % model) def checksum_data(data): _chksum = 0 for byte in data: _chksum = (_chksum + byte) & 0xFF return _chksum def do_download(radio): do_ident(radio) data = bytes() def status(): status = chirp_common.Status() status.cur = len(data) status.max = radio._memsize status.msg = "Cloning from radio" radio.status_fn(status) LOG.debug('Radio address 0x%04x' % len(data)) # Addresses 0x0000-0xBF00 pulled by block number (divide by 0x100) for block in range(0, 0xBF + 1): send(radio, make_frame('R', block)) cmd = radio.pipe.read(1) chunk = b'' if cmd == b'Z': data += bytes(b'\xff' * 256) LOG.debug('Radio reports empty block %02x' % block) elif cmd == b'W': chunk = bytes(radio.pipe.read(256)) if len(chunk) != 256: LOG.error('Received %i for block %02x' % (len(chunk), block)) raise errors.RadioError('Radio did not send block') data += chunk else: LOG.error('Radio sent %r (%02x), expected W(0x57)' % (cmd, chr(cmd))) raise errors.RadioError('Radio sent unexpected response') LOG.debug('Read block index %02x' % block) status() chksum = radio.pipe.read(1) if len(chksum) != 1: LOG.error('Checksum was %r' % chksum) raise errors.RadioError('Radio sent invalid checksum') _chksum = checksum_data(chunk) if chunk and _chksum != ord(chksum): LOG.error( 'Checksum failed for %i byte block 0x%02x: %02x != %02x' % ( len(chunk), block, _chksum, ord(chksum))) raise errors.RadioError('Checksum failure while reading block. ' 'Check serial cable.') radio.pipe.write(b'\x06') if radio.pipe.read(1) != b'\x06': raise errors.RadioError('Post-block exchange failed') # Addresses 0xC000 - 0xD1F0 pulled by address for block in range(0x0100, 0x1200, 0x40): send(radio, make_frame('S', block, b'\x40')) x = radio.pipe.read(1) if x != b'X': raise errors.RadioError('Radio did not send block') chunk = radio.pipe.read(0x40) data += chunk LOG.debug('Read memory address %04x' % block) status() radio.pipe.write(b'\x06') if radio.pipe.read(1) != b'\x06': raise errors.RadioError('Post-block exchange failed') radio.pipe.write(b'E') if radio.pipe.read(1) != b'\x06': raise errors.RadioError('Radio failed to acknowledge completion') LOG.debug('Read %i bytes total' % len(data)) return data def do_upload(radio): do_ident(radio) def status(addr): status = chirp_common.Status() status.cur = addr status.max = radio._memsize status.msg = "Cloning to radio" radio.status_fn(status) for block in range(0, 0xBF + 1): addr = block * 0x100 chunk = bytes(radio._mmap[addr:addr + 0x100]) if all(byte == b'\xff' for byte in chunk): LOG.debug('Sending zero block %i, range 0x%04x' % (block, addr)) send(radio, make_frame('Z', block, b'\xFF')) else: checksum = checksum_data(chunk) send(radio, make_frame('W', block, chunk + bytes([checksum]))) ack = radio.pipe.read(1) if ack != b'\x06': LOG.error('Radio refused block 0x%02x with %r' % (block, ack)) raise errors.RadioError('Radio refused data block') status(addr) addr_base = 0xC000 for addr in range(addr_base, radio._memsize, 0x40): block_addr = addr - addr_base + 0x0100 chunk = radio._mmap[addr:addr + 0x40] send(radio, make_frame('X', block_addr, b'\x40' + chunk)) ack = radio.pipe.read(1) if ack != b'\x06': LOG.error('Radio refused address 0x%02x with %r' % (block_addr, ack)) raise errors.RadioError('Radio refused data block') status(addr) radio.pipe.write(b'E') if radio.pipe.read(1) != b'\x06': raise errors.RadioError('Radio failed to acknowledge completion') def reset(self): try: self.pipe.baudrate = 9600 self.pipe.write(b'E') time.sleep(0.5) self.pipe.baudrate = 19200 self.pipe.write(b'E') except Exception: LOG.error('Unable to send reset sequence') class KenwoodTKx180Radio(chirp_common.CloneModeRadio): """Kenwood TK-x180""" VENDOR = 'Kenwood' MODEL = 'TK-x180' BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False FORMATS = [directory.register_format('Kenwood KPG-89D', '*.dat')] _system_start = 0x0B00 _memsize = 0xD100 def __init__(self, *a, **k): self._zones = [] chirp_common.CloneModeRadio.__init__(self, *a, **k) _dat_header = (b'KPG89D\xFF\xFF\xFF\xFFV1.61' + self._model + (b'\xFF' * 11) + (b'\xFF' * 32)) def sync_in(self): try: data = do_download(self) self._mmap = memmap.MemoryMapBytes(data) except errors.RadioError: reset(self) raise except Exception as e: reset(self) LOG.exception('General failure') raise errors.RadioError('Failed to download from radio: %s' % e) self.process_mmap() def sync_out(self): try: do_upload(self) except Exception as e: reset(self) LOG.exception('General failure') raise errors.RadioError('Failed to upload to radio: %s' % e) @classmethod def match_model(cls, filedata, filename): return (filename.endswith('.dat') and filedata[15:21] == cls._model) def save_mmap(self, filename): if filename.lower().endswith('.dat'): with open(filename, 'wb') as f: f.write(self._dat_header) f.write(self._mmap.get_packed()) LOG.info('Wrote DAT file') else: super().save_mmap(filename) def load_mmap(self, filename): if filename.lower().endswith('.dat'): with open(filename, 'rb') as f: self._dat_header = f.read(0x40) LOG.debug('DAT header:\n%s' % util.hexprint(self._dat_header)) self._mmap = memmap.MemoryMapBytes(f.read()) LOG.info('Loaded DAT file') self.process_mmap() else: super().load_mmap(filename) @property def is_portable(self): return self._model.startswith(b'P') def probe_layout(self): start_addrs = [] tmp_format = '#seekto 0x0A00; ul16 zone_starts[128];' mem = bitwise.parse(tmp_format, self._mmap) zone_format = """struct zoneinfo { u8 number; u8 zonetype; u8 unknown1[2]; u8 count; char name[12]; u8 unknown2[15]; };""" zone_addresses = [] for i in range(0, 128): if mem.zone_starts[i] == 0xFFFF: break zone_addresses.append(mem.zone_starts[i]) zone_format += '#seekto 0x%x; struct zoneinfo zone%i;' % ( mem.zone_starts[i], i) zoneinfo = bitwise.parse(zone_format, self._mmap) zones = [] for i, addr in enumerate(zone_addresses): zone = getattr(zoneinfo, 'zone%i' % i) if zone.zonetype != 0x31: LOG.error('Zone %i is type 0x%02x; ' 'I only support 0x31 (conventional)') raise errors.RadioError( 'Unsupported non-conventional zone found in radio; ' 'Refusing to load to safeguard your data!') zones.append((addr, zone.count)) LOG.debug('Zones: %s' % zones) return zones def process_mmap(self): self._zones = self.probe_layout() mem_format = HEADER_FORMAT for index, (addr, count) in enumerate(self._zones): mem_format += '\n\n' + ( SYSTEM_MEM_FORMAT % { 'addr': addr, 'count': max(count, 2), # bitwise bug, one-element array 'index': index}) self._memobj = bitwise.parse(mem_format, self._mmap) def expand_mmap(self, zone_sizes): """Remap memory into zones of the specified sizes, copying things around to keep the contents, as appropriate.""" old_zones = self._zones old_memobj = self._memobj self._mmap = memmap.MemoryMapBytes(bytes(self._mmap.get_packed())) new_format = HEADER_FORMAT addr = self._system_start self._zones = [] for index, count in enumerate(zone_sizes): new_format += SYSTEM_MEM_FORMAT % { 'addr': addr, 'count': max(count, 2), # bitwise bug 'index': index} self._zones.append((addr, count)) addr += 0x20 + (count * 0x30) self._memobj = bitwise.parse(new_format, self._mmap) # Set all known zone addresses and clear the rest for index in range(0, 128): try: self._memobj.zone_starts[index] = self._zones[index][0] except IndexError: self._memobj.zone_starts[index] = 0xFFFF for zone_number, count in enumerate(zone_sizes): dest_zone = getattr(self._memobj, 'zone%i' % zone_number) dest = dest_zone.memories dest_zoneinfo = dest_zone.zoneinfo if zone_number < len(old_zones): LOG.debug('Copying existing zone %i' % zone_number) _, old_count = old_zones[zone_number] source_zone = getattr(old_memobj, 'zone%i' % zone_number) source = source_zone.memories source_zoneinfo = source_zone.zoneinfo if old_count != count: LOG.debug('Zone %i going from %i to %i' % (zone_number, old_count, count)) # Copy the zone record from the source, but then update # the count dest_zoneinfo.set_raw(source_zoneinfo.get_raw(asbytes=False)) dest_zoneinfo.count = count source_i = 0 for dest_i in range(0, min(count, old_count)): dest[dest_i].set_raw(source[dest_i].get_raw(asbytes=False)) else: LOG.debug('New zone %i' % zone_number) dest_zone.zoneinfo.number = zone_number + 1 dest_zone.zoneinfo.zonetype = 0x31 dest_zone.zoneinfo.count = count dest_zone.zoneinfo.name = ( 'Zone %i' % (zone_number + 1)).ljust(12) # Copy the settings we care about from the first zone z0info = self._memobj.zone0.zoneinfo dest_zone.zoneinfo.timeout = z0info.timeout dest_zone.zoneinfo.tot_alert = z0info.tot_alert dest_zone.zoneinfo.tot_rekey = z0info.tot_rekey dest_zone.zoneinfo.tot_reset = z0info.tot_reset def shuffle_zone(self): """Sort the memories in the zone according to logical channel number""" # FIXME: Move this to the zone raw_memories = self.raw_memories memories = [(i, raw_memories[i].number) for i in range(0, self.raw_zoneinfo.count)] current = memories[:] memories.sort(key=lambda t: t[1]) if current == memories: LOG.debug('Shuffle not required') return raw_data = [raw_memories[i].get_raw(asbytes=False) for i, n in memories] for i, raw_mem in enumerate(raw_data): raw_memories[i].set_raw(raw_mem) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = ('This radio is zone-based, which is different from how ' 'most radios work (that CHIRP supports). The zone count ' 'can be adjusted in the Settings tab, but you must save ' 'and re-load the file after changing that value in order ' 'to be able to add/edit memories there.') rp.experimental = ('This driver is very experimental. Every attempt ' 'has been made to be overly pedantic to avoid ' 'destroying data. However, you should use caution, ' 'maintain backups, and proceed at your own risk.') return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_ctone = True rf.has_cross = True rf.has_tuning_step = False rf.has_settings = True rf.has_bank = False rf.has_sub_devices = True rf.has_rx_dtcs = True rf.can_odd_split = True rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ['Tone->Tone', 'DTCS->', '->DTCS', 'Tone->DTCS', 'DTCS->Tone', '->Tone', 'DTCS->DTCS'] rf.valid_bands = self.VALID_BANDS rf.valid_modes = ['FM', 'NFM'] rf.valid_tuning_steps = [2.5, 5.0, 6.25, 12.5, 10.0, 15.0, 20.0, 25.0, 50.0, 100.0] rf.valid_duplexes = ['', '-', '+', 'split', 'off'] rf.valid_power_levels = POWER_LEVELS rf.valid_name_length = 12 rf.valid_characters = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' '0123456789' '!"#$%&\'()~+-,./:;<=>?@[\\]^`{}*| ') rf.memory_bounds = (1, 512) return rf @property def raw_zone(self): return getattr(self._memobj, 'zone%i' % self._zone) @property def raw_zoneinfo(self): return self.raw_zone.zoneinfo @property def raw_memories(self): return self.raw_zone.memories @property def max_mem(self): return self.raw_memories[self.raw_zoneinfo.count].number def _get_raw_memory(self, number): for i in range(0, self.raw_zoneinfo.count): if self.raw_memories[i].number == number: return self.raw_memories[i] return None def get_raw_memory(self, number): return repr(self._get_raw_memory(number)) @staticmethod def _decode_tone(toneval): # DCS examples: # D024N - 2814 - 0010 1000 0001 0100 # ^--DCS # D024I - A814 - 1010 1000 0001 0100 # ^----inverted # D754I - A9EC - 1010 1001 1110 1100 # code in octal-------^^^^^^^^^^^ pol = toneval & 0x8000 and 'R' or 'N' if toneval == 0xFFFF: return '', None, None elif toneval & 0x2000: # DTCS code = int('%o' % (toneval & 0x1FF)) return 'DTCS', code, pol else: return 'Tone', toneval / 10.0, None @staticmethod def _encode_tone(mode, val, pol): if not mode: return 0xFFFF elif mode == 'Tone': return int(val * 10) elif mode == 'DTCS': code = int('%i' % val, 8) code |= 0x2800 if pol == 'R': code |= 0x8000 return code else: raise errors.RadioError('Unsupported tone mode %r' % mode) def get_memory(self, number): mem = chirp_common.Memory() mem.number = number _mem = self._get_raw_memory(number) if _mem is None: mem.empty = True return mem mem.name = str(_mem.name).rstrip('\x00') mem.freq = int(_mem.rx_freq) * 10 chirp_common.split_tone_decode(mem, self._decode_tone(_mem.tx_tone), self._decode_tone(_mem.rx_tone)) if _mem.wide: mem.mode = 'FM' else: mem.mode = 'NFM' mem.power = POWER_LEVELS[_mem.highpower] offset = (int(_mem.tx_freq) - int(_mem.rx_freq)) * 10 if _mem.tx_freq.get_raw() == b'\xFF\xFF\xFF\xFF': mem.offset = 0 mem.duplex = 'off' elif offset == 0: mem.duplex = '' mem.offset = 0 elif abs(offset) < 10000000: mem.duplex = offset < 0 and '-' or '+' mem.offset = abs(offset) else: mem.duplex = 'split' mem.offset = int(_mem.tx_freq) * 10 skipbyte = self._memobj.skipflags[(mem.number - 1) // 8] skipbit = skipbyte & (1 << (mem.number - 1) % 8) mem.skip = skipbit and 'S' or '' return mem def set_memory(self, mem): _mem = self._get_raw_memory(mem.number) if _mem is None: LOG.debug('Need to expand zone %i' % self._zone) # Calculate the new zone sizes and remap memory new_zones = [x[1] for x in self._parent._zones] new_zones[self._zone] = new_zones[self._zone] + 1 self._parent.expand_mmap(new_zones) # Assign the new memory (at the end) to the desired # number _mem = self.raw_memories[self.raw_zoneinfo.count - 1] _mem.number = mem.number # Sort the memory into place self.shuffle_zone() # Now find it in the right spot _mem = self._get_raw_memory(mem.number) if _mem is None: raise errors.RadioError('Internal error after ' 'memory allocation') # Default values for unknown things _mem.unknown1[0] = 0x36 _mem.unknown1[1] = 0x36 _mem.unknown2 = [0xFF for i in range(0, 19)] _mem.unknown3_1 = 0xF _mem.unknown3_2 = 0x1 _mem.unknown3_3 = 0x0 _mem.unknown4 = 0xFF if mem.empty: LOG.debug('Need to shrink zone %i' % self._zone) # Make the memory sort to the end, and sort the zone _mem.number = 0xFF self.shuffle_zone() # Calculate the new zone sizes and remap memory new_zones = [x[1] for x in self._parent._zones] new_zones[self._zone] = new_zones[self._zone] - 1 self._parent.expand_mmap(new_zones) return _mem.name = mem.name[:12].encode().rstrip().ljust(12, b'\x00') _mem.rx_freq = mem.freq // 10 txtone, rxtone = chirp_common.split_tone_encode(mem) _mem.tx_tone = self._encode_tone(*txtone) _mem.rx_tone = self._encode_tone(*rxtone) _mem.wide = mem.mode == 'FM' _mem.highpower = mem.power == POWER_LEVELS[1] if mem.duplex == '': _mem.tx_freq = mem.freq // 10 elif mem.duplex == 'split': _mem.tx_freq = mem.offset // 10 elif mem.duplex == 'off': _mem.tx_freq.set_raw(b'\xff\xff\xff\xff') elif mem.duplex == '-': _mem.tx_freq = (mem.freq - mem.offset) // 10 elif mem.duplex == '+': _mem.tx_freq = (mem.freq + mem.offset) // 10 else: raise errors.RadioError('Unsupported duplex mode %r' % mem.duplex) skipbyte = self._memobj.skipflags[(mem.number - 1) // 8] if mem.skip == 'S': skipbyte |= (1 << (mem.number - 1) % 8) else: skipbyte &= ~(1 << (mem.number - 1) % 8) def _pure_choice_setting(self, settings_key, name, choices, default='Off'): if default is not None: ui_choices = [default] + choices else: ui_choices = choices s = RadioSetting( settings_key, name, RadioSettingValueList( ui_choices, get_choice(self._memobj.settings, settings_key, choices, default))) s.set_apply_callback(set_choice, self._memobj.settings, settings_key, choices, default) return s def _inverted_flag_setting(self, key, name, obj=None): if obj is None: obj = self._memobj.settings def apply_inverted(setting, key): setattr(obj, key, not int(setting.value)) v = not getattr(obj, key) s = RadioSetting( key, name, RadioSettingValueBoolean(v)) s.set_apply_callback(apply_inverted, key) return s def _get_common1(self): settings = self._memobj.settings common1 = RadioSettingGroup('common1', 'Common 1') common1.append(self._pure_choice_setting('sublcd', 'Sub LCD Display', SUBLCD, default='None')) def apply_clockfmt(setting): settings.clockfmt = CLOCKFMT.index(str(setting.value)) clockfmt = RadioSetting( 'clockfmt', 'Clock Format', RadioSettingValueList(CLOCKFMT, CLOCKFMT[settings.clockfmt])) clockfmt.set_apply_callback(apply_clockfmt) common1.append(clockfmt) def apply_datefmt(setting): settings.datefmt = DATEFMT.index(str(setting.value)) datefmt = RadioSetting( 'datefmt', 'Date Format', RadioSettingValueList(DATEFMT, DATEFMT[settings.datefmt])) datefmt.set_apply_callback(apply_datefmt) common1.append(datefmt) common1.append(self._pure_choice_setting('micsense', 'Mic Sense High', MICSENSE)) def apply_modereset(setting): val = int(setting.value) if val == 0: val = 0xFFFF settings.modereset = val _modereset = int(settings.modereset) if _modereset == 0xFFFF: _modereset = 0 modereset = RadioSetting( 'modereset', 'Mode Reset Timer', RadioSettingValueInteger(0, 300, _modereset)) modereset.set_apply_callback(apply_modereset) common1.append(modereset) inverted_flags = [('power_switch_memory', 'Power Switch Memory'), ('scrambler_memory', 'Scrambler Memory'), ('off_hook_decode', 'Off-Hook Decode'), ('ssi', 'Signal Strength Indicator'), ('ignition_sense', 'Ingnition Sense')] for key, name in inverted_flags: if self.is_portable and key in ONLY_MOBILE_SETTINGS: # Skip settings that are not valid for portables continue common1.append(self._inverted_flag_setting(key, name)) if not self.is_portable and 'ignition_mode' in ONLY_MOBILE_SETTINGS: common1.append(self._pure_choice_setting('ignition_mode', 'Ignition Mode', ['Ignition & SW', 'Ignition Only'], None)) def apply_it(setting): settings.ignition_time = int(setting.value) / 600 _it = int(settings.ignition_time) * 600 it = RadioSetting( 'it', 'Ignition Timer (s)', RadioSettingValueInteger(10, 28800, _it)) it.set_apply_callback(apply_it) if not self.is_portable and 'it' in ONLY_MOBILE_SETTINGS: common1.append(it) return common1 def _get_common2(self): settings = self._memobj.settings common2 = RadioSettingGroup('common2', 'Common 2') def apply_ponmsgtext(setting): settings.pon_msgtext = ( str(setting.value)[:12].strip().ljust(12, '\x00')) common2.append( self._pure_choice_setting('pon_msgtype', 'Power On Message Type', STARTUP_MODES)) _text = str(settings.pon_msgtext).rstrip('\x00') text = RadioSetting('settings.pon_msgtext', 'Power On Text', RadioSettingValueString( 0, 12, _text)) text.set_apply_callback(apply_ponmsgtext) common2.append(text) def apply_volume(setting, key): setattr(settings, key, VOLUMES[str(setting.value)]) volumes = {'poweron_tone': 'Power-on Tone', 'control_tone': 'Control Tone', 'warning_tone': 'Warning Tone', 'alert_tone': 'Alert Tone', 'sidetone': 'Sidetone', 'locator_tone': 'Locator Tone'} for value, name in volumes.items(): setting = getattr(settings, value) volume = RadioSetting('settings.%s' % value, name, RadioSettingValueList( VOLUMES.keys(), VOLUMES_REV.get(int(setting), 0))) volume.set_apply_callback(apply_volume, value) common2.append(volume) def apply_vol_level(setting, key): setattr(settings, key, int(setting.value)) levels = {'lo_volume': 'Low Volume Level (Fixed Volume)', 'hi_volume': 'High Volume Level (Fixed Volume)', 'min_volume': 'Minimum Audio Volume', 'max_volume': 'Maximum Audio Volume'} for value, name in levels.items(): setting = getattr(settings, value) if 'Audio' in name: minimum = 0 else: minimum = 1 volume = RadioSetting( 'settings.%s' % value, name, RadioSettingValueInteger(minimum, 31, int(setting))) volume.set_apply_callback(apply_vol_level, value) common2.append(volume) def apply_vo(setting): val = int(setting.value) if val < 0: val = abs(val) | 0x80 settings.tone_volume_offset = val _voloffset = int(settings.tone_volume_offset) if _voloffset & 0x80: _voloffset = abs(_voloffset & 0x7F) * -1 voloffset = RadioSetting( 'tvo', 'Tone Volume Offset', RadioSettingValueInteger( -5, 5, _voloffset)) voloffset.set_apply_callback(apply_vo) common2.append(voloffset) def apply_mvp(setting): settings.min_vol_preset = MIN_VOL_PRESET[str(setting.value)] _volpreset = int(settings.min_vol_preset) volpreset = RadioSetting( 'mvp', 'Minimum Volume Type', RadioSettingValueList(MIN_VOL_PRESET.keys(), MIN_VOL_PRESET_REV[_volpreset])) volpreset.set_apply_callback(apply_mvp) if not self.is_portable and 'mvp' in ONLY_MOBILE_SETTINGS: common2.append(volpreset) return common2 def _get_conventional(self): settings = self._memobj.settings conv = RadioSettingGroup('conv', 'Conventional') inverted_flags = [('busy_led', 'Busy LED'), ('ost_memory', 'OST Status Memory'), ('tone_off', 'Tone Off'), ('ptt_release', 'PTT Release tone'), ('ptt_proceed', 'PTT Proceed Tone')] for key, name in inverted_flags: conv.append(self._inverted_flag_setting(key, name)) def apply_pttt(setting): settings.ptt_timer = int(setting.value) pttt = RadioSetting( 'pttt', 'PTT Proceed Tone Timer (ms)', RadioSettingValueInteger(0, 6000, int(settings.ptt_timer))) pttt.set_apply_callback(apply_pttt) conv.append(pttt) self._get_ost(conv) return conv def _get_zones(self): zones = RadioSettingGroup('zones', 'Zones') zone_count = RadioSetting('_zonecount', 'Number of Zones', RadioSettingValueInteger( 1, 128, len(self._zones))) zone_count.set_doc('Number of zones in the radio. ' 'Requires a save and re-load of the ' 'file to take effect. Reducing this number ' 'will DELETE memories in affected zones!') zones.append(zone_count) for i in range(len(self._zones)): zone = RadioSettingSubGroup('zone%i' % i, 'Zone %i' % (i + 1)) _zone = getattr(self._memobj, 'zone%i' % i).zoneinfo _name = str(_zone.name).rstrip('\x00') name = RadioSetting('name%i' % i, 'Name', RadioSettingValueString(0, 12, _name)) zone.append(name) def apply_timer(setting, key, zone_number): val = int(setting.value) if val == 0: val = 0xFFFF _zone = getattr(self._memobj, 'zone%i' % zone_number).zoneinfo setattr(_zone, key, val) def collapse(val): val = int(val) if val == 0xFFFF: val = 0 return val timer = RadioSetting( 'timeout', 'Time-out Timer', RadioSettingValueInteger(15, 1200, collapse(_zone.timeout))) timer.set_apply_callback(apply_timer, 'timeout', i) zone.append(timer) timer = RadioSetting( 'tot_alert', 'TOT Pre-Alert', RadioSettingValueInteger(0, 10, collapse(_zone.tot_alert))) timer.set_apply_callback(apply_timer, 'tot_alert', i) zone.append(timer) timer = RadioSetting( 'tot_rekey', 'TOT Re-Key Time', RadioSettingValueInteger(0, 60, collapse(_zone.tot_rekey))) timer.set_apply_callback(apply_timer, 'tot_rekey', i) zone.append(timer) timer = RadioSetting( 'tot_reset', 'TOT Reset Time', RadioSettingValueInteger(0, 15, collapse(_zone.tot_reset))) timer.set_apply_callback(apply_timer, 'tot_reset', i) zone.append(timer) zone.append(self._inverted_flag_setting( 'bcl_override', 'BCL Override', _zone)) zones.append(zone) return zones def _get_ost(self, parent): tones = chirp_common.TONES[:] def apply_tone(setting, index, which): if str(setting.value) == 'Off': val = 0xFFFF else: val = int(float(str(setting.value)) * 10) setattr(self._memobj.ost_tones[index], '%stone' % which, val) def _tones(): return ['Off'] + [str(x) for x in tones] ostgroup = RadioSettingGroup('ost', 'OST') ostgroup.set_doc('Operator Selectable Tone') parent.append(ostgroup) for i in range(0, 40): _ost = self._memobj.ost_tones[i] ost = RadioSettingSubGroup('ost%i' % i, 'OST %i' % (i + 1)) cur = str(_ost.name).rstrip('\x00') name = RadioSetting('name%i' % i, 'Name', RadioSettingValueString(0, 12, cur)) ost.append(name) if _ost.rxtone == 0xFFFF: cur = 'Off' else: cur = round(int(_ost.rxtone) / 10.0, 1) if cur not in tones: LOG.debug('Non-standard OST rx tone %i %s' % (i, cur)) tones.append(cur) tones.sort() rx = RadioSetting('rxtone%i' % i, 'RX Tone', RadioSettingValueList(_tones(), str(cur))) rx.set_apply_callback(apply_tone, i, 'rx') ost.append(rx) if _ost.txtone == 0xFFFF: cur = 'Off' else: cur = round(int(_ost.txtone) / 10.0, 1) if cur not in tones: LOG.debug('Non-standard OST tx tone %i %s' % (i, cur)) tones.append(cur) tones.sort() tx = RadioSetting('txtone%i' % i, 'TX Tone', RadioSettingValueList(_tones(), str(cur))) tx.set_apply_callback(apply_tone, i, 'tx') ost.append(tx) ostgroup.append(ost) def get_settings(self): settings = self._memobj.settings zones = self._get_zones() common1 = self._get_common1() common2 = self._get_common2() conv = self._get_conventional() top = RadioSettings(zones, common1, common2, conv) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue elif element.get_name() == '_zonecount': new_zone_count = int(element.value) zone_sizes = [x[1] for x in self._zones[:new_zone_count]] if len(self._zones) > new_zone_count: self.expand_mmap(zone_sizes[:new_zone_count]) elif len(self._zones) < new_zone_count: self.expand_mmap(zone_sizes + ( [0] * (new_zone_count - len(self._zones)))) elif element.has_apply_callback(): element.run_apply_callback() def get_sub_devices(self): zones = [] for i, _ in enumerate(self._zones): zone = getattr(self._memobj, 'zone%i' % i) class _Zone(KenwoodTKx180RadioZone): VENDOR = self.VENDOR MODEL = self.MODEL VALID_BANDS = self.VALID_BANDS VARIANT = 'Zone %s' % ( str(zone.zoneinfo.name).rstrip('\x00').rstrip()) _model = self._model zones.append(_Zone(self, i)) return zones class KenwoodTKx180RadioZone(KenwoodTKx180Radio): _zone = None def __init__(self, parent, zone=0): if isinstance(parent, KenwoodTKx180Radio): self._parent = parent else: LOG.warning('Parent was not actually our parent, expect failure') self._zone = zone @property def _zones(self): return self._parent._zones @property def _memobj(self): return self._parent._memobj def load_mmap(self, filename): self._parent.load_mmap(filename) def get_features(self): rf = KenwoodTKx180Radio.get_features(self) rf.has_sub_devices = False rf.memory_bounds = (1, 250) return rf def get_sub_devices(self): return [] if has_future: @directory.register class KenwoodTK7180Radio(KenwoodTKx180Radio): MODEL = 'TK-7180' VALID_BANDS = [(136000000, 174000000)] _model = b'M7180\x04' @directory.register class KenwoodTK8180Radio(KenwoodTKx180Radio): MODEL = 'TK-8180' VALID_BANDS = [(400000000, 520000000)] _model = b'M8180\x06' @directory.register class KenwoodTK2180Radio(KenwoodTKx180Radio): MODEL = 'TK-2180' VALID_BANDS = [(136000000, 174000000)] _model = b'P2180\x04' # K1,K3 are technically 450-470 (K3 == keypad) @directory.register class KenwoodTK3180K1Radio(KenwoodTKx180Radio): MODEL = 'TK-3180K' VALID_BANDS = [(400000000, 520000000)] _model = b'P3180\x06' # K2,K4 are technically 400-470 (K4 == keypad) @directory.register class KenwoodTK3180K2Radio(KenwoodTKx180Radio): MODEL = 'TK-3180K2' VALID_BANDS = [(400000000, 520000000)] _model = b'P3180\x07' @directory.register class KenwoodTK8180E(KenwoodTKx180Radio): MODEL = 'TK-8180E' VALID_BANDS = [(400000000, 520000000)] _model = b'M8189\'' @directory.register class KenwoodTK7180ERadio(KenwoodTKx180Radio): MODEL = 'TK-7180E' VALID_BANDS = [(136000000, 174000000)] _model = b'M7189$' chirp-20240224/chirp/drivers/radtel_rt490.py0000644000175000017500000020520414562116574017424 0ustar hibbyhibby# Copyright 2023 angeof9 angelof9@protonmail.com # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see http://www.gnu.org/licenses/. # # This file is dual-licensed by the copyright holder, under the GPLv3 # for inclusion in CHIRP here. # The code is also available under the BSD 2-Clause "Simplified" License # here: # https://chirp.danplanet.com/attachments/7833 # Python3 byte clean by Darryl Pogue # Pep8 style compliant by Jim Unroe import logging import struct from chirp import ( bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueInteger, RadioSettingValueList, RadioSettingValueString, RadioSettingValueMap, RadioSettingValueFloat, InvalidValueError ) LOG = logging.getLogger(__name__) # 'True' or 'False' # True unlocks: # - FM preset # - Channel memory # preset # - Killswitch (with revive killed radios) # - Bands settings # - Disable radio identification string verification # (good to recover from a bad state) RT490_EXPERIMENTAL = True MEM_FORMAT_RT490 = """ struct { // Memory settings lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 signal; // int 0->14, Signal 1->15 u8 pttid; // ['OFF', 'BOT', 'EOT', 'Both'] u8 dcp:4, // What is DCP ? FHSS ? DC-FHSS ??? TODO power:4; // POWER_LEVELS u8 unknown3_0:1, // Used by the driver to store AM/NAM flag // (thank you Radtel for free space) narrow:1, // bool true=NFM false=FM (col[7] a) unknown3_1:1, unknown3_2:1, bcl:1, // bool (col[9] a2) scan:1, // bool (col[10] a3) tx_enable:1, // bool (col[1] a4) learn:1; // bool ??? TODO (col[14] a5) } memory[%(memsize)d]; // #seekto 0x1000; // Memory names (@4096) struct { char name[12]; u8 ffpad[4]; } memname[%(memsize)d]; // #seekto 0x2000; // GOOD DCP keys ??? TODO ?? (@8192) struct { u8 code[4]; } memcode[%(memsize)d]; // up to @x2400 // Filled with xFF during download (=> no need to // fill with xFF), ready to upload #seekto 0x3400; // Custom ANI Names (@13312) struct { char name[10]; u8 ffpad[6]; } custom_ani_names[10]; // Filled with xFF during download (=> no need to // fill with xFF), ready to upload #seekto 0x3500; // ANI Codes (@13568) struct { u8 anicode[6]; u8 ffpad[10]; } anicodes[60]; // Filled with xFF during download (=> no need to // fill with xFF), ready to upload #seekto 0x3900; // Custom channel names (@14592) struct { char name[10]; u8 ffpad[6]; } custom_channel_names[10]; // Filled with xFF during download (=> no need to // fill with xFF), ready to upload #seekto 0x3A00; // Settings (@14848) struct { u8 squelch; // 0: int 0 -> 9 u8 savemode; // 1: ['OFF', 'Normal', 'Super', 'Deep'] u8 vox; // 2: off=0, 1 -> 9 u8 backlight; // 3: ['OFF', '5s', '15s', '20s', '30s', '1m', // '2m', '3m'] u8 tdr; // 4: bool u8 timeout; // 5: n*30seconds, 0-240s u8 beep; // 6: bool u8 voice; // 7: bool u8 byte_not_used_10; // 8: Always 1 u8 dtmfst; // 9: ['OFF', 'KB Side Tone', 'ANI Side Tone', // 'KB ST + ANI ST'] u8 scanmode; // 10: ['TO', 'CO', 'SE'] u8 pttid; // 11: ['OFF', 'BOT', 'EOT', 'Both'] u8 pttiddelay; // 12: ['0', '100ms', '200ms', '400ms', '600ms', // '800ms', '1000ms'] u8 cha_disp; // 13: ['Name', 'Freq', 'Channel ID'] u8 chb_disp; // 14: ['Name', 'Freq', 'Channel ID'] u8 bcl; // 15: bool u8 autolock; // 0: ['OFF', '5s', '10s', 15s'] u8 alarm_mode; // 1: ['Site', 'Tone', 'Code'] u8 alarmsound; // 2: bool u8 txundertdr; // 3: ['OFF', 'A', 'B'] u8 tailnoiseclear; // 4: [off, on] u8 rptnoiseclear; // 5: n*100ms, 0-1000 u8 rptnoisedelay; // 6: n*100ms, 0-1000 u8 roger; // 7: bool u8 active_channel; // 8: 0 or 1 u8 fmradio; // 9: boolean, inverted u8 workmodeb:4, // 10:up ['VFO', 'CH Mode'] workmodea:4; // 10:down ['VFO', 'CH Mode'] u8 kblock; // 11: bool // TODO TEST WITH autolock u8 powermsg; // 12: 0=Image / 1=Voltage u8 byte_not_used_21; // 13: Always 0 u8 rpttone; // 14: ['1000Hz', '1450Hz', '1750Hz', '2100Hz'] u8 byte_not_used_22; // 15: pad with xFF u8 vox_delay; // 0: [str(float(a)/10)+'s' for a in range(5,21)] // '0.5s' to '2.0s' u8 timer_menu_quit; // 1: ['5s', '10s', '15s', '20s', '25s', '30s', // '35s', '40s', '45s', '50s', '60s'] u8 byte_not_used_30; // 2: pad with xFF u8 byte_not_used_31; // 3: pad with xFF u8 enable_killsw; // 4: bool u8 display_ani; // 5: bool u8 byte_not_used_32; // 6: pad with xFF u8 enable_gps; // 7: bool u8 scan_dcs; // 8: ['All', 'Receive', 'Transmit'] u8 ani_id; // 9: int 0-59 (ANI 1-60) u8 rx_time; // 10: bool u8 ffpad0[5]; // 11: Pad xFF u8 cha_memidx; // 0: Memory index when channel A use memories u8 byte_not_used_40; u8 chb_memidx; // 2: Memory index when channel B use memories u8 byte_not_used_41; u8 ffpad1[10]; ul16 fmpreset; } settings; // Filled with xFF during download (=> no need to // fill with xFF), ready to upload struct settings_vfo_chan { u8 rxfreq[8]; // 0 ul16 rxtone; // 8 ul16 txtone; // 10 ul16 byte_not_used0; // 12 Pad xFF u8 sftd:4, // 14 Shift dir ['OFF', '+', '-'] signal:4; // 14 int 0->14, Signal 1->15 u8 byte_not_used1; // 15 Pad xFF u8 power; // 16:0 POWER_LEVELS u8 fhss:4, // 17 ['OFF', 'FHSS 1', 'FHSS 2', 'FHSS 3', // 'FHSS 4'] narrow:4; // 17 bool true=NFM false=FM u8 byte_not_used2; // 18 Pad xFF but received 0x00 ??? u8 freqstep; // 19:3 ['2.5 KHz', '5.0 KHz', '6.25 KHz', // '10.0 KHz', '12.5 KHz', '20.0 KHz', // '25.0 KHz', '50.0 KHz'] u8 byte_not_used3; // 20:4 Pad xFF but received 0x00 ??? TODO u8 offset[6]; // 21:5 Freq NN.NNNN (without the dot) TEST TEST u8 byte_not_used4; // 27:11 Pad xFF u8 byte_not_used5; // 28 Pad xFF u8 byte_not_used6; // 29 Pad xFF u8 byte_not_used7; // 30 Pad xFF u8 byte_not_used8; // 31:15 Pad xFF }; // #seekto 0x3A40; // VFO A/B (@14912) struct { struct settings_vfo_chan vfo_a; struct settings_vfo_chan vfo_b; } settings_vfo; // #seekto 0x3A80; // Side keys settings (@14976) struct { // Values from Radio u8 pf2_short; // { '7': 'FM', '10': 'Tx Power', '28': 'Scan', // '29': 'Search, '1': 'PPT B' } u8 pf2_long; // { '7': 'FM', '10': 'Tx Power', '28': 'Scan', // '29': 'Search' } u8 pf3_short; // {'7': 'FM', '10': 'Tx Power', '28': 'Scan', // '29': 'Search'} u8 ffpad; // Pad xFF } settings_sidekeys; struct dtmfcode { u8 code[5]; // 5 digits DTMF u8 ffpad[11]; // Pad xFF }; // Filled with xFF during download (=> no need to // fill with xFF), ready to upload #seekto 0x3B00; // DTMF (@15104) struct dtmfcode settings_dtmfgroup[15]; struct { // @15296+3x16 u8 byte_not_used1; // 0: Pad xFF something here u8 byte_not_used2; // 1: Pad xFF something here u8 byte_not_used3; // 2: Pad xFF something here u8 byte_not_used4; // 3: Pad xFF u8 byte_not_used5; // 4: Pad xFF u8 unknown_dtmf; // 5: 0 TODO ???? wtf is alarmcode/alarmcall TODO u8 pttid; // 6: [off, BOT, EOT, Both] u8 dtmf_speed_on; // 7: ['50ms', '100ms', '200ms', '300ms', '500ms'] u8 dtmf_speed_off; // 8:0 ['50ms', '100ms', '200ms', '300ms', '500ms'] } settings_dtmf; // Filled with xFF during download (=> no need to // fill with xFF), ready to upload #seekto 0x3C00; // DTMF Kill/ReLive Codes (@15360) struct { u8 kill_dtmf[6]; // 0: Kill DTMF u8 ffpad1[2]; // Pad xFF u8 revive_dtmf[6]; // 8: Revive DTMF u8 ffpad2[2]; // Pad xFF } settings_killswitch; // Some unknown data between 0x3E00 and 0x3F00 #seekto 0x3F80; // Hmm hmm struct { u8 unknown_data_0[16]; u8 unknown_data_1; u8 active; // Bool radio killed (killed=0, active=1) u8 unknown_data_2[46]; } management_settings; struct band { u8 enable; // 0 bool / enable-disable Tx on band bbcd freq_low[2]; // 1 lowest band frequency bbcd freq_high[2]; // 3 highest band frequency }; // #seekto 0x3FC0; // Bands settings (@16320) struct { struct band band136; // 0 Settings for 136MHz band struct band band400; // 5 Settings for 400MHz band struct band band200; // 10 Settings for 200MHz band u8 byte_not_used1; // 15 struct band band350; // 0 Settings for 350MHz band u8 byte_not_used2[43]; // 5 } settings_bands; """ CMD_ACK = b"\x06" DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) DTMFCHARS = '0123456789ABCD*#' def _enter_programming_mode(radio): serial = radio.pipe exito = False for i in range(0, 5): serial.write(radio._magic) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except Exception: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) try: serial.write(b"F") ident = serial.read(8) except Exception: raise errors.RadioError("Error communicating with radio") if not ident.startswith(radio._fingerprint) and not RT490_EXPERIMENTAL: LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") def _exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except Exception: raise errors.RadioError("Radio refused to exit programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"R" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] except Exception: raise errors.RadioError("Failed to read block at %04x" % block_addr) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except Exception: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) _write_block(radio, addr, radio.BLOCK_SIZE) _exit_programming_mode(radio) @directory.register class RT490Radio(chirp_common.CloneModeRadio): """RADTEL RT-490""" VENDOR = "Radtel" MODEL = "RT-490" BLOCK_SIZE = 0x40 # 64 bytes BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False POWER_LEVELS = [chirp_common.PowerLevel("H", watts=5.00), chirp_common.PowerLevel("L", watts=3.00)] # magic = progmode + modelType + garbage (works with any last char) _magic = b"PROGROMJJCCU" # fingerprint is default band ranges of the radio # the driver can change band ranges and fingerprint will # change accordingly, so it is not used to verify radio id. _fingerprint = b"\x01\x36\x01\x80\x04\x00\x05\x20" # Ranges of memory used when uploading data to radio # same as official software _ranges = [ (0x0000, 0x2400), (0x3400, 0x3C40), (0x3FC0, 0x4000) ] if RT490_EXPERIMENTAL: # Experimental driver (already heavily tested) _ranges = [(0x0000, 0x2400), (0x3400, 0x3C40), (0x3F80, 0x4000)] # Danger zone # _ranges = [(0x0000, 0x2500), (0x3400, 0x3C40), (0x3E00, 0x4000)] # 16KB of memory, download read everything # same as official software (remark: loops if overread :)) _memsize = 16384 POWER_LEVELS_LIST = [str(i) for i in POWER_LEVELS] FHSS_LIST = ['OFF', 'ENCRYPT 1', 'ENCRYPT 2', 'ENCRYPT 3', 'ENCRYPT 4'] DCP_LIST = ['OFF', 'DCP1', 'DCP2', 'DCP3', 'DCP4'] # Same as FHSS ? # # Seems yes TUNING_STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] TUNING_STEPS_LIST = [str(i)+' KHz' for i in TUNING_STEPS] SIGNAL = [str(i) for i in range(1, 16)] PTTID = ['OFF', 'BOT', 'EOT', 'Both'] PTTIDDELAYS = ['0', '100ms', '200ms', '400ms', '600ms', '800ms', '1000ms'] DTMF_SPEEDS = ['50ms', '100ms', '200ms', '300ms', '500ms'] SIDEKEY_VALUEMAP = [('FM', 7), ('Tx Power', 10), ('Scan', 28), ('Search', 29), ('PTT B', 1)] KEY_CHARS = '0123456789ABCDEF' FULL_CHARSET_ASCII = ("".join([chr(x) for x in range(ord(" "), ord("~") + 1)] + [chr(x) for x in range(128, 255)] + [chr(0)])) VFO_SFTD = ['OFF', '+', '-'] WORKMODES = ['VFO', 'Memory Mode'] SAVEMODES = ['OFF', 'Normal', 'Super', 'Deep'] DISPLAYMODES = ['Name', 'Freq', 'Memory ID'] SCANMODES = ['TO', 'CO', 'SE'] ALARMMODES = ['On Site', 'Send Sound', 'Send Code'] TDRTXMODES = ['OFF', 'A', 'B'] SCANDCSMODES = ['All', 'Receive', 'Transmit'] POWERMESSAGES = ['Image', 'Voltage'] FMRADIO = ['ON', 'OFF'] ENABLERADIO = ['Killed', 'Active'] CHANNELS = ['A', 'B'] TOT_LIST = ['OFF'] + [str(i*30) + "s" for i in range(1, 9)] VOX_LIST = ['OFF'] + [str(i) for i in range(1, 9)] BACKLIGHT_TO = ['OFF', '5s', '10s', '15s', '20s', '30s', '1m', '2m', '3m'] AUTOLOCK_TO = ['OFF', '5s', '10s', '15s'] MENUEXIT_TO = ['5s', '10s', '15s', '20s', '25s', '30s', '35s', '40s', '45s', '50s', '60s'] SQUELCHLVLS = [str(i) for i in range(10)] ANI_IDS = [str(i+1) for i in range(60)] VOXDELAYLIST = [str(float(a)/10)+'s' for a in range(5, 21)] DTMFSTLIST = ['OFF', 'DT Side Tone', 'ANI Side Tone', 'DT ST + ANI ST'] RPTTONES = ['1000Hz', '1450Hz', '1750Hz', '2100Hz'] RPTNOISE = [str(a)+'s' for a in range(11)] _memory_size = _upper = 256 # Number of memory slots _mem_params = (_upper-1) _frs = _murs = _pmr = _gmrs = True @classmethod def match_model(cls, filedata, filename): return False def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: self._set_setting(element) def _set_setting(self, setting): # WIP _mem = self._memobj key = setting.get_name() val = setting.value if key.startswith('dummy'): return elif key.startswith('settings_dtmfgroup.'): if str(val) == "": setattr(_mem.settings_dtmfgroup[int(key.split('@')[1])-1], 'code', [0xFF]*5) else: tmp = [DTMFCHARS.index(c) for c in str(val)] tmp += [0xFF] * (5 - len(tmp)) setattr(_mem.settings_dtmfgroup[int(key.split('@')[1])-1], 'code', tmp) elif key.startswith('settings.'): if key.endswith('_memidx'): val = int(val) - 1 if key.endswith('fmpreset'): tmp = val.get_value() * 10 setattr(_mem.settings, key.split('.')[1], tmp) else: setattr(_mem.settings, key.split('.')[1], int(val)) elif key.startswith('settings_dtmf.'): attr = key.split('.')[1] setattr(_mem.settings_dtmf, attr, int(val)) if attr.startswith('pttid'): setattr(_mem.settings, attr, int(val)) elif key.startswith('settings_sidekeys.'): setattr(_mem.settings_sidekeys, key.split('.')[1], int(val)) elif key.startswith('settings_vfo.'): # TODO rx/tx tones tmp = key.split('.') attr = tmp[2] vfo = tmp[1] # LOG.debug(">>> PRE key '%s'" % key) # LOG.debug(">>> PRE val '%s'" % val) if attr.startswith('rxfreq'): value = chirp_common.parse_freq(str(val)) / 10 for i in range(7, -1, -1): _mem.settings_vfo[vfo].rxfreq[i] = value % 10 value /= 10 elif attr.startswith('offset'): value = int(float(str(val)) * 10000) for i in range(5, -1, -1): _mem.settings_vfo[vfo].offset[i] = value % 10 value /= 10 else: setattr(_mem.settings_vfo[vfo], attr, int(val)) elif key.startswith('settings_bands.'): tmp = key.split('.') attr = tmp[2] band = tmp[1] setattr(_mem.settings_bands[band], attr, int(val)) elif key.startswith('settings_killswitch.'): attr = key.split('.')[1] if attr.endswith('dtmf'): if str(val) == "": setattr(_mem.settings_killswitch, attr, [0x01, 0x02, 0x01, 0x03, 0x01, 0x04]) else: setattr(_mem.settings_killswitch, attr, [DTMFCHARS.index(c) for c in str(val)]) elif attr.startswith('enable'): setattr(_mem.settings_killswitch, attr, int(val)) else: LOG.debug(">>> TODO key '%s'" % key) LOG.debug(">>> TODO val '%s'" % val) elif key.startswith('custom_') or key.startswith('anicode') \ or key.startswith('memcode'): tmp = key.split('@') if key.startswith('anicode'): val = [DTMFCHARS.index(c) for c in str(val)] val += [0xFF] * (6 - len(val)) for i in range(10): _mem[str(tmp[0])][int(tmp[2])]["ffpad"][i] = 0xFF elif key.startswith('memcode'): if len(str(val)) > 0: tmpp = str(val).zfill(6) val = self._encode_key(tmpp) else: val = (0xFF, 0xFF, 0xFF, 0xFF) if key.startswith('custom_'): for i in range(6): _mem[str(tmp[0])][int(tmp[2])]["ffpad"][i] = 0xFF setattr(_mem[str(tmp[0])][int(tmp[2])], str(tmp[1]), val) elif key.startswith('management_settings'): setattr(_mem.management_settings, key.split('.')[1], int(val)) else: LOG.debug(">>> TODO _set_setting key '%s'" % key) LOG.debug(">>> TODO _set_setting val '%s'" % val) def _get_settings_bands(self): _mem = self._memobj ret = RadioSettingGroup('bands', 'Bands') bands = [('136', _mem.settings_bands.band136), ('200', _mem.settings_bands.band200), ('350', _mem.settings_bands.band350), ('400', _mem.settings_bands.band400)] for label, band in bands: rs = RadioSetting('settings_bands.band%s.enable' % label, 'Enable Band %s' % label, RadioSettingValueBoolean(band.enable)) ret.append(rs) rsi = RadioSettingValueInteger(1, 1000, band.freq_low) # if label == '136' or label == '400': # rsi.set_mutable(False) rs = RadioSetting("settings_bands.band%s.freq_low" % label, "Band %s Lower Limit (MHz) (EXPERIMENTAL)" % label, rsi) ret.append(rs) rsi = RadioSettingValueInteger(1, 1000, band.freq_high) # if label == '350': # rsi.set_mutable(False) rs = RadioSetting("settings_bands.band%s.freq_high" % label, "Band %s Upper Limit (MHz) (EXPERIMENTAL)" % label, rsi) ret.append(rs) return ret def _get_settings_ks(self): _mem = self._memobj ret = RadioSettingGroup('killswitch', 'Killswitch') # Kill Enable/Disable enable_killsw rsvb = RadioSettingValueBoolean(_mem.settings.enable_killsw) ret.append(RadioSetting('settings.enable_killsw', 'Enable Killswitch', rsvb)) # Kill DTMF cur = ''.join( DTMFCHARS[i] for i in _mem.settings_killswitch.kill_dtmf if int(i) < 0xF) ret.append( RadioSetting('settings_killswitch.kill_dtmf', 'DTMF Kill', RadioSettingValueString(6, 6, cur, autopad=False, charset=DTMFCHARS))) # Revive DTMF cur = ''.join( DTMFCHARS[i] for i in _mem.settings_killswitch.revive_dtmf if int(i) < 0xF) ret.append( RadioSetting('settings_killswitch.revive_dtmf', 'DTMF Revive', RadioSettingValueString(6, 6, cur, autopad=False, charset=DTMFCHARS))) # Enable/Disable entire radio rs = RadioSettingValueString(0, 255, "Can be used to revive radio") rs.set_mutable(False) ret.append(RadioSetting('dummy', 'Factory reserved', rs)) tmp = 1 if int(_mem.management_settings.active) > 0 else 0 ret.append(RadioSetting('management_settings.active', 'Radio Status', RadioSettingValueList(self.ENABLERADIO, self.ENABLERADIO[tmp]))) return ret def _get_settings_dtmf(self): _mem = self._memobj dtmf = RadioSettingGroup('dtmf', 'DTMF') # DTMF Group msgs = ["Allowed chars (%s)" % DTMFCHARS, "Input from 0 to 5 characters." ] for msg in msgs: rsvs = RadioSettingValueString(0, 255, msg, autopad=False) rsvs.set_mutable(False) rs = RadioSetting('dummy_dtmf_msg_%i' % msgs.index(msg), 'Input rule %i' % int(msgs.index(msg)+1), rsvs) dtmf.append(rs) for i in range(1, 16): cur = ''.join( DTMFCHARS[i] for i in _mem.settings_dtmfgroup[i - 1].code if int(i) < 0xF) dtmf.append( RadioSetting( 'settings_dtmfgroup.code@%i' % i, 'PTT ID Code %i' % i, RadioSettingValueString(0, 5, cur, autopad=False, charset=DTMFCHARS))) # DTMF Speed (on time in ms) dtmf_speed_on = int(_mem.settings_dtmf.dtmf_speed_on) if dtmf_speed_on > len(self.DTMF_SPEEDS)-1: _mem.settings_dtmf.dtmf_speed_on = 0 LOG.debug('DTMF Speed On overflow') cur = self.DTMF_SPEEDS[dtmf_speed_on] dtmf.append( RadioSetting( 'settings_dtmf.dtmf_speed_on', 'DTMF Speed (on time in ms)', RadioSettingValueList(self.DTMF_SPEEDS, cur))) # DTMF Speed (on time in ms) dtmf_speed_off = int(_mem.settings_dtmf.dtmf_speed_off) if dtmf_speed_off > len(self.DTMF_SPEEDS)-1: _mem.settings_dtmf.dtmf_speed_off = 0 LOG.debug('DTMF Speed Off overflow') cur = self.DTMF_SPEEDS[dtmf_speed_off] dtmf.append( RadioSetting( 'settings_dtmf.dtmf_speed_off', 'DTMF Speed (off time in ms)', RadioSettingValueList(self.DTMF_SPEEDS, cur))) # PTT ID pttid = int(_mem.settings_dtmf.pttid) if pttid > len(self.PTTID)-1: _mem.settings_dtmf.pttid = 0 LOG.debug('PTT ID overflow') cur = self.PTTID[pttid] dtmf.append( RadioSetting( 'settings_dtmf.pttid', 'Send DTMF Code (PTT ID)', RadioSettingValueList(self.PTTID, cur))) # PTT ID Delay pttiddelay = int(_mem.settings.pttiddelay) if pttiddelay > len(self.PTTIDDELAYS)-1: _mem.settings.pttiddelay = 0 LOG.debug('PTT ID Delay overflow') cur = self.PTTIDDELAYS[pttiddelay] rsvl = RadioSettingValueList(self.PTTIDDELAYS, cur) dtmf.append(RadioSetting('settings.pttiddelay', 'PTT ID Delay', rsvl)) rsvl = RadioSettingValueList(self.DTMFSTLIST, self.DTMFSTLIST[_mem.settings.dtmfst]) dtmf.append(RadioSetting('settings.dtmfst', 'DTMF Side Tone (Required for GPS ID)', rsvl)) return dtmf def _get_settings_sidekeys(self): _mem = self._memobj ret = RadioSettingGroup('sidekeys', 'Side Keys') rsvm = RadioSettingValueMap(self.SIDEKEY_VALUEMAP, _mem.settings_sidekeys.pf2_short) ret.append(RadioSetting('settings_sidekeys.pf2_short', 'Side key 1 (PTT2) Short press', rsvm)) rsvm = RadioSettingValueMap(self.SIDEKEY_VALUEMAP[:-1], _mem.settings_sidekeys.pf2_long) ret.append(RadioSetting('settings_sidekeys.pf2_long', 'Side key 1 (PTT2) Long press', rsvm)) rsvm = RadioSettingValueMap(self.SIDEKEY_VALUEMAP[:-1], _mem.settings_sidekeys.pf3_short) ret.append(RadioSetting('settings_sidekeys.pf3_short', 'Side key 2 (PTT3) Short press', rsvm)) rs = RadioSettingValueString(0, 255, "MONI") rs.set_mutable(False) ret.append(RadioSetting('dummy', 'Side key 2 (PTT3) Long press', rs)) return ret def _get_settings_vfo(self, vfo, chan): # WIP TODO Rx/Tx tones _mem = self._memobj ret = RadioSettingGroup('settings_vfo@%s' % chan.lower(), 'VFO %s Settings' % chan) rsvl = RadioSettingValueList(self.WORKMODES, self.WORKMODES[_mem.settings[ 'workmode'+chan.lower()]]) ret.append(RadioSetting('settings.workmode%s' % chan.lower(), 'VFO %s Workmode' % chan, rsvl)) tmp = ''.join(DTMFCHARS[i] for i in _mem.settings_vfo[ 'vfo_'+chan.lower()].rxfreq if i < 0xFF) rsvf = RadioSettingValueFloat(66, 550, chirp_common.format_freq( int(tmp) * 10), resolution=0.00001, precision=5) ret.append(RadioSetting('settings_vfo.vfo_%s.rxfreq' % chan.lower(), 'Rx Frequency', rsvf)) # TODO Rx/Tx tones rsvl = RadioSettingValueList(self.VFO_SFTD, self.VFO_SFTD[_mem.settings_vfo[ 'vfo_'+chan.lower()].sftd]) ret.append(RadioSetting('settings_vfo.vfo_%s.sftd' % chan.lower(), 'Freq offset direction', rsvl)) tmp = ''.join(DTMFCHARS[i] for i in _mem.settings_vfo[ 'vfo_'+chan.lower()].offset if i < 0xFF) rsvf = RadioSettingValueFloat(0, 99.9999, float(tmp) / 10000) ret.append(RadioSetting('settings_vfo.vfo_%s.offset' % chan.lower(), 'Tx Offset', rsvf)) rsvl = RadioSettingValueList(self.SIGNAL, self.SIGNAL[ _mem.settings_vfo[ 'vfo_'+chan.lower()].signal]) ret.append(RadioSetting('settings_vfo.vfo_%s.signal' % chan.lower(), 'PTT ID Code (S-Code)', rsvl)) rsvl = RadioSettingValueList(self.POWER_LEVELS_LIST, self.POWER_LEVELS_LIST[ _mem.settings_vfo[ 'vfo_'+chan.lower()].power]) ret.append(RadioSetting('settings_vfo.vfo_%s.power' % chan.lower(), 'Tx Power', rsvl)) rsvl = RadioSettingValueList(self.FHSS_LIST, self.FHSS_LIST[ _mem.settings_vfo[ 'vfo_'+chan.lower()].fhss]) ret.append(RadioSetting('settings_vfo.vfo_%s.fhss' % chan.lower(), 'FHSS (Encryption)', rsvl)) rsvl = RadioSettingValueList(['Wide', 'Narrow'], ['Wide', 'Narrow'][ _mem.settings_vfo[ 'vfo_'+chan.lower()].narrow]) ret.append(RadioSetting('settings_vfo.vfo_%s.narrow' % chan.lower(), 'Wide / Narrow', rsvl)) rsvl = RadioSettingValueList(self.TUNING_STEPS_LIST, self.TUNING_STEPS_LIST[ _mem.settings_vfo[ 'vfo_'+chan.lower()].freqstep]) ret.append(RadioSetting('settings_vfo.vfo_%s.freqstep' % chan.lower(), 'Tuning Step', rsvl)) return ret def _get_custom_channel_names(self): _mem = self._memobj ret = RadioSettingGroup('ccn', 'Custom Channel Names') msgs = ["Add custom chan names to radio", "-> Menu 09 CH-NAME", "Allowed chars (ASCII only)", "Input from 0 to 10 characters." ] for msg in msgs: rsvs = RadioSettingValueString(0, 255, msg, autopad=False) rsvs.set_mutable(False) rs = RadioSetting('dummy_cnames_msg_%i' % msgs.index(msg), 'Input rule %i' % int(msgs.index(msg)+1), rsvs) ret.append(rs) for i in range(0, len(_mem.custom_channel_names)): tmp = ''.join([str(j) for j in _mem.custom_channel_names[i].name if ord(str(j)) < 0xFF and ord(str(j)) > 0x00]) rsvs = RadioSettingValueString(0, 10, tmp, autopad=True, charset=self.FULL_CHARSET_ASCII) ret.append(RadioSetting('custom_channel_names@name@%i' % i, 'Custom Channel Name (%i)' % i, rsvs)) return ret def _get_custom_ani_names(self): _mem = self._memobj ret = RadioSettingGroup('can', 'Custom ANI Names') msgs = ["Can be used as radio id in GPS.", "Allowed chars (ASCII only)", "Input from 0 to 10 characters." ] for msg in msgs: rsvs = RadioSettingValueString(0, 255, msg, autopad=False) rsvs.set_mutable(False) rs = RadioSetting('dummy_caninames_msg_%i' % msgs.index(msg), 'Input rule %i' % int(msgs.index(msg)+1), rsvs) ret.append(rs) for i in range(0, len(_mem.custom_ani_names)): tmp = ''.join([str(j) for j in _mem.custom_ani_names[i].name if ord(str(j)) < 0xFF and ord(str(j)) > 0x00]) rsvs = RadioSettingValueString(0, 10, tmp, autopad=True, charset=self.FULL_CHARSET_ASCII) ret.append(RadioSetting('custom_ani_names@name@%i' % i, 'Custom ANI Name (%i)' % (i+51), rsvs)) return ret def _get_anicodes(self): _mem = self._memobj ret = RadioSettingGroup('ani', 'ANI Codes') split = len(_mem.anicodes) - len(_mem.custom_ani_names) msgs = ["Allowed chars (%s)" % DTMFCHARS, "Input from 0 to 6 characters." ] for msg in msgs: rsvs = RadioSettingValueString(0, 255, msg, autopad=False) rsvs.set_mutable(False) rs = RadioSetting('dummy_canic_msg_%i' % msgs.index(msg), 'Input rule %i' % int(msgs.index(msg)+1), rsvs) ret.append(rs) for i in range(0, split): tmp = ''.join([DTMFCHARS[int(j)] for j in _mem.anicodes[i].anicode if int(j) < 0xFF]) # LOG.debug("ANI Code (%i) '%s'" % (i, tmp)) rsvs = RadioSettingValueString(0, 6, tmp, autopad=False, charset=DTMFCHARS) ret.append(RadioSetting('anicodes@anicode@%i' % i, 'ANI-ID (%i) Code' % (i+1), rsvs)) for i in range(split, len(_mem.anicodes)): tmp = ''.join([DTMFCHARS[int(j)] for j in _mem.anicodes[i].anicode if int(j) < 0xFF]) tmp2 = ''.join([str(j) for j in _mem.custom_ani_names[i-split].name if ord(str(j)) < 0xFF and ord(str(j)) > 0x00]) # LOG.debug("ANI Code (%s) (%i) '%s'" % (tmp2, i, tmp)) rsvs = RadioSettingValueString(0, 6, tmp, autopad=False, charset=DTMFCHARS) ret.append(RadioSetting('anicodes@anicode@%i' % i, 'ANI-ID (%s) (%i) Code' % (tmp2, i+1), rsvs)) return ret def _get_settings_adv(self): _mem = self._memobj ret = RadioSettingGroup('advanced', 'Advanced') if RT490_EXPERIMENTAL: rsvi = RadioSettingValueInteger( 1, self._memory_size, int(_mem.settings.cha_memidx)+1) ret.append(RadioSetting("settings.cha_memidx", "Channel A Memory index", rsvi)) rsvi = RadioSettingValueInteger(1, self._memory_size, int(_mem.settings.chb_memidx)+1) ret.append(RadioSetting("settings.chb_memidx", "Channel B Memory index", rsvi)) ret.append(RadioSetting('settings.vox', 'VOX Sensitivity', RadioSettingValueList(self.VOX_LIST, self.VOX_LIST[_mem.settings.vox]))) ret.append(RadioSetting('settings.vox_delay', 'VOX Delay', RadioSettingValueList(self.VOXDELAYLIST, self.VOXDELAYLIST[ _mem.settings.vox_delay]))) ret.append(RadioSetting('settings.tdr', 'Dual Receive (TDR)', RadioSettingValueBoolean(_mem.settings.tdr))) ret.append(RadioSetting('settings.txundertdr', 'Tx under TDR', RadioSettingValueList(self.TDRTXMODES, self.TDRTXMODES[ _mem.settings.txundertdr]))) ret.append(RadioSetting('settings.voice', 'Menu Voice Prompts', RadioSettingValueBoolean(_mem.settings.voice))) ret.append(RadioSetting('settings.scanmode', 'Scan Mode', RadioSettingValueList(self.SCANMODES, self.SCANMODES[ _mem.settings.scanmode]))) ret.append(RadioSetting('settings.bcl', 'Busy Channel Lockout', RadioSettingValueBoolean(_mem.settings.bcl))) ret.append(RadioSetting('settings.display_ani', 'Display ANI ID', RadioSettingValueBoolean(_mem.settings.display_ani))) ret.append(RadioSetting('settings.ani_id', 'ANI ID', RadioSettingValueList(self.ANI_IDS, self.ANI_IDS[_mem.settings.ani_id]))) ret.append(RadioSetting('settings.alarm_mode', 'Alarm Mode', RadioSettingValueList(self.ALARMMODES, self.ALARMMODES[ _mem.settings.alarm_mode]))) ret.append(RadioSetting('settings.alarmsound', 'Alarm Sound', RadioSettingValueBoolean(_mem.settings.alarmsound))) ret.append(RadioSetting('settings.fmradio', 'Enable FM Radio', RadioSettingValueList(self.FMRADIO, self.FMRADIO[_mem.settings.fmradio]))) if RT490_EXPERIMENTAL: tmp = _mem.settings.fmpreset / 10.0 if tmp < 65.0 or tmp > 108.0: tmp = 80.0 ret.append(RadioSetting("settings.fmpreset", "FM Radio Freq", RadioSettingValueFloat(65, 108, tmp, resolution=0.1, precision=1))) ret.append(RadioSetting('settings.kblock', 'Enable Keyboard Lock', RadioSettingValueBoolean(_mem.settings.kblock))) ret.append(RadioSetting('settings.autolock', 'Autolock Keyboard', RadioSettingValueList(self.AUTOLOCK_TO, self.AUTOLOCK_TO[ _mem.settings.autolock]))) ret.append(RadioSetting('settings.timer_menu_quit', 'Menu Exit Time', RadioSettingValueList(self.MENUEXIT_TO, self.MENUEXIT_TO[ _mem.settings.timer_menu_quit]))) ret.append(RadioSetting('settings.enable_gps', 'Enable GPS', RadioSettingValueBoolean(_mem.settings.enable_gps))) ret.append(RadioSetting('settings.scan_dcs', 'CDCSS Save Modes', RadioSettingValueList(self.SCANDCSMODES, self.SCANDCSMODES[ _mem.settings.scan_dcs]))) ret.append(RadioSetting('settings.tailnoiseclear', 'Tail Noise Clear', RadioSettingValueBoolean(_mem.settings.tailnoiseclear))) ret.append(RadioSetting('settings.rptnoiseclear', 'Rpt Noise Clear', RadioSettingValueList(self.RPTNOISE, self.RPTNOISE[ _mem.settings.rptnoiseclear]))) ret.append(RadioSetting('settings.rptnoisedelay', 'Rpt Noise Delay', RadioSettingValueList(self.RPTNOISE, self.RPTNOISE[ _mem.settings.rptnoisedelay]))) ret.append(RadioSetting('settings.rpttone', 'Rpt Tone', RadioSettingValueList(self.RPTTONES, self.RPTTONES[ _mem.settings.rpttone]))) return ret def _get_settings_basic(self): _mem = self._memobj ret = RadioSettingGroup('basic', 'Basic') ret.append(RadioSetting('settings.squelch', 'Carrier Squelch Level', RadioSettingValueList(self.SQUELCHLVLS, self.SQUELCHLVLS[ _mem.settings.squelch]))) ret.append(RadioSetting('settings.savemode', 'Battery Savemode', RadioSettingValueList(self.SAVEMODES, self.SAVEMODES[ _mem.settings.savemode]))) ret.append(RadioSetting('settings.backlight', 'Backlight Timeout', RadioSettingValueList(self.BACKLIGHT_TO, self.BACKLIGHT_TO[ _mem.settings.backlight]))) ret.append(RadioSetting('settings.timeout', 'Timeout Timer (TOT)', RadioSettingValueList(self.TOT_LIST, self.TOT_LIST[ _mem.settings.timeout]))) ret.append(RadioSetting('settings.beep', 'Beep', RadioSettingValueBoolean(_mem.settings.beep))) ret.append(RadioSetting('settings.active_channel', 'Active Channel', RadioSettingValueList(self.CHANNELS, self.CHANNELS[ _mem.settings.active_channel]))) ret.append(RadioSetting('settings.cha_disp', 'Channel A Display Mode', RadioSettingValueList(self.DISPLAYMODES, self.DISPLAYMODES[ _mem.settings.cha_disp]))) ret.append(RadioSetting('settings.chb_disp', 'Channel B Display Mode', RadioSettingValueList(self.DISPLAYMODES, self.DISPLAYMODES[ _mem.settings.chb_disp]))) ret.append(RadioSetting('settings.roger', 'Roger Beep', RadioSettingValueBoolean(_mem.settings.roger))) ret.append(RadioSetting('settings.powermsg', 'Power Message', RadioSettingValueList(self.POWERMESSAGES, self.POWERMESSAGES[ _mem.settings.powermsg]))) ret.append(RadioSetting('settings.rx_time', 'Show RX Time', RadioSettingValueBoolean(_mem.settings.rx_time))) return ret def _get_memcodes(self): ret = RadioSettingGroup('mc', 'Memory Channel Privacy Codes') msgs = ["Only hexadecimal chars accepted.", "Allowed chars (%s)" % self.KEY_CHARS, "Input from 0 to 6 characters. If code", "length is less than 6 chars it will be", "padded with leading zeros.", "Ex: 1D32EB or 0F12 or AB521, etc...", "Enable Code for the Location on the", "'Other' tab in 'Memory Properties'." ] for msg in msgs: rsvs = RadioSettingValueString(0, 255, msg, autopad=False) rsvs.set_mutable(False) rs = RadioSetting('dummy_memcodes_msg_%i' % msgs.index(msg), 'Input rule %i' % int(msgs.index(msg)+1), rsvs) ret.append(rs) for i in range(self._memory_size): code = "" if self._memobj.memcode[i].code[3] < 0xFF: code = self._decode_key(self._memobj.memcode[i].code) code = code.zfill(6) rsvs = RadioSettingValueString(0, 6, code, autopad=False, charset=self.KEY_CHARS) rs = RadioSetting('memcode@code@%i' % i, 'Memory Location (%i) Privacy Code' % int(i+1), rsvs) ret.append(rs) return ret def get_settings(self): radio_settings = [] basic = self._get_settings_basic() radio_settings.append(basic) adv = self._get_settings_adv() radio_settings.append(adv) vfoa = self._get_settings_vfo(self._memobj.settings_vfo.vfo_a, 'A') radio_settings.append(vfoa) vfob = self._get_settings_vfo(self._memobj.settings_vfo.vfo_b, 'B') radio_settings.append(vfob) sk = self._get_settings_sidekeys() radio_settings.append(sk) dtmf = self._get_settings_dtmf() radio_settings.append(dtmf) ccn = self._get_custom_channel_names() radio_settings.append(ccn) can = self._get_custom_ani_names() radio_settings.append(can) ani = self._get_anicodes() radio_settings.append(ani) mcodes = self._get_memcodes() radio_settings.append(mcodes) if RT490_EXPERIMENTAL: ks = self._get_settings_ks() radio_settings.append(ks) bands = self._get_settings_bands() radio_settings.append(bands) top = RadioSettings(*radio_settings) return top def get_raw_memory(self, number): return repr(self._memobj.memory[number]) # TODO Add Code when RadioSettingValueString is fixed def _get_extra(self, _mem, num): group = RadioSettingGroup('extra', 'Extra') # LOG.debug("Get extra %i" % num) s = RadioSetting('bcl', 'Busy Channel Lockout', RadioSettingValueBoolean(_mem.bcl)) group.append(s) dcp = int(_mem.dcp) if dcp > len(self.FHSS_LIST)-1: _mem.dcp = cur = 0 LOG.debug('DCP ID / FHSS overflow for channel %d' % num) cur = self.FHSS_LIST[dcp] s = RadioSetting('dcp', 'FHSS (Encryption)', RadioSettingValueList(self.FHSS_LIST, cur)) group.append(s) # Does not work, no error, why ??? TODO """ code = "" if self._memobj.memcode[num-1].code[3] < 0xFF: code = self._decode_key(self._memobj.memcode[num-1].code) code = code.zfill(6) LOG.debug('CODE "%s"' % code) s = RadioSetting('dcp_code', 'DCP code', RadioSettingValueString(0, 6, code, autopad=False, charset=self.KEY_CHARS)) group.append(s) """ pttid = int(_mem.pttid) if pttid > len(self.PTTID)-1: _mem.pttid = cur = 0 LOG.debug('PTTID overflow for channel %d' % num) cur = self.PTTID[pttid] s = RadioSetting('pttid', 'Send DTMF Code (PTT ID)', RadioSettingValueList(self.PTTID, cur)) group.append(s) cur = self.SIGNAL[int(_mem.signal)] s = RadioSetting('signal', 'PTT ID Code (S-Code)', RadioSettingValueList(self.SIGNAL, cur)) group.append(s) s = RadioSetting('learn', 'Use Memory Privacy Code as Tx/Rx DCS (Learn)', RadioSettingValueBoolean(_mem.learn)) group.append(s) return group # TODO Add Code when RadioSettingValueString is fixed def _set_extra(self, _mem, mem): # memidx = mem.number - 1 # commented because not used _mem.bcl = int(mem.extra['bcl'].value) _mem.dcp = int(mem.extra['dcp'].value) _mem.pttid = int(mem.extra['pttid'].value) _mem.signal = int(mem.extra['signal'].value) # self._memobj.memcode[mem.number].code = \ # self._encode_key(mem.extra['dcp_code'].value) if (int(mem.extra['learn'].value) > 0) and \ (self._memobj.memcode[mem.number-1].code[3] == 0xA0): _mem.learn = 1 elif (int(mem.extra['learn'].value) > 0) and \ (self._memobj.memcode[mem.number-1].code[3] != 0xA0): _mem.learn = 0 raise InvalidValueError( "Use Memory Privacy Code as Tx/Rx DCS (Learn) requires " "that a memory code has been previously set for this memory." "Go in 'Settings' -> 'Memory Channel Privacy Codes' and set " "a code for the current memory before enabling 'Learn'.") else: _mem.learn = 0 def _is_txinh(self, _mem): raw_tx = b"" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw() return raw_tx == b"\xFF\xFF\xFF\xFF" def get_memory(self, num): memidx = num - 1 _mem = self._memobj.memory[memidx] _nam = self._memobj.memname[memidx] mem = chirp_common.Memory() mem.number = num if int(_mem.rxfreq) == 166666665: mem.empty = True return mem mem.name = ''.join([str(c) for c in _nam.name if ord(str(c)) < 127]).rstrip() mem.freq = int(_mem.rxfreq) * 10 offset = (int(_mem.txfreq) - int(_mem.rxfreq)) * 10 if self._is_txinh(_mem) or _mem.tx_enable == 0: mem.duplex = 'off' # _mem.txfreq = _mem.rxfreq # TODO REMOVE (force fix broken saves) elif offset == 0: mem.duplex = '' mem.offset = 0 elif abs(offset) < 100000000: mem.duplex = offset < 0 and '-' or '+' mem.offset = abs(offset) else: mem.duplex = 'split' mem.offset = int(_mem.txfreq) * 10 mem.power = self.POWER_LEVELS[_mem.power] if _mem.unknown3_0 and _mem.narrow: mem.mode = 'NAM' elif _mem.unknown3_0 and not _mem.narrow: mem.mode = 'AM' elif not _mem.unknown3_0 and _mem.narrow: mem.mode = 'NFM' elif not _mem.unknown3_0 and not _mem.narrow: mem.mode = 'FM' else: LOG.exception('Failed to get mode for %i' % num) mem.skip = '' if _mem.scan else 'S' # LOG.warning('got txtone: %s' % repr(self._decode_tone(_mem.txtone))) # LOG.warning('got rxtone: %s' % repr(self._decode_tone(_mem.rxtone))) txtone = self._decode_tone(_mem.txtone) rxtone = self._decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) try: mem.extra = self._get_extra(_mem, num) except Exception: LOG.exception('Failed to get extra for %i' % num) return mem def set_memory(self, mem): memidx = mem.number - 1 _mem = self._memobj.memory[memidx] _nam = self._memobj.memname[memidx] if mem.empty: _mem.set_raw(b'\xff' * 16) _nam.set_raw(b'\xff' * 16) return if int(_mem.rxfreq) == 166666665: LOG.debug('Initializing new memory %i' % memidx) _mem.set_raw(b'\x00' * 16) _nam.name = mem.name.ljust(12, chr(255)) # with xFF pad (mimic factory # behavior) _mem.rxfreq = mem.freq / 10 _mem.tx_enable = 1 if mem.duplex == '': _mem.txfreq = mem.freq / 10 elif mem.duplex == 'split': _mem.txfreq = mem.offset / 10 elif mem.duplex == 'off': _mem.tx_enable = 0 _mem.txfreq = mem.freq / 10 # Optional but keeps compat with # vendor software elif mem.duplex == '-': _mem.txfreq = (mem.freq - mem.offset) / 10 elif mem.duplex == '+': _mem.txfreq = (mem.freq + mem.offset) / 10 else: raise errors.RadioError('Unsupported duplex mode %r' % mem.duplex) txtone, rxtone = chirp_common.split_tone_encode(mem) # LOG.warning('tx tone is %s' % repr(txtone)) # LOG.warning('rx tone is %s' % repr(rxtone)) _mem.txtone = self._encode_tone(*txtone) _mem.rxtone = self._encode_tone(*rxtone) try: _mem.power = self.POWER_LEVELS.index(mem.power) except ValueError: _mem.power = 0 if int(_mem.rxfreq) < 30000000: _mem.unknown3_0 = mem.mode in ['AM', 'NAM'] else: _mem.unknown3_0 = 0 _mem.narrow = mem.mode[0] == 'N' _mem.scan = mem.skip != 'S' if mem.extra: self._set_extra(_mem, mem) def sync_out(self): try: do_upload(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT490 % {"memsize": self._memory_size}, self._mmap) def get_features(self): # GOOD ? rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_cross = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.valid_name_length = 12 rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = ["", "+", "-", "split", "off"] rf.valid_modes = ["FM", "NFM", "AM", "NAM"] rf.memory_bounds = (1, 256) rf.valid_tuning_steps = self.TUNING_STEPS rf.valid_bands = [(108000000, 136000000), (136000000, 180000000), (200000000, 260000000), (350000000, 400000000), (400000000, 520000000)] return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_upload = _("This driver is in development and should be " "considered as experimental.") rp.experimental = _("This driver is in development and should be " "considered as experimental.") rp.info = _("This driver is in development and should be considered " "as experimental.") return rp def _encode_key(self, key): arr = bytearray(4) arr[3] = 160 arr[2] = self.KEY_CHARS.index(key[0]) # << 4 arr[2] = arr[2] << 4 arr[2] |= self.KEY_CHARS.index(key[1]) arr[1] = self.KEY_CHARS.index(key[2]) # << 4 arr[1] = arr[1] << 4 arr[1] |= self.KEY_CHARS.index(key[3]) arr[0] = self.KEY_CHARS.index(key[4]) # << 4 arr[0] = arr[0] << 4 arr[0] |= self.KEY_CHARS.index(key[5]) return arr def _decode_key(self, key): ret = "" if key[3] == 0xA0: ret += self.KEY_CHARS[key[2] >> 4] ret += self.KEY_CHARS[key[2] & 0xF] ret += self.KEY_CHARS[key[1] >> 4] ret += self.KEY_CHARS[key[1] & 0xF] ret += self.KEY_CHARS[key[0] >> 4] ret += self.KEY_CHARS[key[0] & 0xF] LOG.debug('DCP Code: "%s"' % ret) return ret def _decode_tone(self, toneval): if toneval in (0, 0xFFFF): # LOG.debug('no tone value: %s' % toneval) return None, None, None elif toneval < 670: toneval = toneval - 1 index = toneval % len(DTCS_CODES) if index != int(toneval): pol = 'R' # index -= 1 else: pol = 'N' return 'DTCS', DTCS_CODES[index], pol else: return 'Tone', toneval / 10.0, 'N' def _encode_tone(self, mode, val, pol): if not mode: return 0x0000 elif mode == 'Tone': return int(val * 10) elif mode == 'DTCS': index = DTCS_CODES.index(val) if pol == 'R': index += len(DTCS_CODES) index += 1 # LOG.debug('Encoded dtcs %s/%s to %04x' % (val, pol, index)) return index else: raise errors.RadioError('Unsupported tone mode %r' % mode) @directory.register class MML8629Radio(RT490Radio): """MMLradio JC-8629""" VENDOR = "MMLradio" MODEL = "JC-8629" @directory.register class JJCC8629Radio(RT490Radio): """JJCC JC-8629""" VENDOR = "JJCC" MODEL = "JC-8629" @directory.register class SocotranJC8629Radio(RT490Radio): """Socotran JC-8629""" VENDOR = "Socotran" MODEL = "JC-8629" @directory.register class SocotranFB8629Radio(RT490Radio): """Socotran FB-8629""" VENDOR = "Socotran" MODEL = "FB-8629" @directory.register class Jianpai8629Radio(RT490Radio): """Jianpai 8800 Plus""" VENDOR = "Jianpai" MODEL = "8800_Plus" @directory.register class Boristone8RSRadio(RT490Radio): """Boristone 8RS""" VENDOR = "Boristone" MODEL = "8RS" @directory.register class AbbreeAR869Radio(RT490Radio): """Abbree AR-869""" VENDOR = "Abbree" MODEL = "AR-869" @directory.register class HamGeekHG590Radio(RT490Radio): """HamGeek HG-590""" VENDOR = "HamGeek" MODEL = "HG-590" IMHEX_DESC = """ // Perfect tool for binary reverse engineering // https://github.com/WerWolv/ImHex // Below is the pattern """ IMHEX_PATTERN = """ struct memory { // Memory settings u8 rxfreq[4]; u8 txfreq[4]; u16 rxtone; u16 txtone; u8 signal; // int 0->14, Signal 1->15 u8 pttid; // ['OFF', 'BOT', 'EOT', 'Both'] u8 dcp_power; // POWER_LEVELS u8 unknown3_0_narrow_unknown3_1_bcl_scan_tx_enable_learn; // bool ??? TODO }; struct memname { char name[12]; padding[4]; }; struct memcode { u8 code[4]; }; struct custom_ani_names { char name[12]; padding[4]; }; struct anicodes { u8 anicode[6]; padding[10]; }; struct custom_channel_names { char name[12]; padding[4]; }; bitfield workmode { b : 4; a : 4; }; struct settings { u8 squelch; // 0: int 0 -> 9 u8 savemode; // 1: ['OFF', 'Normal', 'Super', 'Deep'] u8 vox; // 2: off=0, 1 -> 9 u8 backlight; // 3: ['OFF', '5s', '15s', '20s', '30s', '1m', '2m', // '3m'] u8 tdr; // 4: bool u8 timeout; // 5: n*30seconds, 0-240s u8 beep; // 6: bool u8 voice; // 7: bool u8 byte_not_used_10; // 8: Always 1 u8 dtmfst; // 9: ['OFF', 'KB Side Tone', 'ANI Side Tone', // 'KB ST + ANI ST'] u8 scanmode; // 10: ['TO', 'CO', 'SE'] u8 pttid; // 11: ['OFF', 'BOT', 'EOT', 'Both'] u8 pttiddelay; // 12: ['0', '100ms', '200ms', '400ms', '600ms', // '800ms', '1000ms'] u8 cha_disp; // 13: ['Name', 'Freq', 'Channel ID'] u8 chb_disp; // 14: ['Name', 'Freq', 'Channel ID'] u8 bcl; // 15: bool u8 autolock; // 0: ['OFF', '5s', '10s', 15s'] u8 alarm_mode; // 1: ['Site', 'Tone', 'Code'] u8 alarmsound; // 2: bool u8 txundertdr; // 3: ['OFF', 'A', 'B'] u8 tailnoiseclear; // 4: [off, on] u8 rptnoiseclear; // 5: n*100ms, 0-1000 u8 rptnoisedelay; // 6: n*100ms, 0-1000 u8 roger; // 7: bool u8 active_channel; // 8: 0 or 1 u8 fmradio; // 9: boolean, inverted workmode _workmode; // 10: up ['VFO', 'CH Mode'] u8 kblock; // 11: bool // TODO TEST WITH autolock u8 powermsg; // 12: 0=Image / 1=Voltage u8 byte_not_used_21; // 13: Always 0 u8 rpttone; // 14: ['1000Hz', '1450Hz', '1750Hz', '2100Hz'] u8 byte_not_used_22; // 15: pad with xFF u8 vox_delay; // 0: [str(float(a)/10)+'s' for a in range(5,21)] // '0.5s' to '2.0s' u8 timer_menu_quit; // 1: ['5s', '10s', '15s', '20s', '25s', '30s', // '35s', '40s', '45s', '50s', '60s'] u8 byte_not_used_30; // 2: pad with xFF u8 byte_not_used_31; // 3: pad with xFF u8 enable_killsw; // 4: bool u8 display_ani; // 5: bool u8 byte_not_used_32; // 6: pad with xFF u8 enable_gps; // 7: bool u8 scan_dcs; // 8: ['All', 'Receive', 'Transmit'] u8 ani_id; // 9: int 0-59 (ANI 1-60) u8 rx_time; // 10: bool padding[5]; // 11: Pad xFF u8 cha_memidx; // 0: Memory index when channel A use memories u8 byte_not_used_40; u8 chb_memidx; // 2: Memory index when channel B use memories u8 byte_not_used_41; padding[10]; u16 fmpreset; }; struct settings_vfo_chan { u8 rxfreq[8]; // 0 u16 rxtone; // 8 u16 txtone; // 10 u16 byte_not_used0; // 12 Pad xFF u8 sftd_signal; // 14 int 0->14, Signal 1->15 u8 byte_not_used1; // 15 Pad xFF u8 power; // 16:0 POWER_LEVELS u8 fhss_narrow; // 17 bool true=NFM false=FM u8 byte_not_used2; // 18 Pad xFF but received 0x00 ??? u8 freqstep; // 19:3 ['2.5 KHz', '5.0 KHz', '6.25 KHz', // '10.0 KHz', '12.5 KHz', '20.0 KHz', // '25.0 KHz', '50.0 KHz'] u8 byte_not_used3; // 20:4 Pad xFF but received 0x00 ??? TODO u8 offset[6]; // 21:5 Freq NN.NNNN (without the dot) TEST TEST u8 byte_not_used4; // 27:11 Pad xFF u8 byte_not_used5; // 28 Pad xFF u8 byte_not_used6; // 29 Pad xFF u8 byte_not_used7; // 30 Pad xFF u8 byte_not_used8; // 31:15 Pad xFF }; struct settings_vfo { settings_vfo_chan vfo_a; settings_vfo_chan vfo_b; }; struct settings_sidekeys { // Values from Radio u8 pf2_short; // { '7': 'FM', '10': 'Tx Power', '28': 'Scan', // '29': 'Search, '1': 'PPT B' } u8 pf2_long; // { '7': 'FM', '10': 'Tx Power', '28': 'Scan', // '29': 'Search' } u8 pf3_short; // { '7': 'FM', '10': 'Tx Power', '28': 'Scan', // '29': 'Search' } u8 ffpad; // Pad xFF }; struct dtmfcode { u8 code[5]; // 5 digits DTMF padding[11]; // Pad xFF }; struct settings_dtmf { // @15296+3x16 u8 byte_not_used1; // 0: Pad xFF u8 byte_not_used2; // 1: Pad xFF u8 byte_not_used3; // 2: Pad xFF u8 byte_not_used4; // 3: Pad xFF u8 byte_not_used5; // 4: Pad xFF u8 unknown_dtmf; // 5: 0 TODO ???? wtf is alarmcode/alarmcall TODO u8 pttid; // 6: [off, BOT, EOT, Both] u8 dtmf_speed_on; // 7: ['50ms', '100ms', '200ms', '300ms', '500ms'] u8 dtmf_speed_off; // 8:0 ['50ms', '100ms', '200ms', '300ms', '500ms'] }; struct settings_dtmf_global { dtmfcode settings_dtmfgroup[15]; settings_dtmf _settings_dtmf; }; struct settings_killswitch { u8 kill_dtmf[6]; // 0: Kill DTMF padding[2]; // Pad xFF u8 revive_dtmf[6]; // 8: Revive DTMF padding[2]; // Pad xFF }; struct management_settings { u8 unknown_data_0[16]; u8 unknown_data_1; u8 active; // Bool radio killed (killed=0, active=1) padding[46]; }; struct band { u8 enable; // 0 bool / enable-disable Tx on band u8 freq_low[2]; // 1 lowest band frequency u8 freq_high[2]; // 3 highest band frequency }; struct settings_bands { band band136; // 0 Settings for 136MHz band band band400; // 5 Settings for 400MHz band band band200; // 10 Settings for 200MHz band padding[1]; // 15 band band350; // 0 Settings for 350MHz band padding[43];// 5 }; memory mem[256] @ 0x0000; memname mname[256] @ 0x1000; memcode mcode[256] @ 0x2000; custom_ani_names caninames[10] @ 0x3400; anicodes anic[60] @ 0x3500; custom_channel_names ccnames[10] @ 0x3900; settings _settings @ 0x3A00; settings_vfo _settings_vfo @ 0x3A40; settings_sidekeys _settings_sidekeys @ 0x3A80; settings_dtmf_global _settings_dtmf_global @ 0x3B00; settings_killswitch _settings_killswitch @ 0x3C00; management_settings _management_settings @ 0x3F80; settings_bands _settings_bands @ 0x3FC0; """ chirp-20240224/chirp/drivers/retevis_rt87.py0000644000175000017500000011051214522657251017547 0ustar hibbyhibby# Copyright 2021 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Retevis RT87 radio management module""" import logging import struct from chirp import ( bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueInteger, RadioSettingValueList, RadioSettingValueString, ) LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct memory { bbcd rx_freq[4]; bbcd tx_freq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 unknown10:2, pttid:2, unknown11:1, highpower:1, option:2; u8 optsigtype:3, unknown20:1, narrow:1, vox:1, bcl:2; u8 unknown31:1, scanadd:1, unknown32:3, scrambler:3; u8 unknown4; }; struct name { char name[10]; }; #seekto 0x0010; struct memory channels[128]; #seekto 0x0830; struct { u8 scanmode:2, // Scan Modes (Time, Carrier, Seek) [17] autolock:1, // Auto Keypad Lock (Off, On) [18] unknown_0830:2, manager:1, // Manager (Off, On) unknown_08301:2; u8 batterydis:1, // Battery Display (Voltage, Icon) [20] unknown_0831:1, sidetone:1, // Side Tone (Off, On) unknown_08311:1, chnameshow:1, // Display Channel Names (Off, On) [25] voice:1, // Voice Prompt (Off, On) [19] beep:1, // Beep (Off, On) [09] batterysave:1; // Battery Save aka Receiver Saver (Off, On) [16] u8 unknown_0832:3, manual:1, // Manual (Disabled, Enabled) cancelcodesql:1, // Cancel Code Squelch When Press PTT (Disabled, // Enabled) ani:1, // Automatic Number Identity (Off, On) [10] roger:1, // Roger Time (Off, On) [14] dwatch:1; // Inhibit Receiver When Radio Working (Disabled, [15] // aka Dual Watch/Monitor Enabled) u8 unknown_0833:2, txsel:1, // Priority Transmit (Edit, Busy) [02] dwait:1, // Dual Wait/Standby (Off, On) [06] unknown_08331:1, dtmfsig:1, // DTMF Signaling (Code Squelch, Selective Call) msgmode:2; // Message Mode (Off, DC, MSG, Image) [23] u8 unk_0834:4, squelch:4; // Squelch Level (0 - 9) [05] u8 unk_0835:4, tot:4; // Time-out Timer (Off, 30sec, 60sec, 90sec, [11] // 120sec, 150sec, 180sec, // 210sec, 240sec, 270sec) u8 unknown_0836:2, voxdelaytime:2, // VOX Delay Time (1sec, 2sec, 3sec, 4sec) voxgainlevel:4; // VOX Gain Level (1 - 8) [03] u8 unknown_0837; u8 unknown_0838; u8 unknown_0839; u8 lamp:5, // Lamp 00000 Off [07] // 00001 On // 00010 5s // 00100 10s (default) // 01000 20s // 10000 30s brightness:3; // Brightness 000 Off [08] // 001 1 // 010 2 // 011 3 // 100 4 // 101 5 // 110 6 (default) // 111 7 u8 unknown_083B:1, pf1:3, // PF1 (Off, Reverse, Opt Call, 1750 Hz, A/B) [21] unknown_083B1:1, pf2:3; // PF2 (Off, Reverse, Opt Call, 1750 Hz, A/B) [22] u8 unknown_083c; // factory = 05, reset = FF u8 unknown_083d; // factory = 12, reset = FF u8 unknown_083e; // factory = 50, reset = FF u8 stunmode; // Stun Mode (Stun Rx/Tx, Stun Tx, Normal) } settings; #seekto 0x08C0; struct { char line1[16]; // PowerOn Message Line 1 (16 characters) char line2[16]; // PowerOn Message Line 2 (16 characters) char line3[16]; // PowerOn Message Line 3 (16 characters) char line4[16]; // PowerOn Message Line 4 (16 characters) } poweron_msg; #seekto 0x0D20; struct { u8 unknown_0d20:4, autoresettimer:4; // Auto Reset Timer[s] u8 delay; // Digit Delay u8 unknown_0d22:4, dtmflen:4; // DTMF Code Length u8 unknown_0d23; u8 unknown_0d24:4, intcode:4; // Intermediate Code u8 unknown_0d25:4, groupcode:4; // Group Code } optsig; #seekto 0x0D30; struct { u8 mskid[2]; // MSK ID Code } msk; #seekto 0x0D38; struct { u8 mskcall[2]; // MSK CallList u8 unused[2]; } msklist[10]; #seekto 0x0D90; struct { u8 bot[7]; // PTT-ID BOT (Beginning of Transmission) u8 unused_0d97; u8 eot[7]; // PTT-ID EOT (End of Transmission) "0123456789ABCD#* " u8 unused_0d9f; } pttid; #seekto 0x0DA8; struct { char code[7]; // Local Name } msk_name; #seekto 0x0DB0; struct { u8 code[16]; // MSK CallList } dtmfenc[10]; #seekto 0x0E50; struct { u8 stunid[4]; // Stun/Wake-Up ID Code } stun; #seekto 0x1900; struct name names[128]; """ # Radio supports UPPER/lower case and symbols CHARSET_ASCII_PLUS = chirp_common.CHARSET_ALPHANUMERIC + \ "!\"#$%&'()*+,-./:;<=>?@[\\]^_`" POWER_LEVELS = [chirp_common.PowerLevel('Low', watts=1), chirp_common.PowerLevel('High', watts=4)] VALID_BANDS = [(136000000, 174000000), (400000000, 480000000)] RT87_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) NUMERIC_CHARSET = list("0123456789") DTMF_CHARSET = NUMERIC_CHARSET + list("ABCD*#") LIST_BATTERY = ["Volt", "Icon"] LIST_BCL = ["Off", "Carrier", "QT/DQT"] LIST_BRIGHTNESS = ["Off"] + ["%s" % x for x in range(1, 8)] LIST_DTMFLEN = ["%s" % x for x in range(30, 160, 10)] LIST_DTMFSIG = ["Code Squelch", "Selective Call"] LIST_INTCODE = list(DTMF_CHARSET) LIST_OPTION = ["Off", "Compand", "Scramble"] LIST_POWERON = ["Off", "Voltage", "Message", "Picture"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_RESET = ["Off", "1 second"] + ["%s seconds" % x for x in range(2, 16)] LIST_SCNREV = ["Time Operated", "Carrier Operated", "Seek"] LIST_SIDEKEY = ["Off", "Reverse", "Opt Call", "1750 Hz", "A/B"] LIST_TOT = ["Off"] + ["%s seconds" % x for x in range(30, 300, 30)] LIST_TXSEL = ["Edit", "Busy"] LIST_VFOMR = ["Frequency (VFO)", "Channel (MR)"] LIST_VOXDELAYTIME = ["1 second", "2 seconds", "3 seconds", "4 seconds"] LED_CHOICES = ["Off", "On", "5 seconds", "10 seconds", "20 seconds", "30 seconcds"] LED_VALUES = [0x00, 0x01, 0x02, 0x04, 0x08, 0x10] DELAY_CHOICES = ["%s ms" % x for x in range(300, 1250, 50)] DELAY_VALUES = [x for x in range(0, 95, 5)] STUN_CHOICES = ["Stun Rx/Tx", "Stun Tx", "Normal"] STUN_VALUES = [0x55, 0xAA, 0xFF] GROUP_CHOICES = ["Off", "A", "B", "C", "D", "*", "#"] GROUP_VALUES = [0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F] def _identify(radio): try: magic = radio._MAGIC radio.pipe.write(magic) echo = radio.pipe.read(len(magic)) # Chew the echoed response if magic != echo: LOG.debug("expecting echo\n%s\n", util.hexprint(magic)) LOG.debug("got echo\n%s\n", util.hexprint(echo)) raise Exception("Got false echo. Expected: '{}', got: '{}'." .format(magic, echo)) ack = radio.pipe.read(2) if ack != b"\x06\x30": raise errors.RadioError("Radio did not ACK first command: %r" % ack) except: LOG.exception('') raise errors.RadioError("Unable to communicate with the radio") def _download(radio): _identify(radio) data = bytes([]) for i in range(0, 0x2000, 0x40): msg = struct.pack('>cHb', b'R', i, 0x40) radio.pipe.write(msg) echo = radio.pipe.read(len(msg)) # Chew the echoed response if msg != echo: LOG.debug("expecting echo\n%s\n", util.hexprint(msg)) LOG.debug("got echo\n%s\n", util.hexprint(echo)) raise Exception("Got false echo. Expected: '{}', got: '{}'." .format(msg, echo)) block = radio.pipe.read(0x40 + 4) if len(block) != (0x40 + 4): raise errors.RadioError("Radio sent a short block (%02x/%02x)" % ( len(block), 0x44)) data += block[4:] if radio.status_fn: status = chirp_common.Status() status.cur = i status.max = 0x2000 status.msg = "Cloning from radio" radio.status_fn(status) radio.pipe.write(b"E") return memmap.MemoryMapBytes(data) def _upload(radio): _identify(radio) for start_addr, end_addr, block_size in radio._ranges: for addr in range(start_addr, end_addr, block_size): msg = struct.pack('>cHb', b'W', addr, block_size) msg += radio._mmap[addr:(addr + block_size)] radio.pipe.write(msg) radio.pipe.read(block_size + 4) ack = radio.pipe.read(1) if ack != b'\x06': raise errors.RadioError('Radio did not ACK block %i (0x%04x)' % (addr, addr)) if radio.status_fn: status = chirp_common.Status() status.cur = addr status.max = 0x2000 status.msg = "Cloning to radio" radio.status_fn(status) radio.pipe.write(b"E") def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True class Rt87BaseRadio(chirp_common.CloneModeRadio): VENDOR = "Retevis" MODEL = "RT87 Base" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _MAGIC = b"PGM2017" def get_features(self): rf = chirp_common.RadioFeatures() # General rf.has_bank = False rf.has_rx_dtcs = True rf.has_tuning_step = False rf.has_ctone = True rf.has_cross = True rf.has_settings = True # Attributes rf.valid_modes = ["FM", "NFM"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_duplexes = ['', '-', '+', 'split', 'off'] rf.valid_tuning_steps = [0.5, 2.5, 5, 6.25, 10, 12.5, 25, 37.5, 50, 100] rf.valid_bands = VALID_BANDS rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS rf.valid_characters = CHARSET_ASCII_PLUS rf.valid_name_length = 10 rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.memory_bounds = (1, 128) rf.can_odd_split = True return rf def sync_in(self): """Download from radio""" try: data = _download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return (repr(self._memobj.channels[number - 1]) + repr(self._memobj.names[number - 1])) def _get_memobjs(self, number): return (self._memobj.channels[number - 1], self._memobj.names[number - 1]) def _decode_tone(self, toneval): pol = "N" rawval = (toneval[1].get_bits(0xFF) << 8) | toneval[0].get_bits(0xFF) if toneval[0].get_bits(0xFF) == 0xFF: mode = "" val = 0 elif toneval[1].get_bits(0xC0) == 0xC0: mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) pol = "R" elif toneval[1].get_bits(0x80): mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) else: mode = "Tone" val = int(toneval) / 10.0 return mode, val, pol def _encode_tone(self, _toneval, mode, val, pol): toneval = 0 if mode == "Tone": toneval = int("%i" % (val * 10), 16) elif mode == "DTCS": toneval = int("%i" % val, 16) toneval |= 0x8000 if pol == "R": toneval |= 0x4000 else: toneval = 0xFFFF _toneval[0].set_raw(toneval & 0xFF) _toneval[1].set_raw((toneval >> 8) & 0xFF) def _is_txinh(self, _mem): raw_tx = "" for i in range(0, 4): raw_tx += _mem.tx_freq[i].get_raw(asbytes=False) return raw_tx == "\xFF\xFF\xFF\xFF" def _bbcd2num(self, bcdarr, strlen=8): # doing bbcd LOG.debug(bcdarr.get_value()) string = ''.join("%02X" % b for b in bcdarr) LOG.debug("@_bbcd2num, received: %s" % string) if strlen <= 8: string = string[:strlen] return string def _num2bbcd(self, value, strlen=8): numstr = value.get_value() numstr = str.ljust(numstr.strip(), strlen, "F") bcdarr = list(bytearray.fromhex(numstr)) LOG.debug("@_num2bbcd, sending: %s" % bcdarr) return bcdarr def get_memory(self, number): _mem, _name = self._get_memobjs(number) mem = chirp_common.Memory() if isinstance(number, str): mem.number = SPECIALS[number] mem.extd_number = number else: mem.number = number if _mem.get_raw(asbytes=False).startswith("\xFF\xFF\xFF\xFF"): mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 if self._is_txinh(_mem): # TX freq not set mem.duplex = "off" mem.offset = 0 else: # TX freq set offset = (int(_mem.tx_freq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.tx_freq) * 10): mem.duplex = "split" mem.offset = int(_mem.tx_freq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 txmode, txval, txpol = self._decode_tone(_mem.tx_tone) rxmode, rxval, rxpol = self._decode_tone(_mem.rx_tone) chirp_common.split_tone_decode(mem, (txmode, txval, txpol), (rxmode, rxval, rxpol)) mem.mode = 'NFM' if _mem.narrow else 'FM' mem.skip = '' if _mem.scanadd else 'S' mem.power = POWER_LEVELS[int(_mem.highpower)] mem.name = str(_name.name).rstrip('\xFF ') # Extra mem.extra = RadioSettingGroup("extra", "Extra") rs = RadioSettingValueList(LIST_BCL, LIST_BCL[_mem.bcl]) rset = RadioSetting("bcl", "BCL", rs) mem.extra.append(rset) rs = RadioSettingValueList(LIST_PTTID, LIST_PTTID[_mem.pttid]) rset = RadioSetting("pttid", "PTT-ID", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(bool(_mem.vox)) rset = RadioSetting("vox", "VOX", rs) mem.extra.append(rset) rs = RadioSettingValueList(LIST_OPTION, LIST_OPTION[_mem.option]) rset = RadioSetting("option", "Option", rs) mem.extra.append(rset) rs = RadioSettingValueInteger(1, 8, _mem.scrambler + 1) rset = RadioSetting("scrambler", "Compander/Scrambler", rs) mem.extra.append(rset) return mem def set_memory(self, mem): _mem, _name = self._get_memobjs(mem.number) if mem.empty: _mem.set_raw('\xFF' * 16) _name.set_raw('\xFF' * 10) return _mem.set_raw('\x00' * 16) _mem.rx_freq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.tx_freq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.tx_freq = mem.offset / 10 elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 else: _mem.tx_freq = mem.freq / 10 (txmode, txval, txpol), (rxmode, rxval, rxpol) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.tx_tone, txmode, txval, txpol) self._encode_tone(_mem.rx_tone, rxmode, rxval, rxpol) _mem.narrow = mem.mode == 'NFM' _mem.scanadd = mem.skip != 'S' _mem.highpower = POWER_LEVELS.index(mem.power) if mem.power else 1 _name.name = mem.name.rstrip(' ').ljust(10, '\xFF') # extra settings for setting in mem.extra: if setting == "scrambler": setattr(_mem, setting.get_name(), element.value - 1) else: setattr(_mem, setting.get_name(), setting.value) def _get_settings(self): _msg = self._memobj.poweron_msg _optsig = self._memobj.optsig _settings = self._memobj.settings _stun = self._memobj.stun _msk = self._memobj.msk _mskname = self._memobj.msk_name basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) # Menu 01: SCAN # Menu 02: TX.SEL aka PRI rs = RadioSettingValueList(LIST_TXSEL, LIST_TXSEL[_settings.txsel]) rset = RadioSetting("txsel", "Priority Transmit", rs) basic.append(rset) # Menu 03: VOX (VOX Gain Level) rs = RadioSettingValueInteger(1, 8, _settings.voxgainlevel + 1) rset = RadioSetting("voxgainlevel", "VOX Gain Level", rs) basic.append(rset) # Function Setting: VOX Delay Time rs = RadioSettingValueList(LIST_VOXDELAYTIME, LIST_VOXDELAYTIME[_settings.voxdelaytime]) rset = RadioSetting("voxdelaytime", "VOX Delay Time", rs) basic.append(rset) # Menu 04: TX POW (TX Power) # Menu 05: SQL (Squelch Level) rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) basic.append(rset) # Menu 06: D.WAIT aka DW (Dual Wait/Standby) rs = RadioSettingValueBoolean(bool(_settings.dwait)) rset = RadioSetting("dwait", "Dual Wait/Standby", rs) basic.append(rset) # Menu 07: LED (Backlight Time) def apply_lamp_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = LED_CHOICES.index(val) val = LED_VALUES[index] obj.set_value(val) if _settings.lamp in LED_VALUES: idx = LED_VALUES.index(_settings.lamp) else: idx = LED_VALUES.index(0x04) rs = RadioSettingValueList(LED_CHOICES, LED_CHOICES[idx]) rset = RadioSetting("settings.lamp", "Backlight Time", rs) rset.set_apply_callback(apply_lamp_listvalue, _settings.lamp) basic.append(rset) # Menu 08: BRIGHT (Backlight Brightness) rs = RadioSettingValueList(LIST_BRIGHTNESS, LIST_BRIGHTNESS[_settings.brightness]) rset = RadioSetting("brightness", "Backlight Brightness", rs) basic.append(rset) # Menu 09: BEEP (Key Beep) rs = RadioSettingValueBoolean(bool(_settings.beep)) rset = RadioSetting("beep", "Key Beep", rs) basic.append(rset) # Menu 10: ANI (Automatic Number Identification) rs = RadioSettingValueBoolean(bool(_settings.ani)) rset = RadioSetting("ani", "ANI", rs) basic.append(rset) # Menu 11: TOT (Transmitter Time-out Timer) rs = RadioSettingValueList(LIST_TOT, LIST_TOT[_settings.tot]) rset = RadioSetting("tot", "Time-Out Timer", rs) basic.append(rset) # Menu 12: BUSY LOCK # Menu 13: VOX SW # Menu 14: ROGER (Transmit Ended Beep) rs = RadioSettingValueBoolean(bool(_settings.roger)) rset = RadioSetting("roger", "Roger Beep", rs) basic.append(rset) # Menu 15: DW (Dual Watch/Monitor) rs = RadioSettingValueBoolean(bool(_settings.dwatch)) rset = RadioSetting("dwatch", "Dual Watch/Monitor", rs) basic.append(rset) # Menu 16: RX SAVE (Battery Save) rs = RadioSettingValueBoolean(bool(_settings.batterysave)) rset = RadioSetting("batterysave", "Battery Save", rs) basic.append(rset) # Menu 17: SCN-REV (Scan Mode) rs = RadioSettingValueList(LIST_SCNREV, LIST_SCNREV[_settings.scanmode]) rset = RadioSetting("scanmode", "Scan Mode", rs) basic.append(rset) # Menu 18: AUTOLK (Auto Keypad Lock) rs = RadioSettingValueBoolean(bool(_settings.autolock)) rset = RadioSetting("autolock", "Auto Keypad Lock", rs) basic.append(rset) # Menu 19: VOICE (Voice Prompt) rs = RadioSettingValueBoolean(bool(_settings.voice)) rset = RadioSetting("voice", "Voice Prompt", rs) basic.append(rset) # Menu 20: BATT SHOW (Battery Display Method) rs = RadioSettingValueList(LIST_BATTERY, LIST_BATTERY[_settings.batterydis]) rset = RadioSetting("batterydis", "Battery Display Method", rs) basic.append(rset) # Menu 21: PF1 (Side-Key 1) rs = RadioSettingValueList(LIST_SIDEKEY, LIST_SIDEKEY[_settings.pf1]) rset = RadioSetting("pf1", "Side Key Function 1", rs) basic.append(rset) # Menu 22: PF2 (Side-Key 2) rs = RadioSettingValueList(LIST_SIDEKEY, LIST_SIDEKEY[_settings.pf2]) rset = RadioSetting("pf2", "Side Key Function 2", rs) basic.append(rset) # Menu 23: OPN.SET (Power-On Display) rs = RadioSettingValueList(LIST_POWERON, LIST_POWERON[_settings.msgmode]) rset = RadioSetting("msgmode", "Power-On Display Method", rs) basic.append(rset) # Menu 24: PON.MSG (Power-On Message Editing) def _filter(name): filtered = "" for char in str(name): if char in CHARSET_ASCII_PLUS: filtered += char else: filtered += " " return filtered rs = RadioSettingValueString(0, 16, _filter(_msg.line1)) rset = RadioSetting("poweron_msg.line1", "Power-On Message 1", rs) basic.append(rset) rs = RadioSettingValueString(0, 16, _filter(_msg.line2)) rset = RadioSetting("poweron_msg.line2", "Power-On Message 2", rs) basic.append(rset) rs = RadioSettingValueString(0, 16, _filter(_msg.line3)) rset = RadioSetting("poweron_msg.line3", "Power-On Message 3", rs) basic.append(rset) rs = RadioSettingValueString(0, 16, _filter(_msg.line4)) rset = RadioSetting("poweron_msg.line4", "Power-On Message 4", rs) basic.append(rset) # Menu 25: CHNAME SHOW (Channel Name Show) rs = RadioSettingValueBoolean(bool(_settings.chnameshow)) rset = RadioSetting("chnameshow", "Display Channel Names", rs) basic.append(rset) # Menu 26: CH.NAME (Channel Name Editing) # Menu 27: OFFSET (Repeater Shift) # Menu 28: C-CDC (TX/RX Tone Coder) # Menu 29: R-CDC (RX Tone Coder) # Menu 30: T-CDC (TX Tone Coder) # Menu 31: SFT-D (Shift Direction) # Menu 32: STEP (STEP) # Menu 33: N/W (Channel Spacing Select) # Menu 34: CTCSS SCAN (CTCSS Scan) # Menu 35: DCS SSCAN (DCS Scan) # Menu 36: SCR.NO (Scrambler) # Menu 37: APRO (Voice Compander/Scrambler) pttid = RadioSettingGroup("pttid", "PTT ID Settings") group.append(pttid) # PTT ID Setting: BOT _codeobj = self._memobj.pttid.bot _code = "".join([DTMF_CHARSET[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 7, _code, False) val.set_charset(DTMF_CHARSET) rs = RadioSetting("pttid.bot", "PTT ID BOT Code", val) def apply_bot_code(setting, obj): value = [] for j in range(0, 7): try: value.append(DTMF_CHARSET.index(str(setting.value)[j])) except IndexError: value.append(0xFF) obj.bot = value rs.set_apply_callback(apply_bot_code, self._memobj.pttid) pttid.append(rs) # PTT ID Setting: EOT _codeobj = self._memobj.pttid.eot _code = "".join([DTMF_CHARSET[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 7, _code, False) val.set_charset(DTMF_CHARSET) rs = RadioSetting("pttid.eot", "PTT ID EOT Code", val) def apply_eot_code(setting, obj): value = [] for j in range(0, 7): try: value.append(DTMF_CHARSET.index(str(setting.value)[j])) except IndexError: value.append(0xFF) obj.eot = value rs.set_apply_callback(apply_eot_code, self._memobj.pttid) pttid.append(rs) # Optional Signal optsig = RadioSettingGroup("optsig", "Option Signal") group.append(optsig) # Common Set common = RadioSettingGroup("common", "Common Set") optsig.append(common) # Common Set: Digit Delay[ms] (broken in OEM software) def apply_delay_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = DELAY_CHOICES.index(val) val = DELAY_VALUES[index] obj.set_value(val) if _optsig.delay in DELAY_VALUES: idx = DELAY_VALUES.index(_optsig.delay) else: idx = DELAY_VALUES.index(30) rs = RadioSettingValueList(DELAY_CHOICES, DELAY_CHOICES[idx]) rset = RadioSetting("optsig.delay", "Digit Delay", rs) rset.set_apply_callback(apply_delay_listvalue, _optsig.delay) common.append(rset) # Common Set: Auto Reset Timer[s] rs = RadioSettingValueList(LIST_RESET, LIST_RESET[_optsig.autoresettimer]) rset = RadioSetting("optsig.autoresettimer", "Auto Reset Timer", rs) common.append(rset) # Common Set: Side Tone rs = RadioSettingValueBoolean(bool(_settings.sidetone)) rset = RadioSetting("sidetone", "Side Tone", rs) common.append(rset) # Common Set: Stun Mode def apply_stun_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = STUN_CHOICES.index(val) val = STUN_VALUES[index] obj.set_value(val) if _settings.stunmode in STUN_VALUES: idx = STUN_VALUES.index(_settings.stunmode) else: idx = STUN_VALUES.index(0xFF) rs = RadioSettingValueList(STUN_CHOICES, STUN_CHOICES[idx]) rset = RadioSetting("settings.stunmode", "Stun Mode", rs) rset.set_apply_callback(apply_stun_listvalue, _settings.stunmode) common.append(rset) # Common Set: Stun/Wake-Up ID def _filter(name): filtered = "" for char in str(name): if char in NUMERIC_CHARSET: filtered += char else: filtered += " " return filtered codesetting = getattr(_stun, "stunid") codestr = self._bbcd2num(codesetting, 8) code = RadioSettingValueString(0, 8, _filter(codestr)) code.set_charset(NUMERIC_CHARSET + list(" ")) rs = RadioSetting("stun.stunid", "Stun ID Code", code) common.append(rs) # Common Set: Manager rs = RadioSettingValueBoolean(bool(_settings.manager)) rset = RadioSetting("manager", "Manager", rs) common.append(rset) # MSK msk = RadioSettingGroup("msk", "MSK") optsig.append(msk) # MSK: ID Code codesetting = getattr(_msk, "mskid") codestr = self._bbcd2num(codesetting, 4) code = RadioSettingValueString(0, 4, _filter(codestr)) code.set_charset(NUMERIC_CHARSET + list(" ")) rs = RadioSetting("msk.mskid", "MSK ID Code", code) msk.append(rs) # MSK: Local Name rs = RadioSettingValueString(0, 7, _filter(_mskname.code)) rset = RadioSetting("msk_name.code", "Local Name", rs) msk.append(rset) # MSK: CallList for i in range(0, 10): codesetting = getattr(self._memobj.msklist[i], "mskcall") codestr = self._bbcd2num(codesetting, 4) code = RadioSettingValueString(0, 4, _filter(codestr)) code.set_charset(NUMERIC_CHARSET + list(" ")) code.set_mutable(False) rs = RadioSetting("msklist/%i.mskcall" % i, "CallList %i" % i, code) msk.append(rs) # DTMF dtmf = RadioSettingGroup("dtmf", "DTMF") optsig.append(dtmf) # DTMF: Encode for i in range(0, 10): _codeobj = self._memobj.dtmfenc[i].code _code = "".join([DTMF_CHARSET[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 16, _code, False) val.set_charset(DTMF_CHARSET) rs = RadioSetting("dtmfenc/%i.code" % i, "Encode %i" % i, val) def apply_code(setting, obj): code = [] for j in range(0, 16): try: code.append(DTMF_CHARSET.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.dtmfenc[i]) dtmf.append(rs) # DTMF: DTMF Signaling rs = RadioSettingValueList(LIST_DTMFSIG, LIST_DTMFSIG[_settings.dtmfsig]) rset = RadioSetting("dtmfsig", "DTMF Signaling", rs) dtmf.append(rset) # DTMF: Intermediate Code rs = RadioSettingValueList(LIST_INTCODE, LIST_INTCODE[_optsig.intcode]) rset = RadioSetting("optsig.intcode", "Intermediate Code", rs) dtmf.append(rset) # DTMF: Group Code def apply_group_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = GROUP_CHOICES.index(val) val = GROUP_VALUES[index] obj.set_value(val) if _optsig.groupcode in GROUP_VALUES: idx = GROUP_VALUES.index(_optsig.groupcode) else: idx = GROUP_VALUES.index(0x00) rs = RadioSettingValueList(GROUP_CHOICES, GROUP_CHOICES[idx]) rset = RadioSetting("optsig.groupcode", "Group Code", rs) rset.set_apply_callback(apply_group_listvalue, _optsig.groupcode) dtmf.append(rset) # DTMF: DTMF Code Length rs = RadioSettingValueList(LIST_DTMFLEN, LIST_DTMFLEN[_optsig.dtmflen - 3]) rset = RadioSetting("optsig.dtmflen", "DTMF Code Length", rs) dtmf.append(rset) return group def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("failed to parse settings") traceback.print_exc() return None def set_settings(self, settings): _mem = self._memobj _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("using apply callback") element.run_apply_callback() elif setting == "voxgainlevel": setattr(obj, setting, int(element.value) - 1) elif setting == "stunid": numstr = self._num2bbcd(element.value, 8) setattr(_mem.stun, setting, numstr) elif setting == "mskid": numstr = self._num2bbcd(element.value, 4) setattr(_mem.msk, setting, numstr) elif setting == "dtmflen": setattr(obj, setting, int(element.value) + 3) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @directory.register class RT87(Rt87BaseRadio): VENDOR = "Retevis" MODEL = "RT87" _ranges = [ (0x0000, 0x0A00, 0x40), (0x0BC0, 0x0C00, 0x08), (0x0C00, 0x0F00, 0x40), (0x1000, 0x2000, 0x40), ] chirp-20240224/chirp/drivers/th_uv3r25.py0000644000175000017500000001403014466370044016740 0ustar hibbyhibby# Copyright 2015 Eric Allen # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """TYT uv3r (2.5 kHz) radio management module""" from chirp import chirp_common, bitwise, directory from chirp.drivers.wouxun import do_download, do_upload from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean from chirp.drivers.th_uv3r import TYTUV3RRadio, tyt_uv3r_prep, THUV3R_CHARSET def tyt_uv3r_download(radio): tyt_uv3r_prep(radio) return do_download(radio, 0x0000, 0x0B30, 0x0010) def tyt_uv3r_upload(radio): tyt_uv3r_prep(radio) return do_upload(radio, 0x0000, 0x0B30, 0x0010) mem_format = """ // 20 bytes per memory struct memory { ul32 rx_freq; // 4 bytes ul32 tx_freq; // 8 bytes ul16 rx_tone; // 10 bytes ul16 tx_tone; // 12 bytes u8 unknown1a:1, iswide:1, bclo_n:1, vox_n:1, tail:1, power_high:1, voice_mode:2; u8 name[6]; // 19 bytes u8 unknown2; // 20 bytes }; #seekto 0x0010; struct memory memory[128]; #seekto 0x0A80; u8 emptyflags[16]; u8 skipflags[16]; """ VOICE_MODE_LIST = ["Compander", "Scrambler", "None"] @directory.register class TYTUV3R25Radio(TYTUV3RRadio): MODEL = "TH-UV3R-25" _memsize = 2864 NEEDS_COMPAT_SERIAL = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.80)] def get_features(self): rf = super(TYTUV3R25Radio, self).get_features() rf.valid_tuning_steps = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 37.50, 50.0, 100.0] rf.valid_power_levels = self.POWER_LEVELS return rf def sync_in(self): self.pipe.timeout = 2 self._mmap = tyt_uv3r_download(self) self.process_mmap() def sync_out(self): tyt_uv3r_upload(self) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number bit = 1 << ((number - 1) % 8) byte = (number - 1) / 8 if self._memobj.emptyflags[byte] & bit: mem.empty = True return mem mem.freq = _mem.rx_freq * 10 mem.offset = abs(_mem.rx_freq - _mem.tx_freq) * 10 if _mem.tx_freq == _mem.rx_freq: mem.duplex = "" elif _mem.tx_freq < _mem.rx_freq: mem.duplex = "-" elif _mem.tx_freq > _mem.rx_freq: mem.duplex = "+" mem.mode = _mem.iswide and "FM" or "NFM" self._decode_tone(mem, _mem) mem.skip = (self._memobj.skipflags[byte] & bit) and "S" or "" for char in _mem.name: try: c = THUV3R_CHARSET[char] except: c = "" mem.name += c mem.name = mem.name.rstrip() mem.power = self.POWER_LEVELS[not _mem.power_high] mem.extra = RadioSettingGroup("extra", "Extra Settings") rs = RadioSetting("bclo_n", "Busy Channel Lockout", RadioSettingValueBoolean(not _mem.bclo_n)) mem.extra.append(rs) rs = RadioSetting("vox_n", "VOX", RadioSettingValueBoolean(not _mem.vox_n)) mem.extra.append(rs) rs = RadioSetting("tail", "Squelch Tail Elimination", RadioSettingValueBoolean(_mem.tail)) mem.extra.append(rs) rs = RadioSetting("voice_mode", "Voice Mode", RadioSettingValueList( VOICE_MODE_LIST, VOICE_MODE_LIST[_mem.voice_mode-1])) mem.extra.append(rs) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] bit = 1 << ((mem.number - 1) % 8) byte = (mem.number - 1) // 8 if mem.empty: self._memobj.emptyflags[byte] |= bit _mem.set_raw("\xFF" * 20) return self._memobj.emptyflags[byte] &= ~bit _mem.rx_freq = mem.freq / 10 if mem.duplex == "": _mem.tx_freq = _mem.rx_freq elif mem.duplex == "-": _mem.tx_freq = _mem.rx_freq - mem.offset / 10.0 elif mem.duplex == "+": _mem.tx_freq = _mem.rx_freq + mem.offset / 10.0 _mem.iswide = mem.mode == "FM" self._encode_tone(mem, _mem) if mem.skip: self._memobj.skipflags[byte] |= bit else: self._memobj.skipflags[byte] &= ~bit name = [] for char in mem.name.ljust(6): try: c = THUV3R_CHARSET.index(char) except: c = THUV3R_CHARSET.index(" ") name.append(c) _mem.name = name if mem.power == self.POWER_LEVELS[0]: _mem.power_high = 1 else: _mem.power_high = 0 for element in mem.extra: if element.get_name() == 'voice_mode': setattr(_mem, element.get_name(), int(element.value) + 1) elif element.get_name().endswith('_n'): setattr(_mem, element.get_name(), 1 - int(element.value)) else: setattr(_mem, element.get_name(), element.value) @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize chirp-20240224/chirp/drivers/uvk5.py0000644000175000017500000021007314565616503016101 0ustar hibbyhibby# Quansheng UV-K5 driver (c) 2023 Jacek Lipkowski # # based on template.py Copyright 2012 Dan Smith # # # This is a preliminary version of a driver for the UV-K5 # It is based on my reverse engineering effort described here: # https://github.com/sq5bpf/uvk5-reverse-engineering # # Warning: this driver is experimental, it may brick your radio, # eat your lunch and mess up your configuration. # # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, bitwise, memmap, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) # Show the obfuscated version of commands. Not needed normally, but # might be useful for someone who is debugging a similar radio DEBUG_SHOW_OBFUSCATED_COMMANDS = False # Show the memory being written/received. Not needed normally, because # this is the same information as in the packet hexdumps, but # might be useful for someone debugging some obscure memory issue DEBUG_SHOW_MEMORY_ACTIONS = False MEM_FORMAT = """ #seekto 0x0000; struct { ul32 freq; ul32 offset; u8 rxcode; u8 txcode; u8 txcodeflag:4, rxcodeflag:4; //u8 flags1; u8 flags1_unknown7:1, flags1_unknown6:1, flags1_unknown5:1, enable_am:1, flags1_unknown3:1, is_in_scanlist:1, shift:2; //u8 flags2; u8 flags2_unknown7:1, flags2_unknown6:1, flags2_unknown5:1, bclo:1, txpower:2, bandwidth:1, freq_reverse:1; //u8 dtmf_flags; u8 dtmf_flags_unknown7:1, dtmf_flags_unknown6:1, dtmf_flags_unknown5:1, dtmf_flags_unknown4:1, dtmf_flags_unknown3:1, dtmf_pttid:2, dtmf_decode:1; u8 step; u8 scrambler; } channel[214]; #seekto 0xd60; struct { u8 is_scanlist1:1, is_scanlist2:1, compander:2, is_free:1, band:3; } channel_attributes[200]; #seekto 0xe40; ul16 fmfreq[20]; #seekto 0xe70; u8 call_channel; u8 squelch; u8 max_talk_time; u8 noaa_autoscan; u8 key_lock; u8 vox_switch; u8 vox_level; u8 mic_gain; u8 unknown3; u8 channel_display_mode; u8 crossband; u8 battery_save; u8 dual_watch; u8 backlight_auto_mode; u8 tail_note_elimination; u8 vfo_open; #seekto 0xe90; u8 beep_control; u8 key1_shortpress_action; u8 key1_longpress_action; u8 key2_shortpress_action; u8 key2_longpress_action; u8 scan_resume_mode; u8 auto_keypad_lock; u8 power_on_dispmode; u8 password[4]; #seekto 0xea0; u8 keypad_tone; u8 language; #seekto 0xea8; u8 alarm_mode; u8 reminding_of_end_talk; u8 repeater_tail_elimination; #seekto 0xeb0; char logo_line1[16]; char logo_line2[16]; #seekto 0xed0; struct { u8 side_tone; char separate_code; char group_call_code; u8 decode_response; u8 auto_reset_time; u8 preload_time; u8 first_code_persist_time; u8 hash_persist_time; u8 code_persist_time; u8 code_interval_time; u8 permit_remote_kill; } dtmf_settings; #seekto 0xee0; struct { char dtmf_local_code[3]; char unused1[5]; char kill_code[5]; char unused2[3]; char revive_code[5]; char unused3[3]; char dtmf_up_code[16]; char dtmf_down_code[16]; } dtmf_settings_numbers; #seekto 0xf18; u8 scanlist_default; u8 scanlist1_priority_scan; u8 scanlist1_priority_ch1; u8 scanlist1_priority_ch2; u8 scanlist2_priority_scan; u8 scanlist2_priority_ch1; u8 scanlist2_priority_ch2; u8 scanlist_unknown_0xff; #seekto 0xf40; struct { u8 flock; u8 tx350; u8 killed; u8 tx200; u8 tx500; u8 en350; u8 enscramble; } lock; #seekto 0xf50; struct { char name[16]; } channelname[200]; #seekto 0x1c00; struct { char name[8]; char number[3]; char unused_00[5]; } dtmfcontact[16]; #seekto 0x1ed0; struct { struct { u8 start; u8 mid; u8 end; } low; struct { u8 start; u8 mid; u8 end; } medium; struct { u8 start; u8 mid; u8 end; } high; u8 unused_00[7]; } perbandpowersettings[7]; #seekto 0x1f40; ul16 battery_level[6]; """ # bits that we will save from the channel structure (mostly unknown) SAVE_MASK_0A = 0b11001100 SAVE_MASK_0B = 0b11101100 SAVE_MASK_0C = 0b11100000 SAVE_MASK_0D = 0b11111000 SAVE_MASK_0E = 0b11110001 SAVE_MASK_0F = 0b11110000 # flags1 FLAGS1_OFFSET_NONE = 0b00 FLAGS1_OFFSET_MINUS = 0b10 FLAGS1_OFFSET_PLUS = 0b01 POWER_HIGH = 0b10 POWER_MEDIUM = 0b01 POWER_LOW = 0b00 # power UVK5_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.50), chirp_common.PowerLevel("Med", watts=3.00), chirp_common.PowerLevel("High", watts=5.00), ] # scrambler SCRAMBLER_LIST = ["off", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] # channel display mode CHANNELDISP_LIST = ["Frequency", "Channel No", "Channel Name"] # battery save BATSAVE_LIST = ["OFF", "1:1", "1:2", "1:3", "1:4"] # Backlight auto mode BACKLIGHT_LIST = ["Off", "1s", "2s", "3s", "4s", "5s"] # Crossband receiving/transmitting CROSSBAND_LIST = ["Off", "Band A", "Band B"] DUALWATCH_LIST = CROSSBAND_LIST # ctcss/dcs codes TMODES = ["", "Tone", "DTCS", "DTCS"] TONE_NONE = 0 TONE_CTCSS = 1 TONE_DCS = 2 TONE_RDCS = 3 CTCSS_TONES = [ 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8, 136.5, 141.3, 146.2, 151.4, 156.7, 159.8, 162.2, 165.5, 167.9, 171.3, 173.8, 177.3, 179.9, 183.5, 186.2, 189.9, 192.8, 196.6, 199.5, 203.5, 206.5, 210.7, 218.1, 225.7, 229.1, 233.6, 241.8, 250.3, 254.1 ] # lifted from ft4.py DTCS_CODES = [ 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754 ] FLOCK_LIST = ["Off", "FCC", "CE", "GB", "430", "438"] SCANRESUME_LIST = ["TO: Resume after 5 seconds", "CO: Resume after signal disappears", "SE: Stop scanning after receiving a signal"] WELCOME_LIST = ["Full Screen", "Welcome Info", "Voltage"] KEYPADTONE_LIST = ["Off", "Chinese", "English"] LANGUAGE_LIST = ["Chinese", "English"] ALARMMODE_LIST = ["SITE", "TONE"] REMENDOFTALK_LIST = ["Off", "ROGER", "MDC"] RTE_LIST = ["Off", "100ms", "200ms", "300ms", "400ms", "500ms", "600ms", "700ms", "800ms", "900ms"] MEM_SIZE = 0x2000 # size of all memory PROG_SIZE = 0x1d00 # size of the memory that we will write MEM_BLOCK = 0x80 # largest block of memory that we can reliably write # fm radio supported frequencies FMMIN = 76.0 FMMAX = 108.0 # bands supported by the UV-K5 BANDS = { 0: [50.0, 76.0], 1: [108.0, 135.9999], 2: [136.0, 199.9990], 3: [200.0, 299.9999], 4: [350.0, 399.9999], 5: [400.0, 469.9999], 6: [470.0, 600.0] } # for radios with modified firmware: BANDS_NOLIMITS = { 0: [18.0, 76.0], 1: [108.0, 135.9999], 2: [136.0, 199.9990], 3: [200.0, 299.9999], 4: [350.0, 399.9999], 5: [400.0, 469.9999], 6: [470.0, 1300.0] } SPECIALS = { "F1(50M-76M)A": 200, "F1(50M-76M)B": 201, "F2(108M-136M)A": 202, "F2(108M-136M)B": 203, "F3(136M-174M)A": 204, "F3(136M-174M)B": 205, "F4(174M-350M)A": 206, "F4(174M-350M)B": 207, "F5(350M-400M)A": 208, "F5(350M-400M)B": 209, "F6(400M-470M)A": 210, "F6(400M-470M)B": 211, "F7(470M-600M)A": 212, "F7(470M-600M)B": 213 } VFO_CHANNEL_NAMES = ["F1(50M-76M)A", "F1(50M-76M)B", "F2(108M-136M)A", "F2(108M-136M)B", "F3(136M-174M)A", "F3(136M-174M)B", "F4(174M-350M)A", "F4(174M-350M)B", "F5(350M-400M)A", "F5(350M-400M)B", "F6(400M-470M)A", "F6(400M-470M)B", "F7(470M-600M)A", "F7(470M-600M)B"] SCANLIST_LIST = ["None", "1", "2", "1+2"] DTMF_CHARS = "0123456789ABCD*# " DTMF_CHARS_ID = "0123456789ABCDabcd" DTMF_CHARS_KILL = "0123456789ABCDabcd" DTMF_CHARS_UPDOWN = "0123456789ABCDabcd#* " DTMF_CODE_CHARS = "ABCD*# " DTMF_DECODE_RESPONSE_LIST = ["None", "Ring", "Reply", "Both"] KEYACTIONS_LIST = ["None", "Flashlight on/off", "Power select", "Monitor", "Scan on/off", "VOX on/off", "Alarm on/off", "FM radio on/off", "Transmit 1750 Hz"] def xorarr(data: bytes): """the communication is obfuscated using this fine mechanism""" tbl = [22, 108, 20, 230, 46, 145, 13, 64, 33, 53, 213, 64, 19, 3, 233, 128] ret = b"" idx = 0 for byte in data: ret += bytes([byte ^ tbl[idx]]) idx = (idx+1) % len(tbl) return ret def calculate_crc16_xmodem(data: bytes): """ if this crc was used for communication to AND from the radio, then it would be a measure to increase reliability. but it's only used towards the radio, so it's for further obfuscation """ poly = 0x1021 crc = 0x0 for byte in data: crc = crc ^ (byte << 8) for _ in range(8): crc = crc << 1 if crc & 0x10000: crc = (crc ^ poly) & 0xFFFF return crc & 0xFFFF def _send_command(serport, data: bytes): """Send a command to UV-K5 radio""" LOG.debug("Sending command (unobfuscated) len=0x%4.4x:\n%s", len(data), util.hexprint(data)) crc = calculate_crc16_xmodem(data) data2 = data + struct.pack("HBB", 0xabcd, len(data), 0) + \ xorarr(data2) + \ struct.pack(">H", 0xdcba) if DEBUG_SHOW_OBFUSCATED_COMMANDS: LOG.debug("Sending command (obfuscated):\n%s", util.hexprint(command)) try: result = serport.write(command) except Exception as e: raise errors.RadioError("Error writing data to radio") from e return result def _receive_reply(serport): header = serport.read(4) if len(header) != 4: LOG.warning("Header short read: [%s] len=%i", util.hexprint(header), len(header)) raise errors.RadioError("Header short read") if header[0] != 0xAB or header[1] != 0xCD or header[3] != 0x00: LOG.warning("Bad response header: %s len=%i", util.hexprint(header), len(header)) raise errors.RadioError("Bad response header") cmd = serport.read(int(header[2])) if len(cmd) != int(header[2]): LOG.warning("Body short read: [%s] len=%i", util.hexprint(cmd), len(cmd)) raise errors.RadioError("Command body short read") footer = serport.read(4) if len(footer) != 4: LOG.warning("Footer short read: [%s] len=%i", util.hexprint(footer), len(footer)) raise errors.RadioError("Footer short read") if footer[2] != 0xDC or footer[3] != 0xBA: LOG.debug("Reply before bad response footer (obfuscated)" "len=0x%4.4x:\n%s", len(cmd), util.hexprint(cmd)) LOG.warning("Bad response footer: %s len=%i", util.hexprint(footer), len(footer)) raise errors.RadioError("Bad response footer") if DEBUG_SHOW_OBFUSCATED_COMMANDS: LOG.debug("Received reply (obfuscated) len=0x%4.4x:\n%s", len(cmd), util.hexprint(cmd)) cmd2 = xorarr(cmd) LOG.debug("Received reply (unobfuscated) len=0x%4.4x:\n%s", len(cmd2), util.hexprint(cmd2)) return cmd2 def _getstring(data: bytes, begin, maxlen): tmplen = min(maxlen+1, len(data)) ss = [data[i] for i in range(begin, tmplen)] key = 0 for key, val in enumerate(ss): if val < ord(' ') or val > ord('~'): return ''.join(chr(x) for x in ss[0:key]) return '' def _sayhello(serport): hellopacket = b"\x14\x05\x04\x00\x6a\x39\x57\x64" tries = 5 while True: LOG.debug("Sending hello packet") _send_command(serport, hellopacket) rep = _receive_reply(serport) if rep: break tries -= 1 if tries == 0: LOG.warning("Failed to initialise radio") raise errors.RadioError("Failed to initialize radio") if rep.startswith(b'\x18\x05'): raise errors.RadioError("Radio is in programming mode, " "restart radio into normal mode") firmware = _getstring(rep, 4, 24) LOG.info("Found firmware: %s", firmware) return firmware def _readmem(serport, offset, length): LOG.debug("Sending readmem offset=0x%4.4x len=0x%4.4x", offset, length) readmem = b"\x1b\x05\x08\x00" + \ struct.pack("> 8) & 0xff): return True LOG.warning("Bad data from writemem") raise errors.RadioError("Bad response to writemem") def _resetradio(serport): resetpacket = b"\xdd\x05\x00\x00" _send_command(serport, resetpacket) def do_download(radio): """download eeprom from radio""" serport = radio.pipe serport.timeout = 0.5 status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE status.msg = "Downloading from radio" radio.status_fn(status) eeprom = b"" f = _sayhello(serport) if not f: raise errors.RadioError('Unable to determine firmware version') if not radio.k5_approve_firmware(f): raise errors.RadioError( 'Firmware version is not supported by this driver') radio.metadata = {'uvk5_firmware': f} addr = 0 while addr < MEM_SIZE: data = _readmem(serport, addr, MEM_BLOCK) status.cur = addr radio.status_fn(status) if data and len(data) == MEM_BLOCK: eeprom += data addr += MEM_BLOCK else: raise errors.RadioError("Memory download incomplete") return memmap.MemoryMapBytes(eeprom) def do_upload(radio): """upload configuration to radio eeprom""" serport = radio.pipe serport.timeout = 0.5 status = chirp_common.Status() status.cur = 0 status.msg = "Uploading to radio" if radio._upload_calibration: status.max = MEM_SIZE - radio._cal_start start_addr = radio._cal_start stop_addr = MEM_SIZE else: status.max = PROG_SIZE start_addr = 0 stop_addr = PROG_SIZE radio.status_fn(status) f = _sayhello(serport) if not f: raise errors.RadioError('Unable to determine firmware version') if not radio.k5_approve_firmware(f): raise errors.RadioError( 'Firmware version is not supported by this driver') LOG.info('Uploading image from firmware %r to radio with %r', radio.metadata.get('uvk5_firmware', 'unknown'), f) addr = start_addr while addr < stop_addr: dat = radio.get_mmap()[addr:addr+MEM_BLOCK] _writemem(serport, dat, addr) status.cur = addr - start_addr radio.status_fn(status) if dat: addr += MEM_BLOCK else: raise errors.RadioError("Memory upload incomplete") status.msg = "Uploaded OK" _resetradio(serport) return True def _find_band(nolimits, hz): mhz = hz/1000000.0 if nolimits: B = BANDS_NOLIMITS else: B = BANDS # currently the hacked firmware sets band=1 below 50 MHz if nolimits and mhz < 50.0: return 1 for a in B: if mhz >= B[a][0] and mhz <= B[a][1]: return a return False class UVK5RadioBase(chirp_common.CloneModeRadio): """Quansheng UV-K5""" VENDOR = "Quansheng" MODEL = "UV-K5" BAUD_RATE = 38400 NEEDS_COMPAT_SERIAL = False _cal_start = 0 _expanded_limits = False _upload_calibration = False _pttid_list = ["off", "BOT", "EOT", "BOTH"] _steps = [1.0, 2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 8.33] @classmethod def k5_approve_firmware(cls, firmware): # All subclasses must implement this raise NotImplementedError() def get_prompts(x=None): rp = chirp_common.RadioPrompts() rp.experimental = _( 'This is an experimental driver for the Quansheng UV-K5. ' 'It may harm your radio, or worse. Use at your own risk.\n\n' 'Before attempting to do any changes please download ' 'the memory image from the radio with chirp ' 'and keep it. This can be later used to recover the ' 'original settings. \n\n' 'some details are not yet implemented') rp.pre_download = _( "1. Turn radio on.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Click OK to download image from device.\n\n" "It will may not work if you turn on the radio " "with the cable already attached\n") rp.pre_upload = _( "1. Turn radio on.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Click OK to upload the image to device.\n\n" "It will may not work if you turn on the radio " "with the cable already attached") return rp # Return information about this radio's features, including # how many memories it has, what bands it supports, etc def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.valid_dtcs_codes = DTCS_CODES rf.has_rx_dtcs = True rf.has_ctone = True rf.has_settings = True rf.has_comment = False rf.valid_name_length = 10 rf.valid_power_levels = UVK5_POWER_LEVELS rf.valid_special_chans = list(SPECIALS.keys()) rf.valid_duplexes = ["", "-", "+", "off"] # hack so we can input any frequency, # the 0.1 and 0.01 steps don't work unfortunately rf.valid_tuning_steps = list(self._steps) rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_modes = ["FM", "NFM", "AM", "NAM"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_skips = [""] # This radio supports memories 1-200, 201-214 are the VFO memories rf.memory_bounds = (1, 200) rf.valid_bands = [] for a in BANDS_NOLIMITS: rf.valid_bands.append( (int(BANDS_NOLIMITS[a][0]*1000000), int(BANDS_NOLIMITS[a][1]*1000000))) return rf # Do a download of the radio from the serial port def sync_in(self): self._mmap = do_download(self) self.process_mmap() # Do an upload of the radio to the serial port def sync_out(self): do_upload(self) def _check_firmware_at_load(self): firmware = self.metadata.get('uvk5_firmware') if not firmware: LOG.warning(_('This image is missing firmware information. ' 'It may have been generated with an old or ' 'modified version of CHIRP. It is advised that ' 'you download a fresh image from your radio and ' 'use that going forward for the best safety and ' 'compatibility.')) elif not self.k5_approve_firmware(self.metadata['uvk5_firmware']): raise errors.RadioError( 'Image firmware is %r but is not supported by ' 'this driver' % firmware) # Convert the raw byte array into a memory object structure def process_mmap(self): self._check_firmware_at_load() self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # Return a raw representation of the memory object, which # is very helpful for development def get_raw_memory(self, number): return repr(self._memobj.channel[number-1]) def _find_band(self, hz): return _find_band(self._expanded_limits, hz) def validate_memory(self, mem): msgs = super().validate_memory(mem) if mem.duplex == 'off': return msgs # find tx frequency if mem.duplex == '-': txfreq = mem.freq - mem.offset elif mem.duplex == '+': txfreq = mem.freq + mem.offset else: txfreq = mem.freq # find band band = self._find_band(txfreq) if band is False: msg = "Transmit frequency %.4f MHz is not supported by this radio"\ % (txfreq/1000000.0) msgs.append(chirp_common.ValidationError(msg)) band = self._find_band(mem.freq) if band is False: msg = "The frequency %.4f MHz is not supported by this radio" \ % (mem.freq/1000000.0) msgs.append(chirp_common.ValidationError(msg)) return msgs def _set_tone(self, mem, _mem): ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) if txmode == "Tone": txtoval = CTCSS_TONES.index(txtone) txmoval = 0b01 elif txmode == "DTCS": txmoval = txpol == "R" and 0b11 or 0b10 txtoval = DTCS_CODES.index(txtone) else: txmoval = 0 txtoval = 0 if rxmode == "Tone": rxtoval = CTCSS_TONES.index(rxtone) rxmoval = 0b01 elif rxmode == "DTCS": rxmoval = rxpol == "R" and 0b11 or 0b10 rxtoval = DTCS_CODES.index(rxtone) else: rxmoval = 0 rxtoval = 0 _mem.rxcodeflag = rxmoval _mem.txcodeflag = txmoval _mem.rxcode = rxtoval _mem.txcode = txtoval def _get_tone(self, mem, _mem): rxtype = _mem.rxcodeflag txtype = _mem.txcodeflag rx_tmode = TMODES[rxtype] tx_tmode = TMODES[txtype] rx_tone = tx_tone = None if tx_tmode == "Tone": if _mem.txcode < len(CTCSS_TONES): tx_tone = CTCSS_TONES[_mem.txcode] else: tx_tone = 0 tx_tmode = "" elif tx_tmode == "DTCS": if _mem.txcode < len(DTCS_CODES): tx_tone = DTCS_CODES[_mem.txcode] else: tx_tone = 0 tx_tmode = "" if rx_tmode == "Tone": if _mem.rxcode < len(CTCSS_TONES): rx_tone = CTCSS_TONES[_mem.rxcode] else: rx_tone = 0 rx_tmode = "" elif rx_tmode == "DTCS": if _mem.rxcode < len(DTCS_CODES): rx_tone = DTCS_CODES[_mem.rxcode] else: rx_tone = 0 rx_tmode = "" tx_pol = txtype == 0x03 and "R" or "N" rx_pol = rxtype == 0x03 and "R" or "N" chirp_common.split_tone_decode(mem, (tx_tmode, tx_tone, tx_pol), (rx_tmode, rx_tone, rx_pol)) def _get_mem_extra(self, mem, _mem): tmpscn = SCANLIST_LIST[0] # We'll also look at the channel attributes if a memory has them if mem.number <= 200: _mem3 = self._memobj.channel_attributes[mem.number - 1] # free memory bit if _mem3.is_free > 0: mem.empty = True # scanlists if _mem3.is_scanlist1 > 0 and _mem3.is_scanlist2 > 0: tmpscn = SCANLIST_LIST[3] # "1+2" elif _mem3.is_scanlist1 > 0: tmpscn = SCANLIST_LIST[1] # "1" elif _mem3.is_scanlist2 > 0: tmpscn = SCANLIST_LIST[2] # "2" mem.extra = RadioSettingGroup("Extra", "extra") # BCLO is_bclo = bool(_mem.bclo > 0) rs = RadioSetting("bclo", "BCLO", RadioSettingValueBoolean(is_bclo)) mem.extra.append(rs) # Frequency reverse - whatever that means, don't see it in the manual is_frev = bool(_mem.freq_reverse > 0) rs = RadioSetting("frev", "FreqRev", RadioSettingValueBoolean(is_frev)) mem.extra.append(rs) # PTTID try: pttid = self._pttid_list[_mem.dtmf_pttid] except IndexError: pttid = 0 rs = RadioSetting("pttid", "PTTID", RadioSettingValueList( self._pttid_list, pttid)) mem.extra.append(rs) # DTMF DECODE is_dtmf = bool(_mem.dtmf_decode > 0) rs = RadioSetting("dtmfdecode", _("DTMF decode"), RadioSettingValueBoolean(is_dtmf)) mem.extra.append(rs) # Scrambler if _mem.scrambler & 0x0f < len(SCRAMBLER_LIST): enc = _mem.scrambler & 0x0f else: enc = 0 rs = RadioSetting("scrambler", _("Scrambler"), RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[enc])) mem.extra.append(rs) rs = RadioSetting("scanlists", _("Scanlists"), RadioSettingValueList( SCANLIST_LIST, tmpscn)) mem.extra.append(rs) def _get_mem_mode(self, _mem): if _mem.enable_am > 0: if _mem.bandwidth > 0: return "NAM" else: return "AM" else: if _mem.bandwidth > 0: return "NFM" else: return "FM" def _get_specials(self): return dict(SPECIALS) # Extract a high-level memory object from the low-level memory map # This is called to populate a memory in the UI def get_memory(self, number2): mem = chirp_common.Memory() if isinstance(number2, str): number = self._get_specials()[number2] mem.extd_number = number2 else: number = number2 - 1 mem.number = number + 1 _mem = self._memobj.channel[number] # We'll consider any blank (i.e. 0 MHz frequency) to be empty if (_mem.freq == 0xffffffff) or (_mem.freq == 0): mem.empty = True self._get_mem_extra(mem, _mem) if mem.empty: return mem if number > 199: mem.immutable = ["name", "scanlists"] else: _mem2 = self._memobj.channelname[number] for char in _mem2.name: if str(char) == "\xFF" or str(char) == "\x00": break mem.name += str(char) mem.name = mem.name.rstrip() # Convert your low-level frequency to Hertz mem.freq = int(_mem.freq)*10 mem.offset = int(_mem.offset)*10 if (mem.offset == 0): mem.duplex = '' else: if _mem.shift == FLAGS1_OFFSET_MINUS: if _mem.freq == _mem.offset: # fake tx disable by setting tx to 0 MHz mem.duplex = 'off' mem.offset = 0 else: mem.duplex = '-' elif _mem.shift == FLAGS1_OFFSET_PLUS: mem.duplex = '+' else: mem.duplex = '' # tone data self._get_tone(mem, _mem) mem.mode = self._get_mem_mode(_mem) # tuning step try: mem.tuning_step = self._steps[_mem.step] except IndexError: mem.tuning_step = 2.5 # power if _mem.txpower == POWER_HIGH: mem.power = UVK5_POWER_LEVELS[2] elif _mem.txpower == POWER_MEDIUM: mem.power = UVK5_POWER_LEVELS[1] else: mem.power = UVK5_POWER_LEVELS[0] # We'll consider any blank (i.e. 0 MHz frequency) to be empty if (_mem.freq == 0xffffffff) or (_mem.freq == 0): mem.empty = True else: mem.empty = False return mem def set_settings(self, settings): _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue # basic settings # call channel if element.get_name() == "call_channel": _mem.call_channel = int(element.value)-1 # squelch if element.get_name() == "squelch": _mem.squelch = int(element.value) # TOT if element.get_name() == "tot": _mem.max_talk_time = int(element.value) # NOAA autoscan if element.get_name() == "noaa_autoscan": _mem.noaa_autoscan = element.value and 1 or 0 # VOX switch if element.get_name() == "vox_switch": _mem.vox_switch = element.value and 1 or 0 # vox level if element.get_name() == "vox_level": _mem.vox_level = int(element.value)-1 # mic gain if element.get_name() == "mic_gain": _mem.mic_gain = int(element.value) # Channel display mode if element.get_name() == "channel_display_mode": _mem.channel_display_mode = CHANNELDISP_LIST.index( str(element.value)) # Crossband receiving/transmitting if element.get_name() == "crossband": _mem.crossband = CROSSBAND_LIST.index(str(element.value)) # Battery Save if element.get_name() == "battery_save": _mem.battery_save = BATSAVE_LIST.index(str(element.value)) # Dual Watch if element.get_name() == "dualwatch": _mem.dual_watch = DUALWATCH_LIST.index(str(element.value)) # Backlight auto mode if element.get_name() == "backlight_auto_mode": _mem.backlight_auto_mode = \ BACKLIGHT_LIST.index(str(element.value)) # Tail tone elimination if element.get_name() == "tail_note_elimination": _mem.tail_note_elimination = element.value and 1 or 0 # VFO Open if element.get_name() == "vfo_open": _mem.vfo_open = element.value and 1 or 0 # Beep control if element.get_name() == "beep_control": _mem.beep_control = element.value and 1 or 0 # Scan resume mode if element.get_name() == "scan_resume_mode": _mem.scan_resume_mode = SCANRESUME_LIST.index( str(element.value)) # Keypad lock if element.get_name() == "key_lock": _mem.key_lock = element.value and 1 or 0 # Auto keypad lock if element.get_name() == "auto_keypad_lock": _mem.auto_keypad_lock = element.value and 1 or 0 # Power on display mode if element.get_name() == "welcome_mode": _mem.power_on_dispmode = WELCOME_LIST.index(str(element.value)) # Keypad Tone if element.get_name() == "keypad_tone": _mem.keypad_tone = KEYPADTONE_LIST.index(str(element.value)) # Language if element.get_name() == "language": _mem.language = LANGUAGE_LIST.index(str(element.value)) # Alarm mode if element.get_name() == "alarm_mode": _mem.alarm_mode = ALARMMODE_LIST.index(str(element.value)) # Reminding of end of talk if element.get_name() == "reminding_of_end_talk": _mem.reminding_of_end_talk = REMENDOFTALK_LIST.index( str(element.value)) # Repeater tail tone elimination if element.get_name() == "repeater_tail_elimination": _mem.repeater_tail_elimination = RTE_LIST.index( str(element.value)) # Logo string 1 if element.get_name() == "logo1": b = str(element.value).rstrip("\x20\xff\x00")+"\x00"*12 _mem.logo_line1 = b[0:12]+"\x00\xff\xff\xff" # Logo string 2 if element.get_name() == "logo2": b = str(element.value).rstrip("\x20\xff\x00")+"\x00"*12 _mem.logo_line2 = b[0:12]+"\x00\xff\xff\xff" # unlock settings # FLOCK if element.get_name() == "flock": _mem.lock.flock = FLOCK_LIST.index(str(element.value)) # 350TX if element.get_name() == "tx350": _mem.lock.tx350 = element.value and 1 or 0 # 200TX if element.get_name() == "tx200": _mem.lock.tx200 = element.value and 1 or 0 # 500TX if element.get_name() == "tx500": _mem.lock.tx500 = element.value and 1 or 0 # 350EN if element.get_name() == "en350": _mem.lock.en350 = element.value and 1 or 0 # SCREN if element.get_name() == "enscramble": _mem.lock.enscramble = element.value and 1 or 0 # KILLED if element.get_name() == "killed": _mem.lock.killed = element.value and 1 or 0 # fm radio for i in range(1, 21): freqname = "FM_" + str(i) if element.get_name() == freqname: val = str(element.value).strip() try: val2 = int(float(val)*10) except Exception: val2 = 0xffff if val2 < FMMIN*10 or val2 > FMMAX*10: val2 = 0xffff # raise errors.InvalidValueError( # "FM radio frequency should be a value " # "in the range %.1f - %.1f" % (FMMIN , FMMAX)) _mem.fmfreq[i-1] = val2 # dtmf settings if element.get_name() == "dtmf_side_tone": _mem.dtmf_settings.side_tone = \ element.value and 1 or 0 if element.get_name() == "dtmf_separate_code": _mem.dtmf_settings.separate_code = str(element.value) if element.get_name() == "dtmf_group_call_code": _mem.dtmf_settings.group_call_code = element.value if element.get_name() == "dtmf_decode_response": _mem.dtmf_settings.decode_response = \ DTMF_DECODE_RESPONSE_LIST.index(str(element.value)) if element.get_name() == "dtmf_auto_reset_time": _mem.dtmf_settings.auto_reset_time = \ int(int(element.value)/10) if element.get_name() == "dtmf_preload_time": _mem.dtmf_settings.preload_time = \ int(int(element.value)/10) if element.get_name() == "dtmf_first_code_persist_time": _mem.dtmf_settings.first_code_persist_time = \ int(int(element.value)/10) if element.get_name() == "dtmf_hash_persist_time": _mem.dtmf_settings.hash_persist_time = \ int(int(element.value)/10) if element.get_name() == "dtmf_code_persist_time": _mem.dtmf_settings.code_persist_time = \ int(int(element.value)/10) if element.get_name() == "dtmf_code_interval_time": _mem.dtmf_settings.code_interval_time = \ int(int(element.value)/10) if element.get_name() == "dtmf_permit_remote_kill": _mem.dtmf_settings.permit_remote_kill = \ element.value and 1 or 0 if element.get_name() == "dtmf_dtmf_local_code": k = str(element.value).rstrip("\x20\xff\x00") + "\x00"*3 _mem.dtmf_settings_numbers.dtmf_local_code = k[0:3] if element.get_name() == "dtmf_dtmf_up_code": k = str(element.value).strip("\x20\xff\x00") + "\x00"*16 _mem.dtmf_settings_numbers.dtmf_up_code = k[0:16] if element.get_name() == "dtmf_dtmf_down_code": k = str(element.value).rstrip("\x20\xff\x00") + "\x00"*16 _mem.dtmf_settings_numbers.dtmf_down_code = k[0:16] if element.get_name() == "dtmf_kill_code": k = str(element.value).strip("\x20\xff\x00") + "\x00"*5 _mem.dtmf_settings_numbers.kill_code = k[0:5] if element.get_name() == "dtmf_revive_code": k = str(element.value).strip("\x20\xff\x00") + "\x00"*5 _mem.dtmf_settings_numbers.revive_code = k[0:5] # dtmf contacts for i in range(1, 17): varname = "DTMF_" + str(i) if element.get_name() == varname: k = str(element.value).rstrip("\x20\xff\x00") + "\x00"*8 _mem.dtmfcontact[i-1].name = k[0:8] varnumname = "DTMFNUM_" + str(i) if element.get_name() == varnumname: k = str(element.value).rstrip("\x20\xff\x00") + "\xff"*3 _mem.dtmfcontact[i-1].number = k[0:3] # scanlist stuff if element.get_name() == "scanlist_default": val = (int(element.value) == 2) and 1 or 0 _mem.scanlist_default = val if element.get_name() == "scanlist1_priority_scan": _mem.scanlist1_priority_scan = \ element.value and 1 or 0 if element.get_name() == "scanlist2_priority_scan": _mem.scanlist2_priority_scan = \ element.value and 1 or 0 if element.get_name() == "scanlist1_priority_ch1" or \ element.get_name() == "scanlist1_priority_ch2" or \ element.get_name() == "scanlist2_priority_ch1" or \ element.get_name() == "scanlist2_priority_ch2": val = int(element.value) if val > 200 or val < 1: val = 0xff else: val -= 1 if element.get_name() == "scanlist1_priority_ch1": _mem.scanlist1_priority_ch1 = val if element.get_name() == "scanlist1_priority_ch2": _mem.scanlist1_priority_ch2 = val if element.get_name() == "scanlist2_priority_ch1": _mem.scanlist2_priority_ch1 = val if element.get_name() == "scanlist2_priority_ch2": _mem.scanlist2_priority_ch2 = val if element.get_name() == "key1_shortpress_action": _mem.key1_shortpress_action = KEYACTIONS_LIST.index( str(element.value)) if element.get_name() == "key1_longpress_action": _mem.key1_longpress_action = KEYACTIONS_LIST.index( str(element.value)) if element.get_name() == "key2_shortpress_action": _mem.key2_shortpress_action = KEYACTIONS_LIST.index( str(element.value)) if element.get_name() == "key2_longpress_action": _mem.key2_longpress_action = KEYACTIONS_LIST.index( str(element.value)) if element.get_name() == "nolimits": LOG.warning("User expanded band limits") self._expanded_limits = bool(element.value) def get_settings(self): _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") keya = RadioSettingGroup("keya", "Programmable keys") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") dtmfc = RadioSettingGroup("dtmfc", "DTMF Contacts") scanl = RadioSettingGroup("scn", "Scan Lists") unlock = RadioSettingGroup("unlock", "Unlock Settings") fmradio = RadioSettingGroup("fmradio", _("FM Radio")) roinfo = RadioSettingGroup("roinfo", _("Driver information")) top = RadioSettings( basic, keya, dtmf, dtmfc, scanl, unlock, fmradio, roinfo) # Programmable keys tmpval = int(_mem.key1_shortpress_action) if tmpval >= len(KEYACTIONS_LIST): tmpval = 0 rs = RadioSetting("key1_shortpress_action", "Side key 1 short press", RadioSettingValueList( KEYACTIONS_LIST, KEYACTIONS_LIST[tmpval])) keya.append(rs) tmpval = int(_mem.key1_longpress_action) if tmpval >= len(KEYACTIONS_LIST): tmpval = 0 rs = RadioSetting("key1_longpress_action", "Side key 1 long press", RadioSettingValueList( KEYACTIONS_LIST, KEYACTIONS_LIST[tmpval])) keya.append(rs) tmpval = int(_mem.key2_shortpress_action) if tmpval >= len(KEYACTIONS_LIST): tmpval = 0 rs = RadioSetting("key2_shortpress_action", "Side key 2 short press", RadioSettingValueList( KEYACTIONS_LIST, KEYACTIONS_LIST[tmpval])) keya.append(rs) tmpval = int(_mem.key2_longpress_action) if tmpval >= len(KEYACTIONS_LIST): tmpval = 0 rs = RadioSetting("key2_longpress_action", "Side key 2 long press", RadioSettingValueList( KEYACTIONS_LIST, KEYACTIONS_LIST[tmpval])) keya.append(rs) # DTMF settings tmppr = bool(_mem.dtmf_settings.side_tone > 0) rs = RadioSetting( "dtmf_side_tone", "DTMF Sidetone", RadioSettingValueBoolean(tmppr)) dtmf.append(rs) tmpval = str(_mem.dtmf_settings.separate_code) if tmpval not in DTMF_CODE_CHARS: tmpval = '*' val = RadioSettingValueString(1, 1, tmpval) val.set_charset(DTMF_CODE_CHARS) rs = RadioSetting("dtmf_separate_code", "Separate Code", val) dtmf.append(rs) tmpval = str(_mem.dtmf_settings.group_call_code) if tmpval not in DTMF_CODE_CHARS: tmpval = '#' val = RadioSettingValueString(1, 1, tmpval) val.set_charset(DTMF_CODE_CHARS) rs = RadioSetting("dtmf_group_call_code", "Group Call Code", val) dtmf.append(rs) tmpval = _mem.dtmf_settings.decode_response if tmpval >= len(DTMF_DECODE_RESPONSE_LIST): tmpval = 0 rs = RadioSetting("dtmf_decode_response", "Decode Response", RadioSettingValueList( DTMF_DECODE_RESPONSE_LIST, DTMF_DECODE_RESPONSE_LIST[tmpval])) dtmf.append(rs) tmpval = _mem.dtmf_settings.auto_reset_time if tmpval > 60 or tmpval < 5: tmpval = 5 rs = RadioSetting("dtmf_auto_reset_time", "Auto reset time (s)", RadioSettingValueInteger(5, 60, tmpval)) dtmf.append(rs) tmpval = int(_mem.dtmf_settings.preload_time) if tmpval > 100 or tmpval < 3: tmpval = 30 tmpval *= 10 rs = RadioSetting("dtmf_preload_time", "Pre-load time (ms)", RadioSettingValueInteger(30, 1000, tmpval, 10)) dtmf.append(rs) tmpval = int(_mem.dtmf_settings.first_code_persist_time) if tmpval > 100 or tmpval < 3: tmpval = 30 tmpval *= 10 rs = RadioSetting("dtmf_first_code_persist_time", "First code persist time (ms)", RadioSettingValueInteger(30, 1000, tmpval, 10)) dtmf.append(rs) tmpval = int(_mem.dtmf_settings.hash_persist_time) if tmpval > 100 or tmpval < 3: tmpval = 30 tmpval *= 10 rs = RadioSetting("dtmf_hash_persist_time", "#/* persist time (ms)", RadioSettingValueInteger(30, 1000, tmpval, 10)) dtmf.append(rs) tmpval = int(_mem.dtmf_settings.code_persist_time) if tmpval > 100 or tmpval < 3: tmpval = 30 tmpval *= 10 rs = RadioSetting("dtmf_code_persist_time", "Code persist time (ms)", RadioSettingValueInteger(30, 1000, tmpval, 10)) dtmf.append(rs) tmpval = int(_mem.dtmf_settings.code_interval_time) if tmpval > 100 or tmpval < 3: tmpval = 30 tmpval *= 10 rs = RadioSetting("dtmf_code_interval_time", "Code interval time (ms)", RadioSettingValueInteger(30, 1000, tmpval, 10)) dtmf.append(rs) tmpval = bool(_mem.dtmf_settings.permit_remote_kill > 0) rs = RadioSetting( "dtmf_permit_remote_kill", "Permit remote kill", RadioSettingValueBoolean(tmpval)) dtmf.append(rs) tmpval = str(_mem.dtmf_settings_numbers.dtmf_local_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_ID: continue else: tmpval = "103" break val = RadioSettingValueString(3, 3, tmpval) val.set_charset(DTMF_CHARS_ID) rs = RadioSetting("dtmf_dtmf_local_code", "Local code (3 chars 0-9 ABCD)", val) dtmf.append(rs) tmpval = str(_mem.dtmf_settings_numbers.dtmf_up_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_UPDOWN or i == "": continue else: tmpval = "123" break val = RadioSettingValueString(1, 16, tmpval) val.set_charset(DTMF_CHARS_UPDOWN) rs = RadioSetting("dtmf_dtmf_up_code", "Up code (1-16 chars 0-9 ABCD*#)", val) dtmf.append(rs) tmpval = str(_mem.dtmf_settings_numbers.dtmf_down_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_UPDOWN: continue else: tmpval = "456" break val = RadioSettingValueString(1, 16, tmpval) val.set_charset(DTMF_CHARS_UPDOWN) rs = RadioSetting("dtmf_dtmf_down_code", "Down code (1-16 chars 0-9 ABCD*#)", val) dtmf.append(rs) tmpval = str(_mem.dtmf_settings_numbers.kill_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_KILL: continue else: tmpval = "77777" break if not len(tmpval) == 5: tmpval = "77777" val = RadioSettingValueString(5, 5, tmpval) val.set_charset(DTMF_CHARS_KILL) rs = RadioSetting("dtmf_kill_code", "Kill code (5 chars 0-9 ABCD)", val) dtmf.append(rs) tmpval = str(_mem.dtmf_settings_numbers.revive_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_KILL: continue else: tmpval = "88888" break if not len(tmpval) == 5: tmpval = "88888" val = RadioSettingValueString(5, 5, tmpval) val.set_charset(DTMF_CHARS_KILL) rs = RadioSetting("dtmf_revive_code", "Revive code (5 chars 0-9 ABCD)", val) dtmf.append(rs) for i in range(1, 17): varname = "DTMF_"+str(i) varnumname = "DTMFNUM_"+str(i) vardescr = "DTMF Contact "+str(i)+" name" varinumdescr = "DTMF Contact "+str(i)+" number" cntn = str(_mem.dtmfcontact[i-1].name).strip("\x20\x00\xff") cntnum = str(_mem.dtmfcontact[i-1].number).strip("\x20\x00\xff") val = RadioSettingValueString(0, 8, cntn) rs = RadioSetting(varname, vardescr, val) dtmfc.append(rs) val = RadioSettingValueString(0, 3, cntnum) val.set_charset(DTMF_CHARS) rs = RadioSetting(varnumname, varinumdescr, val) dtmfc.append(rs) rs.set_doc("DTMF Contacts are 3 codes (valid: 0-9 * # ABCD), " "or an empty string") # scanlists if _mem.scanlist_default == 1: tmpsc = 2 else: tmpsc = 1 rs = RadioSetting("scanlist_default", "Default scanlist", RadioSettingValueInteger(1, 2, tmpsc)) scanl.append(rs) tmppr = bool((_mem.scanlist1_priority_scan & 1) > 0) rs = RadioSetting( "scanlist1_priority_scan", "Scanlist 1 priority channel scan", RadioSettingValueBoolean(tmppr)) scanl.append(rs) tmpch = _mem.scanlist1_priority_ch1 + 1 if tmpch > 200: tmpch = 0 rs = RadioSetting("scanlist1_priority_ch1", "Scanlist 1 priority channel 1 (0 - off)", RadioSettingValueInteger(0, 200, tmpch)) scanl.append(rs) tmpch = _mem.scanlist1_priority_ch2 + 1 if tmpch > 200: tmpch = 0 rs = RadioSetting("scanlist1_priority_ch2", "Scanlist 1 priority channel 2 (0 - off)", RadioSettingValueInteger(0, 200, tmpch)) scanl.append(rs) tmppr = bool((_mem.scanlist2_priority_scan & 1) > 0) rs = RadioSetting( "scanlist2_priority_scan", "Scanlist 2 priority channel scan", RadioSettingValueBoolean(tmppr)) scanl.append(rs) tmpch = _mem.scanlist2_priority_ch1 + 1 if tmpch > 200: tmpch = 0 rs = RadioSetting("scanlist2_priority_ch1", "Scanlist 2 priority channel 1 (0 - off)", RadioSettingValueInteger(0, 200, tmpch)) scanl.append(rs) tmpch = _mem.scanlist2_priority_ch2 + 1 if tmpch > 200: tmpch = 0 rs = RadioSetting("scanlist2_priority_ch2", "Scanlist 2 priority channel 2 (0 - off)", RadioSettingValueInteger(0, 200, tmpch)) scanl.append(rs) # basic settings # call channel tmpc = _mem.call_channel+1 if tmpc > 200: tmpc = 1 rs = RadioSetting("call_channel", "One key call channel", RadioSettingValueInteger(1, 200, tmpc)) basic.append(rs) # squelch tmpsq = _mem.squelch if tmpsq > 9: tmpsq = 1 rs = RadioSetting("squelch", "Squelch", RadioSettingValueInteger(0, 9, tmpsq)) basic.append(rs) # TOT tmptot = _mem.max_talk_time if tmptot > 10: tmptot = 10 rs = RadioSetting( "tot", "Max talk time [min]", RadioSettingValueInteger(0, 10, tmptot)) basic.append(rs) # NOAA autoscan rs = RadioSetting( "noaa_autoscan", "NOAA Autoscan", RadioSettingValueBoolean( bool(_mem.noaa_autoscan > 0))) basic.append(rs) # VOX switch rs = RadioSetting( "vox_switch", "VOX enabled", RadioSettingValueBoolean( bool(_mem.vox_switch > 0))) basic.append(rs) # VOX Level tmpvox = _mem.vox_level+1 if tmpvox > 10: tmpvox = 10 rs = RadioSetting("vox_level", "VOX Level", RadioSettingValueInteger(1, 10, tmpvox)) basic.append(rs) # Mic gain tmpmicgain = _mem.mic_gain if tmpmicgain > 4: tmpmicgain = 4 rs = RadioSetting("mic_gain", "Mic Gain", RadioSettingValueInteger(0, 4, tmpmicgain)) basic.append(rs) # Channel display mode tmpchdispmode = _mem.channel_display_mode if tmpchdispmode >= len(CHANNELDISP_LIST): tmpchdispmode = 0 rs = RadioSetting( "channel_display_mode", "Channel display mode", RadioSettingValueList( CHANNELDISP_LIST, CHANNELDISP_LIST[tmpchdispmode])) basic.append(rs) # Crossband receiving/transmitting tmpcross = _mem.crossband if tmpcross >= len(CROSSBAND_LIST): tmpcross = 0 rs = RadioSetting( "crossband", "Cross-band receiving/transmitting", RadioSettingValueList( CROSSBAND_LIST, CROSSBAND_LIST[tmpcross])) basic.append(rs) # Battery save tmpbatsave = _mem.battery_save if tmpbatsave >= len(BATSAVE_LIST): tmpbatsave = BATSAVE_LIST.index("1:4") rs = RadioSetting( "battery_save", "Battery Save", RadioSettingValueList( BATSAVE_LIST, BATSAVE_LIST[tmpbatsave])) basic.append(rs) # Dual watch tmpdual = _mem.dual_watch if tmpdual >= len(DUALWATCH_LIST): tmpdual = 0 rs = RadioSetting("dualwatch", "Dual Watch", RadioSettingValueList( DUALWATCH_LIST, DUALWATCH_LIST[tmpdual])) basic.append(rs) # Backlight auto mode tmpback = _mem.backlight_auto_mode if tmpback >= len(BACKLIGHT_LIST): tmpback = 0 rs = RadioSetting("backlight_auto_mode", "Backlight auto mode", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[tmpback])) basic.append(rs) # Tail tone elimination rs = RadioSetting( "tail_note_elimination", "Tail tone elimination", RadioSettingValueBoolean( bool(_mem.tail_note_elimination > 0))) basic.append(rs) # VFO open rs = RadioSetting("vfo_open", "VFO open", RadioSettingValueBoolean(bool(_mem.vfo_open > 0))) basic.append(rs) # Beep control rs = RadioSetting( "beep_control", "Beep control", RadioSettingValueBoolean(bool(_mem.beep_control > 0))) basic.append(rs) # Scan resume mode tmpscanres = _mem.scan_resume_mode if tmpscanres >= len(SCANRESUME_LIST): tmpscanres = 0 rs = RadioSetting( "scan_resume_mode", "Scan resume mode", RadioSettingValueList( SCANRESUME_LIST, SCANRESUME_LIST[tmpscanres])) basic.append(rs) # Keypad locked rs = RadioSetting( "key_lock", "Keypad lock", RadioSettingValueBoolean(bool(_mem.key_lock > 0))) basic.append(rs) # Auto keypad lock rs = RadioSetting( "auto_keypad_lock", "Auto keypad lock", RadioSettingValueBoolean(bool(_mem.auto_keypad_lock > 0))) basic.append(rs) # Power on display mode tmpdispmode = _mem.power_on_dispmode if tmpdispmode >= len(WELCOME_LIST): tmpdispmode = 0 rs = RadioSetting( "welcome_mode", "Power on display mode", RadioSettingValueList( WELCOME_LIST, WELCOME_LIST[tmpdispmode])) basic.append(rs) # Keypad Tone tmpkeypadtone = _mem.keypad_tone if tmpkeypadtone >= len(KEYPADTONE_LIST): tmpkeypadtone = 0 rs = RadioSetting("keypad_tone", "Keypad tone", RadioSettingValueList( KEYPADTONE_LIST, KEYPADTONE_LIST[tmpkeypadtone])) basic.append(rs) # Language tmplanguage = _mem.language if tmplanguage >= len(LANGUAGE_LIST): tmplanguage = 0 rs = RadioSetting("language", "Language", RadioSettingValueList( LANGUAGE_LIST, LANGUAGE_LIST[tmplanguage])) basic.append(rs) # Alarm mode tmpalarmmode = _mem.alarm_mode if tmpalarmmode >= len(ALARMMODE_LIST): tmpalarmmode = 0 rs = RadioSetting("alarm_mode", "Alarm mode", RadioSettingValueList( ALARMMODE_LIST, ALARMMODE_LIST[tmpalarmmode])) basic.append(rs) # Reminding of end of talk tmpalarmmode = _mem.reminding_of_end_talk if tmpalarmmode >= len(REMENDOFTALK_LIST): tmpalarmmode = 0 rs = RadioSetting( "reminding_of_end_talk", "Reminding of end of talk", RadioSettingValueList( REMENDOFTALK_LIST, REMENDOFTALK_LIST[tmpalarmmode])) basic.append(rs) # Repeater tail tone elimination tmprte = _mem.repeater_tail_elimination if tmprte >= len(RTE_LIST): tmprte = 0 rs = RadioSetting( "repeater_tail_elimination", "Repeater tail tone elimination", RadioSettingValueList(RTE_LIST, RTE_LIST[tmprte])) basic.append(rs) # Logo string 1 logo1 = str(_mem.logo_line1).strip("\x20\x00\xff") + "\x00" logo1 = _getstring(logo1.encode('ascii', errors='ignore'), 0, 12) rs = RadioSetting("logo1", _("Logo string 1 (12 characters)"), RadioSettingValueString(0, 12, logo1)) basic.append(rs) # Logo string 2 logo2 = str(_mem.logo_line2).strip("\x20\x00\xff") + "\x00" logo2 = _getstring(logo2.encode('ascii', errors='ignore'), 0, 12) rs = RadioSetting("logo2", _("Logo string 2 (12 characters)"), RadioSettingValueString(0, 12, logo2)) basic.append(rs) # FM radio for i in range(1, 21): freqname = "FM_"+str(i) fmfreq = _mem.fmfreq[i-1]/10.0 if fmfreq < FMMIN or fmfreq > FMMAX: rs = RadioSetting(freqname, freqname, RadioSettingValueString(0, 5, "")) else: rs = RadioSetting(freqname, freqname, RadioSettingValueString(0, 5, str(fmfreq))) fmradio.append(rs) # unlock settings # F-LOCK tmpflock = _mem.lock.flock if tmpflock >= len(FLOCK_LIST): tmpflock = 0 rs = RadioSetting( "flock", "F-LOCK", RadioSettingValueList(FLOCK_LIST, FLOCK_LIST[tmpflock])) unlock.append(rs) # 350TX rs = RadioSetting("tx350", "350TX - unlock 350-400 MHz TX", RadioSettingValueBoolean( bool(_mem.lock.tx350 > 0))) unlock.append(rs) # Killed rs = RadioSetting("Killed", "KILLED Device was disabled (via DTMF)", RadioSettingValueBoolean( bool(_mem.lock.killed > 0))) unlock.append(rs) # 200TX rs = RadioSetting("tx200", "200TX - unlock 174-350 MHz TX", RadioSettingValueBoolean( bool(_mem.lock.tx200 > 0))) unlock.append(rs) # 500TX rs = RadioSetting("tx500", "500TX - unlock 500-600 MHz TX", RadioSettingValueBoolean( bool(_mem.lock.tx500 > 0))) unlock.append(rs) # 350EN rs = RadioSetting("en350", "350EN - unlock 350-400 MHz RX", RadioSettingValueBoolean( bool(_mem.lock.en350 > 0))) unlock.append(rs) # SCREEN rs = RadioSetting("scrambler", "SCREN - scrambler enable", RadioSettingValueBoolean( bool(_mem.lock.enscramble > 0))) unlock.append(rs) # readonly info # Firmware firmware = self.metadata.get('uvk5_firmware', 'UNKNOWN') val = RadioSettingValueString(0, 128, firmware) val.set_mutable(False) rs = RadioSetting("fw_ver", "Firmware Version", val) roinfo.append(rs) # No limits version for hacked firmware val = RadioSettingValueBoolean(self._expanded_limits) rs = RadioSetting("nolimits", "Limits disabled for modified firmware", val) rs.set_warning(_( 'This should only be enabled if you are using modified firmware ' 'that supports wider frequency coverage. Enabling this will cause ' 'CHIRP not to enforce OEM restrictions and may lead to undefined ' 'or unregulated behavior. Use at your own risk!'), safe_value=False) roinfo.append(rs) return top def _set_mem_mode(self, _mem, mode): if mode == "NFM": _mem.bandwidth = 1 _mem.enable_am = 0 elif mode == "FM": _mem.bandwidth = 0 _mem.enable_am = 0 elif mode == "NAM": _mem.bandwidth = 1 _mem.enable_am = 1 elif mode == "AM": _mem.bandwidth = 0 _mem.enable_am = 1 # Store details about a high-level memory to the memory map # This is called when a user edits a memory in the UI def set_memory(self, mem): number = mem.number-1 # Get a low-level memory object mapped to the image _mem = self._memobj.channel[number] _mem4 = self._memobj # empty memory if mem.empty: _mem.set_raw(b"\xFF" * 16) if number < 200: _mem2 = self._memobj.channelname[number] _mem2.set_raw(b"\xFF" * 16) _mem4.channel_attributes[number].is_scanlist1 = 0 _mem4.channel_attributes[number].is_scanlist2 = 0 # Compander in other models, not supported here _mem4.channel_attributes[number].compander = 0 _mem4.channel_attributes[number].is_free = 1 _mem4.channel_attributes[number].band = 0x7 return mem # clean the channel memory, restore some bits if it was used before if _mem.get_raw(asbytes=False)[0] == "\xff": # this was an empty memory _mem.set_raw(b"\x00" * 16) else: # this memory wasn't empty, save some bits that we don't know the # meaning of, or that we don't support yet prev_0a = _mem.get_raw()[0x0a] & SAVE_MASK_0A prev_0b = _mem.get_raw()[0x0b] & SAVE_MASK_0B prev_0c = _mem.get_raw()[0x0c] & SAVE_MASK_0C prev_0d = _mem.get_raw()[0x0d] & SAVE_MASK_0D prev_0e = _mem.get_raw()[0x0e] & SAVE_MASK_0E prev_0f = _mem.get_raw()[0x0f] & SAVE_MASK_0F _mem.set_raw(b"\x00" * 10 + bytes([prev_0a, prev_0b, prev_0c, prev_0d, prev_0e, prev_0f])) if number < 200: _mem4.channel_attributes[number].is_scanlist1 = 0 _mem4.channel_attributes[number].is_scanlist2 = 0 _mem4.channel_attributes[number].compander = 0 _mem4.channel_attributes[number].is_free = 1 _mem4.channel_attributes[number].band = 0x7 # find band band = _find_band(self, mem.freq) self._set_mem_mode(_mem, mem.mode) # frequency/offset _mem.freq = mem.freq/10 _mem.offset = mem.offset/10 if mem.duplex == "": _mem.offset = 0 _mem.shift = 0 elif mem.duplex == '-': _mem.shift = FLAGS1_OFFSET_MINUS elif mem.duplex == '+': _mem.shift = FLAGS1_OFFSET_PLUS elif mem.duplex == 'off': # we fake tx disable by setting the tx freq to 0 MHz _mem.shift = FLAGS1_OFFSET_MINUS _mem.offset = _mem.freq # set band if number < 200: _mem4.channel_attributes[number].is_free = 0 _mem4.channel_attributes[number].band = band # channels >200 are the 14 VFO chanells and don't have names if number < 200: _mem2 = self._memobj.channelname[number] tag = mem.name.ljust(10) + "\x00"*6 _mem2.name = tag # Store the alpha tag # tone data self._set_tone(mem, _mem) # step _mem.step = self._steps.index(mem.tuning_step) # tx power if str(mem.power) == str(UVK5_POWER_LEVELS[2]): _mem.txpower = POWER_HIGH elif str(mem.power) == str(UVK5_POWER_LEVELS[1]): _mem.txpower = POWER_MEDIUM else: _mem.txpower = POWER_LOW for setting in mem.extra: sname = setting.get_name() svalue = setting.value.get_value() if sname == "bclo": _mem.bclo = svalue and 1 or 0 if sname == "pttid": _mem.dtmf_pttid = self._pttid_list.index(svalue) if sname == "frev": _mem.freq_reverse = svalue and 1 or 0 if sname == "dtmfdecode": _mem.dtmf_decode = svalue and 1 or 0 if sname == "scrambler": _mem.scrambler = ( _mem.scrambler & 0xf0) | SCRAMBLER_LIST.index(svalue) if number < 200 and sname == "scanlists": if svalue == "1": _mem4.channel_attributes[number].is_scanlist1 = 1 _mem4.channel_attributes[number].is_scanlist2 = 0 elif svalue == "2": _mem4.channel_attributes[number].is_scanlist1 = 0 _mem4.channel_attributes[number].is_scanlist2 = 1 elif svalue == "1+2": _mem4.channel_attributes[number].is_scanlist1 = 1 _mem4.channel_attributes[number].is_scanlist2 = 1 else: _mem4.channel_attributes[number].is_scanlist1 = 0 _mem4.channel_attributes[number].is_scanlist2 = 0 return mem @directory.register class UVK5Radio(UVK5RadioBase): @classmethod def k5_approve_firmware(cls, firmware): approved_prefixes = ('k5_2.01.', 'app_2.01.', '2.01.', '1o11', '4.00.') return any(firmware.startswith(x) for x in approved_prefixes) @classmethod def detect_from_serial(cls, pipe): firmware = _sayhello(pipe) for rclass in [UVK5Radio] + cls.detected_models(): if rclass.k5_approve_firmware(firmware): return rclass raise errors.RadioError('Firmware %r not supported' % firmware) @directory.register class RA79Radio(UVK5Radio): """Retevis RA79""" VENDOR = "Retevis" MODEL = "RA79" chirp-20240224/chirp/drivers/ft50.py0000644000175000017500000005125014476041037015760 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging import re from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, errors, bitwise, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct flag_struct { u8 unknown1f:5, skip:1, mask:1, used:1; }; struct mem_struct { u8 showname:1, unknown1:3, unknown2:2, unknown3:2; u8 ishighpower:1, power:2, unknown4:1, tuning_step:4; u8 codememno:4, codeorpage:2, duplex:2; u8 tmode:2, tone:6; u8 unknown5:1, dtcs:7; u8 unknown6:6, mode:2; bbcd freq[3]; bbcd offset[3]; u8 name[4]; }; #seekto 0x000C; struct { u8 extendedrx_flg; // Seems to be set to 03 when extended rx is enabled u8 extendedrx; // Seems to be set to 01 when extended rx is enabled } extendedrx_struct; // UNFINISHED!! #seekto 0x001A; struct flag_struct flag[100]; #seekto 0x079C; struct flag_struct flag_repeat[100]; #seekto 0x00AA; struct mem_struct memory[100]; struct mem_struct special[11]; #seekto 0x08C7; struct { u8 sub_display; u8 unknown1s; u8 apo; u8 timeout; u8 lock; u8 rxsave; u8 lamp; u8 bell; u8 cwid[16]; u8 unknown2s; u8 artsmode; u8 artsbeep; u8 unknown3s; u8 unknown4s; struct { u8 header[3]; u8 mem_num; u8 digits[16]; } autodial[8]; struct { u8 header[3]; u8 mem_num; u8 digits[32]; } autodial9_ro; bbcd pagingcodec_ro[2]; bbcd pagingcodep[2]; struct { bbcd digits[2]; } pagingcode[6]; u8 code_dec_c_en:1, code_dec_p_en:1, code_dec_1_en:1, code_dec_2_en:1, code_dec_3_en:1, code_dec_4_en:1, code_dec_5_en:1, code_dec_6_en:1; u8 pagingspeed; u8 pagingdelay; u8 pagingbell; u8 paginganswer; #seekto 0x0E30; u8 squelch; // squelch u8 unknown0c; u8 rptl:1, // repeater input tracking amod:1, // auto mode scnl:1, // scan lamp resm:1, // scan resume mode 0=5sec, 1=carr ars:1, // automatic repeater shift keybeep:1, // keypad beep lck:1, // lock unknown1c:1; u8 lgt:1, pageamsg:1, unknown2c:1, bclo:1, // Busy channel lock out unknown3c:2, cwid_en:1, // CWID off/on tsav:1; // TX save u8 unknown4c:4, artssped:1, // ARTS/SPED: 0=15s, 1=25s unknown5c:1, rvhm:1, // RVHM: 0=home, 1=rev mon:1; // MON: 0=mon, 1=tcal } settings; #seekto 0x080E; struct mem_struct vfo_mem[10]; """ # 10 VFO memories: A145, A220, A380, A430, A800, # B145, B220, B380, B430, B800 DUPLEX = ["", "-", "+"] MODES = ["FM", "AM", "WFM"] SKIP_VALUES = ["", "S"] TMODES = ["", "Tone", "TSQL", "DTCS"] TUNING_STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0] TONES = list(chirp_common.OLD_TONES) # CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ ()+-=*/???|0123456789" # the = displays as an underscored dash on radio # the first ? is an uppercase delta - \xA7 # the second ? is an uppercase gamma - \xD1 # the third ? is an uppercase sigma - \xCF NUMERIC_CHARSET = list("0123456789") CHARSET = [str(x) for x in range(0, 10)] + \ [chr(x) for x in range(ord("A"), ord("Z")+1)] + \ list(" ()+-=*/" + ("\x00" * 3) + "|") + NUMERIC_CHARSET DTMFCHARSET = NUMERIC_CHARSET + list("ABCD*#") POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.0), chirp_common.PowerLevel("L3", watts=2.5), chirp_common.PowerLevel("L2", watts=1.0), chirp_common.PowerLevel("L1", watts=0.1)] SPECIALS = ["L1", "U1", "L2", "U2", "L3", "U3", "L4", "U4", "L5", "U5", "UNK"] @directory.register class FT50Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT-50""" BAUD_RATE = 9600 VENDOR = "Yaesu" MODEL = "FT-50" _model = "" _memsize = 3723 _block_lengths = [10, 16, 112, 16, 16, 1776, 1776, 1] # _block_delay = 0.15 _block_size = 8 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold [PTT] & Knob while turning the\n" " radio on.\n" "4. After clicking OK, press the [PTT] switch to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold [PTT] & Knob while turning the\n" " radio on.\n" "4. Press the [MONI] switch (\"WAIT\" will appear on the LCD).\n" "5. Press OK.\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 100) rf.valid_duplexes = DUPLEX rf.valid_tmodes = TMODES rf.valid_power_levels = POWER_LEVELS rf.valid_tuning_steps = TUNING_STEPS rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 4 rf.valid_modes = MODES # Specials not yet implemented # rf.valid_special_chans = SPECIALS rf.valid_bands = [(76000000, 200000000), (300000000, 540000000), (590000000, 999000000)] # rf.can_odd_split = True rf.has_ctone = False rf.has_bank = False rf.has_settings = True rf.has_dtcs_polarity = False return rf def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0xE89)] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def get_memory(self, number): mem = chirp_common.Memory() _mem = self._memobj.memory[number-1] _flg = self._memobj.flag[number-1] mem.number = number # if not _flg.visible: # mem.empty = True if not _flg.used: mem.empty = True return mem for i in _mem.name: mem.name += CHARSET[i & 0x7F] mem.name = mem.name.rstrip() mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.duplex = DUPLEX[_mem.duplex] mem.offset = chirp_common.fix_rounded_step(int(_mem.offset) * 1000) mem.rtone = mem.ctone = TONES[_mem.tone] mem.tmode = TMODES[_mem.tmode] mem.mode = MODES[_mem.mode] mem.tuning_step = TUNING_STEPS[_mem.tuning_step] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] # Power is stored as 2 bits to describe the 3 low power levels # High power is determined by a different bit. if not _mem.ishighpower: mem.power = POWER_LEVELS[3 - _mem.power] else: mem.power = POWER_LEVELS[0] mem.skip = SKIP_VALUES[_flg.skip] return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] _flg = self._memobj.flag[mem.number-1] _flg_repeat = self._memobj.flag_repeat[mem.number-1] if mem.empty: _flg.used = False return if (len(mem.name) == 0): _mem.name = [0x24] * 4 _mem.showname = 0 else: _mem.showname = 1 for i in range(0, 4): _mem.name[i] = CHARSET.index(mem.name.ljust(4)[i]) _mem.freq = int(mem.freq / 1000) _mem.duplex = DUPLEX.index(mem.duplex) _mem.offset = int(mem.offset / 1000) _mem.mode = MODES.index(mem.mode) _mem.tuning_step = TUNING_STEPS.index(mem.tuning_step) if mem.power: if (mem.power == POWER_LEVELS[0]): # low power level is not changed when high power is selected _mem.ishighpower = 0x01 if (_mem.power == 3): # Set low power to L3 (0x02) if it is # set to 3 (new object default) LOG.debug("SETTING DEFAULT?") _mem.power = 0x02 else: _mem.ishighpower = 0x00 _mem.power = 3 - POWER_LEVELS.index(mem.power) else: _mem.ishighpower = 0x01 _mem.power = 0x02 _mem.tmode = TMODES.index(mem.tmode) try: _mem.tone = TONES.index(mem.rtone) except ValueError: raise errors.UnsupportedToneError( ("This radio does not support tone %s" % mem.rtone)) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _flg.skip = SKIP_VALUES.index(mem.skip) # initialize new channel to safe defaults if not mem.empty and not _flg.used: _flg.used = True _flg.mask = True # Mask = True to be visible on radio _mem.unknown1 = 0x00 _mem.unknown2 = 0x00 _mem.unknown3 = 0x00 _mem.unknown4 = 0x00 _mem.unknown5 = 0x00 _mem.unknown6 = 0x00 _mem.codememno = 0x02 # Not implemented in chirp _mem.codeorpage = 0x00 # Not implemented in chirp # Duplicate flags to repeated part in memory _flg_repeat.skip = _flg.skip _flg_repeat.mask = _flg.mask _flg_repeat.used = _flg.used def _decode_cwid(self, inarr): LOG.debug("@_decode_chars, type: %s" % type(inarr)) LOG.debug(inarr) outstr = "" for i in inarr: if i == 0xFF: break outstr += CHARSET[i & 0x7F] LOG.debug(outstr) return outstr.rstrip() def _encode_cwid(self, instr, length=16): LOG.debug("@_encode_chars, type: %s" % type(instr)) LOG.debug(instr) outarr = [] instr = str(instr) for i in range(0, length): if i < len(instr): outarr.append(CHARSET.index(instr[i])) else: outarr.append(0xFF) return outarr def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") dtmf = RadioSettingGroup("dtmf", "DTMF Code & Paging") arts = RadioSettingGroup("arts", "ARTS") autodial = RadioSettingGroup("autodial", "AutoDial") top = RadioSettings(basic, autodial, arts, dtmf) rs = RadioSetting( "squelch", "Squelch", RadioSettingValueInteger(0, 15, _settings.squelch)) basic.append(rs) rs = RadioSetting( "keybeep", "Keypad Beep", RadioSettingValueBoolean(_settings.keybeep)) basic.append(rs) rs = RadioSetting( "scnl", "Scan Lamp", RadioSettingValueBoolean(_settings.scnl)) basic.append(rs) options = ["off", "30m", "1h", "3h", "5h", "8h"] rs = RadioSetting( "apo", "APO time (hrs)", RadioSettingValueList(options, options[_settings.apo])) basic.append(rs) options = ["off", "1m", "2.5m", "5m", "10m"] rs = RadioSetting( "timeout", "Time Out Timer", RadioSettingValueList(options, options[_settings.timeout])) basic.append(rs) options = ["key", "dial", "key+dial", "ptt", "key+ptt", "dial+ptt", "all"] rs = RadioSetting( "lock", "Lock mode", RadioSettingValueList(options, options[_settings.lock])) basic.append(rs) options = ["off", "0.2", "0.3", "0.5", "1.0", "2.0"] rs = RadioSetting( "rxsave", "RX Save (sec)", RadioSettingValueList(options, options[_settings.rxsave])) basic.append(rs) options = ["5sec", "key", "tgl"] rs = RadioSetting( "lamp", "Lamp mode", RadioSettingValueList(options, options[_settings.lamp])) basic.append(rs) options = ["off", "1", "3", "5", "8", "rpt"] rs = RadioSetting( "bell", "Bell Repetitions", RadioSettingValueList(options, options[_settings.bell])) basic.append(rs) rs = RadioSetting( "cwid_en", "CWID Enable", RadioSettingValueBoolean(_settings.cwid_en)) arts.append(rs) cwid = RadioSettingValueString( 0, 16, self._decode_cwid(_settings.cwid.get_value())) cwid.set_charset(CHARSET) rs = RadioSetting("cwid", "CWID", cwid) arts.append(rs) options = ["off", "rx", "tx", "trx"] rs = RadioSetting( "artsmode", "ARTS Mode", RadioSettingValueList( options, options[_settings.artsmode])) arts.append(rs) options = ["off", "in range", "always"] rs = RadioSetting( "artsbeep", "ARTS Beep", RadioSettingValueList(options, options[_settings.artsbeep])) arts.append(rs) for i in range(0, 8): dialsettings = _settings.autodial[i] dialstr = "" for c in dialsettings.digits: if c < len(DTMFCHARSET): dialstr += DTMFCHARSET[c] dialentry = RadioSettingValueString(0, 16, dialstr) dialentry.set_charset(DTMFCHARSET + list(" ")) rs = RadioSetting("autodial" + str(i+1), "AutoDial " + str(i+1), dialentry) autodial.append(rs) dialstr = "" for c in _settings.autodial9_ro.digits: if c < len(DTMFCHARSET): dialstr += DTMFCHARSET[c] dialentry = RadioSettingValueString(0, 32, dialstr) dialentry.set_mutable(False) rs = RadioSetting("autodial9_ro", "AutoDial 9 (read only)", dialentry) autodial.append(rs) options = ["50ms", "100ms"] rs = RadioSetting( "pagingspeed", "Paging Speed", RadioSettingValueList(options, options[_settings.pagingspeed])) dtmf.append(rs) options = ["250ms", "450ms", "750ms", "1000ms"] rs = RadioSetting( "pagingdelay", "Paging Delay", RadioSettingValueList(options, options[_settings.pagingdelay])) dtmf.append(rs) options = ["off", "1", "3", "5", "8", "rpt"] rs = RadioSetting( "pagingbell", "Paging Bell Repetitions", RadioSettingValueList(options, options[_settings.pagingbell])) dtmf.append(rs) options = ["off", "ans", "for"] rs = RadioSetting( "paginganswer", "Paging Answerback", RadioSettingValueList(options, options[_settings.paginganswer])) dtmf.append(rs) rs = RadioSetting( "code_dec_c_en", "Paging Code C Decode Enable", RadioSettingValueBoolean(_settings.code_dec_c_en)) dtmf.append(rs) _str = str(bitwise.bcd_to_int(_settings.pagingcodec_ro)) code = RadioSettingValueString(0, 3, _str) code.set_charset(NUMERIC_CHARSET + list(" ")) code.set_mutable(False) rs = RadioSetting("pagingcodec_ro", "Paging Code C (read only)", code) dtmf.append(rs) rs = RadioSetting( "code_dec_p_en", "Paging Code P Decode Enable", RadioSettingValueBoolean(_settings.code_dec_p_en)) dtmf.append(rs) _str = str(bitwise.bcd_to_int(_settings.pagingcodep)) code = RadioSettingValueString(0, 3, _str) code.set_charset(NUMERIC_CHARSET + list(" ")) rs = RadioSetting("pagingcodep", "Paging Code P", code) dtmf.append(rs) for i in range(0, 6): num = str(i+1) name = "code_dec_" + num + "_en" rs = RadioSetting( name, "Paging Code " + num + " Decode Enable", RadioSettingValueBoolean(getattr(_settings, name))) dtmf.append(rs) _str = str(bitwise.bcd_to_int(_settings.pagingcode[i].digits)) code = RadioSettingValueString(0, 3, _str) code.set_charset(NUMERIC_CHARSET + list(" ")) rs = RadioSetting("pagingcode" + num, "Paging Code " + num, code) dtmf.append(rs) return top def set_settings(self, uisettings): for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() _settings = self._memobj.settings if re.match(r'autodial\d', setting): # set autodial fields dtmfstr = str(element.value).strip() newval = [] for i in range(0, 16): if i < len(dtmfstr): newval.append(DTMFCHARSET.index(dtmfstr[i])) else: newval.append(0xFF) LOG.debug(newval) idx = int(setting[-1:]) - 1 _settings = self._memobj.settings.autodial[idx] _settings.digits = newval continue if (setting == "pagingcodep"): bitwise.int_to_bcd(_settings.pagingcodep, int(element.value)) continue if re.match(r'pagingcode\d', setting): idx = int(setting[-1:]) - 1 bitwise.int_to_bcd(_settings.pagingcode[idx].digits, int(element.value)) continue newval = element.value oldval = getattr(_settings, setting) if setting == "cwid": newval = self._encode_cwid(newval) LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize def sync_out(self): self.update_checksums() return _clone_out(self) def _clone_out(radio): try: return __clone_out(radio) except Exception as e: raise errors.RadioError("Failed to communicate with the radio: %s" % e) def __clone_out(radio): pipe = radio.pipe pipe.timeout = 1 block_lengths = radio._block_lengths total_written = 0 def _status(): status = chirp_common.Status() status.msg = "Cloning to radio" status.max = sum(block_lengths) status.cur = total_written radio.status_fn(status) start = time.time() blocks = 0 pos = 0 for block in radio._block_lengths: blocks += 1 data = radio.get_mmap()[pos:pos + block] # LOG.debug("Sending block: %s" % util.hexprint(data)) recvd = b"" # Radio echos every block received for byte in data: time.sleep(0.01) pipe.write(bytes([byte])) # flush & sleep so don't loose ack pipe.flush() time.sleep(0.015) recvd += pipe.read(1) # chew the echo # LOG.debug("Echo was %s" % util.hexprint(recvd)) LOG.debug("Bytes sent: %i" % len(data)) # Radio does not ack last block if (blocks < 8): buf = pipe.read(block) LOG.debug("ACK attempt: " + util.hexprint(buf)) if buf and buf[0] != yaesu_clone.CMD_ACK: buf = pipe.read(block) if not buf or buf[-1] != yaesu_clone.CMD_ACK: raise errors.RadioError("Radio did not ack block %i" % blocks) total_written += len(data) _status() pos += block pipe.read(pos) # Chew the echo if using a 2-pin cable LOG.debug("Clone completed in %i seconds" % (time.time() - start)) chirp-20240224/chirp/drivers/th_uvf8d.py0000644000175000017500000004646314556146076016753 0ustar hibbyhibby# Copyright 2013 Dan Smith # Eric Allen # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """TYT TH-UVF8D radio management module""" # TODO: support FM Radio memories # TODO: support bank B (another 128 memories) # TODO: [setting] Battery Save # TODO: [setting] Tail Eliminate # TODO: [setting] Tail Mode import struct import logging from chirp import chirp_common, bitwise, errors, directory, memmap, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) def uvf8d_identify(radio): """Do identify handshake with TYT TH-UVF8D""" try: radio.pipe.write(b"\x02PROGRAM") ack = radio.pipe.read(2) if ack != b"PG": raise errors.RadioError("Radio did not ACK first command: %x" % ord(ack)) except Exception: raise errors.RadioError("Unable to communicate with the radio") radio.pipe.write(b"\x02") ident = radio.pipe.read(32) radio.pipe.write(b"A") r = radio.pipe.read(1) if r != b"A": raise errors.RadioError("Ack failed") return ident def tyt_uvf8d_download(radio): data = uvf8d_identify(radio) for i in range(0, 0x4000, 0x20): msg = struct.pack(">cHb", b"R", i, 0x20) radio.pipe.write(msg) block = radio.pipe.read(0x20 + 4) if len(block) != (0x20 + 4): raise errors.RadioError("Radio sent a short block") radio.pipe.write(b"A") ack = radio.pipe.read(1) if ack != b"A": raise errors.RadioError("Radio NAKed block") data += block[4:] if radio.status_fn: status = chirp_common.Status() status.cur = i status.max = 0x4000 status.msg = "Cloning from radio" radio.status_fn(status) radio.pipe.write(b"ENDR") return memmap.MemoryMapBytes(data) def tyt_uvf8d_upload(radio): """Upload to TYT TH-UVF8D""" data = uvf8d_identify(radio) radio.pipe.timeout = 1 if data != radio._mmap[0:32]: raise errors.RadioError("Model mismatch: \n%s\n%s" % (util.hexprint(data), util.hexprint(radio._mmap[0:32]))) for i in range(0, 0x4000, 0x20): addr = i + 0x20 msg = struct.pack(">cHb", b"W", i, 0x20) msg += radio._mmap[addr:(addr + 0x20)] radio.pipe.write(msg) ack = radio.pipe.read(1) if ack != b"A": raise errors.RadioError("Radio did not ack block %i" % i) if radio.status_fn: status = chirp_common.Status() status.cur = i status.max = 0x4000 status.msg = "Cloning to radio" radio.status_fn(status) # End of clone? radio.pipe.write(b"ENDW") # Checksum? radio.pipe.read(3) # these require working desktop software # TODO: DTMF features (ID, delay, speed, kill, etc.) # TODO: Display Name UVF8D_MEM_FORMAT = """ struct memory { lbcd rx_freq[4]; lbcd tx_freq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 apro:4, rpt_md:2, unknown1:2; u8 bclo:2, wideband:1, ishighpower:1, scanadd:1, vox:1, pttid:2; u8 unknown3:8; u8 unknown4:6, duplex:2; lbcd offset[4]; char unknown5[4]; char name[7]; char unknown6[1]; }; struct fm_broadcast_memory { lbcd freq[3]; u8 unknown; }; struct enable_flags { bit flags[8]; }; #seekto 0x0020; struct memory channels[128]; #seekto 0x2020; struct memory vfo1; struct memory vfo2; #seekto 0x2060; struct { u8 unknown2060:4, tot:4; u8 unknown2061; u8 squelch; u8 unknown2063:4, vox_level:4; u8 tuning_step; char unknown12; u8 lamp_t; char unknown11; u8 unknown2068; u8 ani:1, scan_mode:2, unknown2069:2, beep:1, tx_sel:1, roger:1; u8 light:2, led:2, taileliminate:1, autolk:1, unknown206ax:2; u8 unknown206b:1, b_display:2, a_display:2, ab_switch:1, dwait:1, mode:1; u8 dw:1, unknown206c:6, voice:1; u8 unknown206d:2, rxsave:2, opnmsg:2, lock_mode:2; u8 a_work_area:1, b_work_area:1, unknown206ex:6; u8 a_channel; u8 b_channel; u8 pad3[15]; char ponmsg[7]; } settings; #seekto 0x2E60; struct enable_flags enable[16]; struct enable_flags skip[16]; #seekto 0x2FA0; struct fm_broadcast_memory fm_current; #seekto 0x2FA8; struct fm_broadcast_memory fm_memories[20]; """ THUVF8D_DUPLEX = ["", "-", "+"] THUVF8D_CHARSET = "".join([chr(ord("0") + x) for x in range(0, 10)] + [" -*+"] + [chr(ord("A") + x) for x in range(0, 26)] + ["_/"]) TXSEL_LIST = ["EDIT", "BUSY"] LED_LIST = ["Off", "Auto", "On"] MODE_LIST = ["Memory", "VFO"] AB_LIST = ["A", "B"] DISPLAY_LIST = ["Channel", "Frequency", "Name"] LIGHT_LIST = ["Purple", "Orange", "Blue"] RPTMD_LIST = ["Off", "Reverse", "Talkaround"] VOX_LIST = ["1", "2", "3", "4", "5", "6", "7", "8"] WIDEBAND_LIST = ["Narrow", "Wide"] TOT_LIST = ["Off", "30s", "60s", "90s", "120s", "150s", "180s", "210s", "240s", "270s"] SCAN_MODE_LIST = ["Time", "Carry", "Seek"] OPNMSG_LIST = ["Off", "DC (Battery)", "Message"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5), chirp_common.PowerLevel("Low", watts=0.5), ] PTTID_LIST = ["Off", "BOT", "EOT", "Both"] BCLO_LIST = ["Off", "Wave", "Call"] APRO_LIST = ["Off", "Compander", "Scramble 1", "Scramble 2", "Scramble 3", "Scramble 4", "Scramble 5", "Scramble 6", "Scramble 7", "Scramble 8"] LOCK_MODE_LIST = ["PTT", "Key", "Key+S", "All"] TUNING_STEPS_LIST = ["2.5", "5.0", "6.25", "10.0", "12.5", "25.0", "50.0", "100.0"] BACKLIGHT_TIMEOUT_LIST = ["1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"] SPECIALS = { "VFO1": -2, "VFO2": -1} @directory.register class TYTUVF8DRadio(chirp_common.CloneModeRadio): VENDOR = "TYT" MODEL = "TH-UVF8D" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 128) rf.has_bank = False rf.has_ctone = True rf.has_tuning_step = False rf.has_cross = False rf.has_rx_dtcs = True rf.has_settings = True # it may actually be supported, but I haven't tested rf.can_odd_split = False rf.valid_duplexes = THUVF8D_DUPLEX rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-" rf.valid_bands = [(136000000, 174000000), (400000000, 520000000)] rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS rf.valid_modes = ["FM", "NFM"] rf.valid_special_chans = list(SPECIALS.keys()) rf.valid_name_length = 7 return rf def sync_in(self): self._mmap = tyt_uvf8d_download(self) self.process_mmap() def sync_out(self): tyt_uvf8d_upload(self) @classmethod def match_model(cls, filedata, filename): return filedata.startswith(b"TYT-F10\x00") def process_mmap(self): self._memobj = bitwise.parse(UVF8D_MEM_FORMAT, self._mmap) def _decode_tone(self, toneval): pol = "N" rawval = (toneval[1].get_bits(0xFF) << 8) | toneval[0].get_bits(0xFF) if toneval[0].get_bits(0xFF) == 0xFF: mode = "" val = 0 elif toneval[1].get_bits(0xC0) == 0xC0: mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) pol = "R" elif toneval[1].get_bits(0x80): mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) else: mode = "Tone" val = int(toneval) / 10.0 return mode, val, pol def _encode_tone(self, _toneval, mode, val, pol): toneval = 0 if mode == "Tone": toneval = int("%i" % (val * 10), 16) elif mode == "DTCS": toneval = int("%i" % val, 16) toneval |= 0x8000 if pol == "R": toneval |= 0x4000 else: toneval = 0xFFFF _toneval[0].set_raw(toneval & 0xFF) _toneval[1].set_raw((toneval >> 8) & 0xFF) def get_raw_memory(self, number): return repr(self._memobj.channels[number - 1]) def _get_memobjs(self, number): if isinstance(number, str): return (getattr(self._memobj, number.lower()), None) elif number < 0: for k, v in SPECIALS.items(): if number == v: return (getattr(self._memobj, k.lower()), None) else: return (self._memobj.channels[number - 1], None) def get_memory(self, number): _mem, _name = self._get_memobjs(number) mem = chirp_common.Memory() if isinstance(number, str): mem.number = SPECIALS[number] mem.extd_number = number else: mem.number = number if _mem.get_raw(asbytes=False).startswith("\xFF\xFF\xFF\xFF"): mem.empty = True return mem if isinstance(number, int): e = self._memobj.enable[(number - 1) / 8] enabled = e.flags[7 - ((number - 1) % 8)] s = self._memobj.skip[(number - 1) / 8] dont_skip = s.flags[7 - ((number - 1) % 8)] else: enabled = True dont_skip = True if not enabled: mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 mem.duplex = THUVF8D_DUPLEX[_mem.duplex] mem.offset = int(_mem.offset) * 10 txmode, txval, txpol = self._decode_tone(_mem.tx_tone) rxmode, rxval, rxpol = self._decode_tone(_mem.rx_tone) chirp_common.split_tone_decode(mem, (txmode, txval, txpol), (rxmode, rxval, rxpol)) mem.name = str(_mem.name).rstrip('\xFF ') if dont_skip: mem.skip = '' else: mem.skip = 'S' mem.mode = _mem.wideband and "FM" or "NFM" mem.power = POWER_LEVELS[1 - _mem.ishighpower] mem.extra = RadioSettingGroup("extra", "Extra Settings") rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueBoolean(_mem.vox)) mem.extra.append(rs) rs = RadioSetting("bclo", "Busy Channel Lockout", RadioSettingValueList(BCLO_LIST, BCLO_LIST[_mem.bclo])) mem.extra.append(rs) rs = RadioSetting("apro", "APRO", RadioSettingValueList(APRO_LIST, APRO_LIST[_mem.apro])) mem.extra.append(rs) rs = RadioSetting("rpt_md", "Repeater Mode", RadioSettingValueList(RPTMD_LIST, RPTMD_LIST[_mem.rpt_md])) mem.extra.append(rs) return mem def set_memory(self, mem): _mem, _name = self._get_memobjs(mem.number) e = self._memobj.enable[(mem.number - 1) / 8] s = self._memobj.skip[(mem.number - 1) / 8] if mem.empty: _mem.set_raw("\xFF" * 32) e.flags[7 - ((mem.number - 1) % 8)] = False s.flags[7 - ((mem.number - 1) % 8)] = False return else: e.flags[7 - ((mem.number - 1) % 8)] = True if _mem.get_raw(asbytes=False) == ("\xFF" * 32): LOG.debug("Initializing empty memory") _mem.set_raw("\x00" * 32) _mem.rx_freq = mem.freq / 10 if mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 else: _mem.tx_freq = mem.freq / 10 _mem.duplex = THUVF8D_DUPLEX.index(mem.duplex) _mem.offset = mem.offset / 10 (txmode, txval, txpol), (rxmode, rxval, rxpol) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.tx_tone, txmode, txval, txpol) self._encode_tone(_mem.rx_tone, rxmode, rxval, rxpol) _mem.name = mem.name.rstrip(' ').ljust(7, "\xFF") flag_index = 7 - ((mem.number - 1) % 8) s.flags[flag_index] = (mem.skip == "") _mem.scanadd = (mem.skip == "") _mem.wideband = mem.mode == "FM" _mem.ishighpower = mem.power == POWER_LEVELS[0] for element in mem.extra: setattr(_mem, element.get_name(), element.value) def get_settings(self): _settings = self._memobj.settings group = RadioSettingGroup("basic", "Basic") top = RadioSettings(group) group.append(RadioSetting( "mode", "Mode", RadioSettingValueList( MODE_LIST, MODE_LIST[_settings.mode]))) group.append(RadioSetting( "ab_switch", "A/B", RadioSettingValueList( AB_LIST, AB_LIST[_settings.ab_switch]))) group.append(RadioSetting( "a_channel", "A Selected Memory", RadioSettingValueInteger(1, 128, min(_settings.a_channel + 1, 128)))) group.append(RadioSetting( "b_channel", "B Selected Memory", RadioSettingValueInteger(1, 128, min(_settings.b_channel + 1, 128)))) group.append(RadioSetting( "a_display", "A Channel Display", RadioSettingValueList( DISPLAY_LIST, DISPLAY_LIST[_settings.a_display]))) group.append(RadioSetting( "b_display", "B Channel Display", RadioSettingValueList( DISPLAY_LIST, DISPLAY_LIST[_settings.b_display]))) group.append(RadioSetting( "tx_sel", "Priority Transmit", RadioSettingValueList( TXSEL_LIST, TXSEL_LIST[_settings.tx_sel]))) group.append(RadioSetting( "vox_level", "VOX Level", RadioSettingValueList( VOX_LIST, VOX_LIST[_settings.vox_level]))) group.append(RadioSetting( "squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch))) group.append(RadioSetting( "dwait", "Dual Wait", RadioSettingValueBoolean(_settings.dwait))) group.append(RadioSetting( "led", "LED Mode", RadioSettingValueList(LED_LIST, LED_LIST[_settings.led]))) group.append(RadioSetting( "light", "Light Color", RadioSettingValueList( LIGHT_LIST, LIGHT_LIST[_settings.light]))) group.append(RadioSetting( "beep", "Beep", RadioSettingValueBoolean(_settings.beep))) group.append(RadioSetting( "ani", "ANI", RadioSettingValueBoolean(_settings.ani))) group.append(RadioSetting( "tot", "Timeout Timer", RadioSettingValueList(TOT_LIST, TOT_LIST[_settings.tot]))) group.append(RadioSetting( "roger", "Roger Beep", RadioSettingValueBoolean(_settings.roger))) group.append(RadioSetting( "dw", "Dual Watch", RadioSettingValueBoolean(_settings.dw))) group.append(RadioSetting( "rxsave", "RX Save", RadioSettingValueBoolean(_settings.rxsave))) def _filter(name): return str(name).rstrip("\xFF").rstrip() group.append(RadioSetting( "ponmsg", "Power-On Message", RadioSettingValueString(0, 7, _filter(_settings.ponmsg)))) group.append(RadioSetting( "scan_mode", "Scan Mode", RadioSettingValueList( SCAN_MODE_LIST, SCAN_MODE_LIST[_settings.scan_mode]))) group.append(RadioSetting( 'taileliminate', 'Tail Eliminate', RadioSettingValueBoolean(_settings.taileliminate))) group.append(RadioSetting( "autolk", "Auto Lock", RadioSettingValueBoolean(_settings.autolk))) group.append(RadioSetting( "lock_mode", "Keypad Lock Mode", RadioSettingValueList( LOCK_MODE_LIST, LOCK_MODE_LIST[_settings.lock_mode]))) group.append(RadioSetting( "voice", "Voice Prompt", RadioSettingValueBoolean(_settings.voice))) group.append(RadioSetting( "opnmsg", "Opening Message", RadioSettingValueList( OPNMSG_LIST, OPNMSG_LIST[_settings.opnmsg]))) group.append(RadioSetting( "tuning_step", "Tuning Step", RadioSettingValueList( TUNING_STEPS_LIST, TUNING_STEPS_LIST[_settings.tuning_step]))) group.append(RadioSetting( "lamp_t", "Backlight Timeout", RadioSettingValueList( BACKLIGHT_TIMEOUT_LIST, BACKLIGHT_TIMEOUT_LIST[_settings.lamp_t]))) group.append(RadioSetting( "a_work_area", "A Work Area", RadioSettingValueList( AB_LIST, AB_LIST[_settings.a_work_area]))) group.append(RadioSetting( "b_work_area", "B Work Area", RadioSettingValueList( AB_LIST, AB_LIST[_settings.b_work_area]))) return top def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if element.get_name() == 'rxsave': if bool(element.value.get_value()): _settings.rxsave = 3 else: _settings.rxsave = 0 continue if element.get_name().endswith('_channel'): LOG.debug('%s %s', element.value, type(element.value)) setattr(_settings, element.get_name(), int(element.value) - 1) continue if not isinstance(element, RadioSetting): self.set_settings(element) continue setattr(_settings, element.get_name(), element.value) chirp-20240224/chirp/drivers/boblov_x3plus.py0000644000175000017500000004606514522657251020016 0ustar hibbyhibby""" Radio driver for the Boblov X3 Plus Motorcycle Helmet Radio """ # Copyright 2018 Robert C Jennings # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import struct import time from datetime import datetime from chirp import ( bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueInteger, RadioSettingValueList, ) LOG = logging.getLogger(__name__) @directory.register class BoblovX3Plus(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Boblov X3 Plus motorcycle/cycling helmet radio""" VENDOR = 'Boblov' MODEL = 'X3Plus' BAUD_RATE = 9600 CHANNELS = 16 MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unknown1:1, compander:1, scramble:1, skip:1, highpower:1, narrow:1, unknown2:1, bcl:1; u8 unknown3[3]; } memory[16]; #seekto 0x03C0; struct { u8 unknown1:4, voiceprompt:2, batterysaver:1, beep:1; u8 squelchlevel; u8 unknown2; u8 timeouttimer; u8 voxlevel; u8 unknown3; u8 unknown4; u8 voxdelay; } settings; """ # Radio command data CMD_ACK = '\x06' CMD_IDENTIFY = '\x02' CMD_PROGRAM_ENTER = '.VKOGRAM' CMD_PROGRAM_EXIT = '\x62' # 'b' CMD_READ = 'R' CMD_WRITE = 'W' BLOCK_SIZE = 0x08 VOICE_LIST = ['Off', 'Chinese', 'English'] TIMEOUTTIMER_LIST = ['Off', '30 seconds', '60 seconds', '90 seconds', '120 seconds', '150 seconds', '180 seconds', '210 seconds', '240 seconds', '270 seconds', '300 seconds'] VOXLEVEL_LIST = ['Off', '1', '2', '3', '4', '5', '6', '7', '8', '9'] VOXDELAY_LIST = ['1 seconds', '2 seconds', '3 seconds', '4 seconds', '5 seconds'] X3P_POWER_LEVELS = [chirp_common.PowerLevel('Low', watts=0.5), chirp_common.PowerLevel('High', watts=2.00)] _memsize = 0x03F0 _ranges = [ (0x0000, 0x03F0), ] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = _( "The X3Plus driver is currently experimental.\n" "There are no known issues but you should proceed with" " caution.\n" "Please save an unedited copy of your first successful\n" "download to a CHIRP Radio Images (*.img) file.\n") return rp @classmethod def match_model(cls, filedata, filename): """Given contents of a stored file (@filedata), return True if this radio driver handles the represented model""" if len(filedata) != cls._memsize: return False return b'P310' in filedata[0x03D0:0x03D8] def get_features(self): """Return a RadioFeatures object for this radio""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.valid_modes = ['NFM', 'FM'] # 12.5 kHz, 25 kHz. rf.valid_power_levels = self.X3P_POWER_LEVELS rf.valid_skips = ['', 'S'] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_duplexes = ['', '-', '+', 'split', 'off'] rf.can_odd_split = True rf.has_rx_dtcs = True rf.has_ctone = True rf.has_cross = True rf.valid_cross_modes = [ 'Tone->Tone', 'DTCS->', '->DTCS', 'Tone->DTCS', 'DTCS->Tone', '->Tone', 'DTCS->DTCS'] rf.has_tuning_step = False rf.has_bank = False rf.has_name = False rf.memory_bounds = (1, self.CHANNELS) rf.valid_bands = [(400000000, 470000000)] return rf def process_mmap(self): """Process a newly-loaded or downloaded memory map""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def sync_in(self): "Initiate a radio-to-PC clone operation" LOG.debug('Cloning from radio') status = chirp_common.Status() status.msg = 'Cloning from radio' status.cur = 0 status.max = self._memsize self.status_fn(status) self._enter_programming_mode() data = '' for addr in range(0, self._memsize, self.BLOCK_SIZE): status.cur = addr + self.BLOCK_SIZE self.status_fn(status) block = self._read_block(addr, self.BLOCK_SIZE) data += block LOG.debug('Address: %04x', addr) LOG.debug(util.hexprint(block)) self._exit_programming_mode() self._mmap = memmap.MemoryMap(data) self.process_mmap() def sync_out(self): "Initiate a PC-to-radio clone operation" LOG.debug('Upload to radio') status = chirp_common.Status() status.msg = 'Uploading to radio' status.cur = 0 status.max = self._memsize self.status_fn(status) self._enter_programming_mode() for start_addr, end_addr in self._ranges: for addr in range(start_addr, end_addr, self.BLOCK_SIZE): status.cur = addr + self.BLOCK_SIZE self.status_fn(status) self._write_block(addr, self.BLOCK_SIZE) self._exit_programming_mode() def get_raw_memory(self, number): """Return a raw string describing the memory at @number""" return repr(self._memobj.memory[number - 1]) @staticmethod def _decode_tone(val): val = int(val) if val == 16665: return '', None, None elif val >= 12000: return 'DTCS', val - 12000, 'R' elif val >= 8000: return 'DTCS', val - 8000, 'N' return 'Tone', val / 10.0, None @staticmethod def _encode_tone(memval, mode, value, pol): if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception('Internal error: invalid mode `%s`' % mode) def get_memory(self, number): """Return a Memory object for the memory at location @number""" try: rmem = self._memobj.memory[number - 1] except KeyError: raise errors.InvalidMemoryLocation('Unknown channel %s' % number) if number < 1 or number > self.CHANNELS: raise errors.InvalidMemoryLocation( 'Channel number must be 1 and %s' % self.CHANNELS) mem = chirp_common.Memory() mem.number = number mem.freq = int(rmem.rxfreq) * 10 # A blank (0 MHz) or 0xFFFFFFFF frequency is considered empty if mem.freq == 0 or ( rmem.rxfreq.get_raw(asbytes=False) == '\xFF\xFF\xFF\xFF'): LOG.debug('empty channel %d', number) mem.freq = 0 mem.empty = True return mem if rmem.txfreq.get_raw(asbytes=False) == '\xFF\xFF\xFF\xFF': mem.duplex = 'off' mem.offset = 0 elif int(rmem.rxfreq) == int(rmem.txfreq): mem.duplex = '' mem.offset = 0 else: mem.duplex = '-' if int(rmem.rxfreq) > int(rmem.txfreq) else '+' mem.offset = abs(int(rmem.rxfreq) - int(rmem.txfreq)) * 10 mem.mode = 'NFM' if rmem.narrow else 'FM' mem.skip = 'S' if rmem.skip else '' mem.power = self.X3P_POWER_LEVELS[rmem.highpower] txtone = self._decode_tone(rmem.txtone) rxtone = self._decode_tone(rmem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) mem.extra = RadioSettingGroup('Extra', 'extra') mem.extra.append(RadioSetting('bcl', 'Busy Channel Lockout', RadioSettingValueBoolean( current=(not rmem.bcl)))) mem.extra.append(RadioSetting('scramble', 'Scramble', RadioSettingValueBoolean( current=(not rmem.scramble)))) mem.extra.append(RadioSetting('compander', 'Compander', RadioSettingValueBoolean( current=(not rmem.compander)))) return mem def set_memory(self, memory): """Set the memory object @memory""" rmem = self._memobj.memory[memory.number - 1] if memory.empty: rmem.set_raw('\xFF' * (rmem.size() // 8)) return rmem.rxfreq = memory.freq / 10 set_txtone = True if memory.duplex == 'off': for i in range(0, 4): rmem.txfreq[i].set_raw('\xFF') # If receive only then txtone value should be none self._encode_tone(rmem.txtone, mode='', value=None, pol=None) set_txtone = False elif memory.duplex == 'split': rmem.txfreq = memory.offset / 10 elif memory.duplex == '+': rmem.txfreq = (memory.freq + memory.offset) / 10 elif memory.duplex == '-': rmem.txfreq = (memory.freq - memory.offset) / 10 else: rmem.txfreq = memory.freq / 10 txtone, rxtone = chirp_common.split_tone_encode(memory) if set_txtone: self._encode_tone(rmem.txtone, *txtone) self._encode_tone(rmem.rxtone, *rxtone) rmem.narrow = 'N' in memory.mode rmem.skip = memory.skip == 'S' for setting in memory.extra: # NOTE: Only three settings right now, all are inverted setattr(rmem, setting.get_name(), not int(setting.value)) def get_settings(self): """ Return a RadioSettings list containing one or more RadioSettingGroup or RadioSetting objects. These represent general settings that can be adjusted on the radio. """ cur = self._memobj.settings basic = RadioSettingGroup('basic', 'Basic Settings') rs = RadioSetting('squelchlevel', 'Squelch level', RadioSettingValueInteger( minval=0, maxval=9, current=cur.squelchlevel)) basic.append(rs) rs = RadioSetting('timeouttimer', 'Timeout timer', RadioSettingValueList( options=self.TIMEOUTTIMER_LIST, current=self.TIMEOUTTIMER_LIST[cur.timeouttimer])) basic.append(rs) rs = RadioSetting('voiceprompt', 'Voice prompt', RadioSettingValueList( options=self.VOICE_LIST, current=self.VOICE_LIST[cur.voiceprompt])) basic.append(rs) rs = RadioSetting('voxlevel', 'Vox level', RadioSettingValueList( options=self.VOXLEVEL_LIST, current=self.VOXLEVEL_LIST[cur.voxlevel])) basic.append(rs) rs = RadioSetting('voxdelay', 'VOX delay', RadioSettingValueList( options=self.VOXDELAY_LIST, current=self.VOXDELAY_LIST[cur.voxdelay])) basic.append(rs) basic.append(RadioSetting('batterysaver', 'Battery saver', RadioSettingValueBoolean( current=cur.batterysaver))) basic.append(RadioSetting('beep', 'Beep', RadioSettingValueBoolean( current=cur.beep))) return RadioSettings(basic) def set_settings(self, settings): """ Accepts the top-level RadioSettingGroup returned from get_settings() and adjusts the values in the radio accordingly. This function expects the entire RadioSettingGroup hierarchy returned from get_settings(). """ for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if '.' in element.get_name(): bits = element.get_name().split('.') obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug('Using apply callback') element.run_apply_callback() else: LOG.debug('Setting %s = %s', setting, element.value) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _write(self, data, timeout=3): """ Write data to the serial port and consume the echoed response The radio echos the data it is sent before replying. Send the data to the radio, consume the reply, and ensure that the reply is the same as the data sent. """ serial = self.pipe expected = len(data) resp = b'' start = datetime.now() # LOG.debug('WRITE(%02d): %s', expected, util.hexprint(data).rstrip()) serial.write(data) while True: if not expected: break rbytes = serial.read(expected) resp += rbytes expected -= len(rbytes) if (datetime.now() - start).seconds > timeout: raise errors.RadioError('Timeout while reading from radio') if resp != data: raise errors.RadioError('Echoed response did not match sent data') def _read(self, length, timeout=3): """Read data from the serial port""" resp = b'' serial = self.pipe remaining = length start = datetime.now() if not remaining: return resp while True: rbytes = serial.read(remaining) resp += rbytes remaining -= len(rbytes) if not remaining: break if (datetime.now() - start).seconds > timeout: raise errors.RadioError('Timeout while reading from radio') time.sleep(0.1) # LOG.debug('READ(%02d): %s', length, util.hexprint(resp).rstrip()) return resp def _read_block(self, block_addr, block_size): LOG.debug('Reading block %04x...', block_addr) cmd = struct.pack('>cHb', self.CMD_READ, block_addr, block_size) resp_prefix = self.CMD_WRITE + cmd[1:] try: msg = ('Failed to write command to radio for block ' 'read at %04x' % block_addr) self._write(cmd) msg = ('Failed to read response from radio for block ' 'read at %04x' % block_addr) response = self._read(len(cmd) + block_size) if response[:len(cmd)] != resp_prefix: raise errors.RadioError('Error reading block %04x, ' 'Command not returned.' % (block_addr)) msg = ('Failed to write ACK to radio after block read at ' '%04x' % block_addr) self._write(self.CMD_ACK) msg = ('Failed to read ACK from radio after block read at ' '%04x' % block_addr) ack = self._read(1) except Exception: LOG.debug(msg, exc_info=True) raise errors.RadioError(msg) if ack != self.CMD_ACK: raise errors.RadioError('No ACK reading block ' '%04x.' % (block_addr)) return response[len(cmd):] def _write_block(self, block_addr, block_size): cmd = struct.pack('>cHb', self.CMD_WRITE, block_addr, block_size) data = self.get_mmap()[block_addr:block_addr + 8] LOG.debug('Writing Data:\n%s%s', util.hexprint(cmd), util.hexprint(data)) try: self._write(cmd + data) if self._read(1) != self.CMD_ACK: raise Exception('No ACK') except Exception: msg = 'Failed to send block to radio at %04x' % block_addr LOG.debug(msg, exc_info=True) raise errors.RadioError(msg) def _enter_programming_mode(self): LOG.debug('Entering programming mode') try: msg = 'Error communicating with radio entering programming mode.' self._write(self.CMD_PROGRAM_ENTER) time.sleep(0.5) ack = self._read(1) if not ack: raise errors.RadioError('No response from radio') elif ack != self.CMD_ACK: raise errors.RadioError('Radio refused to enter ' 'programming mode') msg = 'Error communicating with radio during identification' self._write(self.CMD_IDENTIFY) ident = self._read(8) if not ident.startswith('SMP558'): LOG.debug(util.hexprint(ident)) raise errors.RadioError('Radio returned unknown ID string') msg = ('Error communicating with radio while querying ' 'model identifier') self._write(self.CMD_ACK) msg = 'Error communicating with radio on final handshake' ack = self._read(1) if ack != self.CMD_ACK: raise errors.RadioError('Radio refused to enter programming ' 'mode failed on final handshake.') except Exception: LOG.debug(msg, exc_info=True) raise errors.RadioError(msg) def _exit_programming_mode(self): try: self._write(self.CMD_PROGRAM_EXIT) except Exception: msg = 'Radio refused to exit programming mode' LOG.debug(msg, exc_info=True) raise errors.RadioError(msg) LOG.debug('Exited programming mode') chirp-20240224/chirp/drivers/retevis_rt23.py0000644000175000017500000006754414522657251017555 0ustar hibbyhibby# Copyright 2017 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct memory { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unknown1; u8 pttid:2, // PTT-ID unknown2:1, signaling:1, // Signaling(ANI) unknown3:1, bcl:1, // Busy Channel Lockout unknown4:2; u8 unknown5:3, highpower:1, // Power Level isnarrow:1, // Bandwidth scan:1, // Scan Add unknown6:2; u8 unknown7; }; #seekto 0x0010; struct memory channels[128]; #seekto 0x0810; struct memory vfo_a; struct memory vfo_b; #seekto 0x0830; struct { u8 unknown_0830_1:4, color:2, // Background Color dst:1, // DTMF Side Tone txsel:1; // Priority TX Channel Select u8 scans:2, // Scan Mode unknown_0831:1, autolk:1, // Auto Key Lock save:1, // Battery Save beep:1, // Key Beep voice:2; // Voice Prompt u8 vfomr_fm:1, // FM Radio Display Mode led:2, // Background Light unknown_0832_2:1, dw:1, // FM Radio Dual Watch name:1, // Display Names vfomr_a:2; // Display Mode A u8 opnset:2, // Power On Message unknown_0833_1:3, dwait:1, // Dual Standby vfomr_b:2; // Display Mode B u8 mrcha; // mr a ch num u8 mrchb; // mr b ch num u8 fmch; // fm radio ch num u8 unknown_0837_1:1, ste:1, // Squelch Tail Eliminate roger:1, // Roger Beep unknown_0837_2:1, vox:4; // VOX u8 step:4, // Step unknown_0838_1:4; u8 squelch; // Squelch u8 tot; // Time Out Timer u8 rptmod:1, // Repeater Mode volmod:2, // Volume Mode rptptt:1, // Repeater PTT Switch rptspk:1, // Repeater Speaker relay:3; // Cross Band Repeater Enable u8 unknown_083C:4, // 0x083C rptrl:4; // Repeater TX Delay u8 pf1:4, // Function Key 1 pf2:4; // Function Key 2 u8 vot; // VOX Delay Time } settings; #seekto 0x0848; struct { char line1[7]; } poweron_msg; struct limit { bbcd lower[2]; bbcd upper[2]; }; #seekto 0x0850; struct { struct limit vhf; struct limit uhf; } limits; #seekto 0x08D0; struct { char name[7]; u8 unknown2[1]; } names[128]; #seekto 0x0D20; u8 usedflags[16]; u8 scanflags[16]; #seekto 0x0FA0; struct { u8 unknown_0FA0_1:4, dispab:1, // select a/b unknown_0FA0_2:3; } settings2; """ CMD_ACK = b"\x06" BLOCK_SIZE = 0x10 RT23_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("High", watts=2.50)] RT23_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (17, 50, 55, 135, 217, 254, 305, 645, 765))) RT23_CHARSET = chirp_common.CHARSET_UPPER_NUMERIC + \ ":;<=>?@ !\"#$%&'()*+,-./" LIST_COLOR = ["Blue", "Orange", "Purple"] LIST_LED = ["Off", "On", "Auto"] LIST_OPNSET = ["Full", "Voltage", "Message"] LIST_PFKEY = [ "Radio", "Sub-channel Sent", "Scan", "Alarm", "DTMF", "Squelch Off Momentarily", "Battery Power Indicator", "Tone 1750", "Tone 2100", "Tone 1000", "Tone 1450"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_RPTMOD = ["Single", "Double"] LIST_RPTRL = ["0.5S", "1.0S", "1.5S", "2.0S", "2.5S", "3.0S", "3.5S", "4.0S", "4.5S"] LIST_SCANS = ["Time Operated", "Carrier Operated", "Search"] LIST_SIGNALING = ["No", "DTMF"] LIST_TOT = ["OFF"] + ["%s seconds" % x for x in range(30, 300, 30)] LIST_TXSEL = ["Edit", "Busy"] _STEP_LIST = [2.5, 5., 6.25, 10., 12.5, 20., 25., 50.] LIST_STEP = ["{0:.2f}K".format(x) for x in _STEP_LIST] LIST_VFOMR = ["VFO", "MR(Frequency)", "MR(Channel #/Name)"] LIST_VFOMRFM = ["VFO", "Channel"] LIST_VOICE = ["Off", "Chinese", "English"] LIST_VOLMOD = ["Off", "Sub", "Main"] LIST_VOT = ["0.5S", "1.0S", "1.5S", "2.0S", "3.0S"] LIST_VOX = ["OFF"] + ["%s" % x for x in range(1, 6)] def _rt23_enter_programming_mode(radio): serial = radio.pipe magic = b"PROIUAM" exito = False for i in range(0, 5): for j in range(0, len(magic)): time.sleep(0.005) serial.write(magic[j:j + 1]) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) try: serial.write(b"\x02") ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") if not ident.startswith(b"P31183"): LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _rt23_exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _rt23_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, BLOCK_SIZE) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + BLOCK_SIZE + 1) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) chunk = response[4:] cs = 0 for byte in chunk[:-1]: cs += byte if chunk[-1] != (cs & 0xFF): raise Exception("Block failed checksum!") block_data = chunk[:-1] except: raise errors.RadioError("Failed to read block at %04x" % block_addr) return block_data def _rt23_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, BLOCK_SIZE) data = radio.get_mmap()[block_addr:block_addr + BLOCK_SIZE] cs = 0 for byte in data: cs += byte data += bytes([cs & 0xFF]) LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _rt23_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, BLOCK_SIZE): status.cur = addr + BLOCK_SIZE radio.status_fn(status) block = _rt23_read_block(radio, addr, BLOCK_SIZE) if addr == 0 and block.startswith(b"\xFF" * 6): block = b"P31183" + b"\xFF" * 10 data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _rt23_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _rt23_enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, BLOCK_SIZE): status.cur = addr + BLOCK_SIZE radio.status_fn(status) _rt23_write_block(radio, addr, BLOCK_SIZE) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" if len(data) == 0x1000: rid = data[0x0000:0x0006] return rid == b"P31183" else: return False def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True @directory.register class RT23Radio(chirp_common.CloneModeRadio): """RETEVIS RT23""" VENDOR = "Retevis" MODEL = "RT23" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _ranges = [ (0x0000, 0x0EC0), ] _memsize = 0x1000 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.valid_name_length = 7 rf.valid_characters = RT23_CHARSET rf.has_name = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = RT23_POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_dtcs_codes = RT23_DTCS rf.memory_bounds = (1, 128) rf.valid_tuning_steps = _STEP_LIST rf.valid_bands = [ (136000000, 174000000), (400000000, 480000000)] return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_memory(self, number): mem = chirp_common.Memory() _mem = self._memobj.channels[number-1] _nam = self._memobj.names[number - 1] mem.number = number bitpos = (1 << ((number - 1) % 8)) bytepos = ((number - 1) / 8) _scn = self._memobj.scanflags[bytepos] _usd = self._memobj.usedflags[bytepos] isused = bitpos & int(_usd) isscan = bitpos & int(_scn) if not isused: mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw(asbytes=False) == "\xFF\xFF\xFF\xFF": mem.empty = True return mem if _mem.get_raw(asbytes=False) == ("\xFF" * 16): LOG.debug("Initializing empty memory") _mem.set_raw("\x00" * 16) # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if _mem.get_raw(asbytes=False)[4] == "\xFF": # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 for char in _nam.name: if str(char) == "\xFF": char = " " mem.name += str(char) mem.name = mem.name.rstrip() mem.mode = _mem.isnarrow and "NFM" or "FM" rxtone = txtone = None txtone = self.decode_tone(_mem.txtone) rxtone = self.decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) mem.power = RT23_POWER_LEVELS[_mem.highpower] if not isscan: mem.skip = "S" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList( LIST_PTTID, LIST_PTTID[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("signaling", "Optional Signaling", RadioSettingValueList(LIST_SIGNALING, LIST_SIGNALING[ _mem.signaling])) mem.extra.append(rs) return mem def set_memory(self, mem): LOG.debug("Setting %i(%s)" % (mem.number, mem.extd_number)) _mem = self._memobj.channels[mem.number - 1] _nam = self._memobj.names[mem.number - 1] bitpos = (1 << ((mem.number - 1) % 8)) bytepos = ((mem.number - 1) / 8) _scn = self._memobj.scanflags[bytepos] _usd = self._memobj.usedflags[bytepos] if mem.empty: _mem.set_raw("\xFF" * 16) _nam.name = ("\xFF" * 7) _usd &= ~bitpos _scn &= ~bitpos return else: _usd |= bitpos if _mem.get_raw(asbytes=False) == ("\xFF" * 16): LOG.debug("Initializing empty memory") _mem.set_raw("\x00" * 16) _scn |= bitpos _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" _mem.scan = mem.skip != "S" if mem.skip == "S": _scn &= ~bitpos else: _scn |= bitpos _mem.isnarrow = mem.mode == "NFM" ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_mem.txtone, txmode, txtone, txpol) self.encode_tone(_mem.rxtone, rxmode, rxtone, rxpol) _mem.highpower = mem.power == RT23_POWER_LEVELS[1] for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") workmode = RadioSettingGroup("workmode", "Workmode Settings") fmradio = RadioSettingGroup("fmradio", "FM Radio Settings") top = RadioSettings(basic, advanced, other, workmode, fmradio) save = RadioSetting("save", "Battery Saver", RadioSettingValueBoolean(_settings.save)) basic.append(save) vox = RadioSetting("vox", "VOX Gain", RadioSettingValueList( LIST_VOX, LIST_VOX[_settings.vox])) basic.append(vox) squelch = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger( 0, 9, _settings.squelch)) basic.append(squelch) relay = RadioSetting("relay", "Repeater", RadioSettingValueBoolean(_settings.relay)) basic.append(relay) tot = RadioSetting("tot", "Time-out timer", RadioSettingValueList( LIST_TOT, LIST_TOT[_settings.tot])) basic.append(tot) beep = RadioSetting("beep", "Key Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(beep) color = RadioSetting("color", "Background Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_settings.color - 1])) basic.append(color) vot = RadioSetting("vot", "VOX Delay Time", RadioSettingValueList( LIST_VOT, LIST_VOT[_settings.vot])) basic.append(vot) dwait = RadioSetting("dwait", "Dual Standby", RadioSettingValueBoolean(_settings.dwait)) basic.append(dwait) led = RadioSetting("led", "Background Light", RadioSettingValueList( LIST_LED, LIST_LED[_settings.led])) basic.append(led) voice = RadioSetting("voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[_settings.voice])) basic.append(voice) roger = RadioSetting("roger", "Roger Beep", RadioSettingValueBoolean(_settings.roger)) basic.append(roger) autolk = RadioSetting("autolk", "Auto Key Lock", RadioSettingValueBoolean(_settings.autolk)) basic.append(autolk) opnset = RadioSetting("opnset", "Open Mode Set", RadioSettingValueList( LIST_OPNSET, LIST_OPNSET[_settings.opnset])) basic.append(opnset) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = self._memobj.poweron_msg ponmsg = RadioSetting("poweron_msg.line1", "Power-On Message", RadioSettingValueString( 0, 7, _filter(_msg.line1))) basic.append(ponmsg) scans = RadioSetting("scans", "Scan Mode", RadioSettingValueList( LIST_SCANS, LIST_SCANS[_settings.scans])) basic.append(scans) dw = RadioSetting("dw", "FM Radio Dual Watch", RadioSettingValueBoolean(_settings.dw)) basic.append(dw) name = RadioSetting("name", "Display Names", RadioSettingValueBoolean(_settings.name)) basic.append(name) rptrl = RadioSetting("rptrl", "Repeater TX Delay", RadioSettingValueList(LIST_RPTRL, LIST_RPTRL[ _settings.rptrl])) basic.append(rptrl) rptspk = RadioSetting("rptspk", "Repeater Speaker", RadioSettingValueBoolean(_settings.rptspk)) basic.append(rptspk) rptptt = RadioSetting("rptptt", "Repeater PTT Switch", RadioSettingValueBoolean(_settings.rptptt)) basic.append(rptptt) rptmod = RadioSetting("rptmod", "Repeater Mode", RadioSettingValueList( LIST_RPTMOD, LIST_RPTMOD[_settings.rptmod])) basic.append(rptmod) volmod = RadioSetting("volmod", "Volume Mode", RadioSettingValueList( LIST_VOLMOD, LIST_VOLMOD[_settings.volmod])) basic.append(volmod) dst = RadioSetting("dst", "DTMF Side Tone", RadioSettingValueBoolean(_settings.dst)) basic.append(dst) txsel = RadioSetting("txsel", "Priority TX Channel", RadioSettingValueList( LIST_TXSEL, LIST_TXSEL[_settings.txsel])) basic.append(txsel) ste = RadioSetting("ste", "Squelch Tail Eliminate", RadioSettingValueBoolean(_settings.ste)) basic.append(ste) # advanced if _settings.pf1 > 0x0A: val = 0x00 else: val = _settings.pf1 pf1 = RadioSetting("pf1", "PF1 Key", RadioSettingValueList( LIST_PFKEY, LIST_PFKEY[val])) advanced.append(pf1) if _settings.pf2 > 0x0A: val = 0x00 else: val = _settings.pf2 pf2 = RadioSetting("pf2", "PF2 Key", RadioSettingValueList( LIST_PFKEY, LIST_PFKEY[val])) advanced.append(pf2) # other _limit = str(int(_mem.limits.vhf.lower) // 10) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) rs = RadioSetting("limits.vhf.lower", "VHF low", val) other.append(rs) _limit = str(int(_mem.limits.vhf.upper) // 10) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) rs = RadioSetting("limits.vhf.upper", "VHF high", val) other.append(rs) _limit = str(int(_mem.limits.uhf.lower) // 10) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) rs = RadioSetting("limits.uhf.lower", "UHF low", val) other.append(rs) _limit = str(int(_mem.limits.uhf.upper) // 10) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) rs = RadioSetting("limits.uhf.upper", "UHF high", val) other.append(rs) # work mode vfomr_a = RadioSetting("vfomr_a", "Display Mode A", RadioSettingValueList( LIST_VFOMR, LIST_VFOMR[_settings.vfomr_a])) workmode.append(vfomr_a) vfomr_b = RadioSetting("vfomr_b", "Display Mode B", RadioSettingValueList( LIST_VFOMR, LIST_VFOMR[_settings.vfomr_b])) workmode.append(vfomr_b) mrcha = RadioSetting("mrcha", "Channel # A", RadioSettingValueInteger( 1, 128, _settings.mrcha)) workmode.append(mrcha) mrchb = RadioSetting("mrchb", "Channel # B", RadioSettingValueInteger( 1, 128, _settings.mrchb)) workmode.append(mrchb) # fm radio vfomr_fm = RadioSetting("vfomr_fm", "FM Radio Display Mode", RadioSettingValueList( LIST_VFOMRFM, LIST_VFOMRFM[ _settings.vfomr_fm])) fmradio.append(vfomr_fm) fmch = RadioSetting("fmch", "FM Radio Channel #", RadioSettingValueInteger( 1, 25, _settings.fmch)) fmradio.append(fmch) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "color": setattr(obj, setting, int(element.value) + 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) in [0x1000, ]: match_size = True # testing the model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/icv86.py0000644000175000017500000002417014455454300016140 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import icf from chirp import chirp_common, bitwise, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) ICV86_MEM_FORMAT = """ #seekto 0x040; u8 skips[26]; #seekto 0x060; u8 used[26]; #seekto 0x00BF; struct { u8 reserved1[8]; u8 reserved2:6, disp_type:2; u8 reserved3; u8 reserved4:7, dial_assignment:1; u8 reserved5[8]; u8 reserved6:6, lcd:2; u8 reserved7[2]; u8 reserved8:6, mic:2; } settings; #seekto 0x0200; struct { ul32 freq; ul32 offset; char name[5]; u8 reserved1:2, rtone:6; u8 reserved2:2, ctone:6; u8 reserved3:1, dtcs:7; u8 reserved4:5, tuning_step:3; u8 reserved5:2, mode:1, rev:1, duplex:2, reserved6:2; u8 reserved7:2, dtcs_polarity:2, tmode:4; u8 reserved8:5, tx:1, power:2; u8 reserved9; u8 reserved10; u8 reserved11; u8 reserved12; } memory[207]; """ SPECIAL = { "0A": 200, "0B": 201, "1A": 202, "1B": 203, "2A": 204, "2B": 205, "C": 206, } SPECIAL_REV = { 200: "0A", 201: "0B", 202: "1A", 203: "1B", 204: "2A", 205: "2B", 206: "C", } TMODES = ["", "Tone", "TSQL", "DTCS", "DTCS-R"] MODES = ["FM", "NFM"] SKIPS = ["", "S"] DUPLEXES = ["", "-", "+"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] TUNING_STEPS = [5., 10., 12.5, 15., 20., 25., 30., 50.] POWER_LEVELS = [ chirp_common.PowerLevel("High", watts=5.5), chirp_common.PowerLevel("Low", watts=0.5), chirp_common.PowerLevel("Mid", watts=2.5), chirp_common.PowerLevel("Extra High", watts=7.0), ] @directory.register class ICV86Radio(icf.IcomCloneModeRadio): """Icom IC-V86""" VENDOR = "Icom" MODEL = "IC-V86" _model = "\x40\x66\x00\x01" _memsize = 5504 _endframe = "Icom Inc\x2eAC" _ranges = [(0x0000, 5504, 32)] def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.valid_modes = MODES rf.valid_tmodes = TMODES rf.valid_duplexes = DUPLEXES rf.valid_tuning_steps = TUNING_STEPS rf.valid_power_levels = POWER_LEVELS rf.valid_skips = SKIPS rf.valid_name_length = 5 rf.valid_special_chans = sorted(SPECIAL.keys()) rf.valid_bands = [(136000000, 174000000)] rf.has_ctone = True rf.has_offset = True rf.has_bank = False rf.has_settings = True return rf def __init__(self, pipe): icf.IcomCloneModeRadio.__init__(self, pipe) def sync_in(self): icf.IcomCloneModeRadio.sync_in(self) def sync_out(self): icf.IcomCloneModeRadio.sync_out(self) def process_mmap(self): self._memobj = bitwise.parse(ICV86_MEM_FORMAT, self._mmap) def get_settings(self): _settings = self._memobj.settings setmode = RadioSettingGroup("setmode", "General Settings") settings = RadioSettings(setmode) # LCD Backlight opts = ["Off", "On", "Auto"] setmode.append( RadioSetting( "lcd", "LCD Backlight", RadioSettingValueList(opts, opts[_settings.lcd]))) # Mic Gain rs = RadioSetting("mic", "Mic Gain", RadioSettingValueInteger(1, 4, _settings.mic + 1)) def apply_mic(s, obj): setattr(obj, s.get_name(), int(s.value) - 1) rs.set_apply_callback(apply_mic, self._memobj.settings) setmode.append(rs) # Dial Assignment opts = ["Volume", "Tuning"] setmode.append( RadioSetting( "dial_assignment", "Dial Assignment", RadioSettingValueList(opts, opts[_settings.dial_assignment]))) # Display Type opts = ["Frequency", "Channel", "Name"] setmode.append( RadioSetting( "disp_type", "Display Type", RadioSettingValueList(opts, opts[_settings.disp_type]))) return settings def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: setting = element.get_name() LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(_settings, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _get_memory(self, number): bit = 1 << (number % 8) byte = int(number / 8) mem = chirp_common.Memory() mem.number = number _mem = self._memobj.memory[number] if number < 200: _usd = self._memobj.used[byte] _skp = self._memobj.skips[byte] else: mem.extd_number = SPECIAL_REV[number] mem.immutable = ["name", "number", "extd_number", "skip"] _usd = self._memobj.used[byte] if (number <= 206) else None _skp = None if _usd is not None and (_usd & bit): mem.empty = True return mem mem.freq = _mem.freq mem.offset = int(_mem.offset) if number < 200: mem.name = str(_mem.name).rstrip() mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.tuning_step = TUNING_STEPS[_mem.tuning_step] mem.mode = MODES[_mem.mode] mem.duplex = DUPLEXES[_mem.duplex] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.tmode = TMODES[_mem.tmode] mem.power = POWER_LEVELS[_mem.power] # Extras mem.extra = RadioSettingGroup("extra", "Extra") rev = RadioSetting("rev", "Reverse duplex", RadioSettingValueBoolean(bool(_mem.rev))) rev.set_doc("Reverse duplex") mem.extra.append(rev) tx = RadioSetting("tx", "Tx permission", RadioSettingValueBoolean(bool(_mem.tx))) tx.set_doc("Tx permission") mem.extra.append(tx) if _skp is not None: mem.skip = (_skp & bit) and "S" or "" return mem def get_memory(self, number): if not self._mmap: self.sync_in() assert (self._mmap) if isinstance(number, str): try: number = SPECIAL[number] except KeyError: raise errors.InvalidMemoryLocation("Unknown channel %s" % number) return self._get_memory(number) def _fill_memory(self, number): _mem = self._memobj.memory[number] assert (_mem) # zero-fill _mem.freq = 146010000 _mem.offset = 146010000 _mem.name = str("").ljust(5) _mem.reserved1 = 0x0 _mem.rtone = 0x8 _mem.reserved2 = 0x0 _mem.ctone = 0x8 _mem.reserved3 = 0x0 _mem.dtcs = 0x0 _mem.reserved4 = 0x0 _mem.tuning_step = 0x0 _mem.reserved5 = 0x0 _mem.mode = 0x0 _mem.rev = 0x0 _mem.duplex = 0x0 _mem.reserved6 = 0x0 _mem.reserved7 = 0x0 _mem.dtcs_polarity = 0x0 _mem.tmode = 0x0 _mem.tx = 0x1 _mem.reserved8 = 0x0 _mem.power = 0x0 _mem.reserved9 = 0x0 _mem.reserved10 = 0x0 _mem.reserved11 = 0x0 _mem.reserved12 = 0x0 def _set_memory(self, mem): bit = 1 << (mem.number % 8) byte = int(mem.number / 8) _mem = self._memobj.memory[mem.number] _usd = self._memobj.used[byte] if mem.number <= 206 else None _skp = self._memobj.skips[byte] if mem.number < 200 else None assert (_mem) if mem.empty: self._fill_memory(mem.number) if _usd is not None: _usd |= bit return if _usd is None or (_usd & bit): self._fill_memory(mem.number) _mem.freq = mem.freq _mem.offset = int(mem.offset) _mem.name = str(mem.name).ljust(5) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tuning_step = TUNING_STEPS.index(mem.tuning_step) _mem.mode = MODES.index(mem.mode) _mem.duplex = DUPLEXES.index(mem.duplex) _mem.dtcs_polarity = DTCS_POLARITY.index(mem.dtcs_polarity) _mem.tmode = TMODES.index(mem.tmode) _mem.power = 0 if mem.power is None else POWER_LEVELS.index(mem.power) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) if _usd is not None: _usd &= ~bit if _skp is not None: if mem.skip == "S": _skp |= bit else: _skp &= ~bit def set_memory(self, mem): if not self._mmap: self.sync_in() assert (self._mmap) return self._set_memory(mem) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) + \ repr(self._memobj.used[(number)]) chirp-20240224/chirp/drivers/generic_tpe.py0000644000175000017500000000401714430171343017457 0ustar hibbyhibby# Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, directory from chirp.drivers import generic_csv @directory.register class TpeRadio(generic_csv.CSVRadio): """Generic ARRL Travel Plus""" VENDOR = "ARRL" MODEL = "Travel Plus" FILE_EXTENSION = "tpe" FORMATS = [directory.register_format('ARRL TPE', '*.tpe')] ATTR_MAP = { "Sequence Number": (int, "number"), "Location": (str, "comment"), "Call Sign": (str, "name"), "Output Frequency": (chirp_common.parse_freq, "freq"), "Input Frequency": (str, "duplex"), "CTCSS Tones": (lambda v: float(v) if v and float(v) in chirp_common.TONES else 88.5, "rtone"), "Repeater Notes": (str, "comment"), } def _clean_tmode(self, headers, line, mem): try: val = generic_csv.get_datum_by_header(headers, line, "CTCSS Tones") if val and float(val) in chirp_common.TONES: mem.tmode = "Tone" except generic_csv.OmittedHeaderError: pass return mem def _clean_ctone(self, headers, line, mem): # TPE only stores a single tone value mem.ctone = mem.rtone return mem @classmethod def match_model(cls, filedata, filename): return filename.lower().endswith("." + cls.FILE_EXTENSION) chirp-20240224/chirp/drivers/ft2800.py0000644000175000017500000002440514522657251016132 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging from chirp import util, memmap, chirp_common, bitwise, directory, errors from chirp.drivers.yaesu_clone import YaesuCloneModeRadio LOG = logging.getLogger(__name__) CHUNK_SIZE = 16 def _send(s, data): for i in range(0, len(data), CHUNK_SIZE): chunk = data[i:i+CHUNK_SIZE] s.write(chunk) echo = s.read(len(chunk)) if chunk != echo: raise Exception("Failed to read echo chunk") # The IDBLOCK is the first thing sent during an upload or download # and indicates the radio subtype: # USA Unmodified: b"\x0c\x01\x41\x33\x35\x02\x00\xb8" # USA With extended TX mod: b"\x0c\x01\x41\x33\x35\x03\x00\xb9" SUPPORTED_IDBLOCKS = [b"\x0c\x01\x41\x33\x35\x02\x00\xb8", b"\x0c\x01\x41\x33\x35\x03\x00\xb9"] TRAILER = b"\x0c\x02\x41\x33\x35\x00\x00\xb7" ACK = b"\x0C\x06\x00" def _download(radio): data = b"" attempts = 30 for _i in range(0, attempts): data = radio.pipe.read(8) if data in SUPPORTED_IDBLOCKS: radio.subtype = data break LOG.debug('Download attempt %i received %i: %s', _i, len(data), util.hexprint(data)) if radio.status_fn: status = chirp_common.Status() status.max = 1 status.cur = 0 status.msg = "Waiting for radio (%i)" % ( attempts - (_i + 1)) radio.status_fn(status) LOG.debug("Header:\n%s" % util.hexprint(data)) if len(data) != 8: raise Exception("Failed to read header") _send(radio.pipe, ACK) data = b"" while len(data) < radio._block_sizes[1]: time.sleep(0.1) chunk = radio.pipe.read(38) LOG.debug("Got: %i:\n%s" % (len(chunk), util.hexprint(chunk))) if len(chunk) == 8: LOG.debug("END?") elif len(chunk) != 38: LOG.debug("Should fail?") break # raise Exception("Failed to get full data block") else: cs = 0 for byte in chunk[:-1]: cs += byte if chunk[-1] != (cs & 0xFF): raise Exception("Block failed checksum!") data += chunk[5:-1] _send(radio.pipe, ACK) if radio.status_fn: status = chirp_common.Status() status.max = radio._block_sizes[1] status.cur = len(data) status.msg = "Cloning from radio" radio.status_fn(status) LOG.debug("Total: %i" % len(data)) return memmap.MemoryMapBytes(data) def _upload(radio): for _i in range(0, 10): data = radio.pipe.read(256) if not data: break LOG.debug("What is this garbage?\n%s" % util.hexprint(data)) _send(radio.pipe, radio.subtype) time.sleep(1) ack = radio.pipe.read(300) LOG.debug("Ack was (%i):\n%s" % (len(ack), util.hexprint(ack))) if ack != ACK: raise Exception("Radio did not ack ID") block = 0 while block < (radio.get_memsize() // 32): data = b"\x0C\x03\x00\x00" + bytes([block]) data += radio.get_mmap()[block*32:(block+1)*32] cs = 0 for byte in data: cs += byte data += bytes([cs & 0xFF]) LOG.debug("Writing block %i:\n%s" % (block, util.hexprint(data))) _send(radio.pipe, data) time.sleep(0.1) ack = radio.pipe.read(3) if ack != ACK: raise Exception("Radio did not ack block %i" % block) if radio.status_fn: status = chirp_common.Status() status.max = radio._block_sizes[1] status.cur = block * 32 status.msg = "Cloning to radio" radio.status_fn(status) block += 1 _send(radio.pipe, TRAILER) MEM_FORMAT = """ struct { bbcd freq[4]; u8 unknown1[4]; bbcd offset[2]; u8 unknown2[2]; u8 pskip:1, skip:1, unknown3:1, isnarrow:1, power:2, duplex:2; u8 unknown4:6, tmode:2; u8 tone; u8 dtcs; } memory[200]; #seekto 0x0E00; struct { char name[6]; } names[200]; """ MODES = ["FM", "NFM"] TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+", ""] POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=65), chirp_common.PowerLevel("Mid", watts=25), chirp_common.PowerLevel("Low2", watts=10), chirp_common.PowerLevel("Low1", watts=5), ] CHARSET = chirp_common.CHARSET_UPPER_NUMERIC + "()+-=*/???|_" @directory.register class FT2800Radio(YaesuCloneModeRadio): """Yaesu FT-2800""" VENDOR = "Yaesu" MODEL = "FT-2800M" _block_sizes = [8, 7680] _memsize = 7680 @property def subtype(self): # If our image is from before the subtype was stashed, assume # the default unmodified US ID block return bytes(self.metadata.get('subtype_idblock', SUPPORTED_IDBLOCKS[0])) @subtype.setter def subtype(self, value): self.metadata = {'subtype_idblock': [x for x in value]} @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable\n" "3. Press and hold in the MHz, Low, and D/MR keys on the radio " "while turning it on\n" "4. Radio is in clone mode when TX/RX is flashing\n" "5. After clicking OK, " "press the MHz key on the radio to send" " image.\n" " (\"TX\" will appear on the LCD). \n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable\n" "3. Press and hold in the MHz, Low, and D/MR keys on the radio " "while turning it on\n" "4. Radio is in clone mode when TX/RX is flashing\n" "5. Press the Low key on the radio " "(\"RX\" will appear on the LCD).\n" "6. Click OK.") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.has_ctone = False rf.has_tuning_step = False rf.has_dtcs_polarity = False rf.has_bank = False rf.valid_tuning_steps = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] rf.valid_modes = MODES rf.valid_tmodes = TMODES rf.valid_bands = [(137000000, 174000000)] rf.valid_power_levels = POWER_LEVELS rf.valid_duplexes = DUPLEX rf.valid_skips = ["", "S", "P"] rf.valid_name_length = 6 rf.valid_characters = CHARSET return rf def sync_in(self): self.pipe.parity = "E" self.pipe.timeout = 1 start = time.time() try: self._mmap = _download(self) except errors.RadioError: raise except Exception as e: LOG.exception('Failed download') raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Downloaded in %.2f sec" % (time.time() - start)) self.process_mmap() def sync_out(self): self.pipe.timeout = 1 self.pipe.parity = "E" start = time.time() try: _upload(self) except errors.RadioError: raise except Exception as e: LOG.exception('Failed upload') raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Uploaded in %.2f sec" % (time.time() - start)) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xFF": mem.empty = True return mem mem.freq = int(_mem.freq) * 10 mem.offset = int(_mem.offset) * 100000 mem.duplex = DUPLEX[_mem.duplex] mem.tmode = TMODES[_mem.tmode] mem.rtone = chirp_common.TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.name = str(_nam.name).rstrip() mem.mode = _mem.isnarrow and "NFM" or "FM" mem.skip = _mem.pskip and "P" or _mem.skip and "S" or "" mem.power = POWER_LEVELS[_mem.power] return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _nam = self._memobj.names[mem.number] if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) return if _mem.get_raw(asbytes=False)[0] == "\xFF": # Empty -> Non-empty, so initialize _mem.set_raw("\x00" * (_mem.size() // 8)) # initializing unknowns _mem.unknown1 = (0xFF, 0xFF, 0xFF, 0xFF) _mem.unknown2 = (0x00, 0x00) _mem.unknown3 = 0x01 _mem.unknown4 = 0x3C _mem.freq = mem.freq / 10 _mem.offset = mem.offset / 100000 _mem.duplex = DUPLEX.index(mem.duplex) _mem.tmode = TMODES.index(mem.tmode) _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.isnarrow = MODES.index(mem.mode) _mem.pskip = mem.skip == "P" _mem.skip = mem.skip == "S" if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 _nam.name = mem.name.ljust(6)[:6] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize chirp-20240224/chirp/drivers/anytone_iii.py0000644000175000017500000022436414566340166017526 0ustar hibbyhibby# Copyright 2020 Brad Schuler K0BAS # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging import string from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp import errors from chirp import memmap from chirp import util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettingValueFloat, RadioSettings class ATBankModel(chirp_common.BankModel): """AnyTone Banks A-J, Each chan in zero or one bank""" def __init__(self, radio, name='Banks'): super(ATBankModel, self).__init__(radio, name) self._banks = [] self._memBounds = list(range(0, 750)) for i in range(0, 10): self._banks.append( chirp_common.Bank(self, i, string.ascii_uppercase[i])) def get_num_mappings(self): return len(self._banks) def get_mappings(self): return self._banks def add_memory_to_mapping(self, memory, bank): self._radio.set_bank(memory.number, bank.get_index()) def remove_memory_from_mapping(self, memory, mapping): # I would argue that removing a memory from a mapping in which it does # not exist should not throw an error. The end result is the # requested result. The memory is not in the mapping. index = self._radio.get_bank(memory.number) if (index is None or index != mapping.get_index()): raise Exception("Memory %d is not in bank %s" % (memory.number, bank.get_name())) self._radio.clr_bank(memory.number) def get_mapping_memories(self, bank): memories = [] for i in self._memBounds: bank_index = self._radio.get_bank(i) if (bank_index is not None and bank_index == bank.get_index()): memories.append(self._radio.get_memory(i)) return memories def get_memory_mappings(self, memory): bank_index = self._radio.get_bank(memory.number) if bank_index is None: return [] else: return [self._banks[bank_index]] LOG = logging.getLogger(__name__) # TODO: Reverse engineer scramble codes # Examples: 1=x0300 1111=xDA0B 3300=x3323 3400=x4524 # TODO: Reverse engineer derived-value for 2Tone frequencies # Below are some samples: # freq tone derived # 0000 0000 # 288.0 0b40 0823 208.3 # 321.7 0c91 0749 186.5 # 526.8 1494 2397 911.1 # 526.9 1495 2395 910.9 # 712.3 1bd3 1a52 673.8 # 928.1 2441 0286 64.6 # 1527.3 3ba9 0c46 314.2 # 1934.7 4b93 09b1 248.1 # 3116.0 79b8 000c 1.2 mem_format_thruflags = """ struct flag { // Flags about a channel u8 left_only:1, // Channel is 1.25m or AM (meaning left side only) unused:1, // Unused flag scan:2, // chirp_common.SKIP_VALUES group:4; // [A-J, Off] }; #seekto 0x0020; // Read Only struct { u8 unknown1[16]; u8 unknown2[16]; char modellike[14]; u8 unknown3[2]; char serial[16]; u8 zeros16[16]; char date[16]; u8 zeros128[128]; } oem_info; struct flag chan_flags[750]; // Channel flags struct flag limit_flags[10]; // Limit channel flags //u8 effs8[8]; """ mem_format = mem_format_thruflags + """ struct memory { bbcd freq[5]; // rx freq bbcd offset[3]; // tx offset from rx / 100 u8 unknown1:4, tune_step:4; // [2.5k, 5k, 6.25k, 8.33k, 10k, // 12.5k, 15k, 20k, 25k, 30k] u8 rxdcsextra:1, // use with rxcode for index of rx DCS to use txdcsextra:1, // use with txcode for index of tx DCS to use rxdcsinv:1, // inverse DCS rx polarity txdcsinv:1, // inverse DCS tx polarity channel_width:2, // [25 kHz, 20 kHz, 12.5 kHz] rev:1, // reverse the tx and rx frequencies & tones txoff:1; // prevent tx u8 talkaround:1, // Use the rx freq & tone when transmitting compander:1, unknown2:1, is_am:1, // modulation is AM power:2, // [High, Mid1, Mid2, Low] duplex:2; // ['', -, +, off] u8 dtmf_enc_num:4, // zero-based DTMF slot to use for optional // signalling (when optsig = DTMF) rxtmode:2, // ['', Tone, DTCS] txtmode:2; // ['', Tone, DTCS] u8 unknown3:2, txtone:6; // TONES[0..50] & 51=custom u8 unknown4:2, rxtone:6; // TONES[0..50] & 51=custom u8 txcode; // use with txdcsextra for index of tx DCS to use u8 rxcode; // use with rxdcsextra for index of rx DCS to use u8 unknown5:2, pttid:2, // [Off, Begin, End, Begin&End] unknown6:2, bclo:2; // [Off, Repeater, Busy] u8 unknown7:6, band:2; // [2m, 1-1/4m, 350+ MHz, 70cm] u8 unknown8:5, sql_mode:3; // [Carrier, CTCSS/DCS Tones, Opt Sig Only, // Tones & Opt Sig, Tones or Opt Sig] // Implemented in GUI as a combination of rxmode // and opt sig squelch list OPT_SIG_SQL u8 unknown9:6, optsig:2; // [Off, DTMF, 2Tone, 5Tone] u8 unknown10:3, twotone:5; // zero-based 2-tone slot to use for optional // signalling (when optsig = 2Tone) u8 unknown11:1, fivetone:7; // zero-based 5-tone slot to use for optional // signalling (when optsig = 5Tone) u8 unknown12:4, scramble:4; // [Off, 1 ... 9, Define 1, Define 2] char name[7]; ul16 custtone; // custom ctcss tone (%5.1f) * 10 }; struct DTMF12p3 { u8 dtmf[12]; // Each nibble is a DTMF code [0-9A-D*#] u8 num_tones; // Quantity of nibbles/digits in above u8 unknown3[3]; }; struct DTMF7 { u8 dtmf[7]; // Each nibble is a DTMF code [0-9A-D*#] u8 num_tones; // Quantity of nibbles/digits in above }; #seekto 0x0400; // DTMF slots struct DTMF12p3 dtmf_encodings[16]; //#seekto 0x0500; //u8 unknown[64]; #seekto 0x0540; // Hyper channels (12 x 2) struct memory hyper_channels[24]; struct { u8 unknown1:6, display:2; // Display Mode: [freq, chan, name] u8 unknown2:3, sql_left:5; // Left Squelch Level: 1..20 u8 unknown3:3, sql_right:5; // Right Squelch Level: 1..20 u8 unknown4; u8 unknown5:6, scan_tot:2; // Scan Pause Time: [TO, CO, SE] u8 unknown6:7, scan_mode:1; // Scan Mode: [MEM, MSM(Pri Scan)] u8 bg_red; // Background color red intensity // 0-x1f displayed as 1-32d u8 bg_green; // Background color green intensity u8 bg_blue; // Background color blue intensity u8 unknown7:5, tbst_freq:3; // TBST Freq [Off, 1750, 2100, 1000, 1450] Hz u8 unknown8:3, ptt_tot:5; // Talk Timeout Timer: [Off, 1..30] minutes u8 unknown9:6, ptt_lockout:2; // PTT Key Lock: [Off, Right, Left, Both] u8 unknown10:3, apo:5; // Auto Power Off: [Off, 1..18] * 30 minutes u8 unknown11:3, key_bright:5; // Key Light Level: [00-1e] := [1-32] u8 long_key_time; // Long Key Time: # seconds * 100, // so 100 := 1.0 sec, 250 := 2.5 sec u8 unknown12:6, deputy_mute:2; // Mute the Deputy channel (sub band) when // primary is doing this: [Off, Tx, Rx, Tx & Rx] //#seekto 0x0850; u8 disp_chan_lock:1, // Display Channel Lock when display=1(Chan) unknown13:1, keypad_lock:1, // Lock the keypad beep_hi:1, // 0=low 1=high volume no_init:1, // Prohibit initialization: 0=no 1=yes unknown14:3; u8 unknown15:2, clk_shift:1, // CLK Shift: 0=off 1=on ext_spk_on:1, // Enable the external speaker alt_key_mode:1, // Use Alt Keypad Mode: 0=off 1=on beep_on:1, // Enable beep no_tone_elim_tail:1, // Elim squelch tail when no CTCSS/DCS signaling sql_key_mode:1; // SQL Key Function: [Momentary, Toggle] u8 unknown16:5, dtmf_preload_time:3; // DTMF encode preload time: // [100, 300, 500, 800, 1000] ms u8 unknown17:5, dtmf_speed:3; // DTMF transmit time/speed: // [30, 50, 80, 100, 150, 200, 250] ms u8 unknown19:6, tail_elim_type:2; // Tail Eliminator Type: [Off, 120, 180] degrees u8 unknown20:3, key_a_func:5; // Programmable key A function [0-19]: // [Off, DUP, ... Bandwidth, Talk Around] u8 unknown21:3, key_b_func:5; // Programmable key B function u8 unknown22:3, key_c_func:5; // Programmable key C function u8 unknown23:3, key_d_func:5; // Programmable key D function u8 unknown24:7, boot_pw_on:1; // Use boot password (verify password is set!) u8 unknown25:5, rfsql_left:3; // Left RF Squelch Level: // [Off, S-2, S-5, S-9, FULL] u8 unknown26:5, rfsql_right:3; // Right RF Squelch Level u8 scramble1[2]; // Scramble code #1 (unknown encoding) u8 scramble2[2]; // Scramble code #2 (unknown encoding) //#seekto 0x0860 & 0x0880 struct { u8 unknown1; u8 unknown2:6, left_mode:2; // [VFO, Channel, Home] u8 unknown3:6, right_mode:2; // [VFO, Channel, Home] u8 unknown4:6, sub_display:2; // [Freq, DC IN, Off] ul16 left_channel; // Zero-based chan number ul16 right_channel; // Zero-based chan number u8 unknown5; u8 unknown6:6, spkr_mode:2; // Hand/Main [Off/On, On/On, On/Off] u8 unknown7:6, left_vfo_band:2; // [108, 220, 350, 400] MHz u8 unknown8:7, right_vfo_band:1; // [136, 400] MHz u8 unknown9; u8 unknown10:1, vfo_tracked:1, auto_hyper_save:1, auto_rpt_shift:1, auto_am:1, main:1, // [Left, Right] vfo_band_edge:1, unknown11:1; u8 unknown12; u8 unknown13; //#seekto 0x0870 & 0x0890 u8 unknown14:4, left_work_bank:4; // [A - J, Off] u8 unknown15:7, left_bank_mode:1; // [CH, Bank] u8 unknown16:7, left_bank_sw:1; // [Off, On] u8 unknown17:4, right_work_bank:4; // [A - J, Off] u8 unknown18:7, right_bank_mode:1; // [CH, Bank] u8 unknown19:7, right_bank_sw:1; // [Off, On] // This would be better than below: // struct { u8 unknown:7, linked:1; } linkedBanks[10]; // They would need to be in a sub-group of settings in the extras. // A-J (one byte each) 00 or 01 u8 unknown20:7, link_bank_A:1; u8 unknown21:7, link_bank_B:1; u8 unknown22:7, link_bank_C:1; u8 unknown23:7, link_bank_D:1; u8 unknown24:7, link_bank_E:1; u8 unknown25:7, link_bank_F:1; u8 unknown26:7, link_bank_G:1; u8 unknown27:7, link_bank_H:1; u8 unknown28:7, link_bank_I:1; u8 unknown29:7, link_bank_J:1; } hyper_settings[2]; //#seekto 0x08a0; char boot_password[7]; // Boot password u8 unknown30[9]; //#seekto 0x08b0; u8 unknown31[16]; //#seekto 0x08c0; u8 unknown32:4, dtmf_interval_char:4; // DTMF interval character u8 dtmf_group_code; // DTMF Group Code: 0a-0f,ff displayed as A-#,Off u8 unknown33:6, dtmf_dec_resp:2; // DTMF Decoding Response: // [None, Beep, Beep & Respond] u8 unknown34; u8 dtmf_first_dig_time; // DTMF First digit time: 0..250 * 10 ms u8 dtmf_auto_rst_time; // DTMF auto reset time: 0..250 // displayed as 0.0-25.0 in 0.1 increments sec u8 unknown35; u8 dtmf_self_id[3]; // DTMF Self ID: low nibble of each byte is a // DTMF char, exactly 3 chars u8 unknown36; u8 unknown37; u8 unknown38; u8 unknown39:7, dtmf_sidetone_on:1; // DTMF side tone enabled u8 dtmf_enc_delay; // DTMF encode delay: 1..250 * 10 ms u8 dtmf_pttid_delay; // DTMF PTT ID delay: 0,5-75 // shown as [Off,5-75] sec //#seekto 0x08d0; struct DTMF7 dtmf_kill; // DTMF to remotely kill struct DTMF7 dtmf_stun; // DTMF to remotely stun } settings; //#seekto 0x08e0; // 2 Tone settings - for future work //struct { // ul16 calltone1; // Call format 1st tone freq * 10 // ul16 calltone2; // Call format 2nd tone freq * 10 // // (or 00 00 for long tone version of 1st tone) // ul16 calltone1derived; // some derived freq? calculated from 1st tone // ul16 calltone2derived; // some derived freq? calculated from 2nd tone // u8 unknown1:6, // decode_resp:2; // Decode response [None, Beep, Beep & Respond] // u8 tone1_dur; // 1st tone duration * 10 // // shown as range(0.5, 10, 0.1) seconds // u8 tone2_dur; // 2nd tone duration * 10 // // shown as range(0.5, 10, 0.1) seconds // u8 longtone_dur; // Long tone duration * 10 // // shown as range(0.5, 10, 0.1) seconds // u8 gap_time; // Gap time / 100 // // shown as range(0, 2000, 100) msec // u8 auto_rst_time; // Auto reset time * 10 // // shown as range(0, 25, 0.1) sec // u8 unknown:7, // enc_sidetone; // Encode side-tone 0=off 1=on // u8 unknown2:4, // call_format:4; // Call format [A-B, A-C, A-D, B-A, B-C, B-D, // // C-A, C-B, C-D, D-A, D-B, D-C, // // Long A, Long B, Long C] // // Be sure to change callTone1/2 and // // callTone1/2derived when callFormat is changed // //#seekto 0x08f0; // u16 a_tone; // A tone freq * 10 // u16 b_tone; // B tone freq * 10 // u16 c_tone; // C tone freq * 10 // u16 d_tone; // D tone freq * 10 // u8 zeros[8]; //} twotone_settings; //#seekto 0x0900; // Unknown all 0x00 //u8 zeros[512]; //#seekto 0x0b00; // 2 Tone memories (24 slots of 16 bytes) //struct { // ul16 tone1derived; // some derived freq? calculated from 1st tone // ul16 tone2derived; // some derived freq? calculated from 2nd tone // ul16 tone1; // 1st tone freq * 10 // ul16 tone2; // 2nd tone freq * 10 // char name[7]; // Tone name (padded) // u8 zero; //} twotone_slots[24]; //#seekto 0x0c80; // Unknown all 0x24 //u8 twentyfours[128]; //#seekto 0x0d00; // 5 Tone configs (100 slots of 32 bytes) //u8 fivetones[3200]; #seekto 0x1980; // Communication notes struct { char call_id[5]; // Call ID (numeric, max 5 digits (x30-x39) u8 zeros[3]; // 0x00 * 3 } note_call_ids[100]; struct { char name[7]; // Names (ALPHAnumeric max 7 chars) char space; // 0x20 } note_names[100]; //#seekto 0x1fc0; // Unknown all 0x00 //u8 zeros[64]; #seekto 0x2000; struct memory channels[750]; // Normal channels (750 * 32 bytes) //#seekto 0x7dc0; struct memory limit_channels[10]; // Limit channels // (10 * 32 bytes: Five pair of lo/hi) //#seekto 0x7f00; // Unknown //u8 unknown[32]; #seekto 0x7f20; struct DTMF12p3 dtmf_pttid_bot; // DTMF PTT ID Start (BOT) struct DTMF12p3 dtmf_pttid_eot; // DTMF PTT ID End (EOT) //#seekto 0x7f40; //u8 unknown[64] #seekto 0x7f80; // Emergency Information struct { u8 unknown:6, mode:2; // [Alarm, Transpond+Background, // Transpond+Alarm, Both] u8 unknown2:6, eni_type:2; // [None, DTMF, 5Tone] u8 id; // When DTMF: [M1-M16], When 5Tone: 0-99 u8 alarm_time; // [1-255] seconds u8 tx_time; // [0-255] seconds u8 rx_time; // [0-255] seconds u8 unknown3:7, chan_select:1; // [Assigned, Selected] ul16 channel; // [0-749] u8 cycle; // [Continuous, 1-255] } emergency; u8 unknown9[6]; //#seekto 0x7f90; // Unknown //u8 unknown[48] #seekto 0x7fc0; // Welcome message char welcome[7]; //u8 zeros[9]; //#seekto 0x7fd0; //u8 unknown[48]; """ def _is_chan_used(memobj, num): return not memobj.chan_flags[num].unused def _is_limit_chan_used(memobj, num): return not memobj.limit_flags[num].unused def _should_send_addr(memobj, addr): # Skip read-only & out of bounds if addr < 0x0100 or addr >= 0x8000: return False # Skip regions of unknown or uncontrolled by this software if ((addr >= 0x0500 and addr < 0x0540) or (addr >= 0x08e0 and addr < 0x1980) or (addr >= 0x1fc0 and addr < 0x2000) or (addr >= 0x7f00 and addr < 0x7f20) or (addr >= 0x7f40 and addr < 0x7f80) or (addr >= 0x7f90 and addr < 0x7fc0) or addr >= 0x7fd0): return False # Skip unused memories if addr >= 0x2000 and addr < 0x7dc0: return _is_chan_used(memobj, int((addr - 0x2000) / 0x20)) if addr >= 0x7dc0 and addr < 0x7f00: return _is_limit_chan_used(memobj, int((addr - 0x7dc0) / 0x20)) return True def _echo_write(radio, data): try: radio.pipe.write(data) radio.pipe.read(len(data)) except Exception as e: LOG.error("Error writing to radio: %s" % e) raise errors.RadioError("Unable to write to radio") def _read(radio, length): try: data = radio.pipe.read(length) except Exception as e: LOG.error("Error reading from radio: %s" % e) raise errors.RadioError("Unable to read from radio") if len(data) != length: LOG.error("Short read from radio (%i, expected %i)" % (len(data), length)) LOG.debug(util.hexprint(data)) raise errors.RadioError("Short read from radio") return data valid_model = [b'I588UVP'] def _ident(radio): radio.pipe.timeout = 1 _echo_write(radio, b"PROGRAM") response = radio.pipe.read(3) if response != b"QX\x06": LOG.debug("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Unsupported model") _echo_write(radio, b"\x02") response = radio.pipe.read(16) LOG.debug(util.hexprint(response)) if response[-1:] != b"\x06": LOG.debug("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Missing ack") if response[0:7] not in valid_model: LOG.debug("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Unsupported model") # Manufacturer software does this also: _send(radio, b'R', 0x0080, 0x10) def _finish(radio): endframe = b"\x45\x4E\x44" _echo_write(radio, endframe) result = radio.pipe.read(1) if result != b"\x06": LOG.debug("Got:\n%s" % util.hexprint(result)) raise errors.RadioError("Radio did not finish cleanly") def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def _send(radio, cmd, addr, length, data=None): frame = struct.pack(">cHb", cmd, addr, length) if data: frame += data frame += bytes([_checksum(frame[1:])]) frame += b"\x06" _echo_write(radio, frame) LOG.debug("Sent:\n%s" % util.hexprint(frame)) if data: result = radio.pipe.read(1) if result != b"\x06": LOG.debug("Ack was: %s" % util.hexprint(result)) raise errors.RadioError( "Radio did not accept block at %04x" % addr) return result = _read(radio, length + 6) LOG.debug("Got:\n%s" % util.hexprint(result)) header = result[0:4] data = result[4:-2] ack = result[-1:] if ack != b"\x06": LOG.debug("Ack was: %s" % repr(ack)) raise errors.RadioError("Radio NAK'd block at %04x" % addr) _cmd, _addr, _length = struct.unpack(">cHb", header) if _addr != addr or _length != _length: LOG.debug("Expected/Received:") LOG.debug(" Length: %02x/%02x" % (length, _length)) LOG.debug(" Addr: %04x/%04x" % (addr, _addr)) raise errors.RadioError("Radio send unexpected block") cs = _checksum(result[1:-2]) if cs != result[-2]: LOG.debug("Calculated: %02x" % cs) LOG.debug("Actual: %02x" % result[-2]) raise errors.RadioError("Block at 0x%04x failed checksum" % addr) return data def _download(radio): _ident(radio) memobj = None data = b"" for start, end in radio._ranges: for addr in range(start, end, 0x10): if memobj is not None and not _should_send_addr(memobj, addr): block = b"\x00" * 0x10 else: block = _send(radio, b'R', addr, 0x10) data += block status = chirp_common.Status() status.cur = len(data) status.max = end status.msg = "Cloning from radio" radio.status_fn(status) if addr == 0x0400 - 0x10: memobj = bitwise.parse(mem_format_thruflags, data) _finish(radio) return memmap.MemoryMapBytes(data) def _upload(radio): _ident(radio) for start, end in radio._ranges: for addr in range(start, end, 0x10): if not _should_send_addr(radio._memobj, addr): continue block = radio._mmap[addr:addr + 0x10] _send(radio, b'W', addr, len(block), block) status = chirp_common.Status() status.cur = addr status.max = end status.msg = "Cloning to radio" radio.status_fn(status) _finish(radio) def _filter(s, charset): rc = "" for i in range(0, len(s)): c = str(s[i]) rc += (c if c in charset else "") return rc SEVEN_SPACES = " " APO = ['Off'] + ['%.1f hour(s)' % (0.5 * x) for x in range(1, 25)] ONEANDQTRBAND = (220000000, 260000000) LEFT_BANDS = [ (108000000, 180000000), # L-108 ONEANDQTRBAND, # L-220 (350000000, 399995000), # L-350 (400000000, 523000000) # L/R-400 ] RIGHT_BANDS = [ (136000000, 174000000), # R-136 (400000000, 523000000) # L/R-400 ] BCLO = ['Off', 'Repeater', 'Busy'] BEEP_VOL = ['Low', 'High'] CROSS_MODES = list(chirp_common.CROSS_MODES) CROSS_MODES.remove("Tone->") DISPLAY = ['Freq', 'Chan#', 'Name'] DTMF_SLOTS = ['M%d' % x for x in range(1, 17)] DUPLEXES = ['', '-', '+', 'off'] KEY_FUNCS = ['Off', 'DUP', 'PRI On', 'Power', 'Set DCS/CTCSS Code', 'MHz', 'Reverse', 'HM Chan', 'Main L/R Switch', 'VFO/MR', 'Scan', 'Squelch Off', 'Call TBST', 'Call', 'Tone Compande', 'Scramble', 'Add Opt Signal', 'Bandwidth', 'Talk Around'] MODES = ["WFM", "FM", "NFM"] OPT_SIGS = ['Off', 'DTMF', '2Tone', '5Tone'] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Mid1", watts=25), chirp_common.PowerLevel("Mid2", watts=10), chirp_common.PowerLevel("Low", watts=5)] PTT_IDS = ['Off', 'Begin', 'End', 'Begin & End'] RF_SQUELCHES = ['Off', 'S-2', 'S-5', 'S-9', 'FULL'] SCAN_PAUSES = ['TO', 'CO', 'SE'] SCAN_MODES = ['MEM', 'MSM (Pri Scan)'] SCRAMBLE_CODES = ['Off'] for x in range(1, 10): SCRAMBLE_CODES.append('%d' % x) SCRAMBLE_CODES += ['Define 1', 'Define 2'] T_MODES = ['', 'Tone', 'DTCS', ''] TONE2_SLOTS = ['%d' % x for x in range(0, 24)] TONE5_SLOTS = ['%d' % x for x in range(0, 100)] # Future: chirp_common should present TONES instead of hard-coded list TONES = (62.5,) + chirp_common.TONES TOT = ['Off'] + ['%s Minutes' % x for x in range(1, 31)] TUNING_STEPS = [2.5, 5, 6.25, 8.33, 10, 12.5, 15, 20, 25, 30] PTT_KEY_LOCKS = ["Off", "Right", "Left", "Both"] TBST_FREQS = ["Off", "1750 Hz", "2100 Hz", "1000 Hz", "1450 Hz"] LONG_KEY_TIMES = ["1 second", "1.5 seconds", "2 seconds", "2.5 seconds"] DEPUTY_CHAN_MUTES = ["Off", "Tx", "Rx", "Both"] SQL_BTN_MODES = ["Momentary", "Toggle"] SQL_MODES = ["Carrier", "CTCSS/DCS", "Opt Sig Only", "Tones AND Sig", "Tones OR Sig"] OPT_SIG_SQL = ["Off"] + SQL_MODES[2:] TAIL_ELIM_TYPES = ["Off", "120 degrees", "180 degrees"] LIMIT_NAMES = ["Limit %s %d" % (c, i + 1) for i in range(0, 5) for c in ('Lo', 'Hi')] HYPER_NAMES = ["Hyper-%s %s%s" % (h, x, y) for h in ('1', '2') for x in ('', 'H') for y in ('L-108', 'L-220', 'L-350', 'L-400', 'R-136', 'R-400')] HYPER_MODES = ['VFO', 'Channel', 'Home'] HYPER_SUB_DISPLAYS = ['Freq', 'DC IN', 'Off'] HYPER_SPKR_MODES = ['Mic off', 'Mic on', 'Main off'] HYPER_L_VFOS = ['108 MHz', '220 MHz', '350 MHz', '400 MHz'] HYPER_R_VFOS = ['136 MHz', '400 MHz'] HYPER_MAINS = ['Left', 'Right'] HYPER_BANK_MODES = ['CH', 'Bank'] EMER_MODES = ['Alarm', 'Transpond+Background', 'Transpond+Alarm', 'Both'] EMER_ENI_TYPES = ['None', 'DTMF', '5Tone'] EMER_CHAN_SEL = ['Assigned', 'Selected'] EMER_CYCLES = ['Continuous'] + ["%d seconds" % x for x in range(1, 256)] BANK_CHOICES = ["%s" % chr(x) for x in range(ord("A"), ord("J") + 1)] + ['Off'] DTMF_CHARS = "0123456789ABCD*#" DTMF_INTCHARS = "ABCD*#" DTMF_PRELOADS = ['100 ms', '300 ms', '500 ms', '800 ms', '1000 ms'] DTMF_SPEEDS = ['30 ms', '50 ms', '80 ms', '100 ms', '150 ms', '200 ms', '250 ms'] DTMF_GROUPS = list("ABCDEF") + ['Off'] DTMF_RESPONSES = ['None', 'Beep', 'Beep & Respond'] DTMF_PTTDELAYS = ['Off'] + ["%d seconds" % x for x in range(5, 76)] def _dtmf_encode(dtmf_str, numBytes): dtmf_bytes = [] if len(dtmf_str) != 0: _byte = 0x00 for i in range(1, len(dtmf_str)+1): if i % 2 == 0: _byte |= DTMF_CHARS.index(dtmf_str[i-1]) dtmf_bytes.append(_byte) _byte = 0x00 else: _byte = DTMF_CHARS.index(dtmf_str[i-1]) << 4 if len(dtmf_str) % 2 == 1: dtmf_bytes.append(_byte) while (len(dtmf_bytes) < numBytes): dtmf_bytes.append(0) return dtmf_bytes def _dtmf_decode(dtmf_bytes, num_tones): dtmf_str = "" x = 1 while (x <= num_tones): _byte = dtmf_bytes[(x-1)/2] dtmf_str += DTMF_CHARS[_byte >> 4] x += 1 if (x <= num_tones): dtmf_str += DTMF_CHARS[_byte & 0x0F] x += 1 return dtmf_str class _RadioSettingValueOffsetInt(RadioSettingValueInteger): """An integer setting whose real value is offset from displayed value""" def __init__(self, minval, maxval, current, step=1, offset=0): RadioSettingValueInteger.__init__(self, minval, maxval, current, step) self.offset = offset @directory.register class AnyTone5888UVIIIRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """AnyTone 5888UVIII""" VENDOR = "AnyTone" MODEL = "5888UVIII" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _file_ident = b"588UVP" _ranges = [ (0x0000, 0x8000) ] def get_bank_model(self): return ATBankModel(self) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("The Anytone 5888UVIII driver is currently " "experimental. There are no known issues with it, " "but you should proceed with caution. 2-tone, " "5-tone, and scramble settings are limited. ") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_rx_dtcs = True rf.has_bank = True rf.has_cross = True rf.has_settings = True rf.valid_modes = MODES + ['AM'] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = CROSS_MODES rf.valid_duplexes = DUPLEXES rf.valid_tuning_steps = TUNING_STEPS rf.valid_bands = LEFT_BANDS + RIGHT_BANDS rf.valid_skips = chirp_common.SKIP_VALUES rf.valid_power_levels = POWER_LEVELS rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-" rf.valid_name_length = 7 # Future: rf.valid_tones = TONES # Future: update memdetail.py to use rf.valid_dtcs_codes # Future: update memdetail.py to use rf.dtcs_polarity rf.valid_dtcs_codes = chirp_common.ALL_DTCS_CODES rf.memory_bounds = (1, 750) rf.valid_special_chans = LIMIT_NAMES + HYPER_NAMES return rf def sync_in(self): self._mmap = _download(self) self.process_mmap() def sync_out(self): _upload(self) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def _get_memobjs(self, number): if number <= len(self._memobj.channels): _mem = self._memobj.channels[number - 1] _flg = self._memobj.chan_flags[number - 1] elif (number <= len(self._memobj.channels) + len(self._memobj.limit_channels)): _mem = self._memobj.limit_channels[number - len(self._memobj.channels) - 1] _flg = self._memobj.limit_flags[number - len(self._memobj.channels) - 1] else: _mem = self._memobj.hyper_channels[ number - len(self._memobj.channels) - len(self._memobj.limit_channels) - 1] _flg = None return _mem, _flg def _get_dcs_index(self, _mem, which): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) return (int(extra) << 8) | int(base) def _set_dcs_index(self, _mem, which, index): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) base.set_value(index & 0xFF) extra.set_value(index >> 8) def get_raw_memory(self, number): _mem, _flg = self._get_memobjs(number) return repr(_mem) + repr(_flg) def set_bank(self, number, bank_index): _mem, _flg = self._get_memobjs(number) _flg.group = bank_index def clr_bank(self, number): _mem, _flg = self._get_memobjs(number) _flg.group = BANK_CHOICES.index('Off') def get_bank(self, number): _mem, _flg = self._get_memobjs(number) if (_flg.group < 0xa): return _flg.group return None def get_memory(self, number): mem = chirp_common.Memory() is_limit_chan = is_hyper_chan = False if isinstance(number, str): if number in LIMIT_NAMES: is_limit_chan = True mem.number = (len(self._memobj.channels) + LIMIT_NAMES.index(number) + 1) elif number in HYPER_NAMES: is_hyper_chan = True mem.number = (len(self._memobj.channels) + len(LIMIT_NAMES) + HYPER_NAMES.index(number) + 1) mem.extd_number = number elif number > (len(self._memobj.channels) + len(self._memobj.limit_channels)): is_hyper_chan = True mem.number = number mem.extd_number = HYPER_NAMES[number - len(self._memobj.channels) - len(self._memobj.limit_channels) - 1] elif number > len(self._memobj.channels): is_limit_chan = True mem.number = number mem.extd_number = LIMIT_NAMES[number - len(self._memobj.channels) - 1] else: mem.number = number _mem, _flg = self._get_memobjs(mem.number) if not is_hyper_chan and _flg.unused: mem.empty = True _mem.fill_raw(b"\x00") _mem.name = SEVEN_SPACES _flg.scan = 0 mem.freq = int(_mem.freq) mem.offset = int(_mem.offset) * 100 mem.name = (str(_mem.name).rstrip() if not is_limit_chan and not is_hyper_chan else SEVEN_SPACES) mem.duplex = DUPLEXES[_mem.duplex] mem.mode = _mem.is_am and "AM" or MODES[_mem.channel_width] mem.tuning_step = TUNING_STEPS[_mem.tune_step] if _mem.txoff: mem.duplex = DUPLEXES[3] rxtone = txtone = None rxmode = T_MODES[_mem.rxtmode] if _mem.sql_mode == 0 or _mem.sql_mode == 2: rxmode = T_MODES.index('') txmode = T_MODES[_mem.txtmode] if txmode == "Tone": # If custom tone is being used, show as 88.5 and set checkbox in # extras. # Future: Improve chirp_common, so I can add "CUSTOM" into TONES if _mem.txtone == len(TONES): txtone = 88.5 else: txtone = TONES[_mem.txtone] elif txmode == "DTCS": txtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem, 'tx')] if rxmode == "Tone": # If custom tone is being used, show as 88.5 and set checkbox in # extras. # Future: Improve chirp_common, so I can add "CUSTOM" into TONES if _mem.rxtone == len(TONES): rxtone = 88.5 else: rxtone = TONES[_mem.rxtone] elif rxmode == "DTCS": rxtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem, 'rx')] rxpol = _mem.rxdcsinv and "R" or "N" txpol = _mem.txdcsinv and "R" or "N" chirp_common.split_tone_decode(mem, (txmode, txtone, txpol), (rxmode, rxtone, rxpol)) mem.skip = chirp_common.SKIP_VALUES[_flg.scan if not is_hyper_chan else 0] mem.power = POWER_LEVELS[_mem.power] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("rev", "Reverse", RadioSettingValueBoolean(_mem.rev)) mem.extra.append(rs) rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(_mem.compander)) mem.extra.append(rs) rs = RadioSetting("talkaround", "Talkaround", RadioSettingValueBoolean(_mem.talkaround)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTT_IDS, PTT_IDS[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("bclo", "Busy Channel Lockout", RadioSettingValueList(BCLO, BCLO[_mem.bclo])) mem.extra.append(rs) rs = RadioSetting("optsig", "Optional Signaling", RadioSettingValueList(OPT_SIGS, OPT_SIGS[_mem.optsig])) mem.extra.append(rs) rs = RadioSetting("OPTSIGSQL", "Squelch w/Opt Signaling", RadioSettingValueList( OPT_SIG_SQL, SQL_MODES[_mem.sql_mode] if SQL_MODES[_mem.sql_mode] in OPT_SIG_SQL else "Off")) mem.extra.append(rs) rs = RadioSetting("dtmf_enc_num", "DTMF", RadioSettingValueList(DTMF_SLOTS, DTMF_SLOTS[_mem.dtmf_enc_num])) mem.extra.append(rs) rs = RadioSetting("twotone", "2-Tone", RadioSettingValueList(TONE2_SLOTS, TONE2_SLOTS[_mem.twotone])) mem.extra.append(rs) rs = RadioSetting("fivetone", "5-Tone", RadioSettingValueList(TONE5_SLOTS, TONE5_SLOTS[_mem.fivetone])) mem.extra.append(rs) rs = RadioSetting("scramble", "Scrambler Switch", RadioSettingValueList(SCRAMBLE_CODES, SCRAMBLE_CODES[_mem.scramble])) mem.extra.append(rs) # Memory properties dialog is only capable of Boolean and List # RadioSettingValue classes, so cannot configure custtone. # rs = RadioSetting("custtone", "Custom CTCSS", # RadioSettingValueFloat( # min(TONES), # max(TONES), # _mem.custtone and _mem.custtone / 10 or 151.1, # 0.1, # 1)) # mem.extra.append(rs) custtone_str = chirp_common.format_freq(_mem.custtone) rs = RadioSetting("CUSTTONETX", "Use Custom CTCSS (%s) for Tx" % custtone_str, RadioSettingValueBoolean(_mem.txtone == len(TONES))) mem.extra.append(rs) rs = RadioSetting("CUSTTONERX", "Use Custom CTCSS (%s) for Rx" % custtone_str, RadioSettingValueBoolean(_mem.rxtone == len(TONES))) mem.extra.append(rs) return mem def set_memory(self, mem): is_limit_chan = is_hyper_chan = False if mem.number > (len(self._memobj.channels) + len(self._memobj.limit_channels)): is_hyper_chan = True elif mem.number > len(self._memobj.channels): is_limit_chan = True _mem, _flg = self._get_memobjs(mem.number) if mem.empty: if is_hyper_chan: raise errors.InvalidValueError("Hyper memories may not be " "empty.") _mem.set_raw("\x00" * 32) _flg.unused = 1 _flg.group = BANK_CHOICES.index('Off') return if mem.mode == "AM" and (mem.freq < LEFT_BANDS[0][0] or mem.freq > LEFT_BANDS[0][1]): raise errors.InvalidValueError("AM modulation only allowed in 2m " "band.") _mem.set_raw("\x00" * 32) if _flg: # Only non-special memories track this _flg.unused = 0 _mem.freq = mem.freq for band_idx in range(0, len(LEFT_BANDS)): if (mem.freq >= LEFT_BANDS[band_idx][0] and mem.freq <= LEFT_BANDS[band_idx][1]): _mem.band = band_idx break if _flg: # Only non-special memories have this _flg.left_only = 0 if (not is_hyper_chan): if mem.mode == "AM": _flg.left_only = 1 else: _flg.left_only = 1 for low, high in RIGHT_BANDS: if mem.freq >= low and mem.freq <= high: _flg.left_only = 0 break _mem.offset = mem.offset / 100 if is_hyper_chan: mem.name = SEVEN_SPACES else: _mem.name = mem.name.ljust(7) if mem.duplex == "off": _mem.duplex = DUPLEXES.index("") _mem.txoff = 1 else: _mem.duplex = DUPLEXES.index(mem.duplex) _mem.txoff = 0 _mem.is_am = mem.mode == "AM" _mem.tune_step = TUNING_STEPS.index(mem.tuning_step) try: _mem.channel_width = MODES.index(mem.mode) except ValueError: _mem.channel_width = 0 ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) _mem.txtmode = T_MODES.index(txmode) _mem.rxtmode = T_MODES.index(rxmode) if rxmode != '': _mem.sql_mode = SQL_MODES.index("CTCSS/DCS") else: _mem.sql_mode = SQL_MODES.index("Carrier") if txmode == "Tone": _mem.txtone = TONES.index(txtone) elif txmode == "DTCS": self._set_dcs_index(_mem, 'tx', chirp_common.ALL_DTCS_CODES.index(txtone)) if rxmode == "Tone": _mem.rxtone = TONES.index(rxtone) elif rxmode == "DTCS": self._set_dcs_index(_mem, 'rx', chirp_common.ALL_DTCS_CODES.index(rxtone)) _mem.txdcsinv = txpol == "R" _mem.rxdcsinv = rxpol == "R" if not is_hyper_chan: _flg.scan = chirp_common.SKIP_VALUES.index(mem.skip) if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 for setting in mem.extra: if setting.get_name() == "ignore": LOG.debug("*** ignore: %s" % str(setting.value)) # Future: elif setting.get_name() == "custtone": # Future: setattr(_mem, "custtone", setting.value.get_value() * 10) elif setting.get_name() == "OPTSIGSQL": if str(setting.value) != "Off": _mem.sql_mode = SQL_MODES.index(str(setting.value)) elif setting.get_name() == "CUSTTONETX": if setting.value: _mem.txtone = len(TONES) elif setting.get_name() == "CUSTTONERX": if setting.value: _mem.rxtone = len(TONES) else: setattr(_mem, setting.get_name(), setting.value) return mem def get_settings(self): allGroups = RadioSettings() _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") basic.append( RadioSetting( "welcome", "Welcome Message", RadioSettingValueString( 0, 7, _filter(self._memobj.welcome, chirp_common.CHARSET_ASCII)))) basic.append( RadioSetting( "display", "Display", RadioSettingValueList(DISPLAY, DISPLAY[_settings.display]))) basic.append( RadioSetting( "disp_chan_lock", "Lock Chan# Disp", RadioSettingValueBoolean(_settings.disp_chan_lock))) basic.append( RadioSetting( "scan_tot", "Scan Pause Time", RadioSettingValueList( SCAN_PAUSES, SCAN_PAUSES[_settings.scan_tot]))) basic.append( RadioSetting( "scan_mode", "Scan Mode", RadioSettingValueList( SCAN_MODES, SCAN_MODES[_settings.scan_mode]))) basic.append( RadioSetting( "ptt_tot", "Talk Timeout", RadioSettingValueList(TOT, TOT[_settings.ptt_tot]))) basic.append( RadioSetting( "apo", "Auto Power Off", RadioSettingValueList(APO, APO[_settings.apo]))) basic.append( RadioSetting( "beep_on", "Beep", RadioSettingValueBoolean(_settings.beep_on))) basic.append( RadioSetting( "beep_hi", "Beep Volume", RadioSettingValueList(BEEP_VOL, BEEP_VOL[_settings.beep_hi]))) basic.append( RadioSetting( "ext_spk_on", "External Speaker", RadioSettingValueBoolean(_settings.ext_spk_on))) basic.append( RadioSetting( "deputy_mute", "Deputy Chan Mute", RadioSettingValueList( DEPUTY_CHAN_MUTES, DEPUTY_CHAN_MUTES[_settings.deputy_mute]))) basic.append( RadioSetting( "tail_elim_type", "Tail Eliminator", RadioSettingValueList( TAIL_ELIM_TYPES, TAIL_ELIM_TYPES[_settings.tail_elim_type]))) basic.append( RadioSetting( "no_tone_elim_tail", "Eliminate SQL Tail When\nNo Tone Signaling", RadioSettingValueBoolean(_settings.no_tone_elim_tail))) allGroups.append(basic) sqls = RadioSettingGroup("sql", "Squelch Levels") sqls.append( RadioSetting( "sql_left", "Left Squelch", RadioSettingValueInteger(0, 20, _settings.sql_left))) sqls.append( RadioSetting( "sql_right", "Right Squelch", RadioSettingValueInteger(0, 20, _settings.sql_right))) sqls.append( RadioSetting( "rfsql_left", "Left RF Squelch", RadioSettingValueList( RF_SQUELCHES, RF_SQUELCHES[_settings.rfsql_left]))) sqls.append( RadioSetting( "rfsql_right", "Right RF Squelch", RadioSettingValueList( RF_SQUELCHES, RF_SQUELCHES[_settings.rfsql_right]))) allGroups.append(sqls) keys = RadioSettingGroup("keys", "Keys / Buttons") keys.append( RadioSetting( "sql_key_mode", "SQL Key Mode", RadioSettingValueList( SQL_BTN_MODES, SQL_BTN_MODES[_settings.sql_key_mode]))) keys.append( RadioSetting( "key_a_func", "PA Key Function", RadioSettingValueList( KEY_FUNCS, KEY_FUNCS[_settings.key_a_func]))) keys.append( RadioSetting( "key_b_func", "PB Key Function", RadioSettingValueList( KEY_FUNCS, KEY_FUNCS[_settings.key_b_func]))) keys.append( RadioSetting( "key_c_func", "PC Key Function", RadioSettingValueList( KEY_FUNCS, KEY_FUNCS[_settings.key_c_func]))) keys.append( RadioSetting( "key_d_func", "PD Key Function", RadioSettingValueList( KEY_FUNCS, KEY_FUNCS[_settings.key_d_func]))) keys.append( RadioSetting( "key_bright", "Key Light Level", _RadioSettingValueOffsetInt( 1, 32, _settings.key_bright + 1, 1, -1))) keys.append( RadioSetting( "ptt_lockout", "PTT Key Lock", RadioSettingValueList( PTT_KEY_LOCKS, PTT_KEY_LOCKS[_settings.ptt_lockout]))) keys.append( RadioSetting( "keypad_lock", "Keypad Lockout", RadioSettingValueBoolean(_settings.keypad_lock))) allGroups.append(keys) bgColor = RadioSettingGroup("bgColor", "Background Color") bgColor.append( RadioSetting( "bg_red", "Red", _RadioSettingValueOffsetInt( 1, 32, _settings.bg_red + 1, 1, -1))) bgColor.append( RadioSetting( "bg_green", "Green", _RadioSettingValueOffsetInt( 1, 32, _settings.bg_green + 1, 1, -1))) bgColor.append( RadioSetting( "bg_blue", "Blue", _RadioSettingValueOffsetInt( 1, 32, _settings.bg_blue + 1, 1, -1))) allGroups.append(bgColor) pwdGroup = RadioSettingGroup("pwdGroup", "Boot Password") pwdGroup.append( RadioSetting( "boot_pw_on", "Enable", RadioSettingValueBoolean(_settings.boot_pw_on))) pwdGroup.append( RadioSetting( "boot_password", "Password (digits)", RadioSettingValueString( 0, 7, _filter(_settings.boot_password, string.digits), False, string.digits))) allGroups.append(pwdGroup) advanced = RadioSettingGroup("advanced", "Advanced") advanced.append( RadioSetting( "tbst_freq", "TBST Freq", RadioSettingValueList( TBST_FREQS, TBST_FREQS[_settings.tbst_freq]))) advanced.append( RadioSetting( "long_key_time", "Long Key Time", RadioSettingValueList( LONG_KEY_TIMES, LONG_KEY_TIMES[int((_settings.long_key_time-100) / 50)]))) advanced.append( RadioSetting( "clk_shift", "CLK Shift", RadioSettingValueBoolean(_settings.clk_shift))) advanced.append( RadioSetting( "alt_key_mode", "Keypad Alt Mode", RadioSettingValueBoolean(_settings.alt_key_mode))) advanced.append( RadioSetting( "no_init", "Prohibit Initialization", RadioSettingValueBoolean(_settings.no_init))) allGroups.append(advanced) hyperGroups = [ RadioSettingGroup("hyper1", "Hyper 1"), RadioSettingGroup("hyper2", "Hyper 2") ] for idx in range(0, len(hyperGroups)): _hyperSettings = _settings.hyper_settings[idx] hyperGroup = hyperGroups[idx] hyperGroup.append( RadioSetting( "main", "Main Band", RadioSettingValueList( HYPER_MAINS, HYPER_MAINS[_hyperSettings.main]))) hyperGroup.append( RadioSetting( "sub_display", "Sub Display", RadioSettingValueList( HYPER_SUB_DISPLAYS, HYPER_SUB_DISPLAYS[_hyperSettings.sub_display]))) hyperGroup.append( RadioSetting( "spkr_mode", "Speakers", RadioSettingValueList( HYPER_SPKR_MODES, HYPER_SPKR_MODES[_hyperSettings.spkr_mode]))) hyperGroup.append( RadioSetting( "vfo_band_edge", "VFO Band Lock", RadioSettingValueBoolean(_hyperSettings.vfo_band_edge))) hyperGroup.append( RadioSetting( "auto_am", "Auto AM", RadioSettingValueBoolean(_hyperSettings.auto_am))) hyperGroup.append( RadioSetting( "auto_rpt_shift", "Auto Repeater Shift", RadioSettingValueBoolean(_hyperSettings.auto_rpt_shift))) hyperGroup.append( RadioSetting( "auto_hyper_save", "Auto Hyper Save", RadioSettingValueBoolean(_hyperSettings.auto_hyper_save))) hyperGroup.append( RadioSetting( "vfo_tracked", "VFO Tracking", RadioSettingValueBoolean(_hyperSettings.vfo_tracked))) hyperGroup.append( RadioSetting( "left_mode", "Left Mode", RadioSettingValueList( HYPER_MODES, HYPER_MODES[_hyperSettings.left_mode]))) hyperGroup.append( RadioSetting( "right_mode", "Right Mode", RadioSettingValueList( HYPER_MODES, HYPER_MODES[_hyperSettings.right_mode]))) hyperGroup.append( RadioSetting( "left_channel", "Left Channel", _RadioSettingValueOffsetInt( 1, 750, _hyperSettings.left_channel + 1, 1, -1))) hyperGroup.append( RadioSetting( "right_channel", "Right Channel", _RadioSettingValueOffsetInt( 1, 750, _hyperSettings.right_channel + 1, 1, -1))) hyperGroup.append( RadioSetting( "left_vfo_band", "Left VFO Band", RadioSettingValueList( HYPER_L_VFOS, HYPER_L_VFOS[_hyperSettings.left_vfo_band]))) hyperGroup.append( RadioSetting( "right_vfo_band", "Right VFO Band", RadioSettingValueList( HYPER_R_VFOS, HYPER_R_VFOS[_hyperSettings.right_vfo_band]))) hyperGroup.append( RadioSetting( "left_work_bank", "Left Work Bank", RadioSettingValueList( BANK_CHOICES, BANK_CHOICES[_hyperSettings.left_work_bank]))) hyperGroup.append( RadioSetting( "right_work_bank", "Right Work Bank", RadioSettingValueList( BANK_CHOICES, BANK_CHOICES[_hyperSettings.right_work_bank]))) hyperGroup.append( RadioSetting( "left_bank_mode", "Left Bank Mode", RadioSettingValueList( HYPER_BANK_MODES, HYPER_BANK_MODES[_hyperSettings.left_bank_mode]))) hyperGroup.append( RadioSetting( "right_bank_mode", "Right Bank Mode", RadioSettingValueList( HYPER_BANK_MODES, HYPER_BANK_MODES[_hyperSettings.right_bank_mode]))) hyperGroup.append( RadioSetting( "left_bank_sw", "Left Bank Switch", RadioSettingValueBoolean(_hyperSettings.left_bank_sw))) hyperGroup.append( RadioSetting( "right_bank_sw", "Right Bank Switch", RadioSettingValueBoolean(_hyperSettings.right_bank_sw))) for bank in BANK_CHOICES[0:-1]: hyperGroup.append( RadioSetting( "link_bank_%s" % bank, "Bank %s" % bank, RadioSettingValueBoolean( getattr(_hyperSettings, "link_bank_%s" % bank)))) allGroups.append(hyperGroup) notes = RadioSettingGroup("notes", "Comm Notes") for idx in range(0, 100): notes.append( RadioSetting( "note_call_ids.%d" % idx, "Call ID %d (5 digits)" % idx, RadioSettingValueString( 0, 5, _filter(self._memobj.note_call_ids[idx].call_id, string.digits)[idx*8:idx*8+5], False, string.digits))) notes.append( RadioSetting( "note_names.%d" % idx, "Name %d (7 ALPHAnumeric)" % idx, RadioSettingValueString( 0, 7, _filter(self._memobj.note_names[idx].name, chirp_common.CHARSET_UPPER_NUMERIC) [idx*8:idx*8+7], True, chirp_common.CHARSET_UPPER_NUMERIC))) allGroups.append(notes) _emergency = self._memobj.emergency emer = RadioSettingGroup("emergency", "Emergency Info") emer.append( RadioSetting( "mode", "Alarm Mode", RadioSettingValueList( EMER_MODES, EMER_MODES[_emergency.mode]))) emer.append( RadioSetting( "eni_type", "ENI Type", RadioSettingValueList( EMER_ENI_TYPES, EMER_ENI_TYPES[_emergency.eni_type]))) emer.append( RadioSetting( "emergency.id", "DTMF ID", RadioSettingValueList( DTMF_SLOTS, DTMF_SLOTS[_emergency.id] if EMER_ENI_TYPES[_emergency.eni_type] == 'DTMF' else DTMF_SLOTS[0]))) emer.append( RadioSetting( "5ToneId", "5Tone ID", RadioSettingValueInteger( 0, 99, _emergency.id if EMER_ENI_TYPES[_emergency.eni_type] == '5Tone' else 0))) emer.append( RadioSetting( "alarm_time", "Alarm Time (sec)", RadioSettingValueInteger(1, 255, _emergency.alarm_time))) emer.append( RadioSetting( "tx_time", "TX Duration (sec)", RadioSettingValueInteger(1 if _emergency.tx_time > 0 else 0, 255, _emergency.tx_time))) emer.append( RadioSetting( "rx_time", "RX Duration (sec)", RadioSettingValueInteger(1 if _emergency.rx_time > 0 else 0, 255, _emergency.rx_time))) emer.append( RadioSetting( "chan_select", "ENI Channel", RadioSettingValueList( EMER_CHAN_SEL, EMER_CHAN_SEL[_emergency.chan_select]))) emer.append( RadioSetting( "channel", "Assigned Channel", _RadioSettingValueOffsetInt( 1, 750, _emergency.channel + 1, 1, -1))) emer.append( RadioSetting( "cycle", "Cycle", RadioSettingValueList( EMER_CYCLES, EMER_CYCLES[_emergency.cycle]))) allGroups.append(emer) dtmfGroup = RadioSettingGroup("dtmf", "DTMF") for idx in range(0, 16): dtmfGroup.append( RadioSetting( "dtmf_encodings.%d" % idx, "Encode Tone %s" % DTMF_SLOTS[idx], RadioSettingValueString( 0, 12, _dtmf_decode( self._memobj.dtmf_encodings[idx].dtmf, self._memobj.dtmf_encodings[idx].num_tones), False, DTMF_CHARS))) dtmfGroup.append( RadioSetting( "dtmf_preload_time", "Encode Preload Time", RadioSettingValueList( DTMF_PRELOADS, DTMF_PRELOADS[_settings.dtmf_preload_time]))) dtmfGroup.append( RadioSetting( "dtmf_speed", "Speed", RadioSettingValueList( DTMF_SPEEDS, DTMF_SPEEDS[_settings.dtmf_speed]))) dtmfGroup.append( RadioSetting( "dtmf_interval_char", "Interval Character", RadioSettingValueList( list(DTMF_INTCHARS), DTMF_CHARS[_settings.dtmf_interval_char]))) dtmfGroup.append( RadioSetting( "dtmf_group_code", "Group Code", RadioSettingValueList( DTMF_GROUPS, DTMF_GROUPS[_settings.dtmf_group_code-0x0a] if _settings.dtmf_group_code < 0xff else DTMF_GROUPS[6]))) dtmfGroup.append( RadioSetting( "dtmf_dec_resp", "Decode Response", RadioSettingValueList( DTMF_RESPONSES, DTMF_RESPONSES[_settings.dtmf_dec_resp]))) dtmfGroup.append( RadioSetting( "dtmf_first_dig_time", "1st Digit Time (ms)", RadioSettingValueInteger( 0, 2500, _settings.dtmf_first_dig_time * 10, 10))) dtmfGroup.append( RadioSetting( "dtmf_auto_rst_time", "Auto Reset Time (0-25 sec by 0.1)", RadioSettingValueFloat( 0, 25, _settings.dtmf_auto_rst_time / 10, 0.1, 1))) dtmfGroup.append( RadioSetting( "dtmf_self_id", "Self ID", RadioSettingValueString( 3, 3, (DTMF_CHARS[_settings.dtmf_self_id[0] & 0x0F] + DTMF_CHARS[_settings.dtmf_self_id[1] & 0x0F] + DTMF_CHARS[_settings.dtmf_self_id[2] & 0x0F]), True, DTMF_CHARS))) dtmfGroup.append( RadioSetting( "dtmf_sidetone_on", "Use Side Tone", RadioSettingValueBoolean(_settings.dtmf_sidetone_on))) dtmfGroup.append( RadioSetting( "dtmf_enc_delay", "Encode Delay (ms)", RadioSettingValueInteger( 10, 2500, _settings.dtmf_enc_delay * 10, 10))) dtmfGroup.append( RadioSetting( "dtmf_pttid_delay", "PTT ID Delay", RadioSettingValueList( DTMF_PTTDELAYS, DTMF_PTTDELAYS[_settings.dtmf_pttid_delay-4] if _settings.dtmf_pttid_delay >= 5 else DTMF_PTTDELAYS[0]))) dtmfGroup.append( RadioSetting( "dtmf_kill", "Remote Kill", RadioSettingValueString( 0, 7, _dtmf_decode(_settings.dtmf_kill.dtmf, _settings.dtmf_kill.num_tones), False, DTMF_CHARS))) dtmfGroup.append( RadioSetting( "dtmf_stun", "Remote Stun", RadioSettingValueString( 0, 7, _dtmf_decode(_settings.dtmf_stun.dtmf, _settings.dtmf_stun.num_tones), False, DTMF_CHARS))) dtmfGroup.append( RadioSetting( "dtmf_pttid_bot", "PTT ID Start (BOT)", RadioSettingValueString( 0, 12, _dtmf_decode(self._memobj.dtmf_pttid_bot.dtmf, self._memobj.dtmf_pttid_bot.num_tones), False, DTMF_CHARS))) dtmfGroup.append( RadioSetting( "dtmf_pttid_eot", "PTT ID Start (EOT)", RadioSettingValueString( 0, 12, _dtmf_decode(self._memobj.dtmf_pttid_eot.dtmf, self._memobj.dtmf_pttid_eot.num_tones), False, DTMF_CHARS))) allGroups.append(dtmfGroup) # TODO: 2-Tone settings # TODO: 5-Tone settings return allGroups def _set_hyper_settings(self, settings, _hyperSettings): for element in settings: name = element.get_name() if not isinstance(element, RadioSetting): self._set_hyper_settings(element, _hyperSettings) continue elif isinstance(element.value, _RadioSettingValueOffsetInt): setattr(_hyperSettings, name, int(element.value) + element.value.offset) else: setattr(_hyperSettings, name, element.value) def _set_pwd_settings(self, settings): _settings = self._memobj.settings use_pw = pwd = None for element in settings: name = element.get_name() if not isinstance(element, RadioSetting): self._set_pwd_settings(element) continue elif name == "boot_pw_on": use_pw = bool(element.value) elif name == "boot_password": pwd = _filter(str(element.value), string.digits) if (pwd is not None and (len(pwd) or use_pw is False)): setattr(_settings, "boot_pw_on", use_pw and 1 or 0) pwd = pwd + "\x00"*(7-len(pwd)) setattr(_settings, "boot_password", pwd) elif (use_pw is not None and use_pw is True): raise errors.InvalidValueError("Password may not be enabled " "without being set.") def _set_notes_settings(self, settings): _noteCalls = self._memobj.note_call_ids _noteNames = self._memobj.note_names for element in settings: name = str(element.get_name()) if not isinstance(element, RadioSetting): self._set_notes_settings(element) continue elif name.startswith("note_call_ids."): idx = int(name[len("note_call_ids."):]) setattr(self._memobj.note_call_ids[idx], "call_id", str(element.value).ljust(5, "\x00")) elif name.startswith("note_names."): idx = int(name[len("note_names."):]) setattr(self._memobj.note_names[idx], "name", str(element.value).ljust(7)) def _set_emer_settings(self, settings): _emergency = self._memobj.emergency dtmf_id = fivetone_id = None for element in settings: name = str(element.get_name()) if not isinstance(element, RadioSetting): self._set_emer_settings(element) continue elif name == "emergency.id": dtmf_id = element.value elif name == "5ToneId": fivetone_id = element.value elif name == "channel": zb_mem_num = int(element.value) + element.value.offset _mem, _flg = self._get_memobjs(zb_mem_num + 1) if _flg.unused: raise errors.InvalidValueError("Assigned emergency ENI " "channel is empty.") else: setattr(_emergency, name, zb_mem_num) elif isinstance(element.value, _RadioSettingValueOffsetInt): setattr(_emergency, name, int(element.value) + element.value.offset) else: setattr(_emergency, name, element.value) if EMER_ENI_TYPES[_emergency.eni_type] == 'DTMF': setattr(_emergency, "id", dtmf_id) elif EMER_ENI_TYPES[_emergency.eni_type] == '5Tone': setattr(_emergency, "id", fivetone_id) def _set_dtmf_settings(self, settings): def _setDtmf(dtmfStruct, newVal): dtmfStruct.num_tones.set_value(len(newVal)) dtmfStruct.dtmf.set_value(_dtmf_encode(newVal, len(dtmfStruct.dtmf))) for element in settings: name = str(element.get_name()) if not isinstance(element, RadioSetting): self._set_dtmf_settings(element) continue if name.startswith("dtmf_encodings."): idx = int(name[len("dtmf_encodings."):]) _setDtmf(self._memobj.dtmf_encodings[idx], str(element.value)) elif name == "dtmf_interval_char": setattr(self._memobj.settings.dtmf_interval_char, name, DTMF_CHARS.index(str(element.value))) elif name == "dtmf_group_code": setattr(self._memobj.settings, name, int(element.value)+0x0a if int(element.value) != 6 else 0xff) elif name == "dtmf_first_dig_time" or name == "dtmf_enc_delay": setattr(self._memobj.settings, name, int(element.value) / 10) elif name == "dtmf_auto_rst_time": setattr(self._memobj.settings, name, int(element.value) * 10) elif name == "dtmf_self_id": newStr = str(element.value) newVal = [] for charIdx in range(0, 3): newVal.append(DTMF_CHARS.index(newStr[charIdx])) setattr(self._memobj.settings, name, newVal) elif name == "dtmf_pttid_delay": setattr(self._memobj.settings, name, DTMF_PTTDELAYS.index(str(element.value))+4 if element.value != DTMF_PTTDELAYS[0] else 0) elif name == "dtmf_kill" or name == "dtmf_stun": _setDtmf(getattr(self._memobj.settings, name), str(element.value)) elif name == "dtmf_pttid_bot" or name == "dtmf_pttid_eot": _setDtmf(getattr(self._memobj, name), str(element.value)) else: setattr(self._memobj.settings, name, element.value) def set_settings(self, settings): _root = self._memobj _settings = self._memobj.settings for element in settings: name = element.get_name() if isinstance(element, RadioSettingGroup): if name == "hyper1": self._set_hyper_settings( element, _settings.hyper_settings[0]) continue elif name == "hyper2": self._set_hyper_settings( element, _settings.hyper_settings[1]) continue elif name == "pwdGroup": self._set_pwd_settings(element) continue elif name == "notes": self._set_notes_settings(element) continue elif name == "emergency": self._set_emer_settings(element) continue elif name == "dtmf": self._set_dtmf_settings(element) continue if not isinstance(element, RadioSetting): self.set_settings(element) continue if name == "ignore": LOG.debug("*** ignore: %s" % str(element.value)) elif name == "welcome": setattr(_root, "welcome", element.value) elif name == "long_key_time": setattr(_settings, name, 100 + 50 * int(element.value)) elif isinstance(element.value, _RadioSettingValueOffsetInt): setattr(_settings, name, (int(element.value) + element.value.offset)) else: setattr(_settings, name, element.value) @classmethod def match_model(cls, filedata, filename): return cls._file_ident in filedata[0x40:0x4D] chirp-20240224/chirp/drivers/yaesu_clone.py0000644000175000017500000002206514522135005017501 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import time import logging from chirp import bitwise from chirp import chirp_common, util, memmap, errors LOG = logging.getLogger(__name__) CMD_ACK = 0x06 def _safe_read(pipe, count): buf = bytes(b"") first = True for _i in range(0, 60): buf += pipe.read(count - len(buf)) # LOG.debug("safe_read: %i/%i\n" % (len(buf), count)) if buf: if first and buf[0] == CMD_ACK: # LOG.debug("Chewed an ack") buf = buf[1:] # Chew an echo'd ack if using a 2-pin cable first = False if len(buf) == count: break LOG.debug(util.hexprint(buf)) return buf def _chunk_read(pipe, count, status_fn): timer = time.time() block = 32 data = bytes(b"") while len(data) < count: # Don't read past the end of our block if we're not on a 32-byte # boundary chunk_size = min(block, count - len(data)) chunk = pipe.read(chunk_size) if chunk: timer = time.time() data += chunk if data[0] == CMD_ACK: data = data[1:] # Chew an echo'd ack if using a 2-pin cable # LOG.debug("Chewed an ack") if time.time() - timer > 2: # It's been two seconds since we last saw data from the radio, # so it's time to give up. raise errors.RadioError("Timed out reading from radio") status = chirp_common.Status() status.msg = "Cloning from radio" status.max = count status.cur = len(data) status_fn(status) LOG.debug("Read %i/%i" % (len(data), count)) return data def __clone_in(radio): pipe = radio.pipe status = chirp_common.Status() status.msg = "Cloning from radio" status.max = radio.get_memsize() start = time.time() data = bytes(b"") blocks = 0 for block in radio._block_lengths: blocks += 1 if blocks == len(radio._block_lengths): chunk = _chunk_read(pipe, block, radio.status_fn) else: chunk = _safe_read(pipe, block) pipe.write(bytes([CMD_ACK])) if not chunk: raise errors.RadioError("No response from radio") if blocks == 1: LOG.debug('ID block: %s' % util.hexprint(chunk)) if radio.status_fn: status.cur = len(data) radio.status_fn(status) data += chunk if len(data) != radio.get_memsize(): raise errors.RadioError("Received incomplete image from radio") LOG.debug("Clone completed in %i seconds" % (time.time() - start)) return memmap.MemoryMapBytes(data) def _clone_in(radio): try: return __clone_in(radio) except Exception as e: raise errors.RadioError("Failed to communicate with the radio: %s" % e) def _chunk_write(pipe, data, status_fn, block): delay = 0.03 count = 0 for i in range(0, len(data), block): chunk = data[i:i+block] pipe.write(chunk) count += len(chunk) LOG.debug("@_chunk_write, count: %i, blocksize: %i" % (count, block)) time.sleep(delay) status = chirp_common.Status() status.msg = "Cloning to radio" status.max = len(data) status.cur = count status_fn(status) def __clone_out(radio): pipe = radio.pipe block_lengths = radio._block_lengths total_written = 0 def _status(): status = chirp_common.Status() status.msg = "Cloning to radio" status.max = block_lengths[0] + block_lengths[1] + block_lengths[2] status.cur = total_written radio.status_fn(status) start = time.time() blocks = 0 pos = 0 mmap = radio.get_mmap().get_byte_compatible() for block in radio._block_lengths: blocks += 1 if blocks != len(radio._block_lengths): LOG.debug("Sending %i-%i" % (pos, pos+block)) pipe.write(mmap[pos:pos+block]) buf = pipe.read(1) if buf and buf[0] != CMD_ACK: buf = pipe.read(block) if not buf or buf[-1] != CMD_ACK: raise Exception("Radio did not ack block %i" % blocks) else: _chunk_write(pipe, mmap[pos:], radio.status_fn, radio._block_size) pos += block pipe.read(pos) # Chew the echo if using a 2-pin cable LOG.debug("Clone completed in %i seconds" % (time.time() - start)) def _clone_out(radio): try: return __clone_out(radio) except Exception as e: raise errors.RadioError("Failed to communicate with the radio: %s" % e) class YaesuChecksum: """A Yaesu Checksum Object""" def __init__(self, start, stop, address=None): self._start = start self._stop = stop if address: self._address = address else: self._address = stop + 1 @staticmethod def _asbytes(mmap): if hasattr(mmap, 'get_byte_compatible'): return mmap.get_byte_compatible() elif isinstance(mmap, bytes): # NOTE: this won't work for update(), but nothing should be calling # this with a literal expecting that to work return memmap.MemoryMapBytes(bytes(mmap)) elif isinstance(mmap, str): # NOTE: this won't work for update(), but nothing should be calling # this with a literal expecting that to work return memmap.MemoryMap( bitwise.string_straight_encode(mmap)).get_byte_compatible() else: raise TypeError('Unable to convert %s to bytes' % ( type(mmap).__name__)) def get_existing(self, mmap): """Return the existing checksum in mmap""" return self._asbytes(mmap)[self._address][0] def get_calculated(self, mmap): """Return the calculated value of the checksum""" mmap = self._asbytes(mmap) cs = 0 for i in range(self._start, self._stop+1): # NOTE: mmap[i] returns a slice'd bytes, not an int like a # bytes does cs += mmap[i][0] return cs % 256 def update(self, mmap): """Update the checksum with the data in @mmap""" mmap = self._asbytes(mmap) mmap[self._address] = self.get_calculated(mmap) def __str__(self): return "%04X-%04X (@%04X)" % (self._start, self._stop, self._address) class YaesuCloneModeRadio(chirp_common.CloneModeRadio): """Base class for all Yaesu clone-mode radios""" _block_lengths = [8, 65536] _block_size = 8 VENDOR = "Yaesu" NEEDS_COMPAT_SERIAL = False _model = b"ABCDE" @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect data cable.\n" "3. Prepare radio for clone.\n" "4. After clicking OK, press the key to send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect data cable.\n" "3. Prepare radio for clone.\n" "4. Press the key to receive the image.\n") return rp def _checksums(self): """Return a list of checksum objects that need to be calculated""" return [] def update_checksums(self): """Update the radio's checksums from the current memory map""" for checksum in self._checksums(): checksum.update(self._mmap) def check_checksums(self): """Validate the checksums stored in the memory map""" for checksum in self._checksums(): if checksum.get_existing(self._mmap) != \ checksum.get_calculated(self._mmap): raise errors.RadioError("Checksum Failed [%s]" % checksum) LOG.debug("Checksum %s: OK" % checksum) def sync_in(self): self._mmap = _clone_in(self) self.check_checksums() self.process_mmap() def sync_out(self): self.update_checksums() _clone_out(self) @classmethod def match_model(cls, filedata, filename): return filedata[:5] == cls._model and len(filedata) == cls._memsize def _wipe_memory_banks(self, mem): """Remove @mem from all the banks it is currently in""" bm = self.get_bank_model() for bank in bm.get_memory_mappings(mem): bm.remove_memory_from_mapping(mem, bank) chirp-20240224/chirp/drivers/hobbypcb.py0000644000175000017500000002755214446523722017005 0ustar hibbyhibby# Copyright 2016 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import time from chirp import chirp_common, directory, errors from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) BAUDS = [1200, 4800, 9600, 19200, 38400, 57600] POWER_LEVELS = [chirp_common.PowerLevel('Low', dBm=10), chirp_common.PowerLevel('High', dBm=24)] TONE_MODES = ['', 'Tone', 'TSQL', ''] def detect_baudrate(radio): bauds = list(BAUDS) bauds.remove(radio.pipe.baudrate) bauds.insert(0, radio.pipe.baudrate) for baud in bauds: radio.pipe.baudrate = baud radio.pipe.timeout = 0.5 radio.pipe.write(b'\rFW?\r') resp = radio.pipe.read(2) if resp.strip().startswith(b'FW'): resp += radio.pipe.read(16) LOG.info('HobbyPCB %r at baud rate %i' % (resp.strip(), baud)) return baud @directory.register class HobbyPCBRSUV3Radio(chirp_common.LiveRadio): """HobbyPCB RS-UV3""" VENDOR = "HobbyPCB" MODEL = "RS-UV3" BAUD_RATE = 19200 NEEDS_COMPAT_SERIAL = False def __init__(self, *args, **kwargs): super(HobbyPCBRSUV3Radio, self).__init__(*args, **kwargs) if self.pipe: baud = detect_baudrate(self) if not baud: raise errors.RadioError('Radio did not respond') def _cmd(self, command, rsize=None): command = command.encode() LOG.debug('> %s' % command) self.pipe.write(b'%s\r' % command) resp = b'' if rsize is None: complete = lambda: time.sleep(0.1) is None elif rsize == 0: rsize = 1 complete = lambda: resp.endswith(b'\r') else: complete = lambda: len(resp) >= rsize while not complete(): chunk = self.pipe.read(rsize) if not chunk: break resp += chunk LOG.debug('< %r [%i]' % (resp, len(resp))) return resp.decode().strip() def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_name = False rf.has_cross = False rf.has_dtcs = False rf.has_rx_dtcs = False rf.has_dtcs_polarity = False rf.has_tuning_step = False rf.has_mode = False rf.has_settings = True rf.memory_bounds = (1, 9) # This radio supports memories 0-9 rf.valid_bands = [(144000000, 148000000), (220000000, 222000000), (440000000, 450000000), ] rf.valid_tmodes = TONE_MODES rf.valid_power_levels = POWER_LEVELS return rf def get_memory(self, number): _mem = self._cmd('CP%i' % number, 33).split('\r') LOG.debug('Memory elements: %r' % _mem) mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem[0]) * 1000 txfreq = int(_mem[1]) * 1000 mem.offset = abs(txfreq - mem.freq) if mem.freq < txfreq: mem.duplex = '+' elif mem.freq > txfreq: mem.duplex = '-' else: mem.duplex = '' mem.ctone = int(_mem[2]) / 100.0 mem.rtone = mem.ctone mem.tmode = TONE_MODES[int(_mem[3])] mem.power = POWER_LEVELS[int(_mem[5])] return mem def set_memory(self, mem): if mem.tmode in ['', 'Tone']: tone = mem.rtone * 100 else: tone = mem.ctone * 100 if mem.duplex == '+': self._cmd('FT%06i' % ((mem.freq + mem.offset) / 1000)) self._cmd('FR%06i' % (mem.freq / 1000)) elif mem.duplex == '-': self._cmd('FT%06i' % ((mem.freq - mem.offset) / 1000)) self._cmd('FR%06i' % (mem.freq / 1000)) else: self._cmd('FS%06i' % (mem.freq / 1000)) self._cmd('TM%i' % TONE_MODES.index(mem.tmode)) self._cmd('TF%05i' % tone) self._cmd('PW%i' % POWER_LEVELS.index(mem.power)) self._cmd('ST%i' % mem.number) def get_settings(self): def _get(cmd): return self._cmd('%s?' % cmd, 0).split(':')[1].strip() cw = RadioSettingGroup('beacon', 'Beacon Settings') cl = RadioSetting('CL%15s', 'CW Callsign', RadioSettingValueString(0, 15, _get('CL'))) cw.append(cl) cf = RadioSetting('CF%4i', 'CW Audio Frequency', RadioSettingValueInteger(400, 1300, int(_get('CF')))) cw.append(cf) cs = RadioSetting('CS%02i', 'CW Speed', RadioSettingValueInteger(5, 25, int(_get('CS')))) cw.append(cs) bc = RadioSetting('BC%03i', 'CW Beacon Timer', RadioSettingValueInteger(0, 600, int(_get('BC')))) cw.append(bc) bm = RadioSetting('BM%15s', 'Beacon Message', RadioSettingValueString(0, 15, _get('BM'))) cw.append(bm) bt = RadioSetting('BT%03i', 'Beacon Timer', RadioSettingValueInteger(0, 600, int(_get('BT')))) cw.append(bt) it = RadioSetting('IT%03i', 'CW ID Timer', RadioSettingValueInteger(0, 500, int(_get('IT')))) cw.append(it) tg = RadioSetting('TG%7s', 'CW Timeout Message', RadioSettingValueString(0, 7, _get('TG'))) cw.append(tg) io = RadioSettingGroup('io', 'IO') af = RadioSetting('AF%i', 'Arduino LPF', RadioSettingValueBoolean(_get('AF') == 'ON')) io.append(af) input_pin = ['OFF', 'SQ OPEN', 'PTT'] ai = RadioSetting('AI%i', 'Arduino Input Pin', RadioSettingValueList( input_pin, input_pin[int(_get('AI'))])) io.append(ai) output_pin = ['LOW', 'SQ OPEN', 'DTMF DETECT', 'TX ON', 'CTCSS DET', 'HIGH'] ao = RadioSetting('AO%i', 'Arduino Output Pin', RadioSettingValueList( output_pin, output_pin[int(_get('AO'))])) io.append(ao) bauds = [str(x) for x in BAUDS] b1 = RadioSetting('B1%i', 'Arduino Baudrate', RadioSettingValueList( bauds, bauds[int(_get('B1'))])) io.append(b1) b2 = RadioSetting('B2%i', 'Main Baudrate', RadioSettingValueList( bauds, bauds[int(_get('B2'))])) io.append(b2) dtmf = RadioSettingGroup('dtmf', 'DTMF Settings') dd = RadioSetting('DD%04i', 'DTMF Tone Duration', RadioSettingValueInteger(50, 2000, int(_get('DD')))) dtmf.append(dd) dr = RadioSetting('DR%i', 'DTMF Tone Detector', RadioSettingValueBoolean(_get('DR') == 'ON')) dtmf.append(dr) gt = RadioSetting('GT%02i', 'DTMF/CW Tone Gain', RadioSettingValueInteger(0, 15, int(_get('GT')))) dtmf.append(gt) sd = RadioSetting('SD%i', 'DTMF/CW Side Tone', RadioSettingValueBoolean(_get('SD') == 'ON')) dtmf.append(sd) general = RadioSettingGroup('general', 'General') dp = RadioSetting('DP%i', 'Pre-Emphasis', RadioSettingValueBoolean(_get('DP') == 'ON')) general.append(dp) fw = RadioSetting('_fw', 'Firmware Version', RadioSettingValueString(0, 20, _get('FW'))) general.append(fw) gm = RadioSetting('GM%02i', 'Mic Gain', RadioSettingValueInteger(0, 15, int(_get('GM')))) general.append(gm) hp = RadioSetting('HP%i', 'Audio High-Pass Filter', RadioSettingValueBoolean(_get('HP') == 'ON')) general.append(hp) ht = RadioSetting('HT%04i', 'Hang Time', RadioSettingValueInteger(0, 5000, int(_get('HT')))) general.append(ht) ledmode = ['OFF', 'ON', 'SQ OPEN', 'BATT CHG STAT'] ld = RadioSetting('LD%i', 'LED Mode', RadioSettingValueList( ledmode, ledmode[int(_get('LD'))])) general.append(ld) sq = RadioSetting('SQ%i', 'Squelch Level', RadioSettingValueInteger(0, 9, int(_get('SQ')))) general.append(sq) to = RadioSetting('TO%03i', 'Timeout Timer', RadioSettingValueInteger(0, 600, int(_get('TO')))) general.append(to) vu = RadioSetting('VU%02i', 'Receiver Audio Volume', RadioSettingValueInteger(0, 39, int(_get('VU')))) general.append(vu) rc = RadioSetting('RC%i', 'Current Channel', RadioSettingValueInteger(0, 9, 0)) rc.set_doc('Choosing one of these values causes the radio ' 'to change to the selected channel. The radio ' 'cannot tell CHIRP what channel is selected.') general.append(rc) return RadioSettings(general, cw, io, dtmf) def set_settings(self, settings): def _set(thing): # Try to only set something if it's new query = '%s?' % thing[:2] cur = self._cmd(query, 0) if cur.strip(): cur = cur.split()[1].strip() new = thing[2:].strip() if cur in ['ON', 'OFF']: cur = int(cur == 'ON') new = int(new) elif cur.isdigit(): cur = int(cur) new = int(new) if new != cur: LOG.info('Setting %s (%r != %r)' % (thing, cur, new)) self._cmd(thing) time.sleep(1) for group in settings: for setting in group: if setting.get_name().startswith('_'): LOG.debug('Skipping %s' % setting) continue cmd = setting.get_name() value = setting.value.get_value() if hasattr(setting.value, '_options'): value = setting.value._options.index(value) fullcmd = (cmd % value).strip() _set(fullcmd) chirp-20240224/chirp/drivers/ft1500m.py0000644000175000017500000001626214430171343016274 0ustar hibbyhibby# Copyright 2019 Josh Small VK2HFF # - Derived from ./ft1802.py Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # FT-1500M Clone Procedure # 1. Turn radio off. # 2. Connect cable to mic jack. # 3. Press and hold in the [MHz],[LOW] and [D/MR] keys # while turning the radio on. # 4. In Chirp, choose Download from Radio. # 5. Press the [MHz(SET)] key to send image. # or # 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). # 5. In Chirp, choose Upload to Radio. from chirp.drivers import yaesu_clone from chirp import chirp_common, bitwise, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean MEM_FORMAT = """ #seekto 0x002a; struct { u8 unknown_f:4, pskip:1, skip:1, visible:1, valid:1; } flags[130]; #seekto 0x00ca; struct { u8 unknown1a:2, narrow:1, clk_shift:1, unknown1b:4; u8 unknown2a:3, unknown2b:2, tune_step:3; bbcd freq[3]; u8 tone; u8 name[6]; u8 unknown3; u8 offset; u8 unknown4a:1, unknown4b:1, unknown4c:2, unknown4d:4; u8 unknown5a:2, tmode:2, power:2, duplex:2; } memory[130]; """ MODES = ["FM", "NFM"] TMODES = ["", "Tone", "TSQL"] DUPLEX = ["", "-", "+"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] POWER_LEVELS = [chirp_common.PowerLevel("LOW1", watts=5), chirp_common.PowerLevel("LOW2", watts=10), chirp_common.PowerLevel("LOW3", watts=25), chirp_common.PowerLevel("HIGH", watts=50), ] CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-/?()?_" @directory.register class FT1500Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT-1500M""" VENDOR = "Yaesu" MODEL = "FT-1500M" BAUD_RATE = 9600 _model = "AH4N0" _block_lengths = [10, 16, 3953] _memsize = 3979 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to mic jack.\n" "3. Press and hold in the [MHz], [LOW], and [D/MR] keys\n" " while turning the radio on.\n" "4. After clicking OK, press the [MHz(SET)] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to mic jack.\n" "3. Press and hold in the [MHz], [LOW], and [D/MR] keys\n" " while turning the radio on.\n" "4. Press the [D/MR(MW)] key (\"--WAIT--\" will appear on the" " LCD).\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 129) rf.can_odd_split = False rf.has_ctone = False rf.has_tuning_step = True rf.has_dtcs_polarity = False rf.has_bank = False rf.valid_tuning_steps = STEPS rf.valid_modes = MODES rf.valid_tmodes = TMODES rf.valid_bands = [(137000000, 174000000)] rf.valid_power_levels = POWER_LEVELS rf.valid_duplexes = DUPLEX rf.valid_skips = ["", "S", "P"] rf.valid_name_length = 6 rf.valid_characters = CHARSET rf.has_cross = False return rf def _checksums(self): return [yaesu_clone.YaesuChecksum(0, self._memsize-2)] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) + \ repr(self._memobj.flags[number]) def get_memory(self, number): _mem = self._memobj.memory[number] _flag = self._memobj.flags[number] visible = _flag["visible"] valid = _flag["valid"] skip = _flag["skip"] pskip = _flag["pskip"] mem = chirp_common.Memory() mem.number = number if not visible: mem.empty = True if not valid: mem.empty = True return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = chirp_common.fix_rounded_step(int(_mem.offset) * 100000) mem.duplex = DUPLEX[_mem.duplex] mem.tuning_step = STEPS[_mem.tune_step] or STEPS[0] mem.tmode = TMODES[_mem.tmode] mem.rtone = chirp_common.TONES[_mem.tone] for i in _mem.name: if i == 0xFF: break if i & 0x80 == 0x80: mem.name += CHARSET[0x80 ^ int(i)] else: mem.name += CHARSET[i] mem.name = mem.name.rstrip() mem.mode = _mem.narrow and "NFM" or "FM" mem.skip = pskip and "P" or skip and "S" or "" mem.power = POWER_LEVELS[_mem.power] mem.extra = RadioSettingGroup("extra", "Extra Settings") rs = RadioSetting("clk_shift", "Clock Shift", RadioSettingValueBoolean(_mem.clk_shift)) mem.extra.append(rs) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _flag = self._memobj.flags[mem.number] valid = _flag["valid"] visible = _flag["visible"] if not mem.empty and not valid: _flag["valid"] = True _mem.unknown1a = 0x00 _mem.clk_shift = 0x00 _mem.unknown1b = 0x00 _mem.unknown2a = 0x00 _mem.unknown2b = 0x00 _mem.unknown3 = 0x00 _mem.unknown4a = 0x00 _mem.unknown4b = 0x00 _mem.unknown4c = 0x00 _mem.unknown4d = 0x00 _mem.unknown5a = 0x00 if mem.empty and valid and not visible: _flag["valid"] = False return _flag["visible"] = not mem.empty if mem.empty: return _flag["valid"] = True _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 100000 _mem.duplex = DUPLEX.index(mem.duplex) _mem.tune_step = STEPS.index(mem.tuning_step) _mem.tmode = TMODES.index(mem.tmode) _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.name = [0xFF] * 6 for i in range(0, len(mem.name)): try: _mem.name[i] = CHARSET.index(mem.name[i]) except IndexError: raise Exception("Character `%s' not supported") _mem.narrow = MODES.index(mem.mode) _mem.power = 3 if mem.power is None else POWER_LEVELS.index(mem.power) _flag["pskip"] = mem.skip == "P" _flag["skip"] = mem.skip == "S" for element in mem.extra: setattr(_mem, element.get_name(), element.value) chirp-20240224/chirp/drivers/icw32.py0000644000175000017500000001545314411666130016132 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import icf from chirp import chirp_common, util, directory, bitwise LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x%x; struct { bbcd freq[3]; bbcd offset[3]; u8 ctone; u8 rtone; char name[8]; } memory[111]; #seekto 0x%x; struct { u8 empty:1, skip:1, tmode:2, duplex:2, unk3:1, am:1; } flag[111]; #seekto 0x0E9C; struct { u8 unknown1:7, right_scan_direction:1; u8 right_scanning:1, unknown2:7; u8 unknown3:7, left_scan_direction:1; u8 left_scanning:1, unknown4:7; } state[1]; #seekto 0x0F20; struct { bbcd freq[3]; bbcd offset[3]; u8 ctone; u8 rtone; } callchans[2]; """ DUPLEX = ["", "", "-", "+"] TONE = ["", "", "Tone", "TSQL"] def _get_special(): special = {} for i in range(0, 5): special["M%iA" % (i+1)] = 100 + i*2 special["M%iB" % (i+1)] = 100 + i*2 + 1 return special @directory.register class ICW32ARadio(icf.IcomCloneModeRadio): """Icom IC-W32A""" VENDOR = "Icom" MODEL = "IC-W32A" _model = "\x18\x82\x00\x01" _memsize = 4064 _endframe = "Icom Inc\x2e" _ranges = [(0x0000, 0x0FE0, 16)] _limits = (0, 0) _mem_positions = (0, 1) def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 99) rf.valid_bands = [self._limits] if int(self._limits[0] / 100) == 1: rf.valid_modes = ["FM", "AM"] else: rf.valid_modes = ["FM"] rf.valid_tmodes = ["", "Tone", "TSQL"] rf.valid_name_length = 8 rf.valid_special_chans = sorted(_get_special().keys()) rf.has_sub_devices = self.VARIANT == "" rf.has_ctone = True rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_mode = "AM" in rf.valid_modes rf.has_tuning_step = False rf.has_bank = False return rf def process_mmap(self): fmt = MEM_FORMAT % self._mem_positions self._memobj = bitwise.parse(fmt, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): if isinstance(number, str): number = _get_special()[number] _mem = self._memobj.memory[number] _flg = self._memobj.flag[number] mem = chirp_common.Memory() mem.number = number if number < 100: # Normal memories mem.skip = _flg.skip and "S" or "" else: # Special memories mem.extd_number = util.get_dict_rev(_get_special(), number) if _flg.empty: mem.empty = True return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = int(_mem.offset) * 100 if str(_mem.name)[0] != chr(0xFF): mem.name = str(_mem.name).rstrip() mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.mode = _flg.am and "AM" or "FM" mem.duplex = DUPLEX[_flg.duplex] mem.tmode = TONE[_flg.tmode] if number > 100: mem.immutable = ["number", "skip", "extd_number", "name"] return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _flg = self._memobj.flag[mem.number] _flg.empty = mem.empty if mem.empty: return _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 100 if mem.name: _mem.name = mem.name.ljust(8)[:8] else: _mem.name = "".join(["\xFF" * 8]) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _flg.duplex = DUPLEX.index(mem.duplex) _flg.tmode = TONE.index(mem.tmode) _flg.skip = mem.skip == "S" _flg.am = mem.mode == "AM" if self._memobj.state.left_scanning: LOG.debug("Canceling scan on left VFO") self._memobj.state.left_scanning = 0 if self._memobj.state.right_scanning: LOG.debug("Canceling scan on right VFO") self._memobj.state.right_scanning = 0 def get_sub_devices(self): return [ICW32ARadioVHF(self._mmap), ICW32ARadioUHF(self._mmap)] @classmethod def match_model(cls, filedata, filename): if not len(filedata) == cls._memsize: return False return filedata[-16:] == b"IcomCloneFormat3" class ICW32ARadioVHF(ICW32ARadio): """ICW32 VHF subdevice""" VARIANT = "VHF" _limits = (118000000, 174000000) _mem_positions = (0x0000, 0x0DC0) class ICW32ARadioUHF(ICW32ARadio): """ICW32 UHF subdevice""" VARIANT = "UHF" _limits = (400000000, 470000000) _mem_positions = (0x06E0, 0x0E2E) # IC-W32E are the very same as IC-W32A but have a different _model @directory.register class ICW32ERadio(ICW32ARadio): """Icom IC-W32E""" MODEL = "IC-W32E" _model = "\x18\x82\x00\x02" # an extra byte is added to distinguish file images from IC-W32A # it will be allocated and initialized to 0x00 in _clone_from_radio # (icf.py) but radio will not send it # That byte is not sent to radio because the _clone_to_radio use _ranges # for the send cycle _memsize = ICW32ARadio._memsize + 1 def get_sub_devices(self): # this is needed because sub devices must be of a child class return [ICW32ERadioVHF(self._mmap), ICW32ERadioUHF(self._mmap)] @classmethod def match_model(cls, filedata, filename): if not len(filedata) == cls._memsize: return False return filedata[-16 - 1: -1] == b"IcomCloneFormat3" and \ filedata[-1] in [0, '\x00'] # this is the very same as ICW32ARadioVHF but have ICW32ERadio as parent class class ICW32ERadioVHF(ICW32ERadio): """ICW32 VHF subdevice""" VARIANT = "VHF" _limits = (118000000, 174000000) _mem_positions = (0x0000, 0x0DC0) # this is the very same as ICW32ARadioUHF but have ICW32ERadio as parent class class ICW32ERadioUHF(ICW32ERadio): """ICW32 UHF subdevice""" VARIANT = "UHF" _limits = (400000000, 470000000) _mem_positions = (0x06E0, 0x0E2E) chirp-20240224/chirp/drivers/rh5r_v2.py0000644000175000017500000002007714522657251016477 0ustar hibbyhibby# Copyright 2017 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Rugged RH5R V2 radio management module""" import struct import logging from chirp import chirp_common, bitwise, errors, directory, memmap LOG = logging.getLogger(__name__) def _identify(radio): try: radio.pipe.write("PGM2015") ack = radio.pipe.read(2) if ack != "\x06\x30": raise errors.RadioError("Radio did not ACK first command: %r" % ack) except: LOG.exception('') raise errors.RadioError("Unable to communicate with the radio") def _download(radio): _identify(radio) data = [] for i in range(0, 0x2000, 0x40): msg = struct.pack('>cHb', 'R', i, 0x40) radio.pipe.write(msg) block = radio.pipe.read(0x40 + 4) if len(block) != (0x40 + 4): raise errors.RadioError("Radio sent a short block (%02x/%02x)" % ( len(block), 0x44)) data += block[4:] if radio.status_fn: status = chirp_common.Status() status.cur = i status.max = 0x2000 status.msg = "Cloning from radio" radio.status_fn(status) radio.pipe.write("E") data += 'PGM2015' return memmap.MemoryMap(data) def _upload(radio): _identify(radio) for i in range(0, 0x2000, 0x40): msg = struct.pack('>cHb', 'W', i, 0x40) msg += radio._mmap[i:(i + 0x40)] radio.pipe.write(msg) ack = radio.pipe.read(1) if ack != '\x06': raise errors.RadioError('Radio did not ACK block %i (0x%04x)' % ( i, i)) if radio.status_fn: status = chirp_common.Status() status.cur = i status.max = 0x2000 status.msg = "Cloning from radio" radio.status_fn(status) radio.pipe.write("E") MEM_FORMAT = """ struct memory { bbcd rx_freq[4]; bbcd tx_freq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 unknown10:5, highpower:1, unknown11:2; u8 unknown20:4, narrow:1, unknown21:3; u8 unknown31:1, scanadd:1, unknown32:6; u8 unknown4; }; struct name { char name[7]; }; #seekto 0x0010; struct memory channels[128]; #seekto 0x08C0; struct name names[128]; #seekto 0x2020; struct memory vfo1; struct memory vfo2; """ POWER_LEVELS = [chirp_common.PowerLevel('Low', watts=1), chirp_common.PowerLevel('High', watts=5)] class TYTTHUVF8_V2(chirp_common.CloneModeRadio): VENDOR = "TYT" MODEL = "TH-UVF8F" BAUD_RATE = 9600 _FILEID = b'OEMOEM \\XFF' def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 128) rf.has_bank = False rf.has_ctone = True rf.valid_tuning_steps = [5, 6.25, 10, 12.5] rf.has_tuning_step = False rf.has_cross = True rf.has_rx_dtcs = True rf.has_settings = False rf.can_odd_split = False rf.valid_duplexes = ['', '-', '+'] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-" rf.valid_bands = [(136000000, 174000000), (400000000, 480000000)] rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS rf.valid_modes = ["FM", "NFM"] rf.valid_name_length = 7 rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] return rf def sync_in(self): self._mmap = _download(self) self.process_mmap() def sync_out(self): _upload(self) @classmethod def match_model(cls, filedata, filename): return (filedata.endswith(b"PGM2015") and filedata[0x840:0x848] == cls._FILEID) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return (repr(self._memobj.channels[number - 1]) + repr(self._memobj.names[number - 1])) def _get_memobjs(self, number): return (self._memobj.channels[number - 1], self._memobj.names[number - 1]) def _decode_tone(self, toneval): pol = "N" rawval = (toneval[1].get_bits(0xFF) << 8) | toneval[0].get_bits(0xFF) if toneval[0].get_bits(0xFF) == 0xFF: mode = "" val = 0 elif toneval[1].get_bits(0xC0) == 0xC0: mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) pol = "R" elif toneval[1].get_bits(0x80): mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) else: mode = "Tone" val = int(toneval) / 10.0 return mode, val, pol def _encode_tone(self, _toneval, mode, val, pol): toneval = 0 if mode == "Tone": toneval = int("%i" % (val * 10), 16) elif mode == "DTCS": toneval = int("%i" % val, 16) toneval |= 0x8000 if pol == "R": toneval |= 0x4000 else: toneval = 0xFFFF _toneval[0].set_raw(toneval & 0xFF) _toneval[1].set_raw((toneval >> 8) & 0xFF) def get_memory(self, number): _mem, _name = self._get_memobjs(number) mem = chirp_common.Memory() if isinstance(number, str): mem.number = SPECIALS[number] mem.extd_number = number else: mem.number = number if _mem.get_raw(asbytes=False).startswith("\xFF\xFF\xFF\xFF"): mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 offset = (int(_mem.tx_freq) - int(_mem.rx_freq)) * 10 if not offset: mem.offset = 0 mem.duplex = '' elif offset < 0: mem.offset = abs(offset) mem.duplex = '-' else: mem.offset = offset mem.duplex = '+' txmode, txval, txpol = self._decode_tone(_mem.tx_tone) rxmode, rxval, rxpol = self._decode_tone(_mem.rx_tone) chirp_common.split_tone_decode(mem, (txmode, txval, txpol), (rxmode, rxval, rxpol)) mem.mode = 'NFM' if _mem.narrow else 'FM' mem.skip = '' if _mem.scanadd else 'S' mem.power = POWER_LEVELS[int(_mem.highpower)] mem.name = str(_name.name).rstrip('\xFF ') return mem def set_memory(self, mem): _mem, _name = self._get_memobjs(mem.number) if mem.empty: _mem.set_raw('\xFF' * 16) _name.set_raw('\xFF' * 7) return _mem.set_raw('\x00' * 16) _mem.rx_freq = mem.freq / 10 if mem.duplex == '-': mult = -1 elif not mem.duplex: mult = 0 else: mult = 1 _mem.tx_freq = (mem.freq + (mem.offset * mult)) / 10 (txmode, txval, txpol), (rxmode, rxval, rxpol) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.tx_tone, txmode, txval, txpol) self._encode_tone(_mem.rx_tone, rxmode, rxval, rxpol) _mem.narrow = mem.mode == 'NFM' _mem.scanadd = mem.skip != 'S' _mem.highpower = POWER_LEVELS.index(mem.power) if mem.power else 1 _name.name = mem.name.rstrip(' ').ljust(7, '\xFF') @directory.register class RH5RV2(TYTTHUVF8_V2): VENDOR = "Rugged" MODEL = "RH5R-V2" _FILEID = b'RUGGED \xFF' chirp-20240224/chirp/drivers/ft1d.py0000644000175000017500000026632114562640504016047 0ustar hibbyhibby# Copyright 2010 Dan Smith # Copyright 2014 Angus Ainslie # Copyright 2023 Declan Rieb # Sections of digital settings applied from ft70.py, thus # Copyright 2017 Nicolas Pike # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import re import string import logging from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, bitwise from chirp import memmap from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettingValueList, RadioSettingValueBoolean, \ InvalidValueError from chirp import util LOG = logging.getLogger(__name__) MEM_SETTINGS_FORMAT = """ #seekto 0x047e; struct { u8 unknown1; u8 flag; u16 unknown2; struct { u8 padded_yaesu[16]; } message; } opening_message; #seekto 0x049a; struct { u8 vfo_a; u8 vfo_b; } squelch; #seekto 0x04c1; struct { u8 beep; } beep_select; #seekto 0x04ce; struct { u8 lcd_dimmer; // 14 DIMMER u8 dtmf_delay; // 18 DT DLY u8 unknown0[3]; u8 unknown1:4, lcd_contrast:4; u8 lamp; // 28 LAMP u8 lock; // 30 LOCK u8 unknown2; u8 mic_gain; // 31 MCGAIN u8 unknown2_3; u8 dw_interval; // 21 DW INT u8 ptt_delay; // 42 PTT.DLY u8 rx_save; // 48 RX.SAVE u8 scan_restart; // 53 SCN.STR u8 unknown3; u8 scan_resume; u8 unknown4[5]; u8 tot; u8 unknown5[3]; u8 vfo_mode:1, // 60 VFO.MOD unknown6:1, scan_lamp:1, // 51 SCN.LMP unknown7:1, ars:1, // 45 RPT.ARS dtmf_speed:1, // 20 DT SPD unknown8:1, dtmf_mode:1; u8 busy_led:1, unknown9:2, bclo:1, // 03 BCLO beep_edge:1, // 06 BEP.EDG unknown9_1:3; u8 unknown10:5, password:1, home_rev:1, // 26 HOME/REV moni:1; // 32 MON/T-Call u8 gm_interval:4, // 25 GM INT unknown11:4; u8 vol_mode:1, unknown11_1:7; u8 unknown12:4, home_vfo:1, // 27 HOME->VFO unknown12_1:2, dw_rt:1; // 23 DW RVT; } scan_settings; #seekto 0x54a; struct { u16 in_use; } bank_used[24]; #seekto 0x064a; struct { u8 unknown0[4]; u8 frequency_band; u8 unknown1:6, manual_or_mr:2; u8 unknown2:7, mr_banks:1; u8 unknown3; u16 mr_index; u16 bank_index; u16 bank_enable; u8 unknown4[5]; u8 unknown5:6, power:2; u8 unknown6:4, tune_step:4; u8 unknown7:6, duplex:2; u8 unknown8:6, tone_mode:2; u8 unknown9:2, tone:6; u8 unknown10; u8 unknown11:6, mode:2; bbcd freq0[4]; bbcd offset_freq[4]; u8 unknown12[2]; char label[16]; u8 unknown13[6]; bbcd band_lower[4]; bbcd band_upper[4]; bbcd rx_freq[4]; u8 unknown14[22]; bbcd freq1[4]; u8 unknown15[11]; u8 unknown16:3, volume:5; u8 unknown17[18]; u8 active_menu_item; u8 checksum; } vfo_info[6]; #seekto 0x%(dtmadd)04X; // FT-1D:0e4a, FT2D:094a struct { u8 memory[16]; } dtmf[10]; #seekto 0x0EFE; struct { u8 unknown[2]; u8 name[16]; } bank_info[24]; #seekto 0x154a; // These "channels" seem to actually be a structure: // first five bits are flags // 0 Unused (1=entry is unused) // 1 SW Broadcast // 2 VHF Marine // 3 WX (weather) // 4 ? a mode? ? // 11 bits of index into frequency tables // struct { u16 channel[100]; } bank_members[24]; """ MEM_FORMAT = """ struct memslot { u8 unknown0:2, mode_alt:1, // mode for FTM-3200D clock_shift:1, unknown1:4; u8 mode:2, duplex:2, tune_step:4; bbcd freq[3]; u8 power:2, digmode:2, // 0=Analog, 1=AMS, 2=DN, 3=VW tone_mode:4; u16 charsetbits; char label[16]; bbcd offset[3]; u8 unknown5:2, tone:6; u8 unknown6:1, dcs:7; u16 unknown7; u8 unknown8:2, att:1, autostep:1, automode:1, unknown9:3; }; #seekto 0x2D4A; struct memslot memory[%(memnum)d]; struct memslot Skip[99]; struct memslot PMS[100]; #seekto 0x10ca; struct memslot Home[11]; struct flagslot { u8 nosubvfo:1, unknown:3, pskip:1, skip:1, used:1, valid:1; }; #seekto 0x280A; struct flagslot flag[%(memnum)d]; struct flagslot flagskp[99]; struct flagslot flagPMS[100]; """ MEM_APRS_FORMAT = """ #seekto 0xbeca; struct { u8 rx_baud; u8 custom_symbol; struct { char callsign[6]; u8 ssid; } my_callsign; u8 unknown3:4, selected_position_comment:4; u8 unknown4; u8 set_time_manually:1, tx_interval_beacon:1, ring_beacon:1, ring_msg:1, aprs_mute:1, unknown6:1, tx_smartbeacon:1, af_dual:1; u8 unknown7:1, aprs_units_wind_mph:1, aprs_units_rain_inch:1, aprs_units_temperature_f:1, aprs_units_altitude_ft:1, unknown8:1, aprs_units_distance_m:1, aprs_units_position_mmss:1; u8 unknown9:6, aprs_units_speed:2; u8 unknown11:1, filter_other:1, filter_status:1, filter_item:1, filter_object:1, filter_weather:1, filter_position:1, filter_mic_e:1; u8 unknown12; u8 unknown13; u8 unknown14; u8 unknown15:7, latitude_sign:1; u8 latitude_degree; u8 latitude_minute; u8 latitude_second; u8 unknown16:7, longitude_sign:1; u8 longitude_degree; u8 longitude_minute; u8 longitude_second; u8 unknown17:4, selected_position:4; u8 unknown18:5, selected_beacon_status_txt:3; u8 unknown19:4, beacon_interval:4; u8 unknowni21:4, tx_delay:4; u8 unknown21b:6, gps_units_altitude_ft:1, gps_units_position_sss:1; u8 unknown20:6, gps_units_speed:2; u8 unknown21c[4]; struct { struct { char callsign[6]; u8 ssid; } entry[8]; } digi_path_7; u8 unknown22[18]; struct { char padded_string[16]; } message_macro[7]; u8 unknown23:5, selected_msg_group:3; u8 unknown24; struct { char padded_string[9]; } msg_group[8]; u8 unknown25; u8 unknown25a:2, timezone:6; u8 unknown25b[2]; u8 active_smartbeaconing; struct { u8 low_speed_mph; u8 high_speed_mph; u8 slow_rate_min; u8 fast_rate_sec; u8 turn_angle; u8 turn_slop; u8 turn_time_sec; } smartbeaconing_profile[3]; u8 unknown26:2, flash_msg:6; u8 unknown27:2, flash_grp:6; u8 unknown28:2, flash_bln:6; u8 selected_digi_path; struct { struct { char callsign[6]; u8 ssid; } entry[2]; } digi_path_3_6[4]; u8 unknown30:6, selected_my_symbol:2; u8 unknown31[3]; u8 unknown32:2, vibrate_msg:6; u8 unknown33:2, vibrate_grp:6; u8 unknown34:2, vibrate_bln:6; } aprs; #seekto 0xc26a; struct { char padded_string[60]; } aprs_beacon_status_txt[5]; #seekto 0xFECA; struct { bbcd date[3]; bbcd time[2]; u8 sequence; u8 unknown1; u8 unknown2; char sender_callsign[9]; u8 data_type; u8 yeasu_data_type; u8 unknown4:1, callsign_is_ascii:1, unknown5:6; u8 unknown6; u16 pkt_len; u8 unknown7; u16 in_use; u16 unknown8; u16 unknown9; u16 unknown10; } aprs_beacon_meta[60]; #seekto 0x1064A; struct { char dst_callsign[9]; char path[30]; u16 flags; u8 separator; char body[134]; } aprs_beacon_pkt[60]; #seekto 0x137c4; struct { u8 flag; char dst_callsign[6]; u8 dst_callsign_ssid; char path_and_body[66]; u8 unknown[70]; } aprs_message_pkt[60]; """ MEM_BACKTRACK_FORMAT = """ #seekto 0xdf06; struct { u8 status; // 01 full 08 empty u8 reserved0; // 00 bbcd year; // 17 bbcd mon; // 06 bbcd day; // 01 u8 reserved1; // 06 bbcd hour; // 21 bbcd min; // xx u8 reserved2; // 00 u8 reserved3; // 00 char NShemi[1]; char lat[3]; char lat_min[2]; char lat_dec_sec[4]; char WEhemi[1]; char lon[3]; char lon_min[2]; char lon_dec_sec[4]; } backtrack[3]; """ MEM_GM_FORMAT = """ #seekto 0x04ba; struct { u8 unknown:3, scan_resume:5; // 52 SCN.RSM u8 unknown1:3, dw_resume_interval:5; // 22 DW RSM u8 unknown2; u8 unknown3:3, apo:5; // 02 APO u8 unknown4:6, gm_ring:2; // 24 GM RNG u8 temp_cf; // Placeholder as not found } first_settings; #seekto 0x04c0; struct { u8 unknown1:5, beep_level:3; // 05 BEP.LVL u8 unknown2:6, beep_select:2; // 04 BEEP } beep_settings; #seekto 0x04ed; struct { u8 unknown1:1, unknown2:1, unknown3:1, unknown4:1, unknown5:1, unknown6:1, unknown7:1, unknown8:1; } test_bit_field; #seekto 0x0ced0; struct { char callsign[10]; // 63 MYCALL u16 charset; // character set ID } my_call; #seekto 0xCF30; struct { u8 unknown0; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 unknown5; u8 unknown6; u8 digital_popup; // 15 DIG.POP } digital_settings_more; #seekto 0xCF7C; struct { u8 unknown0:6, ams_tx_mode:2; // AMS TX Mode u8 unknown1; u8 unknown2:7, standby_beep:1; // 07 BEP.STB u8 unknown3; u8 unknown4:6, gm_ring:2; // 24 GM RNG u8 unknown5; u8 rx_dg_id; // RX DG-ID u8 tx_dg_id; // TX DG-ID u8 unknown6:7, vw_mode:1; // 16 DIG VW u8 unknown7; } digital_settings; #seekto 0x1d6d3; struct { char message[32]; } GM[10]; #seekto 0x1ddca; struct { struct { char name[16]; } Category[5]; struct { struct { char ID[5]; // ASCII numerals char name[16]; // blank-fill u8 unknown[3]; } Rooms[20]; } RoomsPerCategory[5]; } WiresX_settings; """ MEM_CHECKSUM_FORMAT = """ #seekto 0x1FDC9; u8 checksum; """ TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+", "split"] MODES = ["FM", "AM", "WFM"] STEPS = list(chirp_common.TUNING_STEPS) STEPS.remove(30.0) STEPS.append(100.0) STEPS.insert(2, 0.0) # There is a skipped tuning step at index 2 (?) SKIPS = ["", "S", "P"] FT1_DTMF_CHARS = list("0123456789ABCD*#-") CHARSET = ["%i" % int(x) for x in range(0, 10)] + \ [chr(x) for x in range(ord("A"), ord("Z") + 1)] + \ [" ", ] + \ [chr(x) for x in range(ord("a"), ord("z") + 1)] + \ list(".,:;*#_-/&()@!?^ ") + list("\x00" * 100) POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00), chirp_common.PowerLevel("L3", watts=2.50), chirp_common.PowerLevel("L2", watts=1.00), chirp_common.PowerLevel("L1", watts=0.05)] SKIPNAMES = ["Skip%i" % i for i in range(901, 1000)] PMSNAMES = ["%s%i" % (c, i) for i in range(1, 51) for c in ['L', 'U']] HOMENAMES = ["Home%i" % i for i in range(1, 12)] ALLNAMES = SKIPNAMES + PMSNAMES + HOMENAMES # list of (array name, (list of memories in that array)) # array names must match names of memories defined for radio SPECIALS = [ ("Skip", SKIPNAMES), ("PMS", PMSNAMES), ("Home", HOMENAMES) ] # Band edges are integer Hz. VALID_BANDS = [ (510000, 1790000), (1800000, 50490000), (50500000, 75990000), (76000000, 107990000), (108000000, 136990000), (145000000, 169920000), (174000000, 221950000), (222000000, 419990000), (420000000, 469990000), (470000000, 773990000), (810010000, 999000000) ] class FT1Bank(chirp_common.NamedBank): """A FT1D bank""" def get_name(self): _bank = self._model._radio._memobj.bank_info[self.index] name = "" for i in _bank.name: if i == 0xFF: break name += CHARSET[i & 0x7F] return name.rstrip() def set_name(self, name): _bank = self._model._radio._memobj.bank_info[self.index] _bank.name = [CHARSET.index(x) for x in name.ljust(16)[:16]] class FT1BankModel(chirp_common.BankModel): """A FT1D bank model""" def __init__(self, radio, name='Banks'): super(FT1BankModel, self).__init__(radio, name) _banks = self._radio._memobj.bank_info self._bank_mappings = [] for index, _bank in enumerate(_banks): bank = FT1Bank(self, "%i" % index, "BANK-%i" % index) bank.index = index self._bank_mappings.append(bank) def get_num_mappings(self): return len(self._bank_mappings) def get_mappings(self): return self._bank_mappings def _channel_numbers_in_bank(self, bank): _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xFFFF: return set() _members = self._radio._memobj.bank_members[bank.index] return set([int(ch) + 1 for ch in _members.channel if ch != 0xFFFF]) def update_vfo(self): chosen_bank = [None, None] chosen_mr = [None, None] flags = self._radio._memobj.flag # Find a suitable bank and MR for VFO A and B. for bank in self.get_mappings(): for channel in self._channel_numbers_in_bank(bank): chosen_bank[0] = bank.index chosen_mr[0] = channel if channel & 0x7000 != 0: # Ignore preset channels without comment DAR break if not flags[channel].nosubvfo: chosen_bank[1] = bank.index chosen_mr[1] = channel break if chosen_bank[1]: break for vfo_index in (0, 1): # 3 VFO info structs are stored as 3 pairs of (master, backup) vfo = self._radio._memobj.vfo_info[vfo_index * 2] vfo_bak = self._radio._memobj.vfo_info[(vfo_index * 2) + 1] if vfo.checksum != vfo_bak.checksum: LOG.warn("VFO settings are inconsistent with backup") else: if ((chosen_bank[vfo_index] is None) and (vfo.bank_index != 0xFFFF)): LOG.info("Disabling banks for VFO %d" % vfo_index) vfo.bank_index = 0xFFFF vfo.mr_index = 0xFFFF vfo.bank_enable = 0xFFFF elif ((chosen_bank[vfo_index] is not None) and (vfo.bank_index == 0xFFFF)): LOG.info("Enabling banks for VFO %d" % vfo_index) vfo.bank_index = chosen_bank[vfo_index] vfo.mr_index = chosen_mr[vfo_index] vfo.bank_enable = 0x0000 vfo_bak.bank_index = vfo.bank_index vfo_bak.mr_index = vfo.mr_index vfo_bak.bank_enable = vfo.bank_enable def _update_bank_with_channel_numbers(self, bank, channels_in_bank): _members = self._radio._memobj.bank_members[bank.index] if len(channels_in_bank) > len(_members.channel): raise Exception("Too many entries in bank %d" % bank.index) empty = 0 for index, channel_number in enumerate(sorted(channels_in_bank)): _members.channel[index] = channel_number - 1 if channel_number & 0x7000 != 0: LOG.warn("Bank %d uses Yaesu preset frequency id=%04X. " "Chirp cannot see or change that entry." % ( bank.index, channel_number)) empty = index + 1 for index in range(empty, len(_members.channel)): _members.channel[index] = 0xFFFF def add_memory_to_mapping(self, memory, bank): channels_in_bank = self._channel_numbers_in_bank(bank) channels_in_bank.add(memory.number) self._update_bank_with_channel_numbers(bank, channels_in_bank) _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0x06 self.update_vfo() def remove_memory_from_mapping(self, memory, bank): channels_in_bank = self._channel_numbers_in_bank(bank) try: channels_in_bank.remove(memory.number) except KeyError: raise Exception("Memory %i is not in bank %s. Cannot remove" % (memory.number, bank)) self._update_bank_with_channel_numbers(bank, channels_in_bank) if not channels_in_bank: _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0xFFFF self.update_vfo() def get_mapping_memories(self, bank): memories = [] for channel in self._channel_numbers_in_bank(bank): memories.append(self._radio.get_memory(channel)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in self._channel_numbers_in_bank(bank): banks.append(bank) return banks # Note: other radios like FTM3200Radio subclass this radio @directory.register class FT1Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT1DR""" BAUD_RATE = 38400 VENDOR = "Yaesu" MODEL = "FT-1D" VARIANT = "R" FORMATS = [directory.register_format('FT1D ADMS-6', '*.ft1d')] class_specials = SPECIALS _model = b"AH44M" _memsize = 130507 _block_lengths = [10, 130497] _block_size = 32 MAX_MEM_SLOT = 900 _mem_params = { "memnum": 900, # size of memories array "flgnum": 900, # size of flags array "dtmadd": 0xe4a, # location of DTMF storage } _has_vibrate = False _has_af_dual = True _adms_ext = '.ft1d' _SG_RE = re.compile(r"(?P[-+NESW]?)(?P[\d]+)[\s\.,]*" r"(?P[\d]*)[\s\']*(?P[\d]*)") _RX_BAUD = ("off", "1200 baud", "9600 baud") _TX_DELAY = ("100ms", "150ms", "200ms", "250ms", "300ms", "400ms", "500ms", "750ms", "1000ms") _WIND_UNITS = ("m/s", "mph") _RAIN_UNITS = ("mm", "inch") _TEMP_UNITS = ("C", "F") _ALT_UNITS = ("m", "ft") _DIST_UNITS = ("km", "mile") _POS_UNITS = ("dd.mmmm'", "dd mm'ss\"") _SPEED_UNITS = ("km/h", "knot", "mph") _TIME_SOURCE = ("manual", "GPS") _TZ = ("-13:00", "-13:30", "-12:00", "-12:30", "-11:00", "-11:30", "-10:00", "-10:30", "-09:00", "-09:30", "-08:00", "-08:30", "-07:00", "-07:30", "-06:00", "-06:30", "-05:00", "-05:30", "-04:00", "-04:30", "-03:00", "-03:30", "-02:00", "-02:30", "-01:00", "-01:30", "-00:00", "-00:30", "+01:00", "+01:30", "+02:00", "+02:30", "+03:00", "+03:30", "+04:00", "+04:30", "+05:00", "+05:30", "+06:00", "+06:30", "+07:00", "+07:30", "+08:00", "+08:30", "+09:00", "+09:30", "+10:00", "+10:30", "+11:00", "+11:30") _BEACON_TYPE = ("Off", "Interval", "SmartBeaconing") _SMARTBEACON_PROFILE = ("Off", "Type 1", "Type 2", "Type 3") _BEACON_INT = ("30s", "1m", "2m", "3m", "5m", "10m", "15m", "20m", "30m", "60m") _DIGI_PATHS = ("OFF", "WIDE1-1", "WIDE1-1, WIDE2-1", "Digi Path 4", "Digi Path 5", "Digi Path 6", "Digi Path 7", "Digi Path 8") _MSG_GROUP_NAMES = ("Message Group 1", "Message Group 2", "Message Group 3", "Message Group 4", "Message Group 5", "Message Group 6", "Message Group 7", "Message Group 8") _POSITIONS = ("GPS", "Manual Latitude/Longitude", "Manual Latitude/Longitude", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9") _FLASH = ("OFF", "2 seconds", "4 seconds", "6 seconds", "8 seconds", "10 seconds", "20 seconds", "30 seconds", "60 seconds", "CONTINUOUS", "every 2 seconds", "every 3 seconds", "every 4 seconds", "every 5 seconds", "every 6 seconds", "every 7 seconds", "every 8 seconds", "every 9 seconds", "every 10 seconds", "every 20 seconds", "every 30 seconds", "every 40 seconds", "every 50 seconds", "every minute", "every 2 minutes", "every 3 minutes", "every 4 minutes", "every 5 minutes", "every 6 minutes", "every 7 minutes", "every 8 minutes", "every 9 minutes", "every 10 minutes") _BEEP_SELECT = ("Off", "Key+Scan", "Key") _SQUELCH = ["%d" % x for x in range(0, 16)] _VOLUME = ["%d" % x for x in range(0, 33)] _OPENING_MESSAGE = ("Off", "DC", "Message", "Normal") _SCAN_RESUME = ["%.1fs" % (0.5 * x) for x in range(4, 21)] + \ ["Busy", "Hold"] _SCAN_RESTART = ["%.1fs" % (0.1 * x) for x in range(1, 10)] + \ ["%.1fs" % (0.5 * x) for x in range(2, 21)] _LAMP_KEY = ["Key %d sec" % x for x in range(2, 11)] + ["Continuous", "OFF"] _LCD_CONTRAST = ["Level %d" % x for x in range(1, 16)] _LCD_DIMMER = ["Level %d" % x for x in range(1, 7)] _TOT_TIME = ["Off"] + ["%.1f min" % (0.5 * x) for x in range(1, 21)] _OFF_ON = ("Off", "On") _VOL_MODE = ("Normal", "Auto Back") _DTMF_MODE = ("Manual", "Auto") _DTMF_SPEED = ("50ms", "100ms") _DTMF_DELAY = ("50ms", "250ms", "450ms", "750ms", "1000ms") _MY_SYMBOL = ("/[ Person", "/b Bike", "/> Car", "User selected") _BACKTRACK_STATUS = ("Valid", "Invalid") _NS_HEMI = ("N", "S") _WE_HEMI = ("W", "E") _APRS_HIGH_SPEED_MAX = 70 _MIC_GAIN = ("Level %d" % i for i in range(1, 10)) _AMS_TX_MODE = ("TX Auto", "TX DIGITAL", "TX FM") _VW_MODE = ("On", "Off") _DIG_POP_UP = ("Off", "2sec", "4sec", "6sec", "8sec", "10sec", "20sec", "30sec", "60sec", "Continuous") _STANDBY_BEEP = ("On", "Off") _ON_OFF = ("On", "Off") _TEMP_CF = ("Centigrade", "Fahrenheit") _APO_SELECT = ("Off", "0.5H", "1.0H", "1.5H", "2.0H", "2.5H", "3.0H", "3.5H", "4.0H", "4.5H", "5.0H", "5.5H", "6.0H", "6.5H", "7.0H", "7.5H", "8.0H", "8.5H", "9.0H", "9.5H", "10.0H", "10.5H", "11.0H", "11.5H", "12.0H") _MONI_TCALL = ("Monitor", "Tone-CALL") _HOME_REV = ("Home", "Reverse") _LOCK = ("KEY", "DIAL", "Key+Dial", "PTT", "Key+PTT", "Dial+PTT", "ALL") _PTT_DELAY = ("Off", "20 ms", "50 ms", "100 ms", "200 ms") _BEEP_LEVEL = ("Level %i" % i for i in range(1, 7)) _SET_MODE = ("Level %i" % i for i in range(1, 8)) _RX_SAVE = ("OFF", "0.2s", ".3s", ".4s", ".5s", ".6s", ".7s", ".8s", ".9s", "1.0s", "1.5s", "2.0s", "2.5s", "3.0s", "3.5s", "4.0s", "4.5s", "5.0s", "5.5s", "6.0s", "6.5s", "7.0s", "7.5s", "8.0s", "8.5s", "9.0s", "10.0s", "15s", "20s", "25s", "30s", "35s", "40s", "45s", "50s", "55s", "60s") _VFO_MODE = ("ALL", "BAND") _VFO_SCAN_MODE = ("BAND", "ALL") _MEMORY_SCAN_MODE = ("BAND", "ALL") _RX_BAUD = ("off", "1200 baud", "9600 baud") _TX_DELAY = ("100ms", "150ms", "200ms", "250ms", "300ms", "400ms", "500ms", "750ms", "1000ms") _WIND_UNITS = ("m/s", "mph") _RAIN_UNITS = ("mm", "inch") _TEMP_UNITS = ("C", "F") _ALT_UNITS = ("m", "ft") _DIST_UNITS = ("km", "mile") _POS_UNITS = ("dd.mmmm'", "dd mm'ss\"") _SPEED_UNITS = ("km/h", "knot", "mph") _TIME_SOURCE = ("manual", "GPS") _TZ = ("-13:00", "-13:30", "-12:00", "-12:30", "-11:00", "-11:30", "-10:00", "-10:30", "-09:00", "-09:30", "-08:00", "-08:30", "-07:00", "-07:30", "-06:00", "-06:30", "-05:00", "-05:30", "-04:00", "-04:30", "-03:00", "-03:30", "-02:00", "-02:30", "-01:00", "-01:30", "-00:00", "-00:30", "+01:00", "+01:30", "+02:00", "+02:30", "+03:00", "+03:30", "+04:00", "+04:30", "+05:00", "+05:30", "+06:00", "+06:30", "+07:00", "+07:30", "+08:00", "+08:30", "+09:00", "+09:30", "+10:00", "+10:30", "+11:00", "+11:30") _BEACON_TYPE = ("Off", "Interval", "SmartBeaconing") _SMARTBEACON_PROFILE = ("Off", "Type 1", "Type 2", "Type 3") _BEACON_INT = ("30s", "1m", "2m", "3m", "5m", "10m", "15m", "20m", "30m", "60m") _DIGI_PATHS = ("OFF", "WIDE1-1", "WIDE1-1, WIDE2-1", "Digi Path 4", "Digi Path 5", "Digi Path 6", "Digi Path 7", "Digi Path 8") _MSG_GROUP_NAMES = ("Message Group 1", "Message Group 2", "Message Group 3", "Message Group 4", "Message Group 5", "Message Group 6", "Message Group 7", "Message Group 8") _POSITIONS = ("GPS", "Manual Latitude/Longitude", "Manual Latitude/Longitude", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9") _FLASH = ("OFF", "2 seconds", "4 seconds", "6 seconds", "8 seconds", "10 seconds", "20 seconds", "30 seconds", "60 seconds", "CONTINUOUS", "every 2 seconds", "every 3 seconds", "every 4 seconds", "every 5 seconds", "every 6 seconds", "every 7 seconds", "every 8 seconds", "every 9 seconds", "every 10 seconds", "every 20 seconds", "every 30 seconds", "every 40 seconds", "every 50 seconds", "every minute", "every 2 minutes", "every 3 minutes", "every 4 minutes", "every 5 minutes", "every 6 minutes", "every 7 minutes", "every 8 minutes", "every 9 minutes", "every 10 minutes") _BEEP_SELECT = ("Off", "Key+Scan", "Key") _SQUELCH = ["%d" % x for x in range(0, 16)] _VOLUME = ["%d" % x for x in range(0, 33)] _DG_ID = ["%d" % x for x in range(0, 100)] _GM_RING = ("OFF", "IN RING", "ALWAYS") _GM_INTERVAL = ("LONG", "NORMAL", "OFF") _MYCALL_CHR_SET = list(string.ascii_uppercase) + \ list(string.digits) + ['-', '/'] @classmethod def match_model(cls, filedata, filename): if filename.endswith(cls._adms_ext): return True else: return super().match_model(filedata, filename) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to DATA terminal.\n" "3. Press and hold in the [F] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. After clicking OK, press the [BAND] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to DATA terminal.\n" "3. Press and hold in the [F] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. Press the [Dx] key (\"-WAIT-\" will appear on the LCD).\n") return rp def process_mmap(self): mem_format = MEM_SETTINGS_FORMAT + MEM_FORMAT + MEM_APRS_FORMAT + \ MEM_GM_FORMAT + MEM_BACKTRACK_FORMAT + MEM_CHECKSUM_FORMAT self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.valid_modes = list(MODES) + ['NFM', 'DN'] rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(500000, 999900000)] rf.valid_skips = SKIPS rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 16 rf.memory_bounds = (1, 900) rf.can_odd_split = True rf.has_ctone = False rf.has_bank_names = True rf.has_settings = True rf.valid_special_chans = [name for s in SPECIALS for name in s[1]] return rf def get_raw_memory(self, number): return "\n".join([repr(self._memobj.memory[number - 1]), repr(self._memobj.flag[number - 1])]) def _checksums(self): return [yaesu_clone.YaesuChecksum(0x064A, 0x06C8), yaesu_clone.YaesuChecksum(0x06CA, 0x0748), yaesu_clone.YaesuChecksum(0x074A, 0x07C8), yaesu_clone.YaesuChecksum(0x07CA, 0x0848), yaesu_clone.YaesuChecksum(0x0000, 0x1FDC9)] @staticmethod def _add_ff_pad(val, length): return val.ljust(length, b"\xFF")[:length] @classmethod def _strip_ff_pads(cls, messages): result = [] for msg_text in messages: result.append(str(msg_text).rstrip("\xFF")) return result # Called with a "memref" index to CHIRP memory (int or str) # and optionally with a "extref" extended name. # Find and return the corresponding memobj # Returns: # Corresponding radio memory object # Corresponding radio alag structure (if any) # index into the specific memory object structure (int) ndx # overall index into memory & specials (int) num # an indicator of the specific radio object structure (str) def slotloc(self, memref, extref=None): array = None num = memref ename = "" mstr = isinstance(memref, str) specials = ALLNAMES extr = False if extref is not None: extr = extref in specials if mstr or extr: # named special? ename = memref num = self.MAX_MEM_SLOT + 1 # num = -1 sname = memref if mstr else extref # Find name of appropriate memory and index into that memory for x in self.class_specials: try: ndx = x[1].index(sname) array = x[0] break except Exception: num += len(x[1]) # num -= len(x[1]) if array is None: raise IndexError("Unknown special %s" % memref) num += ndx # num -= ndx elif memref > self.MAX_MEM_SLOT: # numbered special ename = extref ndx = memref - (self.MAX_MEM_SLOT + 1) # Find name of appropriate memory and index into that memory # But assumes specials are in reverse-quantity order for x in self.class_specials: if ndx < len(x[1]): array = x[0] break ndx -= len(x[1]) if array is None: raise IndexError("Unknown memref number %s" % memref) else: array = "memory" ndx = memref - 1 _flag = self._memobj.flag[ndx] if array == "Skip": _flag = self._memobj.flagskp[ndx] elif array == "PMS": _flag = self._memobj.flagPMS[ndx] elif array == "Home": _flag = None _mem = getattr(self._memobj, array)[ndx] return (_mem, _flag, ndx, num, array, ename) # Build CHIRP version (mem) of radio's memory (_mem) def get_memory(self, number): _mem, _flag, ndx, num, array, ename = self.slotloc(number) mem = chirp_common.Memory() mem.number = num if array == "Home": mem.empty = False mem.extd_number = ename mem.name = self._decode_label(_mem) mem.immutable += ["empty", "number", "extd_number", "skip"] elif array != "memory": mem.extd_number = ename mem.immutable += ["name", "extd_number"] else: mem.name = self._decode_label(_mem) if _flag is not None: mem.skip = _flag.pskip and "P" or _flag.skip and "S" or "" mem.empty = False if not _flag.used: mem.empty = True if not _flag.valid: mem.empty = True if mem.empty: mem.freq = 0 mem.offset = 0 mem.duplex = "" mem.power = POWER_LEVELS[0] mem.mode = "FM" mem.tuning_step = 0 else: mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = int(_mem.offset) * 1000 mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] self._get_tmode(mem, _mem) if mem.duplex is None: mem.duplex = DUPLEX[""] else: mem.duplex = DUPLEX[_mem.duplex] if mem.duplex == "split": mem.offset = chirp_common.fix_rounded_step(mem.offset) mem.mode = self._decode_mode(_mem) mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] mem.tuning_step = STEPS[_mem.tune_step] mem.power = self._decode_power_level(_mem) self._get_mem_extra(mem, _mem) return mem def _get_mem_extra(self, mem, _mem): mem.extra = RadioSettingGroup('Extra', 'extra') ams = _mem.digmode == 1 rs = RadioSetting('ysf_ams', 'AMS mode', RadioSettingValueBoolean(ams)) mem.extra.append(rs) def _set_mem_extra(self, mem, _mem): if 'ysf_ams' in mem.extra: # We only set AMS if the memory mode is DN. If it is FM, # then that takes precedence as "analog-only". if mem.mode == 'DN': orig = int(_mem.digmode) _mem.digmode = int(mem.extra['ysf_ams'].value) and 1 or 2 LOG.debug('Changed digmode from %i to %i' % ( orig, _mem.digmode)) def _decode_label(self, mem): charset = ''.join(CHARSET).ljust(256, '.') return str(mem.label).rstrip("\xFF").translate(charset) def _encode_label(self, mem): label = "".join([chr(CHARSET.index(x)) for x in mem.name.rstrip()]).encode() return self._add_ff_pad(label, 16) def _encode_charsetbits(self, mem): # We only speak English here in chirpville return 0x0000 def _decode_power_level(self, mem): return POWER_LEVELS[3 - mem.power] def _encode_power_level(self, mem): if mem.power is None: return 3 # Choose lowest power else: return 3 - POWER_LEVELS.index(mem.power) def _decode_mode(self, mem): mode = MODES[mem.mode] if mode == 'FM' and int(mem.digmode): # DN mode is FM with a digital flag. Since digmode can be AMS or # DN, either will be called 'DN' in chirp return 'DN' if mode == 'FM' and int(mem.mode_alt): return 'NFM' else: return mode def _encode_mode(self, mem): mode = mem.mode if mode == 'NFM': # Narrow is handled by a separate flag mode = 'FM' elif mode == 'DN': # DN mode is FM with a digital flag mode = 'FM' return MODES.index(mode) def _get_tmode(self, mem, _mem): mem.tmode = TMODES[_mem.tone_mode] def _set_tmode(self, _mem, mem): _mem.tone_mode = TMODES.index(mem.tmode) def _set_mode(self, _mem, mem): _mem.mode_alt = mem.mode == 'NFM' if mem.mode == 'DN' and int(_mem.digmode) == 0: # If we are going to DN mode, default to AMS LOG.debug('New mode DN, setting AMS') if 'ysf_ams' not in mem.extra: _mem.digmode = 1 else: # If we have the extra setting, use that, since it will be # applied at the end of set_memory() and we want it to apply # the right value. mem.extra['ysf_ams'].value = True elif mem.mode == 'FM' and int(_mem.digmode): # If we are going back to FM, that means analog-only, so AMS # is disabled LOG.debug('New mode FM, disabling AMS') _mem.digmode = 0 _mem.mode = self._encode_mode(mem) bm = self.get_bank_model() for bank in bm.get_memory_mappings(mem): bm.remove_memory_from_mapping(mem, bank) def _debank(self, mem): bm = self.get_bank_model() for bank in bm.get_memory_mappings(mem): bm.remove_memory_from_mapping(mem, bank) def validate_memory(self, mem): # Only check the home registers for appropriate bands msgs = super().validate_memory(mem) ndx = mem.number - ALLNAMES.index("Home1") - self.MAX_MEM_SLOT - 1 if 10 >= ndx >= 0: f = VALID_BANDS[ndx] if not(f[0] < mem.freq < f[1]): msgs.append(chirp_common.ValidationError( "Frequency outside of band for Home%2d" % (ndx + 1))) return msgs # Modify radio's memory (_mem) corresponding to CHIRP version at 'mem' def set_memory(self, mem): _mem, flag, ndx, num, regtype, ename = self.slotloc(mem.number, mem.extd_number) if mem.empty: self._wipe_memory(_mem) if flag is not None: flag.used = False return _mem.power = self._encode_power_level(mem) _mem.tone = chirp_common.TONES.index(mem.rtone) self._set_tmode(_mem, mem) _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tune_step = STEPS.index(mem.tuning_step) # duplex "off" is equivalent to "" and may show up in tox test. if mem.duplex is None: _mem.duplex = DUPLEX.index("") else: _mem.duplex = DUPLEX.index(mem.duplex) self._set_mode(_mem, mem) if flag is not None: if mem.freq < 30000000 or \ (mem.freq > 88000000 and mem.freq < 108000000) or \ mem.freq > 580000000: flag.nosubvfo = True # Masked from VFO B else: flag.nosubvfo = False # Available in both VFOs if regtype != "Home": self._debank(mem) ndx = num - 1 flag.used = not mem.empty flag.valid = True flag.skip = mem.skip == "S" flag.pskip = mem.skip == "P" freq = mem.freq _mem.freq = int(freq / 1000) _mem.offset = int(mem.offset / 1000) _mem.label = self._encode_label(mem) _mem.charsetbits = self._encode_charsetbits(mem) self._set_mem_extra(mem, _mem) return @classmethod def _wipe_memory(cls, mem): mem.set_raw("\x00" * (mem.size() // 8)) mem.unknown1 = 0x05 def get_bank_model(self): return FT1BankModel(self) @classmethod def _digi_path_to_str(cls, path): path_cmp = [] for entry in path.entry: callsign = str(entry.callsign).rstrip("\xFF") if not callsign: break path_cmp.append("%s-%d" % (callsign, entry.ssid)) return ",".join(path_cmp) @staticmethod def _latlong_sanity(sign, l_d, l_m, l_s, is_lat): if sign not in (0, 1): sign = 0 if is_lat: d_max = 90 else: d_max = 180 if l_d < 0 or l_d > d_max: l_d = 0 l_m = 0 l_s = 0 if l_m < 0 or l_m > 60: l_m = 0 l_s = 0 if l_s < 0 or l_s > 60: l_s = 0 return sign, l_d, l_m, l_s @classmethod def _latlong_to_str(cls, sign, l_d, l_m, l_s, is_lat, to_sexigesimal=True): sign, l_d, l_m, l_s = cls._latlong_sanity(sign, l_d, l_m, l_s, is_lat) mult = sign and -1 or 1 if to_sexigesimal: return "%d,%d'%d\"" % (mult * l_d, l_m, l_s) return "%0.5f" % (mult * l_d + (l_m / 60.0) + (l_s / (60.0 * 60.0))) @classmethod def _str_to_latlong(cls, lat_long, is_lat): sign = 0 result = [0, 0, 0] lat_long = lat_long.strip() if not lat_long: return 1, 0, 0, 0 try: # DD.MMMMM is the simple case, try that first. val = float(lat_long) if val < 0: sign = 1 val = abs(val) result[0] = int(val) result[1] = int(val * 60) % 60 result[2] = int(val * 3600) % 60 except ValueError: # Try DD MM'SS" if DD.MMMMM failed. match = cls._SG_RE.match(lat_long.strip()) if match: if match.group("sign") and (match.group("sign") in "SE-"): sign = 1 else: sign = 0 if match.group("d"): result[0] = int(match.group("d")) if match.group("m"): result[1] = int(match.group("m")) if match.group("s"): result[2] = int(match.group("s")) elif len(lat_long) > 4: raise Exception("Lat/Long should be DD MM'SS\" or DD.MMMMM") return cls._latlong_sanity(sign, result[0], result[1], result[2], is_lat) def _get_aprs_settings(self): menu = RadioSettingGroup("aprs_top", "APRS") menu.append(self._get_aprs_general_settings()) menu.append(self._get_aprs_rx_settings()) menu.append(self._get_aprs_tx_settings()) menu.append(self._get_aprs_smartbeacon()) menu.append(self._get_aprs_msgs()) menu.append(self._get_aprs_beacons()) return menu def _get_aprs_general_settings(self): menu = RadioSettingGroup("aprs_general", "APRS General") aprs = self._memobj.aprs val = RadioSettingValueString( 0, 6, str(aprs.my_callsign.callsign).rstrip("\xFF")) rs = RadioSetting("aprs.my_callsign.callsign", "My Callsign", val) rs.set_apply_callback(self.apply_callsign, aprs.my_callsign) menu.append(rs) val = RadioSettingValueList( chirp_common.APRS_SSID, chirp_common.APRS_SSID[aprs.my_callsign.ssid]) rs = RadioSetting("aprs.my_callsign.ssid", "My SSID", val) menu.append(rs) val = RadioSettingValueList(self._MY_SYMBOL, self._MY_SYMBOL[aprs.selected_my_symbol]) rs = RadioSetting("aprs.selected_my_symbol", "My Symbol", val) menu.append(rs) symbols = list(chirp_common.APRS_SYMBOLS) selected = aprs.custom_symbol if aprs.custom_symbol >= len(chirp_common.APRS_SYMBOLS): symbols.append("%d" % aprs.custom_symbol) selected = len(symbols) - 1 val = RadioSettingValueList(symbols, symbols[selected]) rs = RadioSetting("aprs.custom_symbol_text", "User Selected Symbol", val) rs.set_apply_callback(self.apply_custom_symbol, aprs) menu.append(rs) val = RadioSettingValueList( chirp_common.APRS_POSITION_COMMENT, chirp_common.APRS_POSITION_COMMENT[aprs.selected_position_comment]) rs = RadioSetting("aprs.selected_position_comment", "Position Comment", val) menu.append(rs) latitude = self._latlong_to_str(aprs.latitude_sign, aprs.latitude_degree, aprs.latitude_minute, aprs.latitude_second, True, aprs.aprs_units_position_mmss) longitude = self._latlong_to_str(aprs.longitude_sign, aprs.longitude_degree, aprs.longitude_minute, aprs.longitude_second, False, aprs.aprs_units_position_mmss) # TODO: Rebuild this when aprs_units_position_mmss changes. # TODO: Rebuild this when latitude/longitude change. # TODO: Add saved positions p1 - p10 to memory map. position_str = list(self._POSITIONS) # position_str[1] = "%s %s" % (latitude, longitude) # position_str[2] = "%s %s" % (latitude, longitude) val = RadioSettingValueList(position_str, position_str[aprs.selected_position]) rs = RadioSetting("aprs.selected_position", "My Position", val) menu.append(rs) val = RadioSettingValueString(0, 10, latitude) rs = RadioSetting("latitude", "Manual Latitude", val) rs.set_apply_callback(self.apply_lat_long, aprs) menu.append(rs) val = RadioSettingValueString(0, 11, longitude) rs = RadioSetting("longitude", "Manual Longitude", val) rs.set_apply_callback(self.apply_lat_long, aprs) menu.append(rs) val = RadioSettingValueList( self._TIME_SOURCE, self._TIME_SOURCE[aprs.set_time_manually]) rs = RadioSetting("aprs.set_time_manually", "Time Source", val) menu.append(rs) val = RadioSettingValueList(self._TZ, self._TZ[aprs.timezone]) rs = RadioSetting("aprs.timezone", "Timezone", val) menu.append(rs) val = RadioSettingValueList(self._SPEED_UNITS, self._SPEED_UNITS[aprs.aprs_units_speed]) rs = RadioSetting("aprs.aprs_units_speed", "APRS Speed Units", val) menu.append(rs) val = RadioSettingValueList(self._SPEED_UNITS, self._SPEED_UNITS[aprs.gps_units_speed]) rs = RadioSetting("aprs.gps_units_speed", "GPS Speed Units", val) menu.append(rs) val = RadioSettingValueList( self._ALT_UNITS, self._ALT_UNITS[aprs.aprs_units_altitude_ft]) rs = RadioSetting("aprs.aprs_units_altitude_ft", "APRS Altitude Units", val) menu.append(rs) val = RadioSettingValueList( self._ALT_UNITS, self._ALT_UNITS[aprs.gps_units_altitude_ft]) rs = RadioSetting("aprs.gps_units_altitude_ft", "GPS Altitude Units", val) menu.append(rs) val = RadioSettingValueList( self._POS_UNITS, self._POS_UNITS[aprs.aprs_units_position_mmss]) rs = RadioSetting("aprs.aprs_units_position_mmss", "APRS Position Format", val) menu.append(rs) val = RadioSettingValueList( self._POS_UNITS, self._POS_UNITS[aprs.gps_units_position_sss]) rs = RadioSetting("aprs.gps_units_position_sss", "GPS Position Format", val) menu.append(rs) val = RadioSettingValueList( self._DIST_UNITS, self._DIST_UNITS[aprs.aprs_units_distance_m]) rs = RadioSetting("aprs.aprs_units_distance_m", "APRS Distance Units", val) menu.append(rs) val = RadioSettingValueList(self._WIND_UNITS, self._WIND_UNITS[aprs.aprs_units_wind_mph]) rs = RadioSetting("aprs.aprs_units_wind_mph", "APRS Wind Speed Units", val) menu.append(rs) val = RadioSettingValueList( self._RAIN_UNITS, self._RAIN_UNITS[aprs.aprs_units_rain_inch]) rs = RadioSetting("aprs.aprs_units_rain_inch", "APRS Rain Units", val) menu.append(rs) val = RadioSettingValueList( self._TEMP_UNITS, self._TEMP_UNITS[aprs.aprs_units_temperature_f]) rs = RadioSetting("aprs.aprs_units_temperature_f", "APRS Temperature Units", val) menu.append(rs) return menu def _get_aprs_msgs(self): menu = RadioSettingGroup("aprs_msg", "APRS Messages") aprs_msg = self._memobj.aprs_message_pkt for index in range(0, 60): if aprs_msg[index].flag != 255: astring = \ str(aprs_msg[index].dst_callsign).partition("\xFF")[0] val = RadioSettingValueString( 0, 9, chirp_common.sanitize_string(astring) + "-%d" % aprs_msg[index].dst_callsign_ssid) val.set_mutable(False) rs = RadioSetting( "aprs_msg.dst_callsign%d" % index, "Dst Callsign %d" % index, val) menu.append(rs) astring = \ str(aprs_msg[index].path_and_body).partition("\xFF")[0] val = RadioSettingValueString( 0, 66, chirp_common.sanitize_string(astring)) val.set_mutable(False) rs = RadioSetting( "aprs_msg.path_and_body%d" % index, "Body", val) menu.append(rs) return menu def _get_aprs_beacons(self): menu = RadioSettingGroup("aprs_beacons", "APRS Beacons") aprs_beacon = self._memobj.aprs_beacon_pkt aprs_meta = self._memobj.aprs_beacon_meta for index in range(0, 60): # There is probably a more pythonesque way to do this scl = int(aprs_meta[index].sender_callsign[0]) dcl = int(aprs_beacon[index].dst_callsign[0]) if scl != 255 and scl != 0: # ignore if empty send call callsign = str(aprs_meta[index].sender_callsign).rstrip("\xFF") val = RadioSettingValueString(0, 9, callsign) val.set_mutable(False) rs = RadioSetting( "aprs_beacon.src_callsign%d" % index, "SRC Callsign %d" % index, val) menu.append(rs) if dcl != 255 and dcl != 0: # ignore if empty dest call val = str(aprs_beacon[index].dst_callsign) val = RadioSettingValueString(0, 9, val.rstrip("\xFF")) val.set_mutable(False) rs = RadioSetting( "aprs_beacon.dst_callsign%d" % index, "DST Callsign %d" % index, val) menu.append(rs) date = "%02d/%02d/%02d" % ( aprs_meta[index].date[0], aprs_meta[index].date[1], aprs_meta[index].date[2]) val = RadioSettingValueString(0, 8, date) val.set_mutable(False) rs = RadioSetting("aprs_beacon.date%d" % index, "Date", val) menu.append(rs) time = "%02d:%02d" % ( aprs_meta[index].time[0], aprs_meta[index].time[1]) val = RadioSettingValueString(0, 5, time) val.set_mutable(False) rs = RadioSetting("aprs_beacon.time%d" % index, "Time", val) menu.append(rs) if dcl != 255 and dcl != 0: # ignore if empty dest call path = str(aprs_beacon[index].path).replace("\x00", " ") path = ''.join(c for c in path if c in string.printable).strip() path = str(path).replace("\xE0", "*") val = RadioSettingValueString(0, 32, path) val.set_mutable(False) rs = RadioSetting( "aprs_beacon.path%d" % index, "Digipath", val) menu.append(rs) body = str(aprs_beacon[index].body).rstrip("\xFF") checksum = body[-2:] body = ''.join(s for s in body[:-2] if s in string.printable).translate( str.maketrans( "", "", "\x09\x0a\x0b\x0c\x0d")) try: val = RadioSettingValueString(0, 134, body.strip()) except Exception as e: LOG.error("Error in APRS beacon at index %s", index) raise e val.set_mutable(False) rs = RadioSetting("aprs_beacon.body%d" % index, "Body", val) menu.append(rs) return menu def _get_aprs_rx_settings(self): menu = RadioSettingGroup("aprs_rx", "APRS Receive") aprs = self._memobj.aprs val = RadioSettingValueList(self._RX_BAUD, self._RX_BAUD[aprs.rx_baud]) rs = RadioSetting("aprs.rx_baud", "Modem RX", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.aprs_mute) rs = RadioSetting("aprs.aprs_mute", "APRS Mute", val) menu.append(rs) if self._has_af_dual: val = RadioSettingValueBoolean(aprs.af_dual) rs = RadioSetting("aprs.af_dual", "AF Dual", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.ring_msg) rs = RadioSetting("aprs.ring_msg", "Ring on Message RX", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.ring_beacon) rs = RadioSetting("aprs.ring_beacon", "Ring on Beacon RX", val) menu.append(rs) val = RadioSettingValueList(self._FLASH, self._FLASH[aprs.flash_msg]) rs = RadioSetting("aprs.flash_msg", "Flash on personal message", val) menu.append(rs) if self._has_vibrate: val = RadioSettingValueList(self._FLASH, self._FLASH[aprs.vibrate_msg]) rs = RadioSetting("aprs.vibrate_msg", "Vibrate on personal message", val) menu.append(rs) val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs.flash_bln]) rs = RadioSetting("aprs.flash_bln", "Flash on bulletin message", val) menu.append(rs) if self._has_vibrate: val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs.vibrate_bln]) rs = RadioSetting("aprs.vibrate_bln", "Vibrate on bulletin message", val) menu.append(rs) val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs.flash_grp]) rs = RadioSetting("aprs.flash_grp", "Flash on group message", val) menu.append(rs) if self._has_vibrate: val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs.vibrate_grp]) rs = RadioSetting("aprs.vibrate_grp", "Vibrate on group message", val) menu.append(rs) filter_val = [m.padded_string for m in aprs.msg_group] filter_val = self._strip_ff_pads(filter_val) for index, filter_text in enumerate(filter_val): val = RadioSettingValueString(0, 9, filter_text) rs = RadioSetting("aprs.msg_group_%d" % index, "Message Group %d" % (index + 1), val) menu.append(rs) rs.set_apply_callback(self.apply_ff_padded_string, aprs.msg_group[index]) # TODO: Use filter_val as the list entries and update it on edit. val = RadioSettingValueList( self._MSG_GROUP_NAMES, self._MSG_GROUP_NAMES[aprs.selected_msg_group]) rs = RadioSetting("aprs.selected_msg_group", "Selected Message Group", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_mic_e) rs = RadioSetting("aprs.filter_mic_e", "Receive Mic-E Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_position) rs = RadioSetting("aprs.filter_position", "Receive Position Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_weather) rs = RadioSetting("aprs.filter_weather", "Receive Weather Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_object) rs = RadioSetting("aprs.filter_object", "Receive Object Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_item) rs = RadioSetting("aprs.filter_item", "Receive Item Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_status) rs = RadioSetting("aprs.filter_status", "Receive Status Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_other) rs = RadioSetting("aprs.filter_other", "Receive Other Beacons", val) menu.append(rs) return menu def _get_aprs_tx_settings(self): menu = RadioSettingGroup("aprs_tx", "APRS Transmit") aprs = self._memobj.aprs beacon_type = (aprs.tx_smartbeacon << 1) | aprs.tx_interval_beacon val = RadioSettingValueList(self._BEACON_TYPE, self._BEACON_TYPE[beacon_type]) rs = RadioSetting("aprs.transmit", "TX Beacons", val) rs.set_apply_callback(self.apply_beacon_type, aprs) menu.append(rs) val = RadioSettingValueList(self._TX_DELAY, self._TX_DELAY[aprs.tx_delay]) rs = RadioSetting("aprs.tx_delay", "TX Delay", val) menu.append(rs) val = RadioSettingValueList(self._BEACON_INT, self._BEACON_INT[aprs.beacon_interval]) rs = RadioSetting("aprs.beacon_interval", "Beacon Interval", val) menu.append(rs) desc = [] status = [m.padded_string for m in self._memobj.aprs_beacon_status_txt] status = self._strip_ff_pads(status) for index, msg_text in enumerate(status): val = RadioSettingValueString(0, 60, msg_text) desc.append("Beacon Status Text %d" % (index + 1)) rs = RadioSetting("aprs_beacon_status_txt_%d" % index, desc[-1], val) rs.set_apply_callback(self.apply_ff_padded_string, self._memobj.aprs_beacon_status_txt[index]) menu.append(rs) val = RadioSettingValueList(desc, desc[aprs.selected_beacon_status_txt]) rs = RadioSetting("aprs.selected_beacon_status_txt", "Beacon Status Text", val) menu.append(rs) message_macro = [m.padded_string for m in aprs.message_macro] message_macro = self._strip_ff_pads(message_macro) for index, msg_text in enumerate(message_macro): val = RadioSettingValueString(0, 16, msg_text) rs = RadioSetting("aprs.message_macro_%d" % index, "Message Macro %d" % (index + 1), val) rs.set_apply_callback(self.apply_ff_padded_string, aprs.message_macro[index]) menu.append(rs) path_str = list(self._DIGI_PATHS) path_str[3] = self._digi_path_to_str(aprs.digi_path_3_6[0]) val = RadioSettingValueString(0, 22, path_str[3]) rs = RadioSetting("aprs.digi_path_3", "Digi Path 4 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_3_6[0]) menu.append(rs) path_str[4] = self._digi_path_to_str(aprs.digi_path_3_6[1]) val = RadioSettingValueString(0, 22, path_str[4]) rs = RadioSetting("aprs.digi_path_4", "Digi Path 5 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_3_6[1]) menu.append(rs) path_str[5] = self._digi_path_to_str(aprs.digi_path_3_6[2]) val = RadioSettingValueString(0, 22, path_str[5]) rs = RadioSetting("aprs.digi_path_5", "Digi Path 6 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_3_6[2]) menu.append(rs) path_str[6] = self._digi_path_to_str(aprs.digi_path_3_6[3]) val = RadioSettingValueString(0, 22, path_str[6]) rs = RadioSetting("aprs.digi_path_6", "Digi Path 7 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_3_6[3]) menu.append(rs) path_str[7] = self._digi_path_to_str(aprs.digi_path_7) val = RadioSettingValueString(0, 88, path_str[7]) rs = RadioSetting("aprs.digi_path_7", "Digi Path 8 (8 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_7) menu.append(rs) # Show friendly messages for empty slots rather than blanks. # TODO: Rebuild this when digi_path_[34567] change. # path_str[3] = path_str[3] or self._DIGI_PATHS[3] # path_str[4] = path_str[4] or self._DIGI_PATHS[4] # path_str[5] = path_str[5] or self._DIGI_PATHS[5] # path_str[6] = path_str[6] or self._DIGI_PATHS[6] # path_str[7] = path_str[7] or self._DIGI_PATHS[7] path_str[3] = self._DIGI_PATHS[3] path_str[4] = self._DIGI_PATHS[4] path_str[5] = self._DIGI_PATHS[5] path_str[6] = self._DIGI_PATHS[6] path_str[7] = self._DIGI_PATHS[7] val = RadioSettingValueList(path_str, path_str[aprs.selected_digi_path]) rs = RadioSetting("aprs.selected_digi_path", "Selected Digi Path", val) menu.append(rs) return menu def _get_aprs_smartbeacon(self): menu = RadioSettingGroup("aprs_smartbeacon", "APRS SmartBeacon") aprs = self._memobj.aprs val = RadioSettingValueList( self._SMARTBEACON_PROFILE, self._SMARTBEACON_PROFILE[aprs.active_smartbeaconing]) rs = RadioSetting("aprs.active_smartbeaconing", "SmartBeacon profile", val) menu.append(rs) for profile in range(3): pfx = "type%d" % (profile + 1) path = "aprs.smartbeaconing_profile[%d]" % profile prof = aprs.smartbeaconing_profile[profile] low_val = RadioSettingValueInteger(2, 30, prof.low_speed_mph) high_val = RadioSettingValueInteger(3, self._APRS_HIGH_SPEED_MAX, prof.high_speed_mph) low_val.get_max = lambda: min(30, int(high_val.get_value()) - 1) rs = RadioSetting("%s.low_speed_mph" % path, "%s Low Speed (mph)" % pfx, low_val) menu.append(rs) rs = RadioSetting("%s.high_speed_mph" % path, "%s High Speed (mph)" % pfx, high_val) menu.append(rs) val = RadioSettingValueInteger(1, 100, prof.slow_rate_min) rs = RadioSetting("%s.slow_rate_min" % path, "%s Slow rate (minutes)" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(10, 180, prof.fast_rate_sec) rs = RadioSetting("%s.fast_rate_sec" % path, "%s Fast rate (seconds)" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(5, 90, prof.turn_angle) rs = RadioSetting("%s.turn_angle" % path, "%s Turn angle (degrees)" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(1, 255, prof.turn_slop) rs = RadioSetting("%s.turn_slop" % path, "%s Turn slop" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(5, 180, prof.turn_time_sec) rs = RadioSetting("%s.turn_time_sec" % path, "%s Turn time (seconds)" % pfx, val) menu.append(rs) return menu def _get_digital_settings(self): topmenu = RadioSettingGroup("digital_settings", "Digital") menu = RadioSettingGroup("settings", "Digital Modes") topmenu.append(menu) GMmenu = RadioSettingGroup("first_settings", "Group Monitor(GM)") topmenu.append(GMmenu) WXmenu = RadioSettingGroup("WiresX_settings", "Wires-X") topmenu.append(WXmenu) # MYCALL mycall = self._memobj.my_call mycallstr = str(mycall.callsign).rstrip("\xff").rstrip() mycalle = RadioSettingValueString(0, 10, mycallstr, False, charset=self._MYCALL_CHR_SET) rs = RadioSetting('mycall.callsign', 'MYCALL (10 uppercase chars)', mycalle) rs.set_apply_callback(self.apply_mycall, mycall) menu.append(rs) # Short Press AMS button AMS TX Mode digital_settings = self._memobj.digital_settings val = RadioSettingValueList( self._AMS_TX_MODE, self._AMS_TX_MODE[digital_settings.ams_tx_mode]) rs = RadioSetting("digital_settings.ams_tx_mode", "AMS TX Mode", val) menu.append(rs) # 16 DIG VW Turn the VW mode selection ON or OFF. val = RadioSettingValueList( self._VW_MODE, self._VW_MODE[digital_settings.vw_mode]) rs = RadioSetting("digital_settings.vw_mode", "VW Mode", val) menu.append(rs) # TX DG-ID Long Press Mode Key, Dial val = RadioSettingValueList( self._DG_ID, self._DG_ID[digital_settings.tx_dg_id]) rs = RadioSetting("digital_settings.tx_dg_id", "TX DG-ID", val) menu.append(rs) # RX DG-ID Long Press Mode Key, Mode Key to select, Dial val = RadioSettingValueList( self._DG_ID, self._DG_ID[digital_settings.rx_dg_id]) rs = RadioSetting("digital_settings.rx_dg_id", "RX DG-ID", val) menu.append(rs) # 15 DIG.POP Call sign display pop up time digital_settings_more = self._memobj.digital_settings_more val = RadioSettingValueList( self._DIG_POP_UP, self._DIG_POP_UP[ 0 if digital_settings_more.digital_popup == 0 else digital_settings_more.digital_popup - 9]) rs = RadioSetting("digital_settings_more.digital_popup", "Digital Popup", val) rs.set_apply_callback(self.apply_digital_popup, digital_settings_more) menu.append(rs) # 07 BEP.STB Standby Beep in the digital C4FM mode. On/Off val = RadioSettingValueList( self._STANDBY_BEEP, self._STANDBY_BEEP[digital_settings.standby_beep]) rs = RadioSetting("digital_settings.standby_beep", "Standby Beep", val) menu.append(rs) # GM settings # 24 GM RNG Select the beep option first_settings = self._memobj.first_settings val = RadioSettingValueList( self._GM_RING, self._GM_RING[first_settings.gm_ring]) rs = RadioSetting("first_settings.gm_ring", "GM Ring", val) GMmenu.append(rs) # 25 GM INT transmission interval of digital GM info scan_settings = self._memobj.scan_settings val = RadioSettingValueList( self._GM_INTERVAL, self._GM_INTERVAL[scan_settings.gm_interval]) rs = RadioSetting("scan_settings.gm_interval", "GM Interval", val) GMmenu.append(rs) m = self._memobj.GM for i in range(0, 10): cname = "GM[%d].message" % i msg = str(m[i].message).rstrip("\xff)") val = RadioSettingValueString(0, 32, msg) rs = RadioSetting(cname, "GM Message%2d" % (i + 1), val) GMmenu.append(rs) # WiresX settings wxc = self._memobj.WiresX_settings for i in range(0, 5): cname = "WiresX_settings.Category[%d].name" % (i + 1) c = '' for j in range(0, 16): s = wxc.Category[i].name[j] if int(s) != 0xff: c = c + str(s) val = RadioSettingValueString(0, 16, c) rs = RadioSetting(cname, "Category %d" % (i+1), val) rs.set_apply_callback(self.apply_WiresX_category, wxc.Category[i].name) WXmenu.append(rs) r = wxc.RoomsPerCategory[i] rn = False for j in range(0, 20): idn = "0" if int(r.Rooms[j].ID[1]) != 0xff: idn = r.Rooms[j].ID rn = False elif rn: break elif j > 0: rn = True val = RadioSettingValueInteger(0, 99999, int(str(idn))) vname = "WiresX_settings.RoomsperCategory%s" \ "Rooms[%d].ID" % (i, j) rs = RadioSetting(vname, " Room ID%2s (5 numerals)" % (j+1), val) rs.set_apply_callback(self.apply_WiresX_roomid, r.Rooms[j]) WXmenu.append(rs) cn = '' for l in range(0, 16): s = r.Rooms[j].name[l] if int(s) != 0xff: cn = cn + str(s) val = RadioSettingValueString(0, 16, str(cn)) cname = "WiresX_settings.RoomsperCategory%s" \ "Rooms[%d].name" % (i, j) rs = RadioSetting(cname, " Room Name%2s (16 chars)" % (j+1), val) rs.set_apply_callback(self.apply_WiresX_roomname, r.Rooms[j]) WXmenu.append(rs) pass return topmenu def apply_WiresX_category(cls, setting, obj): val = setting.value.get_value() setattr(obj, "name", val) def apply_WiresX_roomid(self, setting, obj): val = setting.value.get_value() obj.ID = self.zero_pad(val, 5) def apply_WiresX_roomname(cls, setting, obj): val = setting.value.get_value() obj.name = str(val) def _get_dtmf_settings(self): menu = RadioSettingGroup("dtmf_settings", "DTMF") dtmf = self._memobj.scan_settings val = RadioSettingValueList( self._DTMF_MODE, self._DTMF_MODE[dtmf.dtmf_mode]) rs = RadioSetting("scan_settings.dtmf_mode", "DTMF Mode", val) menu.append(rs) val = RadioSettingValueList( self._DTMF_SPEED, self._DTMF_SPEED[dtmf.dtmf_speed]) rs = RadioSetting( "scan_settings.dtmf_speed", "DTMF AutoDial Speed", val) menu.append(rs) val = RadioSettingValueList( self._DTMF_DELAY, self._DTMF_DELAY[dtmf.dtmf_delay]) rs = RadioSetting( "scan_settings.dtmf_delay", "DTMF AutoDial Delay", val) menu.append(rs) for i in range(10): name = "dtmf_%02d" % i dtmfsetting = self._memobj.dtmf[i] dtmfstr = "" for c in dtmfsetting.memory: if c == 0xFF: break if c < len(FT1_DTMF_CHARS): dtmfstr += FT1_DTMF_CHARS[c] dtmfentry = RadioSettingValueString(0, 16, dtmfstr) dtmfentry.set_charset(FT1_DTMF_CHARS + list("abcd ")) rs = RadioSetting(name, name.upper(), dtmfentry) rs.set_apply_callback(self.apply_dtmf, i) menu.append(rs) return menu def _get_misc_settings(self): menu = RadioSettingGroup("misc_settings", "Misc") scan_settings = self._memobj.scan_settings val = RadioSettingValueList( self._LCD_DIMMER, self._LCD_DIMMER[scan_settings.lcd_dimmer]) rs = RadioSetting("scan_settings.lcd_dimmer", "LCD Dimmer", val) menu.append(rs) val = RadioSettingValueList( self._LCD_CONTRAST, self._LCD_CONTRAST[scan_settings.lcd_contrast - 1]) rs = RadioSetting("scan_settings.lcd_contrast", "LCD Contrast", val) rs.set_apply_callback(self.apply_lcd_contrast, scan_settings) menu.append(rs) val = RadioSettingValueList( self._LAMP_KEY, self._LAMP_KEY[scan_settings.lamp]) rs = RadioSetting("scan_settings.lamp", "Lamp", val) menu.append(rs) beep_select = self._memobj.beep_select val = RadioSettingValueList( self._BEEP_SELECT, self._BEEP_SELECT[beep_select.beep]) rs = RadioSetting("beep_select.beep", "Beep Select", val) menu.append(rs) opening_message = self._memobj.opening_message val = RadioSettingValueList( self._OPENING_MESSAGE, self._OPENING_MESSAGE[opening_message.flag]) rs = RadioSetting("opening_message.flag", "Opening Msg Mode", val) menu.append(rs) rs = self._decode_opening_message(opening_message) menu.append(rs) return menu def _decode_opening_message(self, opening_message): msg = "" for i in opening_message.message.padded_yaesu: if i == 0xFF: break msg += CHARSET[i & 0x7F] val = RadioSettingValueString(0, 16, msg) rs = RadioSetting("opening_message.message.padded_yaesu", "Opening Message", val) rs.set_apply_callback(self.apply_ff_padded_yaesu, opening_message.message) return rs def backtrack_ll_validate(self, number, min, max): if str(number).lstrip('0').strip().isdigit() and \ int(str(number).lstrip('0')) <= max and \ int(str(number).lstrip('0')) >= min: return True return False @staticmethod def zero_pad(number, length): """ Applies a leading zero pad of length `length` to `number` """ return str(number).rjust(length, "0") def _get_backtrack_settings(self): menu = RadioSettingGroup("backtrack", "Backtrack") for i in range(3): prefix = '' if i == 0: prefix = "Star " if i == 1: prefix = "L1 " if i == 2: prefix = "L2 " bt_idx = "backtrack[%d]" % i bt = self._memobj.backtrack[i] val = RadioSettingValueList( self._BACKTRACK_STATUS, self._BACKTRACK_STATUS[0 if bt.status == 1 else 1]) rs = RadioSetting( "%s.status" % bt_idx, prefix + "status", val) rs.set_apply_callback(self.apply_backtrack_status, bt) menu.append(rs) if bt.status == 1 and int(bt.year) < 100: val = RadioSettingValueInteger(0, 99, bt.year) else: val = RadioSettingValueInteger(0, 99, 0) rs = RadioSetting( "%s.year" % bt_idx, prefix + "year", val) menu.append(rs) if bt.status == 1 and int(bt.mon) <= 12: val = RadioSettingValueInteger(0, 12, bt.mon) else: val = RadioSettingValueInteger(0, 12, 0) rs = RadioSetting( "%s.mon" % bt_idx, prefix + "month", val) menu.append(rs) if bt.status == 1: val = RadioSettingValueInteger(0, 31, bt.day) else: val = RadioSettingValueInteger(0, 31, 0) rs = RadioSetting( "%s.day" % bt_idx, prefix + "day", val) menu.append(rs) if bt.status == 1: val = RadioSettingValueInteger(0, 23, bt.hour) else: val = RadioSettingValueInteger(0, 23, 0) rs = RadioSetting( "%s.hour" % bt_idx, prefix + "hour", val) menu.append(rs) if bt.status == 1: val = RadioSettingValueInteger(0, 59, bt.min) else: val = RadioSettingValueInteger(0, 59, 0) rs = RadioSetting( "%s.min" % bt_idx, prefix + "min", val) menu.append(rs) if bt.status == 1 and \ (str(bt.NShemi) == 'N' or str(bt.NShemi) == 'S'): val = RadioSettingValueString(0, 1, str(bt.NShemi)) else: val = RadioSettingValueString(0, 1, ' ') rs = RadioSetting( "%s.NShemi" % bt_idx, prefix + "NS hemisphere", val) rs.set_apply_callback(self.apply_NShemi, bt) menu.append(rs) if bt.status == 1 and self.backtrack_ll_validate(bt.lat, 0, 90): val = RadioSettingValueString( 0, 3, self.zero_pad(bt.lat, 3)) else: val = RadioSettingValueString(0, 3, ' ') rs = RadioSetting("%s.lat" % bt_idx, prefix + "Latitude", val) rs.set_apply_callback(self.apply_bt_lat, bt) menu.append(rs) if bt.status == 1 and \ self.backtrack_ll_validate(bt.lat_min, 0, 59): val = RadioSettingValueString( 0, 2, self.zero_pad(bt.lat_min, 2)) else: val = RadioSettingValueString(0, 2, ' ') rs = RadioSetting( "%s.lat_min" % bt_idx, prefix + "Latitude Minutes", val) rs.set_apply_callback(self.apply_bt_lat_min, bt) menu.append(rs) if bt.status == 1 and \ self.backtrack_ll_validate(bt.lat_dec_sec, 0, 9999): val = RadioSettingValueString( 0, 4, self.zero_pad(bt.lat_dec_sec, 4)) else: val = RadioSettingValueString(0, 4, ' ') rs = RadioSetting( "%s.lat_dec_sec" % bt_idx, prefix + "Latitude Decimal Seconds", val) rs.set_apply_callback(self.apply_bt_lat_dec_sec, bt) menu.append(rs) if bt.status == 1 and \ (str(bt.WEhemi) == 'W' or str(bt.WEhemi) == 'E'): val = RadioSettingValueString( 0, 1, str(bt.WEhemi)) else: val = RadioSettingValueString(0, 1, ' ') rs = RadioSetting( "%s.WEhemi" % bt_idx, prefix + "WE hemisphere", val) rs.set_apply_callback(self.apply_WEhemi, bt) menu.append(rs) if bt.status == 1 and self.backtrack_ll_validate(bt.lon, 0, 180): val = RadioSettingValueString( 0, 3, self.zero_pad(bt.lon, 3)) else: val = RadioSettingValueString(0, 3, ' ') rs = RadioSetting("%s.lon" % bt_idx, prefix + "Longitude", val) rs.set_apply_callback(self.apply_bt_lon, bt) menu.append(rs) if bt.status == 1 and \ self.backtrack_ll_validate(bt.lon_min, 0, 59): val = RadioSettingValueString( 0, 2, self.zero_pad(bt.lon_min, 2)) else: val = RadioSettingValueString(0, 2, ' ') rs = RadioSetting( "%s.lon_min" % bt_idx, prefix + "Longitude Minutes", val) rs.set_apply_callback(self.apply_bt_lon_min, bt) menu.append(rs) if bt.status == 1 and \ self.backtrack_ll_validate(bt.lon_dec_sec, 0, 9999): val = RadioSettingValueString( 0, 4, self.zero_pad(bt.lon_dec_sec, 4)) else: val = RadioSettingValueString(0, 4, ' ') rs = RadioSetting( "%s.lon_dec_sec" % bt_idx, prefix + "Longitude Decimal Seconds", val) rs.set_apply_callback(self.apply_bt_lon_dec_sec, bt) menu.append(rs) return menu def _get_scan_settings(self): menu = RadioSettingGroup("scan_settings", "Scan") scan_settings = self._memobj.scan_settings val = RadioSettingValueList( self._VOL_MODE, self._VOL_MODE[scan_settings.vol_mode]) rs = RadioSetting("scan_settings.vol_mode", "Volume Mode", val) menu.append(rs) vfoa = self._memobj.vfo_info[0] val = RadioSettingValueList( self._VOLUME, self._VOLUME[vfoa.volume]) rs = RadioSetting("vfo_info[0].volume", "VFO A Volume", val) rs.set_apply_callback(self.apply_volume, 0) menu.append(rs) vfob = self._memobj.vfo_info[1] val = RadioSettingValueList( self._VOLUME, self._VOLUME[vfob.volume]) rs = RadioSetting("vfo_info[1].volume", "VFO B Volume", val) rs.set_apply_callback(self.apply_volume, 1) menu.append(rs) squelch = self._memobj.squelch val = RadioSettingValueList( self._SQUELCH, self._SQUELCH[squelch.vfo_a]) rs = RadioSetting("squelch.vfo_a", "VFO A Squelch", val) menu.append(rs) val = RadioSettingValueList( self._SQUELCH, self._SQUELCH[squelch.vfo_b]) rs = RadioSetting("squelch.vfo_b", "VFO B Squelch", val) menu.append(rs) val = RadioSettingValueList( self._SCAN_RESTART, self._SCAN_RESTART[scan_settings.scan_restart]) rs = RadioSetting("scan_settings.scan_restart", "Scan Restart", val) menu.append(rs) val = RadioSettingValueList( self._SCAN_RESUME, self._SCAN_RESUME[scan_settings.scan_resume]) rs = RadioSetting("scan_settings.scan_resume", "Scan Resume", val) menu.append(rs) val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.busy_led]) rs = RadioSetting("scan_settings.busy_led", "Busy LED", val) menu.append(rs) val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.scan_lamp]) rs = RadioSetting("scan_settings.scan_lamp", "Scan Lamp", val) menu.append(rs) val = RadioSettingValueList( self._TOT_TIME, self._TOT_TIME[scan_settings.tot]) rs = RadioSetting("scan_settings.tot", "Transmit Timeout (TOT)", val) menu.append(rs) return menu def _get_settings(self): top = RadioSettings(self._get_aprs_settings(), self._get_digital_settings(), self._get_dtmf_settings(), self._get_misc_settings(), self._get_scan_settings(), self._get_backtrack_settings()) return top def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None @staticmethod def apply_custom_symbol(setting, obj): # Ensure new value falls within known bounds, otherwise leave it as # it's a custom value from the radio that's outside our list. if setting.value.get_value() in chirp_common.APRS_SYMBOLS: setattr(obj, "custom_symbol", chirp_common.APRS_SYMBOLS.index(setting.value.get_value())) @classmethod def _apply_callsign(cls, callsign, obj, default_ssid=None): ssid = default_ssid dash_index = callsign.find("-") if dash_index >= 0: ssid = callsign[dash_index + 1:] callsign = callsign[:dash_index] try: ssid = int(ssid) % 16 except ValueError: ssid = default_ssid setattr(obj, "callsign", cls._add_ff_pad(callsign.encode(), 6)) if ssid is not None: setattr(obj, "ssid", ssid) def apply_beacon_type(cls, setting, obj): beacon_type = str(setting.value.get_value()) beacon_index = cls._BEACON_TYPE.index(beacon_type) tx_smartbeacon = beacon_index >> 1 tx_interval_beacon = beacon_index & 1 if tx_interval_beacon: setattr(obj, "tx_interval_beacon", 1) setattr(obj, "tx_smartbeacon", 0) elif tx_smartbeacon: setattr(obj, "tx_interval_beacon", 0) setattr(obj, "tx_smartbeacon", 1) else: setattr(obj, "tx_interval_beacon", 0) setattr(obj, "tx_smartbeacon", 0) # digital settings callback routines def apply_digital_popup(cls, setting, obj): rawval = setting.value.get_value() val = 0 if cls._DIG_POP_UP.index(rawval) == 0 \ else cls._DIG_POP_UP.index(rawval) + 9 obj.digital_popup = val def apply_mycall(cls, setting, obj): cs = setting.value.get_value() if cs[0] in ('-', '/'): raise InvalidValueError("First character of" " call sign can't be - or /: {0:s}" .format(cs)) else: obj.callsign = cls._add_ff_pad(cs.rstrip(), 10) @classmethod def apply_callsign(cls, setting, obj, default_ssid=None): # Uppercase, strip SSID then FF pad to max string length. callsign = setting.value.get_value().upper() cls._apply_callsign(callsign, obj, default_ssid) def apply_digi_path(self, setting, obj): # Parse and map to aprs.digi_path_4_7[0-3] or aprs.digi_path_8 # and FF terminate. path = str(setting.value.get_value()) callsigns = [c.strip() for c in path.split(",")] for index in range(len(obj.entry)): try: self._apply_callsign(callsigns[index], obj.entry[index], 0) except IndexError: self._apply_callsign("", obj.entry[index], 0) if len(callsigns) > len(obj.entry): raise Exception("This path only supports %d entries" % (index + 1)) @classmethod def apply_ff_padded_string(cls, setting, obj): # FF pad. val = setting.value.get_value() max_len = getattr(obj, "padded_string").size() / 8 val = str(val).rstrip() setattr(obj, "padded_string", cls._add_ff_pad(val, max_len)) @classmethod def apply_lat_long(cls, setting, obj): name = setting.get_name() is_latitude = name.endswith("latitude") lat_long = setting.value.get_value().strip() sign, l_d, l_m, l_s = cls._str_to_latlong(lat_long, is_latitude) LOG.debug("%s: %d %d %d %d" % (name, sign, l_d, l_m, l_s)) setattr(obj, "%s_sign" % name, sign) setattr(obj, "%s_degree" % name, l_d) setattr(obj, "%s_minute" % name, l_m) setattr(obj, "%s_second" % name, l_s) def set_settings(self, settings): _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: if element.has_apply_callback(): LOG.debug("Using apply callback") try: element.run_apply_callback() except NotImplementedError as e: LOG.error("ft1d.set_settings: %s", e) continue # Find the object containing setting. obj = _mem bits = element.get_name().split(".") setting = bits[-1] for name in bits[:-1]: if name.endswith("]"): name, index = name.split("[") index = int(index[:-1]) obj = getattr(obj, name)[index] else: obj = getattr(obj, name) try: old_val = getattr(obj, setting) LOG.debug("Setting %s(%r) <= %s" % ( element.get_name(), old_val, element.value)) setattr(obj, setting, element.value) except AttributeError as e: LOG.error("Setting %s is not in the memory map: %s" % (element.get_name(), e)) except Exception: LOG.debug(element.get_name()) raise def apply_ff_padded_yaesu(cls, setting, obj): # FF pad yaesus custom string format. rawval = setting.value.get_value() max_len = getattr(obj, "padded_yaesu").size() / 8 rawval = str(rawval).rstrip() val = [CHARSET.index(x) for x in rawval] for x in range(len(val), max_len): val.append(0xFF) obj.padded_yaesu = val def apply_volume(cls, setting, vfo): val = setting.value.get_value() cls._memobj.vfo_info[(vfo * 2)].volume = val cls._memobj.vfo_info[(vfo * 2) + 1].volume = val def apply_lcd_contrast(cls, setting, obj): rawval = setting.value.get_value() val = cls._LCD_CONTRAST.index(rawval) + 1 obj.lcd_contrast = val def apply_dtmf(cls, setting, i): rawval = setting.value.get_value().upper().rstrip() val = [FT1_DTMF_CHARS.index(x) for x in rawval] for x in range(len(val), 16): val.append(0xFF) cls._memobj.dtmf[i].memory = val def apply_backtrack_status(cls, setting, obj): status = setting.value.get_value() if status == 'Valid': val = 1 else: val = 8 setattr(obj, "status", val) def apply_NShemi(cls, setting, obj): hemi = setting.value.get_value().upper() if hemi != 'N' and hemi != 'S': hemi = ' ' setattr(obj, "NShemi", hemi) def apply_WEhemi(cls, setting, obj): hemi = setting.value.get_value().upper() if hemi != 'W' and hemi != 'E': hemi = ' ' setattr(obj, "WEhemi", hemi) def apply_bt_lat(cls, setting, obj): val = setting.value.get_value() val = cls.backtrack_zero_pad(val, 3) setattr(obj, "lat", val) def apply_bt_lat_min(cls, setting, obj): val = setting.value.get_value() val = cls.backtrack_zero_pad(val, 2) setattr(obj, "lat_min", val) def apply_bt_lat_dec_sec(cls, setting, obj): val = setting.value.get_value() val = cls.backtrack_zero_pad(val, 4) setattr(obj, "lat_dec_sec", val) def apply_bt_lon(cls, setting, obj): val = setting.value.get_value() val = cls.backtrack_zero_pad(val, 3) setattr(obj, "lon", val) def apply_bt_lon_min(cls, setting, obj): val = setting.value.get_value() val = cls.backtrack_zero_pad(val, 2) setattr(obj, "lon_min", val) def apply_bt_lon_dec_sec(cls, setting, obj): val = setting.value.get_value() val = cls.backtrack_zero_pad(val, 4) setattr(obj, "lon_dec_sec", val) def load_mmap(self, filename): if filename.lower().endswith(self._adms_ext): with open(filename, 'rb') as f: self._adms_header = f.read(0x16) LOG.debug('ADMS Header:\n%s', util.hexprint(self._adms_header)) self._mmap = memmap.MemoryMapBytes(self._model + f.read()) LOG.info('Loaded ADMS file') self.process_mmap() else: chirp_common.CloneModeRadio.load_mmap(self, filename) def save_mmap(self, filename): if filename.lower().endswith(self._adms_ext): if not hasattr(self, '_adms_header'): raise Exception('Unable to save .img to %s' % self._adms_ext) with open(filename, 'wb') as f: f.write(self._adms_header) f.write(self._mmap.get_packed()[5:]) LOG.info('Wrote file') else: chirp_common.CloneModeRadio.save_mmap(self, filename) chirp-20240224/chirp/drivers/uv6r.py0000644000175000017500000006727314565075506016127 0ustar hibbyhibby# Copyright 2016: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings, \ InvalidValueError LOG = logging.getLogger(__name__) # #### MAGICS ######################################################### # Baofeng UV-6R magic string MSTRING_UV6R = b"\x50\xBB\xFF\x20\x14\x11\x22" # #### ID strings ##################################################### # Baofeng UV-6R UV6R_fp1 = b" BF230#1" UV6R_fp2 = b" BF230#2" DTMF_CHARS = "0123456789 *#ABCD" STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] LIST_AB = ["A", "B"] LIST_ALMOD = ["Site", "Tone", "Code"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_COLOR = ["Off", "Blue", "Orange", "Purple"] LIST_DTMFSPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_DTMFST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] LIST_MODE = ["Channel", "Name", "Frequency"] LIST_OFF1TO9 = ["Off"] + list("123456789") LIST_OFF1TO10 = LIST_OFF1TO9 + ["10"] LIST_OFFAB = ["Off"] + LIST_AB LIST_RESUME = ["TO", "CO", "SE"] LIST_PONMSG = ["Full", "Message"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_SCODE = ["%s" % x for x in range(1, 16)] LIST_RPSTE = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SHIFTD = ["Off", "+", "-"] LIST_STEDELAY = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] LIST_STEP = [str(x) for x in STEPS] LIST_TCALL = ["Off", "1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] LIST_TIMEOUT = ["%s sec" % x for x in range(15, 615, 15)] LIST_TXPOWER = ["High", "Low"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_WORKMODE = ["Frequency", "Channel"] def model_match(cls, data): """Match the opened/downloaded image to the correct version""" match_rid1 = False match_rid2 = False rid1 = data[0x1FF8:0x2000] if rid1 in cls._fileid: match_rid1 = True rid2 = data[0x1FD0:0x1FD5] if rid2 == cls.MODEL.encode(): match_rid2 = True if match_rid1 and match_rid2: return True else: return False @directory.register class UV6R(bfc.BaofengCommonHT): """Baofeng UV-6R""" VENDOR = "Baofeng" MODEL = "UV-6R" NEEDS_COMPAT_SERIAL = False _fileid = [UV6R_fp2, UV6R_fp1, ] _magic = [MSTRING_UV6R, ] _magic_response_length = 8 _fw_ver_start = 0x1FF0 _recv_block_size = 0x40 _mem_size = 0x2000 _ack_block = False _ranges = [(0x0000, 0x1800), (0x1F40, 0x1F50), (0x1FC0, 0x1FD0), (0x1FE0, 0x1FF0)] _send_block_size = 0x10 MODES = ["FM", "NFM"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" LENGTH_NAME = 7 # older radios may only support 6 character names SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] VALID_BANDS = [(136000000, 174000000), (400000000, 520000000)] PTTID_LIST = LIST_PTTID SCODE_LIST = LIST_SCODE MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1; u8 unknown2:7, lowpower:1; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[128]; #seekto 0x0B00; struct { u8 code[5]; u8 unused[11]; } pttid[15]; #seekto 0x0CAA; struct { u8 code[5]; u8 unused:6, aniid:2; u8 unknown[2]; u8 dtmfon; u8 dtmfoff; } ani; #seekto 0x0E20; struct { u8 unused00:4, squelch:4; u8 unused01:5, step:3; u8 unknown00; u8 unused02:5, save:3; u8 unused03:4, vox:4; u8 unknown01; u8 unused04:4, abr:4; u8 unused05:7, tdr:1; u8 unused06:7, beep:1; u8 unused07:2, timeout:6; u8 unused08:6, tcall:2; u8 unknown02[3]; u8 unused09:6, voice:2; u8 unknown03; u8 unused10:6, dtmfst:2; u8 unknown04; u8 unused11:6, screv:2; u8 unused12:6, pttid:2; u8 unused13:2, pttlt:6; u8 unused14:6, mdfa:2; u8 unused15:6, mdfb:2; u8 unknown05; u8 unused16:7, autolk:1; u8 unknown06[4]; u8 unused17:6, wtled:2; u8 unused18:6, rxled:2; u8 unused19:6, txled:2; u8 unused20:6, almod:2; u8 unknown07[2]; u8 unused22:7, ste:1; u8 unused23:4, rpste:4; u8 unused24:4, rptrl:4; u8 unused25:7, ponmsg:1; u8 unused26:7, roger:1; u8 unknown08[2]; u8 displayab:1, unknown09:2, fmradio:1, alarm:1, unknown10:1, reset:1, menu:1; u8 unknown11; u8 unused29:7, workmode:1; u8 unused30:7, keylock:1; u8 cht; } settings; #seekto 0x0E76; struct { u8 unused0:1, mrcha:7; u8 unused1:1, mrchb:7; } wmchannel; struct vfo { u8 unknown0[8]; u8 freq[8]; u8 offset[6]; ul16 rxtone; ul16 txtone; u8 unused0:7, band:1; u8 unknown3; u8 unknown4:2, sftd:2, scode:4; u8 unknown5; u8 unknown6:1, step:3, unknown7:4; u8 txpower:1, widenarr:1, unknown8:6; }; #seekto 0x0F00; struct { struct vfo a; struct vfo b; } vfo; #seekto 0x0F4E; u16 fm_presets; #seekto 0x1000; struct { char name[7]; u8 unknown[9]; } names[128]; #seekto 0x1F40; struct { u8 sql0; u8 sql1; u8 sql2; u8 sql3; u8 sql4; u8 sql5; u8 sql6; u8 sql7; u8 sql8; u8 sql9; } squelch; struct limit { u8 enable; bbcd lower[2]; bbcd upper[2]; }; #seekto 0x1FC0; struct { struct limit vhf; struct limit uhf; } limits; #seekto 0x1FD0; struct { char line1[8]; char line2[8]; } sixpoweron_msg; // #seekto 0x1FE0; struct { char line1[7]; char line2[7]; } poweron_msg; #seekto 0x1FF0; struct { char line1[8]; char line2[8]; } firmware_msg; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('The BTech UV-6R driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") fm_preset = RadioSettingGroup("fm_preset", "FM Preset") dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") service = RadioSettingGroup("service", "Service Settings") top = RadioSettings(basic, advanced, other, work, fm_preset, dtmfe, service) # Basic settings if _mem.settings.squelch > 0x09: val = 0x00 else: val = _mem.settings.squelch rs = RadioSetting("settings.squelch", "Squelch", RadioSettingValueList( LIST_OFF1TO9, LIST_OFF1TO9[val])) basic.append(rs) if _mem.settings.save > 0x04: val = 0x00 else: val = _mem.settings.save rs = RadioSetting("settings.save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) if _mem.settings.vox > 0x0A: val = 0x00 else: val = _mem.settings.vox rs = RadioSetting("settings.vox", "Vox", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) if _mem.settings.abr > 0x0A: val = 0x00 else: val = _mem.settings.abr rs = RadioSetting("settings.abr", "Backlight Timeout", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) rs = RadioSetting("settings.tdr", "Dual Watch", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean(_mem.settings.beep)) basic.append(rs) if _mem.settings.timeout > 0x27: val = 0x03 else: val = _mem.settings.timeout rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( LIST_TIMEOUT, LIST_TIMEOUT[val])) basic.append(rs) if _mem.settings.voice > 0x02: val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) if _mem.settings.screv > 0x02: val = 0x01 else: val = _mem.settings.screv rs = RadioSetting("settings.screv", "Scan Resume", RadioSettingValueList( LIST_RESUME, LIST_RESUME[val])) basic.append(rs) rs = RadioSetting("settings.pttid", "When to send PTT ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[ _mem.settings.pttid])) basic.append(rs) if _mem.settings.pttlt > 0x1E: val = 0x05 else: val = _mem.settings.pttlt rs = RadioSetting("pttlt", "PTT ID Delay", RadioSettingValueInteger(0, 50, val)) basic.append(rs) rs = RadioSetting("settings.mdfa", "Display Mode (A)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfa])) basic.append(rs) rs = RadioSetting("settings.mdfb", "Display Mode (B)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfb])) basic.append(rs) rs = RadioSetting("settings.autolk", "Auto Lock Keypad", RadioSettingValueBoolean(_mem.settings.autolk)) basic.append(rs) rs = RadioSetting("settings.wtled", "Standby LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.wtled])) basic.append(rs) rs = RadioSetting("settings.rxled", "RX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.rxled])) basic.append(rs) rs = RadioSetting("settings.txled", "TX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.txled])) basic.append(rs) if _mem.settings.almod > 0x02: val = 0x00 else: val = _mem.settings.almod rs = RadioSetting("settings.almod", "Alarm Mode", RadioSettingValueList( LIST_ALMOD, LIST_ALMOD[val])) basic.append(rs) if _mem.settings.tcall > 0x05: val = 0x00 else: val = _mem.settings.tcall rs = RadioSetting("settings.tcall", "Tone Burst Frequency", RadioSettingValueList( LIST_TCALL, LIST_TCALL[val])) basic.append(rs) rs = RadioSetting("settings.ste", "Squelch Tail Eliminate (HT to HT)", RadioSettingValueBoolean(_mem.settings.ste)) basic.append(rs) if _mem.settings.rpste > 0x0A: val = 0x00 else: val = _mem.settings.rpste rs = RadioSetting("settings.rpste", "Squelch Tail Eliminate (repeater)", RadioSettingValueList( LIST_RPSTE, LIST_RPSTE[val])) basic.append(rs) if _mem.settings.rptrl > 0x0A: val = 0x00 else: val = _mem.settings.rptrl rs = RadioSetting("settings.rptrl", "STE Repeater Delay", RadioSettingValueList( LIST_STEDELAY, LIST_STEDELAY[val])) basic.append(rs) rs = RadioSetting("settings.ponmsg", "Power-On Message", RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[ _mem.settings.ponmsg])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger Beep", RadioSettingValueBoolean(_mem.settings.roger)) basic.append(rs) # Advanced settings rs = RadioSetting("settings.reset", "RESET Menu", RadioSettingValueBoolean(_mem.settings.reset)) advanced.append(rs) rs = RadioSetting("settings.menu", "All Menus", RadioSettingValueBoolean(_mem.settings.menu)) advanced.append(rs) rs = RadioSetting("settings.fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_mem.settings.fmradio)) advanced.append(rs) rs = RadioSetting("settings.alarm", "Alarm Sound", RadioSettingValueBoolean(_mem.settings.alarm)) advanced.append(rs) # Other settings def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = _mem.firmware_msg val = RadioSettingValueString(0, 8, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val) other.append(rs) val = RadioSettingValueString(0, 8, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val) other.append(rs) _msg = _mem.sixpoweron_msg val = RadioSettingValueString(0, 8, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1", val) other.append(rs) val = RadioSettingValueString(0, 8, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2", val) other.append(rs) _msg = _mem.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 7, _filter(_msg.line2))) other.append(rs) lower = 136 upper = 174 rs = RadioSetting("limits.vhf.lower", "VHF Lower Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.vhf.lower)) other.append(rs) rs = RadioSetting("limits.vhf.upper", "VHF Upper Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.vhf.upper)) other.append(rs) lower = 400 upper = 520 rs = RadioSetting("limits.uhf.lower", "UHF Lower Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.uhf.lower)) other.append(rs) rs = RadioSetting("limits.uhf.upper", "UHF Upper Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.uhf.upper)) other.append(rs) # Work mode settings rs = RadioSetting("settings.displayab", "Display", RadioSettingValueList( LIST_AB, LIST_AB[_mem.settings.displayab])) work.append(rs) rs = RadioSetting("settings.workmode", "VFO/MR Mode", RadioSettingValueList( LIST_WORKMODE, LIST_WORKMODE[_mem.settings.workmode])) work.append(rs) rs = RadioSetting("settings.keylock", "Keypad Lock", RadioSettingValueBoolean(_mem.settings.keylock)) work.append(rs) rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrcha)) work.append(rs) rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrchb)) work.append(rs) def my_validate(value): _vhf_lower = int(_mem.limits.vhf.lower) _vhf_upper = int(_mem.limits.vhf.upper) _uhf_lower = int(_mem.limits.uhf.lower) _uhf_upper = int(_mem.limits.uhf.upper) value = chirp_common.parse_freq(value) msg = ("Can't be less than %i.0000") if value > 99000000 and value < _vhf_lower * 1000000: raise InvalidValueError(msg % _vhf_lower) msg = ("Can't be between %i.9975-%i.0000") if _vhf_upper * 1000000 <= value and value < _uhf_lower * 1000000: raise InvalidValueError(msg % (_vhf_upper - 1, _uhf_lower)) msg = ("Can't be greater than %i.9975") if value > 99000000 and value >= _uhf_upper * 1000000: raise InvalidValueError(msg % (_uhf_upper - 1)) return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.a.freq)) val1a.set_validate_callback(my_validate) rs = RadioSetting("vfo.a.freq", "VFO A Frequency", val1a) rs.set_apply_callback(apply_freq, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.b.freq)) val1b.set_validate_callback(my_validate) rs = RadioSetting("vfo.b.freq", "VFO B Frequency", val1b) rs.set_apply_callback(apply_freq, _mem.vfo.b) work.append(rs) rs = RadioSetting("vfo.a.sftd", "VFO A Shift", RadioSettingValueList( LIST_SHIFTD, LIST_SHIFTD[_mem.vfo.a.sftd])) work.append(rs) rs = RadioSetting("vfo.b.sftd", "VFO B Shift", RadioSettingValueList( LIST_SHIFTD, LIST_SHIFTD[_mem.vfo.b.sftd])) work.append(rs) def convert_bytes_to_offset(bytes): real_offset = 0 for byte in bytes: real_offset = (real_offset * 10) + byte return chirp_common.format_freq(real_offset * 1000) def apply_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 1000 for i in range(5, -1, -1): obj.offset[i] = value % 10 value /= 10 val1a = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.a.offset)) rs = RadioSetting("vfo.a.offset", "VFO A Offset", val1a) rs.set_apply_callback(apply_offset, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.b.offset)) rs = RadioSetting("vfo.b.offset", "VFO B Offset", val1b) rs.set_apply_callback(apply_offset, _mem.vfo.b) work.append(rs) rs = RadioSetting("vfo.a.txpower", "VFO A Power", RadioSettingValueList( LIST_TXPOWER, LIST_TXPOWER[_mem.vfo.a.txpower])) work.append(rs) rs = RadioSetting("vfo.b.txpower", "VFO B Power", RadioSettingValueList( LIST_TXPOWER, LIST_TXPOWER[_mem.vfo.b.txpower])) work.append(rs) rs = RadioSetting("vfo.a.widenarr", "VFO A Bandwidth", RadioSettingValueList( LIST_BANDWIDTH, LIST_BANDWIDTH[_mem.vfo.a.widenarr])) work.append(rs) rs = RadioSetting("vfo.b.widenarr", "VFO B Bandwidth", RadioSettingValueList( LIST_BANDWIDTH, LIST_BANDWIDTH[_mem.vfo.b.widenarr])) work.append(rs) rs = RadioSetting("vfo.a.scode", "VFO A S-CODE", RadioSettingValueList( LIST_SCODE, LIST_SCODE[_mem.vfo.a.scode])) work.append(rs) rs = RadioSetting("vfo.b.scode", "VFO B S-CODE", RadioSettingValueList( LIST_SCODE, LIST_SCODE[_mem.vfo.b.scode])) work.append(rs) rs = RadioSetting("vfo.a.step", "VFO A Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.a.step])) work.append(rs) rs = RadioSetting("vfo.b.step", "VFO B Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.b.step])) work.append(rs) # broadcast FM settings _fm_presets = self._memobj.fm_presets if _fm_presets <= 108.0 * 10 - 650: preset = _fm_presets / 10.0 + 65 elif _fm_presets >= 65.0 * 10 and _fm_presets <= 108.0 * 10: preset = _fm_presets / 10.0 else: preset = 76.0 rs = RadioSetting("fm_presets", "FM Preset(MHz)", RadioSettingValueFloat(65, 108.0, preset, 0.1, 1)) fm_preset.append(rs) # DTMF settings def apply_code(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) pttid = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) pttid.set_apply_callback(apply_code, self._memobj.pttid[i], 5) dtmfe.append(pttid) if _mem.ani.dtmfon > 0xC3: val = 0x03 else: val = _mem.ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if _mem.ani.dtmfoff > 0xC3: val = 0x03 else: val = _mem.ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) _codeobj = self._memobj.ani.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.code", "ANI Code", val) rs.set_apply_callback(apply_code, self._memobj.ani, 5) dtmfe.append(rs) rs = RadioSetting("ani.aniid", "When to send ANI ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[_mem.ani.aniid])) dtmfe.append(rs) # Service settings for index in range(0, 10): key = "squelch.sql%i" % (index) _obj = self._memobj.squelch val = RadioSettingValueInteger(0, 123, getattr(_obj, "sql%i" % (index))) if index == 0: val.set_mutable(False) name = "Squelch %i" % (index) rs = RadioSetting(key, name, val) service.append(rs) return top @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) in (0x2008, 0x2010): match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/puxing_px888k.py0000644000175000017500000020434414562640504017652 0ustar hibbyhibby# Copyright 2016 Leo Barring # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, directory, memmap, \ bitwise, settings, errors, util from struct import pack import logging LOG = logging.getLogger(__name__) SUPPORT_NONSPLIT_DUPLEX_ONLY = False SUPPORT_SPLIT_BUT_DEFAULT_TO_NONSPLIT_ALWAYS = True UNAMBIGUOUS_CROSS_MODES_ONLY = True # With this setting enabled, some CHIRP settings are stored in # thought-to-be junk/padding data of the channel memories. # Enabling this feature while using CHIRP with an actual radio # and any effects thereof is entirely the responsibility of the user. ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES = False MEM_FORMAT = """ // data fields are generally written 0xff if they are unset struct { #seekto 0x0000; struct { struct { // 0-3 bbcd rx_freq[4]; // 4-7 bbcd tx_freq[4]; // 8-9 A-B struct { u8 digital:1, invert:1, high:6; u8 low; } tone[2]; // tx_squelch on 0, rx_squelch on 1 // C // the duplex sign is not used for memories, // but is kept for interface consistency u8 duplex_sign:2, compander:1, txpower:1, modulation_width:1, txrx_reverse:1, bcl:2; // D u8 scrambler_type:3, use_scrambler:1, opt_signal:2, ptt_id_edge:2; // E-F // u8 _unknown_000E[2]; %s } data[128]; struct { // 0-5, alt 8-D char entry[6]; // 6-8, alt E-F char _unknown_0806[2]; } names[128]; #seekto 0x0c20; bit present[128]; #seekto 0x0c30; bit priority[128]; } channel_memory; #seekto 0x0c00; struct { // 0-3 bbcd rx_freq[4]; // 4-7 bbcd tx_freq[4]; // actually offset, but kept for name consistency // 8 struct { u8 digital:1, invert:1, high:6; u8 low; } tone[2]; // tx_squelch on 0, rx_squelch on 1 // C u8 duplex_sign:2, compander:1, txpower:1, modulation_width:1, txrx_reverse:1, bcl:2; // D u8 scrambler_type:3, use_scrambler:1, opt_signal:2, ptt_id_edge:2; // E-F // u8 _unknown_0C0E[2]; %s } vfo_data[2]; #seekto 0xc40; struct { // 0-5 char model_string[6]; // typically PX888D, unknown if rw or ro // 6-7 u8 _unknown_0C46[2]; // 8-9 struct { bbcd lower_freq[2]; bbcd upper_freq[2]; } band_limits[2]; } model_information; #seekto 0x0c50; char radio_information_string[16]; #seekto 0x0c60; struct { // 0 u8 ptt_cancel_sq:1, dis_ptt_id:1, workmode_b:2, use_roger_beep:1, msk_reverse:1, workmode_a:2; // 1 u8 backlight_color:2, backlight_mode:2, dual_single_watch:1, auto_keylock:1, scan_mode:2; // 2 u8 rx_stun:1, tx_stun:1, boot_message_mode:2, battery_save:1, key_beep:1, voice_announce:2; // 3 bbcd squelch_level; // 4 bbcd tx_timeout; // 5 u8 allow_keypad:1, relay_without_disable_tail:1, _unknown_0C65:1, call_channel_active:1, vox_gain:4; // 6 bbcd vox_delay; // 7 bbcd vfo_step; // 8 bbcd ptt_id_type; // 9 u8 keypad_lock:1, _unknown_0C69_1:1, side_button_hold_mode:2, dtmf_sidetone:1, _unknown_0C69_2:1, side_button_click_mode:2; // A u8 roger_beep:4, main_watch:1, _unknown_0C6A:3; // B u8 channel_a; // C u8 channel_b; // D u8 priority_channel; // E u8 wait_time; // F u8 _unknown_0C6F; // 0-7 on next block u8 _unknown_0C70[8]; // 8-D on next block char boot_message[6]; } opt_settings; #seekto 0x0c80; struct { // these fields are used for all ptt id forms (msk/dtmf/5t) // (only one can be active and stored at a time) // and different constraints are applied depending // on the ptt id type u8 entry[7]; u8 length; } ptt_id_data[2]; // 0 is BOT, 1 is EOT #seekto 0x0c90; struct { // 0 u8 _unknown_0C90; // 1 u8 _unknown_0C91_1:3, channel_stepping:1, unknown_0C91_2:1, receive_range:2, unknown_0C91_3:1; // 2-3 u8 _unknown_0C92[2]; // 4-7 u8 vfo_freq[4]; // 8-F and two more blocks struct { u8 entry[4]; } memory[10]; } fm_radio; #seekto 0x0cc0; struct { char id_code[4]; struct { char entry[4]; } phone_book[9]; } msk_settings; #seekto 0x0cf0; struct { // 0-3 bbcd rx_freq[4]; // 4-7 bbcd tx_freq[4]; // 8 struct { u8 digital:1, invert:1, high:6; u8 low; } tone[2]; // tx_squelch on 0, rx_squelch on 1 // C // the duplex sign is not used for the CALL, // channel but is kept for interface consistency u8 duplex_sign:2, compander:1, txpower:1, modulation_width:1, txrx_reverse:1, bcl:2; // D u8 scrambler_type:3, use_scrambler:1, opt_signal:2, ptt_id_edge:2; // E-F // u8 _unknown_0CFE[2]; %s } call_channel; #seekto 0x0d00; struct { // DTMF codes are stored as hex half-bytes, // 0-9 A-D are mapped straight // DTMF '*' is HEX E, DTMF '#' is HEX F // 0x0d00 struct { u8 digit_length; // 0x05 to 0x14 corresponding to 50-200ms u8 inter_digit_pause; // same u8 first_digit_length; // same u8 first_digit_delay; // 0x02 to 0x14 corresponding to 100-1000ms } timing; #seekto 0x0d30; u8 _unknown_0D30[2]; // 0-1 u8 group_code; // 2 u8 reset_time; // 3 u8 alert_transpond; // 4 u8 id_code[4]; // 5-8 u8 _unknown_0D39[4]; // 9-C u8 id_code_length; // D u8 _unknown_0d3e[2]; // E-F // 0x0d40 u8 tx_stun_code[4]; u8 _unknown_0D44[4]; u8 tx_stun_code_length; u8 cancel_tx_stun_code_length; u8 cancel_tx_stun_code[4]; u8 _unknown_0D4E[2]; // 0x0d50 u8 rxtx_stun_code[4]; u8 _unknown_0D54[4]; u8 rxtx_stun_code_length; u8 cancel_rxtx_stun_code_length; u8 cancel_rxtx_stun_code[4]; u8 _unknown_0D5E[2]; // 0x0d60 struct { u8 entry[5]; u8 _unknown_0D65[3]; u8 length; u8 _unknown_0D69[7]; } phone_book[9]; } dtmf_settings; #seekto 0x0e00; struct { u8 delay; u8 _unknown_0E01[5]; u8 alert_transpond; u8 reset_time; u8 tone_standard; u8 id_code[3]; #seekto 0x0e20; struct { u8 period; u8 group_code:4, repeat_code:4; } tone_settings[4]; // the order is ZVEI1 ZVEI2 CCIR1 CCITT #seekto 0x0e40; // 5-Tone tone standard frequency table // unknown use, changing the values does not seem to have // any effect on the produced sound, but the values are not // overwritten either. il16 tone_frequency_table[16]; // 0xe60 u8 tx_stun_code[5]; u8 _unknown_0E65[3]; u8 tx_stun_code_length; u8 cancel_tx_stun_code_length; u8 cancel_tx_stun_code[5]; u8 _unknown_0E6F; // 0xe70 u8 rxtx_stun_code[5]; u8 _unknown_0E75[3]; u8 rxtx_stun_code_length; u8 cancel_rxtx_stun_code_length; u8 cancel_rxtx_stun_code[5]; u8 _unknown_0E7F; // 0xe80 struct { u8 entry[3]; } phone_book[9]; } five_tone_settings; } mem;""" # various magic numbers and strings, apart from the memory format if ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES: LOG.warn("ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES" "AND/OR DANGEROUS FEATURES ENABLED") MEM_FORMAT = MEM_FORMAT % ( "u8 _unknown_000E_1: 6,\n" " experimental_duplex_mode_indicator: 1,\n" " experimental_cross_mode_indicator: 1;\n" "u8 _unknown_000F;", "u8 _unknown_0C0E_1: 6,\n" " experimental_duplex_mode_indicator: 1,\n" " experimental_cross_mode_indicator: 1;\n" "u8 _unknown_0C0F;", "u8 _unknown_0CFE_1: 6,\n" " experimental_duplex_mode_indicator: 1,\n" " experimental_cross_mode_indicator: 1;\n" "u8 _unknown_0CFF;") # we don't need these settings anymore, because it's exactly what the # experimental features are about SUPPORT_SPLIT_BUT_DEFAULT_TO_NONSPLIT_ALWAYS = False SUPPORT_NONSPLIT_DUPLEX_ONLY = False UNAMBIGUOUS_CROSS_MODES_ONLY = False else: MEM_FORMAT = MEM_FORMAT % ( "u8 _unknown_000E[2];", "u8 _unknown_0C0E[2];", "u8 _unknown_0CFE[2];") FILE_MAGIC = [0xc40, 0xc50, b'\x50\x58\x38\x38\x38\x44\x00\xff' b'\x13\x40\x17\x60\x40\x00\x48\x00'] HANDSHAKE_OUT = b'XONLINE' HANDSHAKE_IN = [b'PX888D\x00\xff'] LOWER_READ_BOUND = 0 UPPER_READ_BOUND = 0x1000 LOWER_WRITE_BOUND = 0 UPPER_WRITE_BOUND = 0x0fc0 BLOCKSIZE = 64 OFF_INT = ["Off"] + [str(x+1) for x in range(100)] OFF_ON = ["Off", "On"] INACTIVE_ACTIVE = ["Inactive", "Active"] NO_YES = ["No", "Yes"] YES_NO = ["Yes", "No"] BANDS = [(134000000, 176000000), # VHF (400000000, 480000000)] # UHF SPECIAL_CHANNELS = {'VFO-A': -2, 'VFO-B': -1, 'CALL': 0} SPECIAL_NUMBERS = {-2: 'VFO-A', -1: 'VFO-B', 0: 'CALL'} DUPLEX_MODES = ['', '+', '-', 'split'] if SUPPORT_NONSPLIT_DUPLEX_ONLY: DUPLEX_MODES = ['', '+', '-'] TONE_MODES = ["", "Tone", "TSQL", "DTCS", "Cross"] CROSS_MODES = ["Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS", "Tone->"] if UNAMBIGUOUS_CROSS_MODES_ONLY: CROSS_MODES = ["Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] MODES = ["NFM", "FM"] # Only the 'High' power level is quantified in the manual for # the radio (4W for VHF, 5W for UHF), a web search turned # up numbers for the 'Low' power level (0.5W for VHF and # 0.7W for UHF), but they are not official to my knowledge # and should be taken with a grain of salt or two. # Numbers used in code is the averages POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=0.6), chirp_common.PowerLevel("High", watts=4.5)] SKIP_MODES = ["", "S"] BCL_MODES = ["Off", "Carrier", "QT/DQT"] SCRAMBLER_MODES = OFF_INT[0:9] PTT_ID_EDGES = ["Off", "BOT", "EOT", "Both"] OPTSIGN_MODES = ["None", "DTMF", "5-Tone", "MSK"] VFO_STRIDE = ['5 kHz', '6.25 kHz', '10 kHz', '12.5 kHz', '25 kHz'] AB = ['A', 'B'] WATCH_MODES = ['Single watch', 'Dual watch'] AB_MODES = ['VFO', 'Memory index', 'Memory name', 'Memory frequency'] SCAN_MODES = ["Time", "Carrier", "Seek"] WAIT_TIMES = [("0.3s", 6), ("0.5s", 10)] +\ [("%ds" % t, t*20) for t in range(1, 13)] BUTTON_MODES = ["Send call list data", "Emergency alarm", "Send 1750 Hz signal", "Open squelch"] BOOT_MESSAGE_TYPES = ["Off", "Battery voltage", "Custom message"] TALKBACK = ['Off', 'Chinese', 'English'] BACKLIGHT_COLORS = list(zip(["Blue", "Orange", "Purple"], range(1, 4))) VOX_GAIN = OFF_INT[0:10] VOX_DELAYS = ['1s', '2s', '3s', '4s'] TRANSMIT_ALARMS = ['Off', '30s', '60s', '90s', '120s', '150s', '180s', '210s', '240s', '270s'] DATA_MODES = ['MSK', 'DTMF', '5-Tone'] ASCIIPART = ''.join([chr(x) for x in range(0x20, 0x7f)]) DTMF = "0123456789ABCD*#" HEXADECIMAL = "0123456789ABCDEF" ROGER_BEEP = OFF_INT[0:11] BACKLIGHT_MODES = ["Off", "Auto", "On"] TONE_RESET_TIME = ['Off'] + ['%ds' % x for x in range(1, 256)] DTMF_TONE_RESET_TIME = TONE_RESET_TIME[0:16] DTMF_GROUPS = list(zip(["Off", "A", "B", "C", "D", "*", "#"], [255] + list(range(10, 16)))) FIVE_TONE_STANDARDS = ['ZVEI1', 'ZVEI2', 'CCIR1', 'CCITT'] # should mimic the defaults in the memedit MemoryEditor somewhat # 0 1 2 3 4 5 6 7 SANE_MEMORY_DEFAULT = b"\x14\x61\x00\x00\x14\x61\x00\x00" + \ b"\xff\xff\xff\xff\xc8\x00\xff\xff" # 8 9 A B C D E F # these two option sets are listed differently like this in the stock software, # so I'm keeping them separate for now if they are in fact identical # in behaviour, that should probably be amended DTMF_ALERT_TRANSPOND = list(zip(['Off', 'Call alert', 'Transpond-alert', 'Transpond-ID code'], [255] + list(range(1, 4)))) FIVE_TONE_ALERT_TRANSPOND = list(zip(['Off', 'Alert tone', 'Transpond', 'Transpond-ID code'], [255] + list(range(1, 4)))) BFM_BANDS = ['87.5-108 MHz', '76.0-91.0 MHz', '76.0-108.0 MHz', '65.0-76.0 MHz'] BFM_STRIDE = ['100 kHz', '50 kHz'] def piperead(pipe, amount): """read some data, catch exceptions, validate length of data read""" try: d = pipe.read(amount) except Exception as e: raise errors.RadioError( "Tried to read %d bytes, but got an exception: %s" % (amount, repr(e))) if d is None: raise errors.RadioError( "Tried to read %d bytes, but read operation returned ." % (amount)) if d is None or len(d) != amount: raise errors.RadioError( "Tried to read %d bytes, but got %d bytes instead." % (amount, len(d))) return d def pipewrite(pipe, data): """write some data, catch exceptions, validate length of data written""" try: n = pipe.write(data) except Exception as e: raise errors.RadioError( "Tried to write %d bytes, but got an exception: %s." % (len(data), repr(e))) if n is None: raise errors.RadioError( "Tried to write %d bytes, but operation returned ." % (len(data))) if n != len(data): raise errors.RadioError( "Tried to write %d bytes, but wrote %d bytes instead." % (len(data), n)) def attempt_initial_handshake(pipe): """try to do the initial handshake""" pipewrite(pipe, HANDSHAKE_OUT) x = piperead(pipe, len(HANDSHAKE_IN[0])) if x in HANDSHAKE_IN: return True LOG.debug("Handshake failed: received: %s expected one of: %s" % (repr(x), repr(HANDSHAKE_IN))) return False def initial_handshake(pipe, tries): """do an initial handshake attempt up to tries times""" x = False for i in range(tries): x = attempt_initial_handshake(pipe) if x: break if not x: raise errors.RadioError("Initial handshake failed all ten tries.") def mk_writecommand(addr): """makes a write command from an address specification""" return pack('>cHc', b'W', addr, b'@') def mk_readcommand(addr): """makes a read command from an address specification""" return pack('>cHc', b'R', addr, b'@') def expect_ack(pipe): x = piperead(pipe, 1) if x != b'\x06': LOG.debug( "Did not get ACK. received: %s, expected: '\\x06'" % repr(x)) raise errors.RadioError("Did not get ACK when expected.") def end_communications(pipe): """tell the radio that we are done""" pipewrite(pipe, b'E') expect_ack(pipe) def read_block(pipe, addr): """read and return a chunk of data at specified address""" r = mk_readcommand(addr) w = mk_writecommand(addr) pipewrite(pipe, r) x = piperead(pipe, len(w)) if x != w: raise errors.RadioError("Received data not following protocol.") block = piperead(pipe, BLOCKSIZE) return block def write_block(pipe, addr, block): """write a chunk of data at specified address""" w = mk_writecommand(addr) pipewrite(pipe, w) pipewrite(pipe, block) expect_ack(pipe) def show_progress(radio, blockaddr, upper, msg): """relay read/write information to the user through the gui""" if radio.status_fn: status = chirp_common.Status() status.cur = blockaddr status.max = upper status.msg = msg radio.status_fn(status) def do_download(radio): """download from the radio to the memory map""" initial_handshake(radio.pipe, 10) memory = memmap.MemoryMapBytes(b'\xff'*0x1000) for blockaddr in range(LOWER_READ_BOUND, UPPER_READ_BOUND, BLOCKSIZE): LOG.debug("Reading block "+str(blockaddr)) block = read_block(radio.pipe, blockaddr) memory.set(blockaddr, block) show_progress(radio, blockaddr, UPPER_READ_BOUND, "Reading radio memory... %04x" % blockaddr) end_communications(radio.pipe) return memory def do_upload(radio): """upload from the memory map to the radio""" memory = radio.get_mmap() initial_handshake(radio.pipe, 10) for blockaddr in range(LOWER_WRITE_BOUND, UPPER_WRITE_BOUND, BLOCKSIZE): LOG.debug("Writing block "+str(blockaddr)) block = memory[blockaddr:blockaddr+BLOCKSIZE] write_block(radio.pipe, blockaddr, block) show_progress(radio, blockaddr, UPPER_WRITE_BOUND, "Writing radio memory... % 04x" % blockaddr) end_communications(radio.pipe) def parse_tone(t): """ parse the tone (ctss, dtcs) part of the mmap into more easily handled data types """ # [ mode, value, polarity ] if int(t.high) == 0x3f and int(t.low) == 0xff: return [None, None, None] elif bool(t.digital): t = ['DTCS', (int(t.high) & 0x0f)*100 + ((int(t.low) & 0xf0) >> 4)*10 + (int(t.low) & 0x0f), ['N', 'R'][bool(t.invert)]] if t[1] not in chirp_common.DTCS_CODES: return [None, None, None] else: t = ['Tone', ((int(t.high) & 0xf0) >> 4)*100 + (int(t.high) & 0x0f)*10 + ((int(t.low) & 0xf0) >> 4) + (int(t.low) & 0x0f)/10.0, None] if t[1] not in chirp_common.TONES: return [None, None, None] return t def unparse_tone(t): """parse tone data back into the format used by the radio""" # [ mode, value, polarity ] if t[0] == 'Tone': tint = int(t[1]*10) t0, tint = tint % 10, tint // 10 t1, tint = tint % 10, tint // 10 t2, tint = tint % 10, tint // 10 high = (tint << 4) | t2 low = (t1 << 4) | t0 digital = False invert = False return digital, invert, high, low elif t[0] == 'DTCS': tint = int(t[1]) t0, tint = tint % 10, tint // 10 t1, tint = tint % 10, tint // 10 high = tint low = (t1 << 4) | t0 digital = True invert = t[2] == 'R' return digital, invert, high, low return None def decode_halfbytes(data, mapping, length): """ construct a string from a datatype where each half-byte maps to a character """ s = '' for i in range(length): if i & 1 == 0: s += mapping[(int(data[i >> 1]) & 0xf0) >> 4] else: s += mapping[int(data[i >> 1]) & 0x0f] return s def encode_halfbytes(data, datapad, mapping, fillvalue, fieldlen): """encode data from a string where each character maps to a half-byte""" if len(data) & 1: # pad to an even length data += datapad o = [fillvalue] * fieldlen for i in range(0, len(data), 2): v = (mapping.index(data[i]) << 4) | mapping.index(data[i+1]) o[i >> 1] = v return bytearray(util.byte_to_int(b) for b in o) def decode_ffstring(data): """decode a string delimited by 0xff""" s = '' for b in data: if int(b) == 0xff: break s += chr(int(b)) return s def encode_ffstring(data, fieldlen): """right-pad to specified length with 0xff bytes""" extra = fieldlen-len(data) if extra > 0: data += '\xff'*extra return bytearray([util.byte_to_int(x) for x in data]) def decode_dtmf(data, length): """decode a field containing dtmf data into a string""" if length == 0xff: return '' return decode_halfbytes(data, DTMF, length) def encode_dtmf(data, length, fieldlen): """encode a string containing dtmf characters into a data field""" return encode_halfbytes(data, '0', DTMF, b'\xff', fieldlen) def decode_5tone(data): """decode a field containing 5-tone data into a string""" if (int(data[2]) & 0x0f) != 0: return '' return decode_halfbytes(data, HEXADECIMAL, 5) def encode_5tone(data, fieldlen): """encode a string containing 5-tone characters into a data field""" return encode_halfbytes(data, '0', HEXADECIMAL, b'\xff', fieldlen) def decode_freq(data): """decode frequency data for the broadcast FM radio memories""" data_out = '' if data[0] != 0xff: data_out = chirp_common.format_freq( int(decode_halfbytes(data, "0123456789", len(data)))*100000) return data_out def encode_freq(data, fieldlen): """encode frequency data for the broadcast FM radio memories""" data_out = bytearray(b'\xff')*fieldlen if data != '': data_out = encode_halfbytes((('%%0%di' % (fieldlen << 1)) % int(chirp_common.parse_freq(data)/10)), '', '0123456789', '', fieldlen) return data_out def sbyn(s, n): """setting by name""" return list(filter(lambda x: x.get_name() == n, s))[0] # These helper classes provide a direct link between the value # of the widget shown in the ui, and the setting in the memory # map of the radio, lessening the need to write large chunks # of code, first for populating the ui from the memory map, # then secondly for parsing the values back. # By supplying the memory map entry to the setting instance, # it is possible to automatically 1) initialize the value of # the setting, as well as 2) automatically update the memory # value when the user changes it in the ui, without adding # any code outside the class. class MappedIntegerSettingValue(settings.RadioSettingValueInteger): """" Integer setting, with the possibility to add translation functions between memory map <-> integer setting """ def __init__(self, val_mem, minval, maxval, step=1, int_from_mem=lambda x: int(x), mem_from_int=lambda x: x, autowrite=True): """ val_mem - memory map entry for the value minval - the minimum value allowed maxval - maximum value allowed step - value stepping int_from_mem - function to convert memory entry to integer mem_from_int - function to convert integer to memory entry autowrite - automatically write the memory map entry when the value is changed """ self._val_mem = val_mem self._int_from_mem = int_from_mem self._mem_from_int = mem_from_int self._autowrite = autowrite settings.RadioSettingValueInteger.__init__( self, minval, maxval, self._int_from_mem(val_mem), step) def set_value(self, x): settings.RadioSettingValueInteger.set_value(self, x) if self._autowrite: self.write_mem() def write_mem(self): if self.get_mutable() and self._mem_from_int is not None: self._val_mem.set_value(self._mem_from_int( settings.RadioSettingValueInteger.get_value(self))) class MappedListSettingValue(settings.RadioSettingValueMap): """Mapped list setting""" def __init__(self, val_mem, options, autowrite=True): """ val_mem - memory map entry for the value options - either a list of strings options to present, mapped to integers 0...n in the memory map entry, or a list of tuples ("option description", memory map value) int_from_mem - function to convert memory entry to integer mem_from_int - function to convert integer to memory entry autowrite - automatically write the memory map entry when the value is changed """ self._val_mem = val_mem self._autowrite = autowrite options = list(options) if not isinstance(options[0], tuple): options = list(zip(options, range(len(options)))) settings.RadioSettingValueMap.__init__( self, options, mem_val=int(val_mem)) def set_value(self, value): settings.RadioSettingValueMap.set_value(self, value) if self._autowrite: self.write_mem() def write_mem(self): if self.get_mutable(): self._val_mem.set_value( settings.RadioSettingValueMap.get_mem_val(self)) class MappedCodedStringSettingValue(settings.RadioSettingValueString): """ generic base class for a number of mapped presented-as-strings values which may need conversion between mem and string, and may store a length value in a separate mem field """ def __init__(self, val_mem, len_mem, min_length, max_length, charset=ASCIIPART, padchar=' ', autowrite=True, str_from_mem=lambda mve, lve: str(mve[0:int(lve)]), mem_val_from_str=lambda s, fl: s[0:fl], mem_len_from_int=lambda l: l): """ val_mem - memory map entry for the value len_mem - memory map entry for the length (or None) min_length - length that the string will be right-padded to max_length - maximum length of the string, set as maxlength for the RadioSettingValueString charset - the allowed charset padchar - the character that will be used to pad short strings, if not in the charset, charset[0] is used autowrite - automatically call write_mem when the ui value change str_from_mem - function to convert from memory entry to string value, form: func(value_entry, length_entry or none) -> string mem_val_from_str - function to convert from string value to memory-fitting value, form: func(string, value_entry_length) -> value to store in value entry mem_len_from_int - function to convert from string length to memory-fitting value, form: func(stringlength) -> value to store in length entry """ self._min_length = min_length self._val_mem = val_mem self._len_mem = len_mem self._padchar = padchar if padchar not in charset: self._padchar = charset[0] self._autowrite = autowrite self._str_from_mem = str_from_mem self._mem_val_from_str = mem_val_from_str self._mem_len_from_int = mem_len_from_int settings.RadioSettingValueString.__init__( self, 0, max_length, self._str_from_mem(self._val_mem, self._len_mem), charset=charset, autopad=False) def set_value(self, value): """ Set the value of the string, pad if below minimum length, unless it's '' to provide a distinction between uninitialized/reset data and needs-to-be-padded data """ while len(value) < self._min_length and len(value) != 0: value += self._padchar settings.RadioSettingValueString.set_value(self, value) if self._autowrite: self.write_mem() def write_mem(self): """update the memory""" if not self.get_mutable() or self._mem_val_from_str is None: return v = self.get_value() l = len(v) self._val_mem.set_value(self._mem_val_from_str(v, len(self._val_mem))) if self._len_mem is not None and self._mem_len_from_int is not None: self._len_mem.set_value(self._mem_len_from_int(l)) class MappedFFStringSettingValue(MappedCodedStringSettingValue): """ Mapped string setting, tailored for the puxing px888k, which uses 0xff terminated strings. """ def __init__(self, val_mem, min_length, max_length, charset=ASCIIPART, padchar=' ', autowrite=True): MappedCodedStringSettingValue.__init__( self, val_mem, None, min_length, max_length, charset=charset, padchar=padchar, autowrite=autowrite, str_from_mem=lambda mve, lve: decode_ffstring(mve), mem_val_from_str=lambda s, fl: encode_ffstring(s, fl), mem_len_from_int=None) class MappedDTMFStringSettingValue(MappedCodedStringSettingValue): """ Mapped string setting, tailored for the puxing px888k field pairs (value and length) storing DTMF codes """ def __init__(self, val_mem, len_mem, min_length, max_length, autowrite=True): MappedCodedStringSettingValue.__init__( self, val_mem, len_mem, min_length, max_length, charset=DTMF, padchar='0', autowrite=autowrite, str_from_mem=lambda mve, lve: decode_dtmf(mve, lve), mem_val_from_str=lambda s, fl: encode_dtmf(s, len(s), fl)) class MappedFiveToneStringSettingValue(MappedCodedStringSettingValue): """ Mapped string setting, tailored for the puxing px888k fields storing 5-Tone codes """ def __init__(self, val_mem, autowrite=True): MappedCodedStringSettingValue.__init__( self, val_mem, None, 0, 5, charset=HEXADECIMAL, padchar='0', autowrite=autowrite, str_from_mem=lambda mve, lve: decode_5tone(mve), mem_val_from_str=lambda s, fl: encode_5tone(s, fl), mem_len_from_int=None) class MappedFreqStringSettingValue(MappedCodedStringSettingValue): """ Mapped string setting, tailored for the puxing px888k fields for the broadcast FM radio frequencies """ def __init__(self, val_mem, autowrite=True): MappedCodedStringSettingValue.__init__( self, val_mem, None, 0, 128, charset=ASCIIPART, padchar=' ', autowrite=autowrite, str_from_mem=lambda mve, lve: decode_freq(mve), mem_val_from_str=lambda s, fl: encode_freq(s, fl)) # These functions lessen the amount of boilerplate on the form # x = RadioSetting("AAA", "BBB", SomeKindOfRadioSettingValue( ... )) # to # x = some_kind_of_setting("AAA", "BBB", ... ) def integer_setting(k, n, *args, **kwargs): return settings.RadioSetting( k, n, MappedIntegerSettingValue(*args, **kwargs)) def list_setting(k, n, *args, **kwargs): return settings.RadioSetting( k, n, MappedListSettingValue(*args, **kwargs)) def ff_string_setting(k, n, *args, **kwargs): return settings.RadioSetting( k, n, MappedFFStringSettingValue(*args, **kwargs)) def dtmf_string_setting(k, n, *args, **kwargs): return settings.RadioSetting( k, n, MappedDTMFStringSettingValue(*args, **kwargs)) def five_tone_string_setting(k, n, *args, **kwargs): return settings.RadioSetting( k, n, MappedFiveToneStringSettingValue(*args, **kwargs)) def frequency_setting(k, n, *args, **kwargs): return settings.RadioSetting( k, n, MappedFreqStringSettingValue(*args, **kwargs)) @directory.register class Puxing_PX888K_Radio(chirp_common.CloneModeRadio): """Puxing PX-888K""" VENDOR = "Puxing" MODEL = "PX-888K" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False @classmethod def match_model(cls, filedata, filename): if len(filedata) == UPPER_READ_BOUND: if filedata[FILE_MAGIC[0]:FILE_MAGIC[1]] == FILE_MAGIC[2]: return True return False def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank_index = False rf.has_dtcs = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_mode = True rf.has_offset = True rf.has_name = True rf.has_bank = False rf.has_bank_names = False rf.has_tuning_step = False rf.has_cross = True rf.has_infinite_number = False rf.has_nostep_tuning = False rf.has_comment = False rf.has_settings = True if SUPPORT_NONSPLIT_DUPLEX_ONLY: rf.can_odd_split = False else: rf.can_odd_split = True rf.valid_modes = MODES rf.valid_tmodes = TONE_MODES rf.valid_duplexes = DUPLEX_MODES rf.valid_bands = BANDS rf.valid_skips = SKIP_MODES rf.valid_power_levels = POWER_LEVELS rf.valid_characters = ASCIIPART rf.valid_name_length = 6 rf.valid_cross_modes = CROSS_MODES rf.memory_bounds = (1, 128) rf.valid_special_chans = list(SPECIAL_CHANNELS.keys()) rf.valid_tuning_steps = [5.0, 6.25, 10.0, 12.5, 25.0] return rf def sync_in(self): self._mmap = do_download(self) self.process_mmap() def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_out(self): do_upload(self) def _set_sane_defaults(self, data): # thanks thayward! data.set_raw(SANE_MEMORY_DEFAULT) def _uninitialize(self, data, n): if isinstance(data, bitwise.arrayDataElement): data.set_value(b"\xff"*n) else: data.set_raw(b"\xff"*n) def _get_memory_structs(self, number): """ fetch the correct data structs no matter if its regular or special channels, no matter if they're referred by name or channel index """ index = 2501 i = -42 designator = 'INVALID' isregular = False iscall = False isvfo = False _data = None _name = None _present = None _priority = None if number in SPECIAL_NUMBERS.keys(): index = number # special by index designator = SPECIAL_NUMBERS[number] elif number in SPECIAL_CHANNELS.keys(): # special by name index = SPECIAL_CHANNELS[number] designator = number elif number > 0: # regular by number index = number designator = number if index < 0: isvfo = True _data = self._memobj.mem.vfo_data[index+2] elif index == 0: iscall = True _data = self._memobj.mem.call_channel elif index > 0: isregular = True i = number - 1 _data = self._memobj.mem.channel_memory.data[i] _name = self._memobj.mem.channel_memory.names[i].entry _present = self._memobj.mem.channel_memory.present[ (i & 0x78) | (7-(i & 0x07))] _priority = self._memobj.mem.channel_memory.priority[ (i & 0x78) | (7-(i & 0x07))] if _data == bytearray(0xff)*16: self._set_sane_defaults(_data) return (index, designator, _data, _name, _present, _priority, isregular, isvfo, iscall) def get_raw_memory(self, number): x = self._get_memory_structs(number) return repr(x[2]) def get_memory(self, number): mem = chirp_common.Memory() (index, designator, _data, _name, _present, _priority, isregular, isvfo, iscall) = self._get_memory_structs(number) mem.number = index # handle empty channels if isregular: if bool(_present): mem.empty = False mem.name = str(decode_ffstring(_name)) mem.skip = SKIP_MODES[1-int(_priority)] else: mem.empty = True mem.name = '' return mem else: mem.empty = False mem.name = '' mem.extd_number = designator # get frequency data mem.freq = int(_data.rx_freq)*10 mem.offset = int(_data.tx_freq)*10 # interpret frequency data # only the vfo channels support duplex, # memory channels operate in split mode all the time if isvfo: mem.duplex = DUPLEX_MODES[int(_data.duplex_sign)] if mem.duplex == '-': mem.offset = mem.freq - mem.offset elif mem.duplex == '': mem.offset = 0 elif mem.duplex == '+': mem.offset = mem.offset - mem.freq else: if mem.freq == mem.offset: mem.duplex = '' mem.offset = 0 elif SUPPORT_NONSPLIT_DUPLEX_ONLY or \ SUPPORT_SPLIT_BUT_DEFAULT_TO_NONSPLIT_ALWAYS: if mem.freq > mem.offset: mem.offset = mem.freq - mem.offset mem.duplex = '-' elif mem.freq < mem.offset: mem.offset = mem.offset - mem.freq mem.duplex = '+' else: mem.duplex = 'split' # get tone data txtone = parse_tone(_data.tone[0]) rxtone = parse_tone(_data.tone[1]) chirp_common.split_tone_decode(mem, txtone, rxtone) ###################################################################### if ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES: # override certain settings based on flags # that we have set in junk areas of the memory # or basically, we BELIEVE this to be junk memory, # hence why it's experimental and dangerous if bool(_data.experimental_cross_mode_indicator) is False: if mem.tmode == 'Tone': mem.cross_mode = 'Tone->' elif mem.tmode == 'TSQL': mem.cross_mode = 'Tone->Tone' elif mem.tmode == 'DTCS': mem.cross_mode = 'DTCS->DTCS' mem.tmode = 'Cross' ###################################################################### # transmit mode and power level mem.mode = MODES[bool(_data.modulation_width)] mem.power = POWER_LEVELS[_data.txpower] # extra channel settings mem.extra = settings.RadioSettingGroup( "extra", "extra", list_setting("Busy channel lockout", "BCL", _data.bcl, BCL_MODES), list_setting("Swap transmit and receive frequencies", "Tx Rx freq swap", _data.txrx_reverse, OFF_ON), list_setting("Use compander", "Use compander", _data.compander, OFF_ON), list_setting("Use scrambler", "Use scrambler", _data.use_scrambler, NO_YES), list_setting("Scrambler selection", "Voice Scrambler", _data.scrambler_type, SCRAMBLER_MODES), list_setting("Send ID code before and/or after transmitting", "PTT ID", _data.ptt_id_edge, PTT_ID_EDGES), list_setting("Optional signal before/after transmission, " + "this setting overrides the PTT ID setting", "Opt Signal", _data.opt_signal, OPTSIGN_MODES)) ###################################################################### if ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES: # override certain settings based on flags # that we have set in junk areas of the memory # or basically, we BELIEVE this to be junk memory, # hence why it's experimental and dangerous if bool(_data.experimental_duplex_mode_indicator) is False: # if this flag is set, this means that we in the gui # have set the duplex mode to something # the channel does not really support, # such as split modes for vfo channels, # and non-split modes for the memory channels mem.duplex = DUPLEX_MODES[int(_data.duplex_sign)] mem.freq = int(_data.rx_freq)*10 mem.offset = int(_data.tx_freq)*10 if isvfo: # we want split, so we have to reconstruct it # from -/0/+ modes if mem.duplex == '-': mem.offset = mem.freq - mem.offset elif mem.duplex == '': mem.offset = mem.freq elif mem.duplex == '+': mem.offset = mem.freq + mem.offset mem.duplex = 'split' else: # we want -/0/+, so we have to reconstruct it # from split modes if mem.freq > mem.offset: mem.offset = mem.freq - mem.offset mem.duplex = '-' elif mem.freq < mem.offset: mem.offset = mem.offset - mem.freq mem.duplex = '+' else: mem.offset = 0 mem.duplex = '' ###################################################################### return mem def set_memory(self, mem): (index, designator, _data, _name, _present, _priority, isregular, isvfo, iscall) = self._get_memory_structs(mem.number) # handle empty channels if mem.empty: if isregular: _present.set_value(False) _priority.set_value(False) self._uninitialize(_data, 16) self._uninitialize(_name, 6) else: raise errors.InvalidValueError( "Can't remove CALL and/or VFO channels!") return # handle regular channel stuff like name and present+priority flags if isregular: if not bool(_present): self._set_sane_defaults(_data) _name.set_value( encode_ffstring(self.filter_name(mem.name.rstrip()), len(_name))) _present.set_value(True) _priority.set_value(1-SKIP_MODES.index(mem.skip)) # frequency data rxf = int(mem.freq/10) txf = int(mem.offset/10) _data.rx_freq.set_value(rxf) if isvfo: # fake split modes on write, for channels # that do not support it, which are some # (the two vfo channels) if mem.duplex == 'split': for band in BANDS: rb = mem.freq in range(band[0], band[1]) tb = mem.offset in range(band[0], band[1]) if rb != tb: raise errors.InvalidValueError( "VFO frequencies should be on the same band") if rxf < txf: _data.duplex_sign.set_value(1) _data.tx_freq.set_value(txf - rxf) elif rxf > txf: _data.duplex_sign.set_value(2) _data.tx_freq.set_value(rxf-txf) else: _data.duplex_sign.set_value(0) _data.tx_freq.set_value(0) else: _data.duplex_sign.set_value(DUPLEX_MODES.index(mem.duplex)) _data.tx_freq.set_value(txf) ###################################################################### if ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES: if mem.duplex == 'split': _data.experimental_duplex_mode_indicator.set_value(0) else: _data.experimental_duplex_mode_indicator.set_value(1) ###################################################################### else: # fake duplex modes on write, for channels # that do not support it, which are most # (all the memory channels) if mem.duplex == '' or mem.duplex is None: _data.tx_freq.set_value(rxf) elif mem.duplex == '+': _data.tx_freq.set_value(rxf + txf) elif mem.duplex == '-': _data.tx_freq.set_value(rxf - txf) else: _data.tx_freq.set_value(txf) ###################################################################### if ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES: if mem.duplex != 'split': _data.experimental_duplex_mode_indicator.set_value(0) else: _data.experimental_duplex_mode_indicator.set_value(1) ###################################################################### # tone data tonedata = chirp_common.split_tone_encode(mem) for i in range(2): dihl = unparse_tone(tonedata[i]) if dihl is not None: _data.tone[i].digital.set_value(dihl[0]) _data.tone[i].invert.set_value(dihl[1]) _data.tone[i].high.set_value(dihl[2]) _data.tone[i].low.set_value(dihl[3]) else: _data.tone[i].digital.set_value(1) _data.tone[i].invert.set_value(1) _data.tone[i].high.set_value(0x3f) _data.tone[i].low.set_value(0xff) ###################################################################### if ENABLE_DANGEROUS_EXPERIMENTAL_FEATURES: if mem.tmode == 'Cross' and mem.cross_mode in ['Tone->', 'Tone->Tone', 'DTCS->DTCS']: _data.experimental_cross_mode_indicator.set_value(0) else: _data.experimental_cross_mode_indicator.set_value(1) ###################################################################### # transmit mode and power level _data.modulation_width.set_value(MODES.index(mem.mode)) if str(mem.power) == 'High': _data.txpower.set_value(1) else: _data.txpower = 0 def get_settings(self): _model = self._memobj.mem.model_information _settings = self._memobj.mem.opt_settings _ptt_id_data = self._memobj.mem.ptt_id_data _msk_settings = self._memobj.mem.msk_settings _dtmf_settings = self._memobj.mem.dtmf_settings _5tone_settings = self._memobj.mem.five_tone_settings _broadcast = self._memobj.mem.fm_radio # for safety reasons we are showing these as read-only model_unit_settings = [ integer_setting("vhflo", "VHF lower bound", _model.band_limits[0].lower_freq, 134, 176, int_from_mem=lambda x:int(int(x)/10), mem_from_int=None), integer_setting("vhfhi", "VHF upper bound", _model.band_limits[0].upper_freq, 134, 176, int_from_mem=lambda x:int(int(x)/10), mem_from_int=None), integer_setting("uhflo", "UHF lower bound", _model.band_limits[1].lower_freq, 400, 480, int_from_mem=lambda x:int(int(x)/10), mem_from_int=None), integer_setting("uhfhi", "UHF upper bound", _model.band_limits[1].upper_freq, 400, 480, int_from_mem=lambda x:int(int(x)/10), mem_from_int=None), ff_string_setting("model", "Model string", _model.model_string, 0, 6) ] for s in model_unit_settings: s.value.set_mutable(False) model_unit_settings.append(ff_string_setting( "info", "Unit Information", self._memobj.mem.radio_information_string, 0, 16)) # tx/rx related settings radio_channel_settings = [ list_setting("vfostep", "VFO step size", _settings.vfo_step, VFO_STRIDE), list_setting("abwatch", "Main watch", _settings.main_watch, AB), list_setting("watchmade", "Watch mode", _settings.main_watch, WATCH_MODES), list_setting("amode", "A mode", _settings.workmode_a, AB_MODES), list_setting("bmode", "B mode", _settings.workmode_b, AB_MODES), integer_setting("achan", "A channel index", _settings.channel_a, 1, 128, int_from_mem=lambda i:i+1, mem_from_int=lambda i:i-1), integer_setting("bchan", "B channel index", _settings.channel_b, 1, 128, int_from_mem=lambda i:i+1, mem_from_int=lambda i:i-1), integer_setting("pchan", "Priority channel index", _settings.priority_channel, 1, 128, int_from_mem=lambda i:i+1, mem_from_int=lambda i:i-1), list_setting("cactive", "Call channel active?", _settings.call_channel_active, NO_YES), list_setting("scanm", "Scan mode", _settings.scan_mode, SCAN_MODES), list_setting("swait", "Wait time", _settings.wait_time, WAIT_TIMES), # it is unclear what this option below does, # possibly squelch tail elimination? list_setting("tail", "Relay without disable tail (?)", _settings.relay_without_disable_tail, NO_YES), list_setting("batsav", "Battery saving mode", _settings.battery_save, OFF_ON), ] # user interface related settings interface_settings = [ list_setting("sidehold", "Side button hold action", _settings.side_button_hold_mode, BUTTON_MODES), list_setting("sideclick", "Side button click action", _settings.side_button_click_mode, BUTTON_MODES), list_setting("bootmt", "Boot message type", _settings.boot_message_mode, BOOT_MESSAGE_TYPES), ff_string_setting("bootm", "Boot message", _settings.boot_message, 0, 6), list_setting("beep", "Key beep", _settings.key_beep, OFF_ON), list_setting("talkback", "Menu talkback", _settings.voice_announce, TALKBACK), list_setting("sidetone", "DTMF sidetone", _settings.dtmf_sidetone, OFF_ON), list_setting("roger", "Roger beep", _settings.use_roger_beep, ROGER_BEEP), list_setting("backlm", "Backlight mode", _settings.backlight_mode, BACKLIGHT_MODES), list_setting("backlc", "Backlight color", _settings.backlight_color, BACKLIGHT_COLORS), integer_setting("squelch", "Squelch level", _settings.squelch_level, 0, 9), list_setting("voxg", "Vox gain", _settings.vox_gain, VOX_GAIN), list_setting("voxd", "Vox delay", _settings.vox_delay, VOX_DELAYS), list_setting("txal", "Trinsmit time alarm", _settings.tx_timeout, TRANSMIT_ALARMS), ] # settings related to tone/data sending and interpretation data_general_settings = [ list_setting("disptt", "Display PTT ID", _settings.dis_ptt_id, NO_YES), list_setting("pttidt", "PTT ID signal type", _settings.ptt_id_type, DATA_MODES) ] data_msk_settings = [ ff_string_setting("bot", "MSK PTT ID (BOT)", _ptt_id_data[0].entry, 0, 6, autowrite=False), ff_string_setting("eot", "MSK PTT ID (EOT)", _ptt_id_data[1].entry, 0, 6, autowrite=False), ff_string_setting("id", "MSK ID code", _msk_settings.id_code, 0, 4, charset=HEXADECIMAL), list_setting("mskr", "MSK reverse", _settings.msk_reverse, NO_YES) ] data_dtmf_settings = [ dtmf_string_setting("bot", "DTMF PTT ID (BOT)", _ptt_id_data[0].entry, _ptt_id_data[0].length, 0, 8, autowrite=False), dtmf_string_setting("eot", "DTMF PTT ID (EOT)", _ptt_id_data[1].entry, _ptt_id_data[1].length, 0, 8, autowrite=False), dtmf_string_setting("id", "DTMF ID code", _dtmf_settings.id_code, _dtmf_settings.id_code_length, 3, 8), integer_setting("time", "Digit time (ms)", _dtmf_settings.timing.digit_length, 50, 200, step=10, int_from_mem=lambda x:x*10, mem_from_int=lambda x:int(x/10)), integer_setting("pause", "Inter digit time (ms)", _dtmf_settings.timing.digit_length, 50, 200, step=10, int_from_mem=lambda x:x*10, mem_from_int=lambda x:int(x/10)), integer_setting("time1", "First digit time (ms)", _dtmf_settings.timing.digit_length, 50, 200, step=10, int_from_mem=lambda x:x*10, mem_from_int=lambda x:int(x/10)), integer_setting("pause1", "First digit delay (ms)", _dtmf_settings.timing.digit_length, 100, 1000, step=50, int_from_mem=lambda x:x*50, mem_from_int=lambda x:int(x/50)), list_setting("arst", "Auto reset time", _dtmf_settings.reset_time, DTMF_TONE_RESET_TIME), list_setting("grp", "Group code", _dtmf_settings.group_code, DTMF_GROUPS), dtmf_string_setting("stunt", "TX Stun code", _dtmf_settings.tx_stun_code, _dtmf_settings.tx_stun_code_length, 3, 8), dtmf_string_setting("cstunt", "TX Stun cancel code", _dtmf_settings.cancel_tx_stun_code, _dtmf_settings.cancel_tx_stun_code_length, 3, 8), dtmf_string_setting("stunrt", "RX/TX Stun code", _dtmf_settings.rxtx_stun_code, _dtmf_settings.rxtx_stun_code_length, 3, 8), dtmf_string_setting("cstunrt", "RX/TX Stun cancel code", _dtmf_settings.cancel_rxtx_stun_code, _dtmf_settings.cancel_rxtx_stun_code_length, 3, 8), list_setting("altr", "Alert/Transpond", _dtmf_settings.alert_transpond, DTMF_ALERT_TRANSPOND), ] data_5tone_settings = [ five_tone_string_setting("bot", "5-Tone PTT ID (BOT)", _ptt_id_data[0].entry, autowrite=False), five_tone_string_setting("eot", "5-Tone PTT ID (EOT)", _ptt_id_data[1].entry, autowrite=False), five_tone_string_setting("id", "5-tone ID code", _5tone_settings.id_code), list_setting("arst", "Auto reset time", _5tone_settings.reset_time, TONE_RESET_TIME), five_tone_string_setting("stunt", "TX Stun code", _5tone_settings.tx_stun_code), five_tone_string_setting("cstunt", "TX Stun cancel code", _5tone_settings.cancel_tx_stun_code), five_tone_string_setting("stunrt", "RX/TX Stun code", _5tone_settings.rxtx_stun_code), five_tone_string_setting("cstunrt", "RX/TX Stun cancel code", _5tone_settings.cancel_rxtx_stun_code), list_setting("altr", "Alert/Transpond", _5tone_settings.alert_transpond, FIVE_TONE_ALERT_TRANSPOND), list_setting("std", "5-Tone standard", _5tone_settings.tone_standard, FIVE_TONE_STANDARDS), ] for i in range(4): s = ['z1', 'z2', 'c1', 'ct'][i] l = FIVE_TONE_STANDARDS[i] data_5tone_settings.append( settings.RadioSettingGroup( s, '%s settings' % l, integer_setting("%speriod" % s, "%s Period (ms)" % l, _5tone_settings.tone_settings[i].period, 20, 255), list_setting("%sgrp" % s, "%s Group code" % l, _5tone_settings.tone_settings[i].group_code, HEXADECIMAL), list_setting("%srpt" % s, "%s Repeat code" % l, _5tone_settings.tone_settings[i].repeat_code, HEXADECIMAL))) data_msk_call_list = [] data_dtmf_call_list = [] data_5tone_call_list = [] for i in range(9): j = i+1 data_msk_call_list.append( ff_string_setting("ce%d" % i, "MSK call entry %d" % j, _msk_settings.phone_book[i].entry, 0, 4, charset=HEXADECIMAL)) data_dtmf_call_list.append( dtmf_string_setting("ce%d" % i, "DTMF call entry %d" % j, _dtmf_settings.phone_book[i].entry, _dtmf_settings.phone_book[i].length, 0, 10)) data_5tone_call_list.append( five_tone_string_setting("ce%d" % i, "5-Tone call entry %d" % j, _5tone_settings.phone_book[i].entry)), data_settings = data_general_settings data_settings.extend([ settings.RadioSettingGroup("MSK_s", "MSK settings", *data_msk_settings), settings.RadioSettingGroup("MSK_c", "MSK call list", *data_msk_call_list), settings.RadioSettingGroup("DTMF_s", "DTMF settings", *data_dtmf_settings), settings.RadioSettingGroup("DTMF_c", "DTMF call list", *data_dtmf_call_list), settings.RadioSettingGroup("5-Tone_s", "5-tone settings", *data_5tone_settings), settings.RadioSettingGroup("5-Tone_c", "5-tone call list", *data_5tone_call_list) ]) # settings related to the various ways the radio can be locked down locking_settings = [ list_setting("autolock", "Automatic timed keypad lock", _settings.auto_keylock, OFF_ON), list_setting("lockon", "Current status of keypad lock", _settings.keypad_lock, INACTIVE_ACTIVE), list_setting("nokeypad", "Disable keypad", _settings.allow_keypad, YES_NO), list_setting("rxstun", "Disable receiver (rx stun)", _settings.rx_stun, NO_YES), list_setting("txstun", "Disable transmitter (tx stun)", _settings.tx_stun, NO_YES), ] # broadcast FM radio settings broadcast_settings = [ list_setting("band", "Frequency interval", _broadcast.receive_range, BFM_BANDS), list_setting("stride", "VFO step", _broadcast.channel_stepping, BFM_STRIDE), frequency_setting("vfo", "VFO frequency (MHz)", _broadcast.vfo_freq) ] for i in range(10): broadcast_settings.append( frequency_setting("bcd%d" % i, "Memory %d frequency" % i, _broadcast.memory[i].entry)) return settings.RadioSettings( settings.RadioSettingGroup("model", "Model/Unit information", *model_unit_settings), settings.RadioSettingGroup("radio", "Radio/Channel settings", *radio_channel_settings), settings.RadioSettingGroup("interface", "Interface", *interface_settings), settings.RadioSettingGroup("data", "Data", *data_settings), settings.RadioSettingGroup("locking", "Locking", *locking_settings), settings.RadioSettingGroup("broadcast", "Broadcast FM radio settings", *broadcast_settings) ) def set_settings(self, s, parent=''): # The helper classes take care of all settings except these below, # since it is a single instance of settings having interdependencies, # i.e., which value that gets written to the memory depends on # the value of another setting. The value of the ptt id type setting # decides which of the msk/dtmf/5-tone ptt id strings are # actually written to memory. ds = sbyn(s, 'data') idts = sbyn(ds, 'pttidt').value idtv = idts.get_value() cs = sbyn(ds, idtv+'_s') tss = [sbyn(cs, e).value for e in ['bot', 'eot']] for ts in tss: ts.write_mem() chirp-20240224/chirp/drivers/vxa700.py0000644000175000017500000002256314522657251016237 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, util, directory, memmap, errors from chirp import bitwise import time import struct import logging LOG = logging.getLogger(__name__) def _send(radio, data): LOG.debug("Sending %s" % repr(data)) radio.pipe.write(data) radio.pipe.flush() echo = radio.pipe.read(len(data)) if len(echo) != len(data): raise errors.RadioError("Invalid echo") def _spoonfeed(radio, data): # count = 0 LOG.debug("Writing %i:\n%s" % (len(data), util.hexprint(data))) for byte in data: radio.pipe.write(byte) radio.pipe.flush() time.sleep(0.01) continue # This is really unreliable for some reason, # so just blindly send the data echo = radio.pipe.read(1) if echo != byte: LOG.debug("%02x != %02x" % (ord(echo), ord(byte))) raise errors.RadioError("No echo?") # count += 1 def _download(radio): count = 0 data = "" while len(data) < radio.get_memsize(): count += 1 chunk = radio.pipe.read(133) if len(chunk) == 0 and len(data) == 0 and count < 30: continue if len(chunk) != 132: raise errors.RadioError("Got short block (length %i)" % len(chunk)) checksum = ord(chunk[-1]) _flag, _length, _block, _data, checksum = \ struct.unpack("BBB128sB", chunk) cs = 0 for byte in chunk[:-1]: cs += ord(byte) if (cs % 256) != checksum: raise errors.RadioError("Invalid checksum at 0x%02x" % len(data)) data += _data _send(radio, "\x06") if radio.status_fn: status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = len(data) status.max = radio.get_memsize() radio.status_fn(status) return memmap.MemoryMap(data) def _upload(radio): for i in range(0, radio.get_memsize(), 128): chunk = radio.get_mmap()[i:i+128] cs = 0x20 + 130 + (i // 128) for byte in chunk: cs += ord(byte) _spoonfeed(radio, struct.pack("BBB128sB", 0x20, 130, i // 128, chunk, cs % 256)) radio.pipe.write("") # This is really unreliable for some reason, so just # blindly proceed # ack = radio.pipe.read(1) ack = "\x06" time.sleep(0.5) if ack != "\x06": LOG.debug(repr(ack)) raise errors.RadioError("Radio did not ack block %i" % (i // 132)) # radio.pipe.read(1) if radio.status_fn: status = chirp_common.Status() status.msg = "Cloning to radio" status.cur = i status.max = radio.get_memsize() radio.status_fn(status) MEM_FORMAT = """ struct memory_struct { u8 unknown1; u8 unknown2:2, isfm:1, power:2, step:3; u8 unknown5:2, showname:1, skip:1, duplex:2, unknown6:2; u8 tmode:2, unknown7:6; u8 unknown8; u8 unknown9:2, tone:6; u8 dtcs; u8 name[8]; u16 freq; u8 offset; }; u8 headerbytes[6]; #seekto 0x0006; u8 invisible_bits[13]; u8 bitfield_pad[3]; u8 invalid_bits[13]; #seekto 0x017F; struct memory_struct memory[100]; """ CHARSET = "".join(["%i" % i for i in range(0, 10)]) + \ "".join([chr(ord("A") + i) for i in range(0, 26)]) + \ "".join([chr(ord("a") + i) for i in range(0, 26)]) + \ "., :;!\"#$%&'()*+-/=<>?@[?]^_`{|}????~??????????????????????????" TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+", ""] POWER = [chirp_common.PowerLevel("Low1", watts=0.050), chirp_common.PowerLevel("Low2", watts=1.000), chirp_common.PowerLevel("Low3", watts=2.500), chirp_common.PowerLevel("High", watts=5.000)] def _wipe_memory(_mem): _mem.set_raw("\x00" * (_mem.size() // 8)) @directory.register class VXA700Radio(chirp_common.CloneModeRadio): """Vertex Standard VXA-700""" VENDOR = "Vertex Standard" MODEL = "VXA-700" _memsize = 4096 def sync_in(self): try: self.pipe.timeout = 2 self._mmap = _download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate " + "with the radio: %s" % e) self.process_mmap() def sync_out(self): # header[4] = 0x00 <- default # 0xFF <- air band only # 0x01 <- air band only # 0x02 <- air band only try: self.pipe.timeout = 2 _upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate " + "with the radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_ctone = False rf.has_dtcs_polarity = False rf.has_tuning_step = False rf.valid_tmodes = TMODES rf.valid_name_length = 8 rf.valid_characters = CHARSET rf.valid_skips = ["", "S"] rf.valid_bands = [(88000000, 165000000)] rf.valid_tuning_steps = \ [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] rf.valid_modes = ["AM", "FM"] rf.valid_power_levels = POWER rf.memory_bounds = (1, 100) return rf def _get_mem(self, number): return self._memobj.memory[number - 1] def get_raw_memory(self, number): _mem = self._get_mem(number) return repr(_mem) + util.hexprint(_mem.get_raw(asbytes=False)) def get_memory(self, number): _mem = self._get_mem(number) byte = (number - 1) // 8 bit = 1 << ((number - 1) % 8) mem = chirp_common.Memory() mem.number = number if self._memobj.invisible_bits[byte] & bit: mem.empty = True if self._memobj.invalid_bits[byte] & bit: mem.empty = True return mem if _mem.step & 0x05: # Not sure this is right, but it seems to be mult = 6250 else: mult = 5000 mem.freq = int(_mem.freq) * mult mem.rtone = chirp_common.TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.offset = int(_mem.offset) * 5000 * 10 mem.mode = _mem.isfm and "FM" or "AM" mem.skip = _mem.skip and "S" or "" mem.power = POWER[_mem.power] for char in _mem.name: try: mem.name += CHARSET[char] except IndexError: break mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._get_mem(mem.number) byte = (mem.number - 1) // 8 bit = 1 << ((mem.number - 1) % 8) if mem.empty and self._memobj.invisible_bits[byte] & bit: self._memobj.invalid_bits[byte] |= bit return if mem.empty: self._memobj.invisible_bits[byte] |= bit return if self._memobj.invalid_bits[byte] & bit: _wipe_memory(_mem) self._memobj.invisible_bits[byte] &= ~bit self._memobj.invalid_bits[byte] &= ~bit _mem.unknown2 = 0x02 # Channels don't display without this _mem.unknown7 = 0x01 # some bit in this field is related to _mem.unknown8 = 0xFF # being able to transmit if chirp_common.required_step(mem.freq) == 12.5: mult = 6250 _mem.step = 0x05 else: mult = 5000 _mem.step = 0x00 _mem.freq = mem.freq / mult _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) _mem.offset = mem.offset // 5000 // 10 _mem.isfm = mem.mode == "FM" _mem.skip = mem.skip == "S" try: _mem.power = POWER.index(mem.power) except ValueError: _mem.power = 3 # High for i in range(0, 8): try: _mem.name[i] = CHARSET.index(mem.name[i]) except IndexError: _mem.name[i] = 0x40 _mem.showname = bool(mem.name.strip()) @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[5] == 0x0F chirp-20240224/chirp/drivers/bf_t1.py0000644000175000017500000007252514522657251016210 0ustar hibbyhibby# Copyright 2017 Pavel Milanes, CO7WT, # # This driver is a community effort as I don't have the radio on my hands, so # I was only the director of the orchestra, without the players this may never # came true, so special thanks to the following hams for their contribution: # - Henk van der Laan, PA3CQN # - Setting Discovery. # - Special channels for RELAY and EMERGENCY. # - Harold Hankins # - Memory limits, testing & bug hunting. # - Dmitry Milkov # - Testing & bug hunting. # - Many others participants in the issue page on Chirp's site. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueFloat, \ RadioSettings import struct import logging LOG = logging.getLogger(__name__) # A note about the memory in these radios # # The '9100' OEM software only manipulates the lower 0x0180 bytes on read/write # operations as we know, the file generated by the OEM software IS NOT an exact # eeprom image, it's a crude text file with a pseudo csv format # # Later investigations by Harold Hankins found that the eeprom extend up to 2k # consistent with a hardware chip K24C16 a 2k x 8 bit serial eeprom MEM_SIZE = 0x0800 # 2048 bytes WRITE_SIZE = 0x0180 # 384 bytes BLOCK_SIZE = 0x10 ACK_CMD = b"\x06" MODES = ["NFM", "FM"] SKIP_VALUES = ["S", ""] TONES = chirp_common.TONES DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) # Special channels SPECIALS = { "EMG": -2, "RLY": -1 } # Settings vars TOT_LIST = ["Off"] + ["%s" % x for x in range(30, 210, 30)] SCAN_TYPE_LIST = ["Time", "Carrier", "Search"] LANGUAGE_LIST = ["Off", "English", "Chinese"] TIMER_LIST = ["Off"] + ["%s h" % (x * 0.5) for x in range(1, 17)] FM_RANGE_LIST = ["76-108", "65-76"] RELAY_MODE_LIST = ["Off", "RX sync", "TX sync"] BACKLIGHT_LIST = ["Off", "Key", "On"] POWER_LIST = ["0.5 Watt", "1.0 Watt"] # This is a general serial timeout for all serial read functions. # Practice has show that about 0.07 sec will be enough to cover all radios. STIMEOUT = 0.07 # this var controls the verbosity in the debug and by default it's low (False) # make it True and you will to get a very verbose debug.log debug = False # #### ID strings ##################################################### # BF-T1 handheld BFT1_magic = b"\x05PROGRAM" BFT1_ident = b" BF9100S" def _clean_buffer(radio): """Cleaning the read serial buffer, hard timeout to survive an infinite data stream""" dump = "1" datacount = 0 try: while len(dump) > 0: dump = radio.pipe.read(100) datacount += len(dump) # hard limit to survive a infinite serial data stream # 5 times bigger than a normal rx block (20 bytes) if datacount > 101: seriale = "Please check your serial port selection." raise errors.RadioError(seriale) except Exception: raise errors.RadioError("Unknown error cleaning the serial buffer") def _rawrecv(radio, amount=0): """Raw read from the radio device""" # var to hold the data to return data = b"" try: if amount == 0: data = radio.pipe.read() else: data = radio.pipe.read(amount) # DEBUG if debug is True: LOG.debug("<== (%d) bytes:\n\n%s" % (len(data), util.hexprint(data))) # fail if no data is received if len(data) == 0: raise errors.RadioError("No data received from radio") except: raise errors.RadioError("Error reading data from radio") return data def _send(radio, data): """Send data to the radio device""" try: radio.pipe.write(data) # DEBUG if debug is True: LOG.debug("==> (%d) bytes:\n\n%s" % (len(data), util.hexprint(data))) except: raise errors.RadioError("Error sending data to radio") def _make_frame(cmd, addr, data=""): """Pack the info in the header format""" frame = struct.pack(">BHB", ord(cmd), addr, BLOCK_SIZE) # add the data if set if len(data) != 0: frame += data return frame def _recv(radio, addr): """Get data from the radio""" # Get the full 20 bytes at a time # 4 bytes header + 16 bytes of data (BLOCK_SIZE) # get the whole block block = _rawrecv(radio, BLOCK_SIZE + 4) # short answer if len(block) < (BLOCK_SIZE + 4): raise errors.RadioError("Wrong block length (short) at 0x%04x" % addr) # long answer if len(block) > (BLOCK_SIZE + 4): raise errors.RadioError("Wrong block length (long) at 0x%04x" % addr) # header validation c, a, l = struct.unpack(">cHB", block[0:4]) if c != b"W" or a != addr or l != BLOCK_SIZE: LOG.debug("Invalid header for block 0x%04x:" % addr) LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (c, a, l)) raise errors.RadioError("Invalid header for block 0x%04x:" % addr) # return the data, 16 bytes of payload return block[4:] def _start_clone_mode(radio, status): """Put the radio in clone mode, 3 tries""" # cleaning the serial buffer _clean_buffer(radio) # prep the data to show in the UI status.cur = 0 status.msg = "Identifying the radio..." status.max = 3 radio.status_fn(status) try: for a in range(0, status.max): # Update the UI status.cur = a + 1 radio.status_fn(status) # send the magic word _send(radio, radio._magic) # Now you get a x06 of ACK if all goes well ack = _rawrecv(radio, 1) if ack == ACK_CMD: # DEBUG LOG.info("Magic ACK received") status.cur = status.max radio.status_fn(status) return True return False except errors.RadioError: raise except Exception as e: raise errors.RadioError("Error sending Magic to radio:\n%s" % e) def _do_ident(radio, status): """Put the radio in PROGRAM mode & identify it""" # set the serial discipline (default) radio.pipe.baudrate = 9600 radio.pipe.parity = "N" radio.pipe.bytesize = 8 radio.pipe.stopbits = 1 radio.pipe.timeout = STIMEOUT # open the radio into program mode if _start_clone_mode(radio, status) is False: raise errors.RadioError("Radio did not enter clone mode, wrong model?") # Ok, poke it to get the ident string _send(radio, b"\x02") ident = _rawrecv(radio, len(radio._id)) # basic check for the ident if len(ident) != len(radio._id): raise errors.RadioError("Radio send a odd identification block.") # check if ident is OK if ident != radio._id: LOG.debug("Incorrect model ID, got this:\n\n" + util.hexprint(ident)) raise errors.RadioError("Radio identification failed.") # handshake _send(radio, ACK_CMD) ack = _rawrecv(radio, 1) # checking handshake if len(ack) == 1 and ack == ACK_CMD: # DEBUG LOG.info("ID ACK received") else: LOG.debug("Radio handshake failed.") raise errors.RadioError("Radio handshake failed.") # DEBUG LOG.info("Positive ident, this is a %s %s" % (radio.VENDOR, radio.MODEL)) return True def _download(radio): """Get the memory map""" # UI progress status = chirp_common.Status() # put radio in program mode and identify it _do_ident(radio, status) # reset the progress bar in the UI status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning from radio..." status.cur = 0 radio.status_fn(status) # cleaning the serial buffer _clean_buffer(radio) data = b"" for addr in range(0, MEM_SIZE, BLOCK_SIZE): # sending the read request _send(radio, _make_frame(b"R", addr)) # read d = _recv(radio, addr) # aggregate the data data += d # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) # close comms with the radio _send(radio, b"\x62") # DEBUG LOG.info("Close comms cmd sent, radio must reboot now.") return data def _upload(radio): """Upload procedure, we only upload to the radio the Writable space""" # UI progress status = chirp_common.Status() # put radio in program mode and identify it _do_ident(radio, status) # get the data to upload to radio data = radio.get_mmap() # Reset the UI progress status.max = WRITE_SIZE // BLOCK_SIZE status.cur = 0 status.msg = "Cloning to radio..." radio.status_fn(status) # cleaning the serial buffer _clean_buffer(radio) # the fun start here, we use WRITE_SIZE instead of the full MEM_SIZE for addr in range(0, WRITE_SIZE, BLOCK_SIZE): # getting the block of data to send d = data[addr:addr + BLOCK_SIZE] # build the frame to send frame = _make_frame(b"W", addr, d) # send the frame _send(radio, frame) # receiving the response ack = _rawrecv(radio, 1) # basic check if len(ack) != 1: raise errors.RadioError("No ACK when writing block 0x%04x" % addr) if ack != ACK_CMD: raise errors.RadioError("Bad ACK writing block 0x%04x:" % addr) # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) # close comms with the radio _send(radio, b"\x62") # DEBUG LOG.info("Close comms cmd sent, radio must reboot now.") def _model_match(cls, data): """Match the opened/downloaded image to the correct version""" # a reliable fingerprint: the model name at rid = data[0x06f8:0x0700] if rid == BFT1_ident: return True return False def _decode_ranges(low, high): """Unpack the data in the ranges zones in the memmap and return a tuple with the integer corresponding to the MHz it means""" return (int(low) * 100000, int(high) * 100000) MEM_FORMAT = """ struct channel { lbcd rxfreq[4]; // rx freq. u8 rxtone; // x00 = none // x01 - x32 = index of the analog tones // x33 - x9b = index of Digital tones // Digital tone polarity is handled below by // ttondinv & ttondinv settings lbcd txoffset[4]; // the difference against RX, direction handled by // offplus & offminus u8 txtone; // Idem to rxtone u8 noskip:1, // if true is included in the scan wide:1, // 1 = Wide, 0 = Narrow ttondinv:1, // if true TX tone is Digital & Inverted unA:1, // rtondinv:1, // if true RX tone is Digital & Inverted unB:1, // offplus:1, // TX = RX + offset offminus:1; // TX = RX - offset u8 empty[5]; }; #seekto 0x0000; struct channel emg; // channel 0 is Emergent CH #seekto 0x0010; struct channel channels[20]; // normal 1-20 mem channels #seekto 0x0150; // Settings struct { lbcd vhfl[2]; // VHF low limit lbcd vhfh[2]; // VHF high limit lbcd uhfl[2]; // UHF low limit lbcd uhfh[2]; // UHF high limit u8 unk0[8]; u8 unk1[2]; // start of 0x0160 <======= u8 squelch; // byte: 0-9 u8 vox; // byte: 0-9 u8 timeout; // tot, 0 off, then 30 sec increments up to 180 u8 batsave:1, // battery save 0 = off, 1 = on fm_funct:1, // fm-radio 0=off, 1=on ( off disables fm button on set ) ste:1, // squelch tail 0 = off, 1 = on blo:1, // busy lockout 0 = off, 1 = on beep:1, // key beep 0 = off, 1 = on lock:1, // keylock 0 = ff, = on backlight:2; // backlight 00 = off, 01 = key, 10 = on u8 scantype; // scan type 0 = timed, 1 = carrier, 2 = stop u8 channel; // active channel 1-20, setting it works on upload u8 fmrange; // fm range 1 = low[65-76](ASIA), 0 = high[76-108](AMERICA) u8 alarm; // alarm (count down timer) // d0 - d16 in half hour increments => off, 0.5 - 8.0 h u8 voice; // voice prompt 0 = off, 1 = English, 2 = Chinese u8 volume; // volume 1-7 as per the radio steps // set to #FF by original software on upload // chirp uploads actual value and works. u16 fm_vfo; // the frequency of the fm receiver. // resulting frequency is 65 + value * 0.1 MHz // 0x145 is then 65 + 325*0.1 = 97.5 MHz u8 relaym; // relay mode, d0 = off, d2 = re-tx, d1 = re-rx // still a mystery on how it works u8 tx_pwr; // tx pwr 0 = low (0.5W), 1 = high(1.0W) } settings; #seekto 0x0170; // Relay CH struct channel rly; """ @directory.register class BFT1(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Baofeng BT-F1 radio & possibly alike radios""" VENDOR = "Baofeng" MODEL = "BF-T1" NEEDS_COMPAT_SERIAL = False _vhf_range = (130000000, 174000000) _uhf_range = (400000000, 520000000) _upper = 20 _magic = BFT1_magic _id = BFT1_ident _bw_shift = False @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is experimental.\n' '\n' 'Please keep a copy of your memories with the original software ' 'if you treasure them, this driver is new and may contain' ' bugs.\n' '\n' '"Emergent CH" & "Relay CH" are implemented via special channels,' 'be sure to click on the button on the interface to access them.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow these instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def get_features(self): """Get the radio's features""" rf = chirp_common.RadioFeatures() rf.valid_special_chans = list(SPECIALS.keys()) rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.has_offset = True rf.has_mode = True rf.valid_modes = MODES rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_duplexes = ["", "-", "+", "split"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = SKIP_VALUES rf.valid_dtcs_codes = DTCS rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] # normal dual bands rf.valid_bands = [self._vhf_range, self._uhf_range] return rf def process_mmap(self): """Process the mem map into the mem object""" # Get it self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # set the band limits as the memmap settings = self._memobj.settings self._vhf_range = _decode_ranges(settings.vhfl, settings.vhfh) self._uhf_range = _decode_ranges(settings.uhfl, settings.uhfh) def sync_in(self): """Download from radio""" data = _download(self) self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Error: %s" % e) def _decode_tone(self, val, inv): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val == 0: return '', None, None elif val < 51: # analog tone return 'Tone', TONES[val - 1], None elif val > 50: # digital tone pol = "N" # polarity? if inv == 1: pol = "R" return 'DTCS', DTCS[val - 51], pol def _encode_tone(self, memtone, meminv, mode, tone, pol): """Parse the tone data to encode from UI to mem""" if mode == '' or mode is None: memtone.set_value(0) meminv.set_value(0) elif mode == 'Tone': # caching errors for analog tones. try: memtone.set_value(TONES.index(tone) + 1) meminv.set_value(0) except: msg = "TCSS Tone '%d' is not supported" % tone LOG.error(msg) raise errors.RadioError(msg) elif mode == 'DTCS': # caching errors for digital tones. try: memtone.set_value(DTCS.index(tone) + 51) if pol == "R": meminv.set_value(True) else: meminv.set_value(False) except: msg = "Digital Tone '%d' is not supported" % tone LOG.error(msg) raise errors.RadioError(msg) else: msg = "Internal error: invalid mode '%s'" % mode LOG.error(msg) raise errors.InvalidDataError(msg) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _get_special(self, number): if isinstance(number, str): return (getattr(self._memobj, number.lower())) elif number < 0: for k, v in SPECIALS.items(): if number == v: return (getattr(self._memobj, k.lower())) else: return self._memobj.channels[number-1] def get_memory(self, number): """Get the mem representation from the radio image""" _mem = self._get_special(number) # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Check if special or normal if isinstance(number, str): mem.number = SPECIALS[number] mem.extd_number = number else: mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xFF": mem.empty = True return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # TX freq (Stored as a difference) mem.offset = int(_mem.txoffset) * 10 mem.duplex = "" # must work out the polarity if mem.offset != 0: if _mem.offminus == 1: mem.duplex = "-" # tx below RX if _mem.offplus == 1: # tx above RX mem.duplex = "+" # split RX/TX in different bands if mem.offset > 71000000: mem.duplex = "split" # show the actual value in the offset, depending on the shift if _mem.offminus == 1: mem.offset = mem.freq - mem.offset if _mem.offplus == 1: mem.offset = mem.freq + mem.offset # wide/narrow mem.mode = MODES[int(_mem.wide)] # skip mem.skip = SKIP_VALUES[_mem.noskip] # tone data rxtone = txtone = None txtone = self._decode_tone(_mem.txtone, _mem.ttondinv) rxtone = self._decode_tone(_mem.rxtone, _mem.rtondinv) chirp_common.split_tone_decode(mem, txtone, rxtone) return mem def set_memory(self, mem): """Set the memory data in the eeprom img from the UI""" # get the eprom representation of this channel _mem = self._get_special(mem.number) # if empty memory if mem.empty: # the channel itself _mem.set_raw("\xFF" * 16) # return it return mem # frequency _mem.rxfreq = mem.freq / 10 # duplex/ offset Offset is an absolute value _mem.txoffset = mem.offset / 10 # must work out the polarity if mem.duplex == "": _mem.offplus = 0 _mem.offminus = 0 elif mem.duplex == "+": _mem.offplus = 1 _mem.offminus = 0 elif mem.duplex == "-": _mem.offplus = 0 _mem.offminus = 1 elif mem.duplex == "split": if mem.freq > mem.offset: _mem.offplus = 0 _mem.offminus = 1 _mem.txoffset = (mem.freq - mem.offset) / 10 else: _mem.offplus = 1 _mem.offminus = 0 _mem.txoffset = (mem.offset - mem.freq) / 10 # wide/narrow _mem.wide = MODES.index(mem.mode) # skip _mem.noskip = SKIP_VALUES.index(mem.skip) # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.txtone, _mem.ttondinv, txmode, txtone, txpol) self._encode_tone(_mem.rxtone, _mem.rtondinv, rxmode, rxtone, rxpol) return mem def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") fm = RadioSettingGroup("fm", "FM Radio") adv = RadioSettingGroup("adv", "Advanced Settings") group = RadioSettings(basic, fm, adv) # ## Basic Settings rs = RadioSetting("tx_pwr", "TX Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_settings.tx_pwr])) basic.append(rs) rs = RadioSetting("channel", "Active Channel", RadioSettingValueInteger(1, 20, _settings.channel)) basic.append(rs) rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("vox", "VOX Level", RadioSettingValueInteger(0, 9, _settings.vox)) basic.append(rs) # volume validation, as the OEM software set 0xFF on write _volume = _settings.volume if _volume > 7: _volume = 7 rs = RadioSetting("volume", "Volume Level", RadioSettingValueInteger(0, 7, _volume)) basic.append(rs) rs = RadioSetting("scantype", "Scan Type", RadioSettingValueList(SCAN_TYPE_LIST, SCAN_TYPE_LIST[ _settings.scantype])) basic.append(rs) rs = RadioSetting("timeout", "Time Out Timer (seconds)", RadioSettingValueList( TOT_LIST, TOT_LIST[_settings.timeout])) basic.append(rs) rs = RadioSetting("voice", "Voice Prompt", RadioSettingValueList( LANGUAGE_LIST, LANGUAGE_LIST[_settings.voice])) basic.append(rs) rs = RadioSetting("alarm", "Alarm Time", RadioSettingValueList( TIMER_LIST, TIMER_LIST[_settings.alarm])) basic.append(rs) rs = RadioSetting("backlight", "Backlight", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.backlight])) basic.append(rs) rs = RadioSetting("blo", "Busy Lockout", RadioSettingValueBoolean(_settings.blo)) basic.append(rs) rs = RadioSetting("ste", "Squelch Tail Eliminate", RadioSettingValueBoolean(_settings.ste)) basic.append(rs) rs = RadioSetting("batsave", "Battery Save", RadioSettingValueBoolean(_settings.batsave)) basic.append(rs) rs = RadioSetting("lock", "Key Lock", RadioSettingValueBoolean(_settings.lock)) basic.append(rs) rs = RadioSetting("beep", "Key Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) # ## FM Settings rs = RadioSetting("fm_funct", "FM Function", RadioSettingValueBoolean(_settings.fm_funct)) fm.append(rs) rs = RadioSetting("fmrange", "FM Range", RadioSettingValueList( FM_RANGE_LIST, FM_RANGE_LIST[_settings.fmrange])) fm.append(rs) # callbacks for the FM VFO def apply_fm_freq(setting, obj): value = int(setting.value.get_value() * 10) - 650 LOG.debug("Setting fm_vfo = %s" % (value)) if self._bw_shift: value = ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8) setattr(obj, setting.get_name(), value) # broadcast FM setting value = _settings.fm_vfo value_shifted = ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8) if value_shifted <= 108.0 * 10 - 650: # storage method 3 (discovered 2022) self._bw_shift = True _fm_vfo = value_shifted / 10.0 + 65 elif value <= 108.0 * 10 - 650: # original storage method (2012) _fm_vfo = value / 10.0 + 65 else: # unknown (undiscovered method or no FM chip?) _fm_vfo = False if _fm_vfo: rs = RadioSetting("fm_vfo", "FM Station", RadioSettingValueFloat(65, 108, _fm_vfo)) rs.set_apply_callback(apply_fm_freq, _settings) fm.append(rs) # ## Advanced def apply_limit(setting, obj): setattr(obj, setting.get_name(), int(setting.value) * 10) rs = RadioSetting("vhfl", "VHF Low Limit", RadioSettingValueInteger(130, 174, int( _settings.vhfl) / 10)) rs.set_apply_callback(apply_limit, _settings) adv.append(rs) rs = RadioSetting("vhfh", "VHF High Limit", RadioSettingValueInteger(130, 174, int( _settings.vhfh) / 10)) rs.set_apply_callback(apply_limit, _settings) adv.append(rs) rs = RadioSetting("uhfl", "UHF Low Limit", RadioSettingValueInteger(400, 520, int( _settings.uhfl) / 10)) rs.set_apply_callback(apply_limit, _settings) adv.append(rs) rs = RadioSetting("uhfh", "UHF High Limit", RadioSettingValueInteger(400, 520, int( _settings.uhfh) / 10)) rs.set_apply_callback(apply_limit, _settings) adv.append(rs) rs = RadioSetting("relaym", "Relay Mode", RadioSettingValueList(RELAY_MODE_LIST, RELAY_MODE_LIST[_settings.relaym])) adv.append(rs) return group def set_settings(self, uisettings): _settings = self._memobj.settings for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: name = element.get_name() value = element.value if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: obj = getattr(_settings, name) setattr(_settings, name, value) LOG.debug("Setting %s: %s" % (name, value)) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == MEM_SIZE: match_size = True # DEBUG if debug is True: LOG.debug("BF-T1 matched!") # testing the firmware model fingerprint match_model = _model_match(cls, filedata) return match_size and match_model chirp-20240224/chirp/drivers/bjuv55.py0000644000175000017500000005007714563632215016331 0ustar hibbyhibby# Copyright 2013 Jens Jensen AF5MI # Based on work by Jim Unroe, Dan Smith, et al. # Special thanks to Mats SM0BTP for equipment donation. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import uv5r from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory from chirp import bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettingValueFloat, InvalidValueError, RadioSettings LOG = logging.getLogger(__name__) BJUV55_MODEL = b"\x50\xBB\xDD\x55\x63\x98\x4D" COLOR_LIST = ["Off", "Blue", "Red", "Pink"] STEPS = list(uv5r.STEPS) STEPS.remove(2.5) STEP_LIST = [str(x) for x in STEPS] MEM_FORMAT = """ #seekto 0x0008; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unused1:3, isuhf:1, scode:4; u8 unknown1:7, txtoneicon:1; u8 mailicon:3, unknown2:4, lowpower:1; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[128]; #seekto 0x0B08; struct { u8 code[5]; u8 unused[11]; } pttid[15]; #seekto 0x0C88; struct { u8 inspection[5]; u8 monitor[5]; u8 alarmcode[5]; u8 unknown1; u8 stun[5]; u8 kill[5]; u8 revive[5]; u8 unknown2; u8 master_control_id[5]; u8 vice_control_id[5]; u8 code[5]; u8 unused1:6, aniid:2; u8 unknown[2]; u8 dtmfon; u8 dtmfoff; } ani; #seekto 0x0E28; struct { u8 squelch; u8 step; u8 tdrab; u8 tdr; u8 vox; u8 timeout; u8 unk2[6]; u8 abr; u8 beep; u8 ani; u8 unknown3[2]; u8 voice; u8 ring_time; u8 dtmfst; u8 unknown5; u8 unknown12:6, screv:2; u8 pttid; u8 pttlt; u8 mdfa; u8 mdfb; u8 bcl; u8 autolk; u8 sftd; u8 unknown6[3]; u8 wtled; u8 rxled; u8 txled; u8 unknown7[5]; u8 save; u8 unknown8; u8 displayab:1, unknown1:2, fmradio:1, alarm:1, unknown2:1, reset:1, menu:1; u8 vfomrlock; u8 workmode; u8 keylock; u8 workmode_channel; u8 password[6]; u8 unknown10[11]; } settings; #seekto 0x0E7E; struct { u8 mrcha; u8 mrchb; } wmchannel; #seekto 0x0F10; struct { u8 freq[8]; u8 unknown1; u8 offset[4]; u8 unknown2; ul16 rxtone; ul16 txtone; u8 unused1:7, band:1; u8 unknown3; u8 unused2:2, sftd:2, scode:4; u8 unknown4; u8 unused3:1, step:3, unused4:4; u8 txpower:1, widenarr:1, unknown5:6; } vfoa; #seekto 0x0F30; struct { u8 freq[8]; u8 unknown1; u8 offset[4]; u8 unknown2; ul16 rxtone; ul16 txtone; u8 unused1:7, band:1; u8 unknown3; u8 unused2:2, sftd:2, scode:4; u8 unknown4; u8 unused3:1, step:3, unused4:4; u8 txpower:1, widenarr:1, unknown5:6; } vfob; #seekto 0x0F57; u8 fm_preset; #seekto 0x1008; struct { char name[6]; u8 unknown2[10]; } names[128]; #seekto 0x%04X; struct { char line1[7]; char line2[7]; } poweron_msg; #seekto 0x1838; struct { char line1[7]; char line2[7]; } firmware_msg; #seekto 0x1849; u8 power_vhf_hi[14]; // 136-174 MHz, 3 MHz divisions u8 power_uhf_hi[14]; // 400-470 MHz, 5 MHz divisions #seekto 0x1889; u8 power_vhf_lo[14]; u8 power_uhf_lo[14]; struct limit { u8 enable; bbcd lower[2]; bbcd upper[2]; }; #seekto 0x1908; struct { struct limit vhf; u8 unk11[11]; struct limit uhf; } limits; """ @directory.register class BaojieBJUV55Radio(uv5r.BaofengUV5R): VENDOR = "Baojie" MODEL = "BJ-UV55" NEEDS_COMPAT_SERIAL = False _basetype = [b"BJ55"] _idents = [BJUV55_MODEL] _mem_params = (0x1928 # poweron_msg offset ) _fw_ver_file_start = 0x1938 _fw_ver_file_stop = 0x193E def get_features(self): rf = super(BaojieBJUV55Radio, self).get_features() rf.valid_name_length = 6 return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) def set_memory(self, mem): super(BaojieBJUV55Radio, self).set_memory(mem) _mem = self._memobj.memory[mem.number] if (mem.freq - mem.offset) > (400 * 1000000): _mem.isuhf = True else: _mem.isuhf = False if mem.tmode in ["Tone", "TSQL"]: _mem.txtoneicon = True else: _mem.txtoneicon = False def _get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") group = RadioSettings(basic, advanced) rs = RadioSetting("squelch", "Carrier Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("save", "Battery Saver", RadioSettingValueInteger(0, 4, _settings.save)) basic.append(rs) rs = RadioSetting("abr", "Backlight", RadioSettingValueBoolean(_settings.abr)) basic.append(rs) rs = RadioSetting("tdr", "Dual Watch (BDR)", RadioSettingValueBoolean(_settings.tdr)) advanced.append(rs) rs = RadioSetting("tdrab", "Dual Watch TX Priority", RadioSettingValueList( uv5r.TDRAB_LIST, uv5r.TDRAB_LIST[_settings.tdrab])) advanced.append(rs) rs = RadioSetting("alarm", "Alarm", RadioSettingValueBoolean(_settings.alarm)) advanced.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) rs = RadioSetting("timeout", "Timeout Timer", RadioSettingValueList( uv5r.TIMEOUT_LIST, uv5r.TIMEOUT_LIST[_settings.timeout])) basic.append(rs) rs = RadioSetting("screv", "Scan Resume", RadioSettingValueList( uv5r.RESUME_LIST, uv5r.RESUME_LIST[_settings.screv])) advanced.append(rs) rs = RadioSetting("mdfa", "Display Mode (A)", RadioSettingValueList( uv5r.MODE_LIST, uv5r.MODE_LIST[_settings.mdfa])) basic.append(rs) rs = RadioSetting("mdfb", "Display Mode (B)", RadioSettingValueList( uv5r.MODE_LIST, uv5r.MODE_LIST[_settings.mdfb])) basic.append(rs) rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueBoolean(_settings.bcl)) advanced.append(rs) rs = RadioSetting("autolk", "Automatic Key Lock", RadioSettingValueBoolean(_settings.autolk)) advanced.append(rs) rs = RadioSetting("fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_settings.fmradio)) advanced.append(rs) rs = RadioSetting("wtled", "Standby LED Color", RadioSettingValueList( COLOR_LIST, COLOR_LIST[_settings.wtled])) basic.append(rs) rs = RadioSetting("rxled", "RX LED Color", RadioSettingValueList( COLOR_LIST, COLOR_LIST[_settings.rxled])) basic.append(rs) rs = RadioSetting("txled", "TX LED Color", RadioSettingValueList( COLOR_LIST, COLOR_LIST[_settings.txled])) basic.append(rs) rs = RadioSetting("reset", "RESET Menu", RadioSettingValueBoolean(_settings.reset)) advanced.append(rs) rs = RadioSetting("menu", "All Menus", RadioSettingValueBoolean(_settings.menu)) advanced.append(rs) if len(self._mmap.get_packed()) == 0x1808: # Old image, without aux block return group other = RadioSettingGroup("other", "Other Settings") group.append(other) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = self._memobj.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString(0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString(0, 7, _filter(_msg.line2))) other.append(rs) limit = "limits" vhf_limit = getattr(self._memobj, limit).vhf rs = RadioSetting("%s.vhf.lower" % limit, "VHF Lower Limit (MHz)", RadioSettingValueInteger( 1, 1000, vhf_limit.lower)) other.append(rs) rs = RadioSetting("%s.vhf.upper" % limit, "VHF Upper Limit (MHz)", RadioSettingValueInteger( 1, 1000, vhf_limit.upper)) other.append(rs) rs = RadioSetting("%s.vhf.enable" % limit, "VHF TX Enabled", RadioSettingValueBoolean(vhf_limit.enable)) other.append(rs) uhf_limit = getattr(self._memobj, limit).uhf rs = RadioSetting("%s.uhf.lower" % limit, "UHF Lower Limit (MHz)", RadioSettingValueInteger( 1, 1000, uhf_limit.lower)) other.append(rs) rs = RadioSetting("%s.uhf.upper" % limit, "UHF Upper Limit (MHz)", RadioSettingValueInteger( 1, 1000, uhf_limit.upper)) other.append(rs) rs = RadioSetting("%s.uhf.enable" % limit, "UHF TX Enabled", RadioSettingValueBoolean(uhf_limit.enable)) other.append(rs) workmode = RadioSettingGroup("workmode", "Work Mode Settings") group.append(workmode) options = ["A", "B"] rs = RadioSetting("displayab", "Display Selected", RadioSettingValueList( options, options[_settings.displayab])) workmode.append(rs) options = ["Frequency", "Channel"] rs = RadioSetting("workmode", "VFO/MR Mode", RadioSettingValueList( options, options[_settings.workmode])) workmode.append(rs) rs = RadioSetting("keylock", "Keypad Lock", RadioSettingValueBoolean(_settings.keylock)) workmode.append(rs) _mrcna = self._memobj.wmchannel.mrcha rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(0, 127, _mrcna)) workmode.append(rs) _mrcnb = self._memobj.wmchannel.mrchb rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(0, 127, _mrcnb)) workmode.append(rs) def my_validate(value): value = chirp_common.parse_freq(value) if 17400000 <= value and value < 40000000: raise InvalidValueError("Can't be between 174.00000-400.00000") return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 obj.band = value >= 40000000 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq( self._memobj.vfoa.freq)) val1a.set_validate_callback(my_validate) rs = RadioSetting("vfoa.freq", "VFO A Frequency", val1a) rs.set_apply_callback(apply_freq, self._memobj.vfoa) workmode.append(rs) val1b = RadioSettingValueString(0, 10, bfc.bcd_decode_freq( self._memobj.vfob.freq)) val1b.set_validate_callback(my_validate) rs = RadioSetting("vfob.freq", "VFO B Frequency", val1b) rs.set_apply_callback(apply_freq, self._memobj.vfob) workmode.append(rs) options = ["Off", "+", "-"] rs = RadioSetting("vfoa.sftd", "VFO A Shift", RadioSettingValueList( options, options[self._memobj.vfoa.sftd])) workmode.append(rs) rs = RadioSetting("vfob.sftd", "VFO B Shift", RadioSettingValueList( options, options[self._memobj.vfob.sftd])) workmode.append(rs) def convert_bytes_to_offset(bytes): real_offset = 0 for byte in bytes: real_offset = (real_offset * 10) + byte return chirp_common.format_freq(real_offset * 10000) def apply_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10000 for i in range(3, -1, -1): obj.offset[i] = value % 10 value /= 10 val1a = RadioSettingValueString( 0, 10, convert_bytes_to_offset(self._memobj.vfoa.offset)) rs = RadioSetting("vfoa.offset", "VFO A Offset (0.00-69.95)", val1a) rs.set_apply_callback(apply_offset, self._memobj.vfoa) workmode.append(rs) val1b = RadioSettingValueString( 0, 10, convert_bytes_to_offset(self._memobj.vfob.offset)) rs = RadioSetting("vfob.offset", "VFO B Offset (0.00-69.95)", val1b) rs.set_apply_callback(apply_offset, self._memobj.vfob) workmode.append(rs) options = ["High", "Low"] rs = RadioSetting("vfoa.txpower", "VFO A Power", RadioSettingValueList( options, options[self._memobj.vfoa.txpower])) workmode.append(rs) rs = RadioSetting("vfob.txpower", "VFO B Power", RadioSettingValueList( options, options[self._memobj.vfob.txpower])) workmode.append(rs) options = ["Wide", "Narrow"] rs = RadioSetting("vfoa.widenarr", "VFO A Bandwidth", RadioSettingValueList( options, options[self._memobj.vfoa.widenarr])) workmode.append(rs) rs = RadioSetting("vfob.widenarr", "VFO B Bandwidth", RadioSettingValueList( options, options[self._memobj.vfob.widenarr])) workmode.append(rs) options = ["%s" % x for x in range(1, 16)] rs = RadioSetting("vfoa.scode", "VFO A PTT-ID", RadioSettingValueList( options, options[self._memobj.vfoa.scode])) workmode.append(rs) rs = RadioSetting("vfob.scode", "VFO B PTT-ID", RadioSettingValueList( options, options[self._memobj.vfob.scode])) workmode.append(rs) rs = RadioSetting("vfoa.step", "VFO A Tuning Step", RadioSettingValueList( STEP_LIST, STEP_LIST[self._memobj.vfoa.step])) workmode.append(rs) rs = RadioSetting("vfob.step", "VFO B Tuning Step", RadioSettingValueList( STEP_LIST, STEP_LIST[self._memobj.vfob.step])) workmode.append(rs) fm_preset = RadioSettingGroup("fm_preset", "FM Radio Preset") group.append(fm_preset) preset = self._memobj.fm_preset / 10.0 + 87 rs = RadioSetting("fm_preset", "FM Preset(MHz)", RadioSettingValueFloat(87, 107.5, preset, 0.1, 1)) fm_preset.append(rs) dtmf = RadioSettingGroup("dtmf", "DTMF Settings") group.append(dtmf) dtmfchars = "0123456789 *#ABCD" for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("pttid/%i.code" % i, "PTT ID Code %i" % (i + 1), val) def apply_code(setting, obj): code = [] for j in range(0, 5): try: code.append(dtmfchars.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.pttid[i]) dtmf.append(rs) _codeobj = self._memobj.ani.code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("ani.code", "ANI Code", val) def apply_code(setting, obj): code = [] for j in range(0, 5): try: code.append(dtmfchars.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmf.append(rs) options = ["Off", "BOT", "EOT", "Both"] rs = RadioSetting("ani.aniid", "ANI ID", RadioSettingValueList( options, options[self._memobj.ani.aniid])) dtmf.append(rs) _codeobj = self._memobj.ani.alarmcode _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("ani.alarmcode", "Alarm Code", val) def apply_code(setting, obj): alarmcode = [] for j in range(5): try: alarmcode.append(dtmfchars.index(str(setting.value)[j])) except IndexError: alarmcode.append(0xFF) obj.alarmcode = alarmcode rs.set_apply_callback(apply_code, self._memobj.ani) dtmf.append(rs) rs = RadioSetting("dtmfst", "DTMF Sidetone", RadioSettingValueList( uv5r.DTMFST_LIST, uv5r.DTMFST_LIST[_settings.dtmfst])) dtmf.append(rs) rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList( uv5r.DTMFSPEED_LIST, uv5r.DTMFSPEED_LIST[self._memobj.ani.dtmfon])) dtmf.append(rs) rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList( uv5r.DTMFSPEED_LIST, uv5r.DTMFSPEED_LIST[self._memobj.ani.dtmfoff])) dtmf.append(rs) return group def _set_fm_preset(self, settings): for element in settings: try: val = element.value value = int(val.get_value() * 10 - 870) LOG.debug("Setting fm_preset = %s" % (value)) self._memobj.fm_preset = value except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/vx170.py0000644000175000017500000000673114446523722016076 0ustar hibbyhibby# Copyright 2014 Jens Jensen # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import yaesu_clone, ft7800 from chirp import chirp_common, directory, bitwise MEM_FORMAT = """ #seekto 0x018A; struct { u16 in_use; } bank_used[24]; #seekto 0x0214; u16 banksoff1; #seekto 0x0294; u16 banksoff2; #seekto 0x097A; struct { u8 name[6]; } bank_names[24]; #seekto 0x0C0A; struct { u16 channels[100]; } banks[24]; #seekto 0x0168; struct { u8 used:1, unknown1:1, mode:1, unknown2:2, duplex:3; bbcd freq[3]; u8 clockshift:1, tune_step:3, unknown5:1, tmode:3; bbcd split[3]; u8 power:2, tone:6; u8 unknown6:1, dtcs:7; u8 unknown7[2]; u8 offset; u8 unknown9[3]; } memory [200]; #seekto 0x0F28; struct { char name[6]; u8 enabled:1, unknown1:7; u8 used:1, unknown2:7; } names[200]; #seekto 0x1768; struct { u8 skip3:2, skip2:2, skip1:2, skip0:2; } flags[50]; """ @directory.register class VX170Radio(ft7800.FTx800Radio): """Yaesu VX-170""" MODEL = "VX-170" _model = "AH022" _memsize = 6057 _block_lengths = [8, 6048, 1] _block_size = 32 POWER_LEVELS_VHF = [chirp_common.PowerLevel("Hi", watts=5.00), chirp_common.PowerLevel("Med", watts=2.00), chirp_common.PowerLevel("Lo", watts=0.50)] MODES = ["FM", "NFM"] TMODES = ["", "Tone", "TSQL", "DTCS"] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [moni] key while turning the radio" " on.\n" "4. Select CLONE in menu, then press F. Radio restarts in clone" " mode.\n" " (\"CLONE\" will appear on the display).\n" "5. After clicking OK, briefly hold [PTT] key to send" " image.\n" " (\"-TX-\" will appear on the LCD). \n") rp.pre_upload = _( "1. Turn radio off.\n" "3. Press and hold in the [moni] key while turning the radio" " on.\n" "4. Select CLONE in menu, then press F. Radio restarts in clone" " mode.\n" " (\"CLONE\" will appear on the display).\n" "5. Press the [moni] key (\"-RX-\" will appear on the LCD).\n") return rp def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, self._memsize - 2)] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_features(self): rf = super(VX170Radio, self).get_features() rf.has_bank = False rf.has_bank_names = False rf.valid_modes = self.MODES rf.memory_bounds = (1, 200) rf.valid_bands = [(137000000, 174000000)] return rf chirp-20240224/chirp/drivers/icq7.py0000644000175000017500000002664214520142245016045 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import icf from chirp import chirp_common, directory, bitwise from chirp.chirp_common import to_GHz, from_GHz from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { bbcd freq[3]; u8 fractional:1, unknown:7; bbcd offset[2]; u16 ctone:6, rtone:6, tune_step:4; } memory[200]; #seekto 0x0690; struct { u8 tmode:2, duplex:2, skip:1, pskip:1, mode:2; } flags[200]; #seekto 0x0690; u8 flags_whole[200]; #seekto 0x0767; struct { i8 rit; u8 squelch; u8 lock:1, ritfunct:1, unknown:6; u8 unknown1[6]; u8 d_sel; u8 autorp; u8 priority; u8 resume; u8 pause; u8 p_scan; u8 bnk_scan; u8 expand; u8 ch; u8 beep; u8 light; u8 ap_off; u8 p_save; u8 monitor; u8 speed; u8 edge; u8 lockgroup; } settings; """ TMODES = ["", "", "Tone", "TSQL", "TSQL"] # last one is pocket beep DUPLEX = ["", "", "-", "+"] MODES = ["FM", "WFM", "AM", "Auto"] STEPS = [5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] AUTORP_LIST = ["Off", "Duplex Only", "Duplex and Tone"] LOCKGROUP_LIST = ["Normal", "No Squelch", "No Volume", "All"] SQUELCH_LIST = ["Open", "Auto"] + ["L%s" % x for x in range(1, 10)] MONITOR_LIST = ["Push", "Hold"] LIGHT_LIST = ["Off", "On", "Auto"] PRIORITY_LIST = ["Off", "On", "Bell"] BANKSCAN_LIST = ["Off", "Bank 0", "Bank 1"] EDGE_LIST = ["%sP" % x for x in range(0, 20)] + ["Band", "All"] PAUSE_LIST = ["%s sec" % x for x in range(2, 22, 2)] + ["Hold"] RESUME_LIST = ["%s sec" % x for x in range(0, 6)] APOFF_LIST = ["Off"] + ["%s min" % x for x in range(30, 150, 30)] D_SEL_LIST = ["100 kHz", "1 MHz", "10 MHz"] @directory.register class ICQ7Radio(icf.IcomCloneModeRadio): """Icom IC-Q7A""" VENDOR = "Icom" MODEL = "IC-Q7A" _model = "\x19\x95\x00\x01" _memsize = 0x7C0 _endframe = "Icom Inc\x2e" _ranges = [(0x0000, 0x07C0, 16)] def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.memory_bounds = (0, 199) rf.valid_modes = list(MODES) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(1000000, 823995000), (849000000, 868995000), (894000000, 1309995000)] rf.valid_skips = ["", "S", "P"] rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_name = False return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return (repr(self._memobj.memory[number]) + repr(self._memobj.flags[number])) def validate_memory(self, mem): if mem.freq < 30000000 and mem.mode != 'AM': return [chirp_common.ValidationError( 'Only AM is allowed below 30 MHz')] return icf.IcomCloneModeRadio.validate_memory(self, mem) def get_memory(self, number): _mem = self._memobj.memory[number] _flag = self._memobj.flags[number] mem = chirp_common.Memory() mem.number = number if self._memobj.flags_whole[number] == 0xFF: mem.empty = True return mem mem.freq = int(_mem.freq) * 1000 if _mem.fractional: mem.freq = chirp_common.fix_rounded_step(mem.freq) mem.offset = int(_mem.offset) * 1000 try: mem.rtone = chirp_common.TONES[_mem.rtone] except IndexError: mem.rtone = 88.5 try: mem.ctone = chirp_common.TONES[_mem.ctone] except IndexError: mem.ctone = 88.5 try: mem.tuning_step = STEPS[_mem.tune_step] except IndexError: LOG.error("Invalid tune step index %i" % _mem.tune_step) mem.tmode = TMODES[_flag.tmode] mem.duplex = DUPLEX[_flag.duplex] if mem.freq < 30000000: mem.mode = "AM" else: mem.mode = MODES[_flag.mode] if _flag.pskip: mem.skip = "P" elif _flag.skip: mem.skip = "S" return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _flag = self._memobj.flags[mem.number] if mem.empty: self._memobj.flags_whole[mem.number] = 0xFF return _mem.set_raw("\x00" * 8) if mem.freq > to_GHz(1): _mem.freq = (mem.freq // 1000) - to_GHz(1) upper = from_GHz(mem.freq) << 4 _mem.freq[0].clr_bits(0xF0) _mem.freq[0].set_bits(upper) else: _mem.freq = mem.freq / 1000 _mem.fractional = chirp_common.is_fractional_step(mem.freq) _mem.offset = mem.offset / 1000 _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.tune_step = STEPS.index(mem.tuning_step) _flag.tmode = TMODES.index(mem.tmode) _flag.duplex = DUPLEX.index(mem.duplex) _flag.mode = MODES.index(mem.mode) _flag.skip = mem.skip == "S" and 1 or 0 _flag.pskip = mem.skip == "P" and 1 or 0 def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) rs = RadioSetting("ch", "Channel Indication Mode", RadioSettingValueBoolean(_settings.ch)) basic.append(rs) rs = RadioSetting("expand", "Expanded Settings Mode", RadioSettingValueBoolean(_settings.expand)) basic.append(rs) rs = RadioSetting("beep", "Beep Tones", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) rs = RadioSetting("autorp", "Auto Repeater Function", RadioSettingValueList( AUTORP_LIST, AUTORP_LIST[_settings.autorp])) basic.append(rs) rs = RadioSetting("ritfunct", "RIT Runction", RadioSettingValueBoolean(_settings.ritfunct)) basic.append(rs) rs = RadioSetting("rit", "RIT Shift (kHz)", RadioSettingValueInteger(-7, 7, _settings.rit)) basic.append(rs) rs = RadioSetting("lock", "Lock", RadioSettingValueBoolean(_settings.lock)) basic.append(rs) rs = RadioSetting("lockgroup", "Lock Group", RadioSettingValueList( LOCKGROUP_LIST, LOCKGROUP_LIST[_settings.lockgroup])) basic.append(rs) rs = RadioSetting("squelch", "Squelch", RadioSettingValueList( SQUELCH_LIST, SQUELCH_LIST[_settings.squelch])) basic.append(rs) rs = RadioSetting("monitor", "Monitor Switch Function", RadioSettingValueList( MONITOR_LIST, MONITOR_LIST[_settings.monitor])) basic.append(rs) rs = RadioSetting("light", "Display Backlighting", RadioSettingValueList( LIGHT_LIST, LIGHT_LIST[_settings.light])) basic.append(rs) rs = RadioSetting("priority", "Priority Watch Operation", RadioSettingValueList( PRIORITY_LIST, PRIORITY_LIST[_settings.priority])) basic.append(rs) rs = RadioSetting("p_scan", "Frequency Skip Function", RadioSettingValueBoolean(_settings.p_scan)) basic.append(rs) rs = RadioSetting("bnk_scan", "Memory Bank Scan Selection", RadioSettingValueList( BANKSCAN_LIST, BANKSCAN_LIST[_settings.bnk_scan])) basic.append(rs) rs = RadioSetting("edge", "Band Edge Scan Selection", RadioSettingValueList( EDGE_LIST, EDGE_LIST[_settings.edge])) basic.append(rs) rs = RadioSetting("pause", "Scan Pause Time", RadioSettingValueList( PAUSE_LIST, PAUSE_LIST[_settings.pause])) basic.append(rs) rs = RadioSetting("resume", "Scan Resume Time", RadioSettingValueList( RESUME_LIST, RESUME_LIST[_settings.resume])) basic.append(rs) rs = RadioSetting("p_save", "Power Saver", RadioSettingValueBoolean(_settings.p_save)) basic.append(rs) rs = RadioSetting("ap_off", "Auto Power-off Function", RadioSettingValueList( APOFF_LIST, APOFF_LIST[_settings.ap_off])) basic.append(rs) rs = RadioSetting("speed", "Dial Speed Acceleration", RadioSettingValueBoolean(_settings.speed)) basic.append(rs) rs = RadioSetting("d_sel", "Dial Select Step", RadioSettingValueList( D_SEL_LIST, D_SEL_LIST[_settings.d_sel])) basic.append(rs) return group def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/tk3140.py0000644000175000017500000005251414566340166016141 0ustar hibbyhibby# Copyright 2023 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import collections import logging import struct from chirp import chirp_common from chirp import bitwise from chirp import directory from chirp.drivers import tk8160 from chirp.drivers import tk8180 from chirp import errors from chirp import memmap from chirp import settings from chirp import util LOG = logging.getLogger(__name__) IndexEntry = collections.namedtuple('IndexEntry', 'zone memory zoneindex slot') EMPTY_INDEX_ENTRY = IndexEntry(0xFF, 0xFF, 0xFF, 0xFF) def send(radio, frame): LOG.debug("%04i P>R:\n%s" % (len(frame), util.hexprint(frame))) radio.pipe.write(frame) def recv(radio, count): buf = radio.pipe.read(count) LOG.debug('%04i: R>P:\n%s' % (len(buf), util.hexprint(buf))) return buf def do_ident(radio): radio.pipe.baudrate = 9600 radio.pipe.databits = 8 radio.pipe.stopbits = 2 radio.pipe.parity = 'N' radio.pipe.timeout = 1 send(radio, b'PROGRAM') ack = recv(radio, 1) if ack != b'\x06': LOG.error('Expected ACK, got %r' % ack) raise errors.RadioError('Radio failed to ack program mode') send(radio, b'\x02') model = recv(radio, 8) if model != radio._model: raise errors.RadioError('Incorrect model') send(radio, b'\x06') ack = recv(radio, 1) if ack != b'\x06': raise errors.RadioError('No ack after model probe') send(radio, b'P') resp = recv(radio, 10) LOG.debug('Radio ident:\n%s' % util.hexprint(resp)) send(radio, b'\x06') ack = recv(radio, 1) if ack != b'\x06': raise errors.RadioError('No ack after version probe') def status(radio, block, msg): s = chirp_common.Status() s.cur = block s.max = 0x7F s.msg = msg radio.status_fn(s) def do_download(radio): do_ident(radio) data = b'' for block in range(0x80): send(radio, struct.pack('>cBB', b'R', 0, block)) cmd = recv(radio, 1) if cmd == b'Z': fillbyte = recv(radio, 1) if len(fillbyte) != 1: LOG.error('Expected fill byte after Z but got none') raise errors.RadioError('Failed to communicate') chunk = fillbyte * 256 elif cmd == b'W': chunk = recv(radio, 256) cs = recv(radio, 1) ccs = sum(chunk) % 256 if cmd != b'Z' and cs[0] != ccs: LOG.error('Checksum mismatch %02x!=%02x at block %02x', cs[0], ccs, block) raise errors.RadioError( 'Checksum mismatch at block %02i' % block) else: LOG.error('Unsupported command %r' % cmd) raise errors.RadioError('Invalid command') data += chunk send(radio, b'\x06') ack = recv(radio, 1) if ack != b'\x06': LOG.error('Expected ACK got %r' % ack) raise errors.RadioError('Failed at block %02x' % block) status(radio, block, 'Receiving from radio') # This is a separate region at the end, read and written in a different # way. Only contains the scan bits (that we know of) for addr in range(0x0320, 0x0340, 0x10): hdr = struct.pack('>cHB', b'S', addr, 0x10) send(radio, hdr) cmd = recv(radio, 1) if cmd != b'X': LOG.error('Unsupported command %r' % cmd) raise errors.RadioError('Invalid command') chunk = recv(radio, 0x10) if len(chunk) == 0x10: send(radio, b'\x06') recv(radio, 1) else: LOG.error('Got short read at %04x:\n%s', addr, util.hexprint(chunk)) raise errors.RadioError('Short read at %04x' % addr) data += chunk return memmap.MemoryMapBytes(data) def do_upload(radio): do_ident(radio) data = radio._mmap.get_packed() for block in range(0x80): if 0x54 <= block < 0x60: LOG.debug('Skipping block 0x%02x' % block) continue addr = block * 256 chunk = data[addr:addr + 256] if len(set(chunk)) == 1: hdr = struct.pack('cBBB', b'Z', 0, block, chunk[0]) send(radio, hdr) else: hdr = struct.pack('cBB', b'W', 0, block) send(radio, hdr) send(radio, chunk) cs = sum(chunk) % 256 send(radio, bytes([cs])) ack = recv(radio, 1) if ack != b'\x06': LOG.error('Expected ACK but got %r' % ack) raise errors.RadioError('Radio NAKd block %i' % block) status(radio, block, 'Sending to radio') for i in range(2): radio_addr = 0x0320 + i * 0x10 memory_addr = 0x8000 + i * 0x10 chunk = data[memory_addr:memory_addr + 0x10] hdr = struct.pack('>cHB', b'X', radio_addr, 0x10) send(radio, hdr) send(radio, chunk) send(radio, bytes([sum(chunk) % 255])) ack = recv(radio, 1) if ack != b'\x06': LOG.error('Expected ACK at %04x, got %r', radio_addr, ack) raise errors.RadioError('Radio NAKd block') send(radio, ack) def exit_program(radio): try: send(radio, b'E') except Exception: pass KEYS = { 0x31: 'DTMF ID (BOT)', 0x32: 'DTMF ID (EOT)', 0x33: 'Display Character', 0x35: 'Home Channel', 0x37: 'Channel Down', 0x38: 'Channel Up', 0x39: 'Key Lock', 0x3A: 'Lamp', 0x3C: 'Memory RCL/STO', 0x3E: 'Memory RCL', 0x3F: 'Memory STO', 0x40: 'Squelch Off Momentary', 0x41: 'Squelch Off Toggle', 0x42: 'Monitor Momentary', 0x43: 'Monitor Toggle', 0x45: 'Redial', 0x46: 'Low RF Power', 0x47: 'Scan', 0x48: 'Scan Add/Del', 0x4A: 'Group Down', 0x4B: 'Group Up', 0x4E: 'OST', 0x4F: 'None', 0x52: 'Talk Around', 0x60: 'Squelch Level', } KEY_NAMES = { 'A': 'akey', 'B': 'bkey', 'C': 'ckey', 'S': 'skey', 'Side 1': 'side1', 'Side 2': 'side2', 'Aux': 'aux', 'Mic PF1': 'pf1', 'Mic PF2': 'pf2', } KNOB = { 0x00: 'None', 0x01: 'Channel Up/Down', 0x02: 'Group Up/Down', } BATTSAVE = { 0xFF: 'Off', 0x30: 'Short', 0x31: 'Medium', 0x32: 'Long', } mem_format = """ #seekto 0x00E; u8 zone_count; u8 memory_count; #seekto 0x01F; // 0xFF=off, 0x30=short, 0x31=med, 0x32=long u8 battsave; #seekto 0x110; // 4F=none 31=dtmfidbot 32=dmtfideot 33=chup 35=home 37=chandn 38=dispchr // 39=keylock 3A=lamp 3C=memrclsto 3E=memrcl 3F=memsto 40=sqlmon 41=sqltog // 42=monmom 43=montog 45=redial 46=lowpower 47=scan 48=scanadd 60=sqllev 52=ta // 4A=grpdn 4B=grpup 4E=OST struct { u8 akey; u8 bkey; u8 ckey; u8 side2; u8 skey; u8 side1; u8 aux; u8 pf1; u8 pf2; } keys; #seekto 0x124; // A1=cha A2=group 4F=none u8 unknown1:6, knob:2; #seekto 0x300; struct { u8 zone; u8 memory; u8 zoneinfo_index; u8 slot; } index[250]; #seekto 0x1000; struct { u8 zone; u8 count; char name[10]; u8 unknown[4]; } zoneinfo[250]; #seekto 0x2000; struct { u8 memory; u8 zone; char name[10]; lbcd rx_freq[4]; lbcd tx_freq[4]; u8 rxsomething; u8 txsomething; ul16 rxtone; ul16 txtone; u8 unknown2[5]; u8 optsig; // ff=None 31=2tone 30=DTMF 32=MSK u8 unknown2_1:1, pttid:1, // 0=on 1=off beatshift:1, // 0=on 1=off bcl:1, // 1=none 0=QT/DQT unknown1_2:1, highpower:1, compander:1, //0=on 1=off wide:1; u8 unknown3_1:4, bcl_optsig:2, // 0 if bcl=carrier 1 if bcl=optsig 3 otherwise mode2tone:2; // F=off C=2tone1 D=2tone2 E=2tone3 u8 unknown4[14]; } memories[250]; #seekto 0x8000; u8 scanbits[32]; """ POWER_LEVELS = [chirp_common.PowerLevel('Low', watts=1), chirp_common.PowerLevel('High', watts=5)] class KenwoodTKx140Radio(chirp_common.CloneModeRadio): VENDOR = 'Kenwood' FORMATS = [directory.register_format('Kenwood KPG-74D', '*.dat')] NEEDS_COMPAT_SERIAL = False def sync_in(self): try: self._mmap = do_download(self) self.process_mmap() except errors.RadioError: raise except Exception as e: LOG.exception('Failed to download: %s' % e) raise errors.RadioError('Failed to download from radio') finally: exit_program(self) def sync_out(self): try: do_upload(self) except errors.RadioError: raise except Exception as e: LOG.exception('Failed to upload: %s' % e) raise errors.RadioError('Failed to upload to radio') finally: exit_program(self) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 250) rf.has_ctone = True rf.has_cross = True rf.has_bank = False rf.has_tuning_step = False rf.has_rx_dtcs = True rf.has_settings = True rf.can_odd_split = True rf.valid_bands = self._valid_bands rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 10 rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ['Tone->Tone', 'DTCS->', '->DTCS', "Tone->DTCS", 'DTCS->Tone', '->Tone', 'DTCS->DTCS'] rf.valid_duplexes = ['', '-', '+', 'split', 'off'] rf.valid_modes = ['FM', 'NFM'] rf.valid_power_levels = list(POWER_LEVELS) rf.valid_tuning_steps = [2.5, 5.0, 6.25, 12.5, 10.0, 15.0, 20.0, 25.0, 50.0, 100.0] rf.has_sub_devices = not self.VARIANT return rf def _get_zone(self, zone): class TKx140Zone(self.__class__): MODEL = self.MODEL VARIANT = 'Group %i' % zone _valid_bands = self._valid_bands def __init__(self, parent, zone): self._memobj = parent._memobj self._zone = zone return TKx140Zone(self, zone) def _get_zone_info(self): zones = collections.defaultdict(int) for i in range(250): zone_obj = self._memobj.zoneinfo[i] if int(zone_obj.zone) != 0xFF: zones[int(zone_obj.zone)] = int(zone_obj.count) return zones def _set_num_zones(self, count): zones = self._get_zone_info() available = [x + 1 for x in range(250) if x + 1 not in zones] for i in range(250): zoneinfo_obj = self._memobj.zoneinfo[i] if i >= count: if i > 0 and zoneinfo_obj.zone != 0xFF: LOG.debug('Deleting zone %i index %i', zoneinfo_obj.zone, i) zoneinfo_obj.set_raw(b'\xFF' * 16) elif zoneinfo_obj.zone == 0xFF: next_zone = available.pop(0) LOG.debug('Adding zone %i index %i', next_zone, i) zoneinfo_obj.zone = next_zone zoneinfo_obj.count = 0 zoneinfo_obj.name = ('Group %i' % next_zone).ljust(10) else: LOG.debug('Keeping existing zone %i index %i', zoneinfo_obj.zone, i) self.sort_index() def get_sub_devices(self): if not self._memobj: return [self._get_zone(1)] return [self._get_zone(zone) for zone, count in self._get_zone_info().items()] def check_index(self, number): for i in range(250): index_obj = self._memobj.index[i] if index_obj.zone == self._zone and index_obj.memory == number: return i, index_obj.slot elif index_obj.zone == 0xFF: # KPG-74D keeps these compacted so that there are no empties # until the end break return None, None def next_slot(self, number): for i in range(250): if self._memobj.memories[i].memory == 0xFF: return i def sort_index(self): zones = [] for i in range(250): zoneinfo_obj = self._memobj.zoneinfo[i] if zoneinfo_obj.zone == 0xFF: break zones.append(int(zoneinfo_obj.zone)) LOG.debug('Enabled zones: %s' % zones) index_entries = [] for i in range(250): mem_obj = self._memobj.memories[i] if mem_obj.zone == 0xFF: # Empty continue if int(mem_obj.zone) not in zones: LOG.debug('Erasing %i:%i from slot %i because zone disabled', mem_obj.zone, mem_obj.memory, i) mem_obj.set_raw(b'\xFF' * 48) continue index_entries.append(IndexEntry(int(mem_obj.zone), int(mem_obj.memory), zones.index(int(mem_obj.zone)), i)) index_entries.sort() zone_counts = collections.defaultdict(int) for i in range(250): try: entry = index_entries[i] zone_counts[entry.zone] += 1 except IndexError: entry = EMPTY_INDEX_ENTRY index_obj = self._memobj.index[i] index_obj.zone = entry.zone index_obj.memory = entry.memory index_obj.zoneinfo_index = entry.zoneindex index_obj.slot = entry.slot for zone_index, zone in enumerate(zones): LOG.debug('Zone %i count %i' % (zone, zone_counts[zone])) self._memobj.zoneinfo[zone_index].count = zone_counts[zone] self._memobj.memory_count = sum(zone_counts.values()) self._memobj.zone_count = len(zones) LOG.debug('Sorted index, %i memories' % self._memobj.memory_count) def get_raw_memory(self, number): _index_entry, slot = self.check_index(number) if slot is not None: return '\n'.join(repr(x) for x in [ self._memobj.memories[slot], self._memobj.index[_index_entry]]) def get_memory(self, number): m = chirp_common.Memory(number) _index_entry, slot = self.check_index(number) if slot is None: m.empty = True return m _mem = self._memobj.memories[slot] _scn = self._memobj.scanbits[slot // 8] mask = 1 << (slot % 8) m.freq = int(_mem.rx_freq) * 10 offset = int(_mem.tx_freq) * 10 - m.freq if _mem.tx_freq.get_raw() == b'\xFF\xFF\xFF\xFF': m.offset = 0 m.duplex = 'off' elif offset < 0: m.offset = abs(offset) m.duplex = '-' elif offset > 0: m.offset = offset m.duplex = '+' else: m.offset = 0 rxtone = tk8180.KenwoodTKx180Radio._decode_tone( _mem.rxtone) txtone = tk8180.KenwoodTKx180Radio._decode_tone( _mem.txtone) chirp_common.split_tone_decode(m, txtone, rxtone) m.name = str(_mem.name).rstrip() m.power = POWER_LEVELS[int(_mem.highpower)] m.mode = 'FM' if _mem.wide else 'NFM' m.skip = '' if _scn & mask else 'S' return m def set_memory(self, mem): index_entry, slot = self.check_index(mem.number) if mem.empty: if slot is not None: self._memobj.memories[slot].set_raw(b'\xFF' * 48) self.sort_index() return if slot is None: slot = self.next_slot(mem.number) _mem = self._memobj.memories[slot] _scn = self._memobj.scanbits[slot // 8] mask = 1 << (slot % 8) # Everything seems to default to 0xFF for "off" _mem.set_raw(b'\xFF' * 48) _mem.memory = mem.number _mem.zone = self._zone self.sort_index() _mem.rxsomething = 0x35 _mem.txsomething = 0x35 _mem.rx_freq = mem.freq // 10 if mem.duplex == '': _mem.tx_freq = mem.freq // 10 elif mem.duplex == 'split': _mem.tx_freq = mem.offset // 10 elif mem.duplex == 'off': _mem.tx_freq.fill_raw(b'\xFF') elif mem.duplex == '-': _mem.tx_freq = (mem.freq - mem.offset) // 10 elif mem.duplex == '+': _mem.tx_freq = (mem.freq + mem.offset) // 10 else: raise errors.RadioError('Unsupported duplex mode %r' % mem.duplex) txtone, rxtone = chirp_common.split_tone_encode(mem) _mem.rxtone = tk8180.KenwoodTKx180Radio._encode_tone(*rxtone) _mem.txtone = tk8180.KenwoodTKx180Radio._encode_tone(*txtone) _mem.wide = mem.mode == 'FM' _mem.highpower = mem.power == POWER_LEVELS[1] _mem.name = mem.name[:10].ljust(10) if mem.skip == 'S': _scn &= ~mask else: _scn |= mask def load_mmap(self, filename): if filename.lower().endswith('.dat'): with open(filename, 'rb') as f: header = f.read(0x40) LOG.debug('DAT header:\n%s' % util.hexprint(header)) self._mmap = memmap.MemoryMapBytes(f.read()) LOG.info('Loaded DAT file') self.process_mmap() else: super().load_mmap(filename) def save_mmap(self, filename): if filename.lower().endswith('.dat'): with open(filename, 'wb') as f: f.write(b'KPG74D\xff\xff\xff\xffV1.10P') f.write(self._model[1:] + (b'\xff' * 9)) f.write(b'\xff' * 32) f.write(self._mmap.get_packed()) LOG.info('Wrote DAT file') else: super().save_mmap(filename) @classmethod def match_model(cls, filedata, filename): if (filename.lower().endswith('.dat') and filedata.startswith(b'KPG74D') and filedata[0xE7:0xEF] == cls._model): return True return super().match_model(filedata, filename) def get_settings(self): num_zones = len(self._get_zone_info()) zones = settings.RadioSettingGroup('zones', 'Zones') zone_count = settings.RadioSetting( 'zonecount', 'Number of Zones', settings.RadioSettingValueInteger(1, 250, num_zones)) zone_count.set_doc('Number of zones in the radio. ' 'Requires a save and re-load of the file to take ' 'effect. Reducing this number will DELETE ' 'memories in the affected zones!') zones.append(zone_count) keys = tk8160.TKx160Radio.make_key_group(self._memobj.keys, KEY_NAMES, KEYS) def apply_knob(setting): rev = {v: k for k, v in KNOB.items()} self._memobj.knob = rev[str(setting.value)] knob = settings.RadioSetting( 'knob', 'Knob', settings.RadioSettingValueList( KNOB.values(), current_index=self._memobj.knob)) knob.set_apply_callback(apply_knob) keys.append(knob) def apply_battsave(setting): rev = {v: k for k, v in BATTSAVE.items()} self._memobj.battsave = rev[str(setting.value)] general = settings.RadioSettingGroup('general', 'General') battsave = settings.RadioSetting( 'battsave', 'Battery Save', settings.RadioSettingValueList( BATTSAVE.values(), BATTSAVE[int(self._memobj.battsave)])) battsave.set_apply_callback(apply_battsave) general.append(battsave) return settings.RadioSettings(zones, keys, general) def set_settings(self, _settings): for element in _settings: if not isinstance(element, settings.RadioSetting): self.set_settings(element) elif element.get_name() == 'zonecount': self._set_num_zones(int(element.value)) elif element.has_apply_callback(): element.run_apply_callback() @directory.register class KenwoodTK2140KRadio(KenwoodTKx140Radio): MODEL = 'TK-2140K' _valid_bands = [(136000000, 174000000)] _model = b'P2140\x04\xFF\xF1' @directory.register class KenwoodTK3140KRadio(KenwoodTKx140Radio): MODEL = 'TK-3140K' _valid_bands = [(400000000, 520000000)] _model = b'P3140\x06\xFF\xF1' @directory.register class KenwoodTK3140K2Radio(KenwoodTKx140Radio): MODEL = 'TK-3140K2' _valid_bands = [(400000000, 520000000)] _model = b'P3140\x07\xFF\xF1' @directory.register class KenwoodTK3140K3Radio(KenwoodTKx140Radio): MODEL = 'TK-3140K3' _valid_bands = [(400000000, 520000000)] _model = b'P3140\x08\xFF\xF1' chirp-20240224/chirp/drivers/id5100.py0000644000175000017500000002473014430171343016101 0ustar hibbyhibby# Copyright 2022 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import chirp_common from chirp import directory from chirp.drivers import icf, id31 from chirp import errors from chirp import bitwise LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { u24 mult1:3, mult2:3, freq:18; u16 offset; u16 rtone:6, ctone:6, unknown1:1, mode:3; u8 dtcs; u8 tuning_step:4, unknown2:4; u8 unknown3; u8 tmode:4, duplex:2, dtcs_polarity:2; char name[16]; u8 dv_code; u8 urcall[7]; u8 rpt1call[7]; u8 rpt2call[7]; } memory[1004]; #seekto 0xC040; u8 usedflags[125]; #seekto 0xC0BE; u8 skipflags[125]; #seekto 0xC13B; u8 pskipflags[125]; #seekto 0xC1C0; struct { u8 bank; u8 index; } bank_info[1000]; #seekto 0xC9C0; char ICFComment[16]; struct { char name[16]; } bank_names[26]; """ TUNE_STEPS = [5.0, 6.25, 8.33, 5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 5.0, 5.0, 5.0, 5.0] MODES = ['FM', 'NFM', '2??', 'AM', 'NAM', 'DV', '6??', '7??'] TMODES = ['', 'Tone', '2??', 'TSQL', '4??', 'DTCS', 'TSQL-R', 'DTCS-R', 'DTCS-T', 'Tone->DTCS', 'DTCS->Tone', 'Tone->Tone'] DUPLEX = ['', '-', '+'] DTCS_POL = ['NN', 'NR', 'RN', 'RR'] SPECIALS = ['144-C0', '144-C1', '430-C0', '430-C1'] MULTS = [5000, 6250, 25000 / 3.0] @directory.register class ID4100Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): VENDOR = 'Icom' MODEL = 'ID-4100' NEEDS_COMPAT_SERIAL = False _model = b'\x38\x66\x00\x01' _endframe = 'Icom Inc.8F' _memsize = 0x2A3C0 _ranges = [(0, _memsize, 64)] _raw_frames = True _highbit_flip = True _num_banks = 26 _bank_class = id31.ID31Bank _can_hispeed = True _icf_data = { 'MapRev': 1, 'EtcData': 0x400001, } def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_ctone = True rf.has_dtcs = True rf.has_dtcs_polarity = True rf.has_bank = True rf.has_bank_index = True rf.has_bank_names = True rf.requires_call_lists = False rf.valid_modes = [x for x in MODES if '?' not in x] rf.valid_tmodes = [x for x in TMODES if '-' not in x and '?' not in x] + ['Cross'] rf.valid_cross_modes = [x for x in TMODES if '->' in x] rf.memory_bounds = (0, 999) rf.valid_bands = [(118000000, 174000000), (375000000, 550000000)] rf.valid_skips = ['', 'S', 'P'] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 16 rf.valid_tuning_steps = list(sorted(set(TUNE_STEPS))) rf.valid_special_chans = list(SPECIALS) return rf def _get_bank(self, loc): _bank = self._memobj.bank_info[loc] _bank.bank &= 0x1F if _bank.bank == 0x1F: return None else: return _bank.bank def _set_bank(self, loc, bank): _bank = self._memobj.bank_info[loc] if bank is None: _bank.bank = 0x1F else: _bank.bank = bank def _get_bank_index(self, loc): _bank = self._memobj.bank_info[loc] return _bank.index def _set_bank_index(self, loc, index): _bank = self._memobj.bank_info[loc] _bank.index = index def _get_raw_memory(self, number): if isinstance(number, str): number = 1000 + SPECIALS.index(number) return number, self._memobj.memory[number] def get_raw_memory(self, number): num, mem = self._get_raw_memory(number) return repr(mem) def get_memory(self, number): num, _mem = self._get_raw_memory(number) m = chirp_common.DVMemory() m.number = num if isinstance(number, str): m.extd_number = number else: _flg = self._memobj.usedflags[num // 8] _skp = self._memobj.skipflags[num // 8] _pskp = self._memobj.pskipflags[num // 8] m.empty = bool(_flg & (1 << num % 8)) if _pskp & 1 << (num % 8): m.skip = 'P' elif _skp & 1 << (num % 8): m.skip = 'S' else: m.skip = '' mult = MULTS[_mem.mult1] m.freq = int(_mem.freq * mult) m.offset = int(_mem.offset * mult) m.tuning_step = TUNE_STEPS[_mem.tuning_step] m.name = str(_mem.name).rstrip() m.mode = MODES[_mem.mode] m.rtone = chirp_common.TONES[_mem.rtone] m.ctone = chirp_common.TONES[_mem.ctone] m.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] m.dtcs_polarity = DTCS_POL[_mem.dtcs_polarity] tmode = TMODES[_mem.tmode] if '->' in tmode: m.tmode = 'Cross' m.cross_mode = tmode elif '-' in tmode and 0: # FIXME m.tmode, extra = tmode.split('-') else: m.tmode = tmode m.duplex = DUPLEX[_mem.duplex] m.dv_code = _mem.dv_code m.dv_urcall = ''.join( chr(x) for x in icf.warp_byte_size(_mem.urcall, 7, 8)) m.dv_rpt1call = ''.join( chr(x) for x in icf.warp_byte_size(_mem.rpt1call, 7, 8)) m.dv_rpt2call = ''.join( chr(x) for x in icf.warp_byte_size(_mem.rpt2call, 7, 8)) return m def set_memory(self, mem): num, _mem = self._get_raw_memory(mem.number) if num < 1000: _flg = self._memobj.usedflags[num // 8] _skp = self._memobj.skipflags[num // 8] _pskp = self._memobj.pskipflags[num // 8] mybit = 1 << (num % 8) _flg |= mybit _skp &= ~mybit _pskp &= ~mybit if mem.empty: return _flg &= ~mybit if mem.skip == 'S': _skp |= mybit elif mem.skip == 'P': _pskp |= mybit if chirp_common.is_6_25(mem.freq): mult = MULTS[1] elif chirp_common.is_8_33(mem.freq): mult = MULTS[2] else: mult = MULTS[0] _mem.mult1 = _mem.mult2 = MULTS.index(mult) _mem.freq = mem.freq / mult _mem.offset = mem.offset / mult _mem.tuning_step = TUNE_STEPS.index(mem.tuning_step) _mem.name = mem.name.ljust(16) _mem.mode = MODES.index(mem.mode) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = DTCS_POL.index(mem.dtcs_polarity) if mem.tmode == 'Cross': _mem.tmode = TMODES.index(mem.cross_mode) else: _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) _mem.unknown1 = 0 _mem.unknown2 = 0 _mem.unknown3 = 0 if isinstance(mem, chirp_common.DVMemory): _mem.dv_code = mem.dv_code _mem.urcall = list( icf.warp_byte_size(mem.dv_urcall.ljust(8), 8, 7)) _mem.rpt1call = list( icf.warp_byte_size(mem.dv_rpt1call.ljust(8), 8, 7)) _mem.rpt2call = list( icf.warp_byte_size(mem.dv_rpt2call.ljust(8), 8, 7)) @directory.register class ID5100Radio(ID4100Radio): MODEL = "ID-5100" _model = b'\x34\x84\x00\x01' # This is only for MapRev=1 _endframe = "Icom Inc.EE" # MapRev=1 Size is 260928 0x3FB40 # MapRev=2 Size is 148160 0x242C0 # MapRev=3 Size is 172928 0x2A380 _memsize = 0x3FB40 _ranges = [(0, _memsize, 64)] _raw_frames = True _highbit_flip = True def process_mmap(self): was_memsize = self._memsize # Apparently the 5100 has different reported memory sizes # depending on firmware version. When we're loading an image, # we should adjust our MapRev and _ranges to be correct for # saving ICF files and uploading. This also means we should # try to detect which version we are talking to and refuse to # upload an image to a radio with a mismatch. self._memsize = len(self._mmap) self._ranges = [(0, self._memsize, 64)] # Major (memory-format-changing) firmware versions, which # correspond to MapRev in an ICF file. maprevs = { 0x3FB40: 1, 0x242C0: 2, 0x2A380: 3, } # The 5100 seems to almost behave like three different radios, # depending on firmware version. These are the endframes that # are expected for a given MapRev. endframes = { 1: 'Icom Inc.EE', 2: 'Icom Inc.0C', 3: 'Icom Inc.8E', } if self._memsize != was_memsize: self._icf_data['MapRev'] = maprevs.get(self._memsize, 0) if self._icf_data['MapRev'] == 0: LOG.error('Unknown memsize %06X!', self._memsize) raise errors.InvalidDataError('Unsupported memory format!') self._endframe = endframes[self._icf_data['MapRev']] LOG.info('Memory length changed from %06X to %06X; new MapRev=%i', was_memsize, self._memsize, self._icf_data['MapRev']) else: LOG.debug('Unchanged memsize at %06X' % self._memsize) self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = _('This driver has been tested with v3 of the ID-5100. ' 'If your radio is not fully updated please help by ' 'opening a bug report with a debug log so we can add ' 'support for the other revisions.') rp.pre_upload = rp.info rp.experimental = rp.info return rp chirp-20240224/chirp/drivers/fd268.py0000644000175000017500000007125114522657251016041 0ustar hibbyhibby# Copyright 2015 Pavel Milanes CO7WT # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap, errors, util, bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 unknown:4, scrambler:1, unknown1:1, unknown2:1, busy_lock:1; u8 unknown3[3]; } memory[99]; #seekto 0x0640; struct { lbcd vrx_freq[4]; lbcd vtx_freq[4]; lbcd vrx_tone[2]; lbcd vtx_tone[2]; u8 shift_plus:1, shift_minus:1, unknown11:2, scramble:1, unknown12:1, unknown13:1, busy_lock:1; u8 unknown14[3]; } vfo; #seekto 0x07B0; struct { u8 ani_mode; char ani[3]; u8 unknown21[12]; u8 unknown22:5, bw1:1, // twin setting of bw (LCD "romb") bs1:1, // twin setting of bs (LCD "S") warning1:1; // twin setting of warning (LCD "Tune") u8 sql[1]; u8 monitorval; u8 tot[1]; u8 powerrank; u8 unknown23[3]; u8 unknown24[8]; char model[8]; u8 unknown26[8]; u8 step; u8 unknown27:2, power:1, lamp:1, lamp_auto:1, key:1, monitor:1, bw:1; u8 unknown28:3, warning:1, bs:1, unknown29:1, wmem:1, wvfo:1; u8 active_ch; u8 unknown30[4]; u8 unknown31[4]; bbcd vfo_shift[4]; } settings; """ MEM_SIZE = 0x0800 CMD_ACK = "\x06" BLOCK_SIZE = 0x08 POWER_LEVELS = ["Low", "High"] LIST_SQL = ["Off"] + ["%s" % x for x in range(1, 10)] LIST_TOT = ["Off"] + ["%s" % x for x in range(10, 100, 10)] ONOFF = ["Off", "On"] STEPF = ["5", "10", "6.25", "12.5", "25"] ACTIVE_CH = ["%s" % x for x in range(1, 100)] KEY_LOCK = ["Automatic", "Manual"] BW = ["Narrow", "Wide"] W_MODE = ["VFO", "Memory"] VSHIFT = ["None", "-", "+"] POWER_RANK = ["%s" % x for x in range(0, 28)] ANI = ["Off", "BOT", "EOT", "Both"] def raw_recv(radio, amount): """Raw read from the radio device""" data = "" try: data = radio.pipe.read(amount) except: raise errors.RadioError("Error reading data from radio") return data def raw_send(radio, data): """Raw write to the radio device""" try: data = radio.pipe.write(data) except: raise errors.RadioError("Error writing data to radio") def make_frame(cmd, addr, length=BLOCK_SIZE): """Pack the info in the format it likes""" return struct.pack(">BHB", ord(cmd), addr, length) def check_ack(r, text): """Check for a correct ACK from radio, raising error 'Text' if something was wrong""" ack = raw_recv(r, 1) if ack != CMD_ACK: raise errors.RadioError(text) else: return True def send(radio, frame, data=""): """Generic send data to the radio""" raw_send(radio, frame) if data != "": raw_send(radio, data) check_ack(radio, "Radio didn't ack the last block of data") def recv(radio): """Generic receive data from the radio, return just data""" # you must get it all 12 at once (4 header + 8 data) rxdata = raw_recv(radio, 12) if (len(rxdata) != 12): raise errors.RadioError( "Radio sent %i bytes, we expected 12" % (len(rxdata))) else: data = rxdata[4:] send(radio, CMD_ACK) check_ack(radio, "Radio didn't ack the sended data") return data def do_magic(radio): """Try to get the radio in program mode, the factory software (FDX-288) tries up to ~16 times to get the correct response, we will do the same, but with a lower count.""" tries = 8 # UI information status = chirp_common.Status() status.cur = 0 status.max = tries status.msg = "Linking to radio, please wait." radio.status_fn(status) # every byte of this magic chain must be send separately magic = "\x02PROGRA" # start the fun, finger crossed please... for a in range(0, tries): # UI update status.cur = a radio.status_fn(status) for i in range(0, len(magic)): send(radio, magic[i]) # Now you get a x06 of ACK ack = raw_recv(radio, 1) if ack == CMD_ACK: return True return False def do_program(radio): """Feidaxin program mode and identification dance""" # try to get the radio in program mode ack = do_magic(radio) if not ack: erc = "Radio did not accept program mode, " erc += "check your cable and radio; then try again." raise errors.RadioError(erc) # now we request identification send(radio, "M") send(radio, "\x02") ident = raw_recv(radio, 8) # ################ WARNING ########################################## # Feidaxin radios has a "send id" procedure in the initial handshake # but it's worthless, once you do a hardware reset the ident area # get all 0xFF. # # Even FDX-288 software appears to match the model by any other # mean, so I detected on a few images that the 3 first bytes are # unique to each radio model, so for now we use that method until # proven otherwise # ################################################################### LOG.debug("Radio's ID string:") LOG.debug(util.hexprint(ident)) # final ACK send(radio, CMD_ACK) check_ack(radio, "Radio refused to enter programming mode") def do_download(radio): """ The download function """ do_program(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data = "" for addr in range(0x0000, MEM_SIZE, BLOCK_SIZE): send(radio, make_frame("R", addr)) d = recv(radio) data += d # UI Update status.cur = addr radio.status_fn(status) return memmap.MemoryMap(data) def do_upload(radio): """The upload function""" do_program(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) for addr in range(0x0000, MEM_SIZE, BLOCK_SIZE): send(radio, make_frame("W", addr), radio.get_mmap()[addr:addr+BLOCK_SIZE]) # UI Update status.cur = addr radio.status_fn(status) def model_match(cls, data): """Use a experimental guess to determine if the radio you just downloaded or the img opened you is for this model""" # Using a few imgs of some FD radio I found that the four first # bytes it's like the model fingerprint, so we have to testing the # model type with this experimental method so far. fp = data[0:4] return fp == cls._IDENT class FeidaxinFD2x8yRadio(chirp_common.CloneModeRadio): """Feidaxin FD-268 & alike Radios""" VENDOR = "Feidaxin" MODEL = "FD-268 & alike Radios" BAUD_RATE = 9600 _memsize = MEM_SIZE _upper = 99 _VFO_DEFAULT = 0 _IDENT = b"" _active_ch = ACTIVE_CH @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('The program mode of this radio has his tricks, ' 'so this driver is *completely experimental*.') rp.pre_download = _( "This radio has a tricky way of enter into program mode,\n" "even the original software has a few tries to get inside.\n" "I will try 8 times (most of the time ~3 will doit) and this\n" "can take a few seconds, if don't work, try again a few times.\n" "If you can get into it, please check the radio and cable.\n") rp.pre_upload = _( "This radio has a tricky way of enter into program mode,\n" "even the original software has a few tries to get inside.\n" "I will try 8 times (most of the time ~3 will doit) and this\n" "can take a few seconds, if don't work, try again a few times.\n" "If you can get into it, please check the radio and cable.\n") return rp def get_features(self): """Return information about this radio's features""" rf = chirp_common.RadioFeatures() # this feature is READ ONLY by now. rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.has_name = False rf.has_offset = True rf.has_mode = False rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_duplexes = ["", "-", "+", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] # we have to remove "Tone->" because this is the same to "TQSL" # I get a few days hitting the wall with my head about this... rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] # Power levels are global and no per channel, so disabled # rf.valid_power_levels = POWER_LEVELS # this radio has no skips rf.valid_skips = [] # this radio modes are global and not per channel, so just FM rf.valid_modes = ["FM"] rf.valid_bands = [self._range] rf.memory_bounds = (1, self._upper) return rf def sync_in(self): """Do a download of the radio eeprom""" data = do_download(self) # as the radio comm protocol's identification is useless # we test the model after having the img if not model_match(self, data): # ok, wrong model, fire an error erc = "EEPROM fingerprint don't match, check if you " erc += "selected the right radio model." raise errors.RadioError(erc) # all ok self._mmap = data self.process_mmap() def sync_out(self): """Do an upload to the radio eeprom""" do_upload(self) def process_mmap(self): """Process the memory object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): """Return a raw representation of the memory object""" return repr(self._memobj.memory[number]) def _decode_tone(self, val): """Parse the tone data to decode from mem, it returns""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def _encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_memory(self, number): """Extract a high-level memory object from the low-level memory map, This is called to populate a memory in the UI""" # Get a low-level memory object mapped to the image _mem = self._memobj.memory[number - 1] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # number mem.number = number # empty if _mem.get_raw(asbytes=False)[0] == "\xFF": mem.empty = True return mem # rx freq mem.freq = int(_mem.rx_freq) * 10 # checking if tx freq is empty, this is "possible" on the # original soft after a warning, and radio is happy with it if _mem.tx_freq.get_raw(asbytes=False) == "\xFF\xFF\xFF\xFF": mem.duplex = "off" mem.offset = 0 else: rx = int(_mem.rx_freq) * 10 tx = int(_mem.tx_freq) * 10 if tx == rx: mem.offset = 0 mem.duplex = "" else: mem.duplex = rx > tx and "-" or "+" mem.offset = abs(tx - rx) # tone data txtone = self._decode_tone(_mem.tx_tone) rxtone = self._decode_tone(_mem.rx_tone) chirp_common.split_tone_decode(mem, txtone, rxtone) # Extra setting group, FD-268 don't uset it at all # FD-288's & others do it? mem.extra = RadioSettingGroup("extra", "Extra") busy = RadioSetting("busy_lock", "Busy Channel Lockout", RadioSettingValueBoolean( bool(_mem.busy_lock))) mem.extra.append(busy) scramble = RadioSetting("scrambler", "Scrambler Option", RadioSettingValueBoolean( bool(_mem.scrambler))) mem.extra.append(scramble) # return mem return mem def set_memory(self, mem): """Store details about a high-level memory to the memory map This is called when a user edits a memory in the UI""" # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] # Empty memory if mem.empty: _mem.set_raw("\xFF" * 16) return # freq rx _mem.rx_freq = mem.freq / 10 # freq tx if mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 elif mem.duplex == "off": for i in range(0, 4): _mem.tx_freq[i].set_raw("\xFF") else: _mem.tx_freq = mem.freq / 10 # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.tx_tone, txmode, txtone, txpol) self._encode_tone(_mem.rx_tone, rxmode, rxtone, rxpol) # extra settings for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) return mem def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic") work = RadioSettingGroup("work", "Work Mode Settings") top = RadioSettings(basic, work) # Basic sql = RadioSetting("settings.sql", "Squelch Level", RadioSettingValueList(LIST_SQL, LIST_SQL[ _mem.settings.sql])) basic.append(sql) tot = RadioSetting("settings.tot", "Time out timer", RadioSettingValueList(LIST_TOT, LIST_TOT[ _mem.settings.tot])) basic.append(tot) key_lock = RadioSetting("settings.key", "Keyboard Lock", RadioSettingValueList(KEY_LOCK, KEY_LOCK[ _mem.settings.key])) basic.append(key_lock) bw = RadioSetting("settings.bw", "Bandwidth", RadioSettingValueList(BW, BW[_mem.settings.bw])) basic.append(bw) powerrank = RadioSetting("settings.powerrank", "Power output adjust", RadioSettingValueList(POWER_RANK, POWER_RANK[ _mem.settings.powerrank])) basic.append(powerrank) lamp = RadioSetting("settings.lamp", "LCD Lamp", RadioSettingValueBoolean(_mem.settings.lamp)) basic.append(lamp) lamp_auto = RadioSetting("settings.lamp_auto", "LCD Lamp auto on/off", RadioSettingValueBoolean( _mem.settings.lamp_auto)) basic.append(lamp_auto) bs = RadioSetting("settings.bs", "Battery Save", RadioSettingValueBoolean(_mem.settings.bs)) basic.append(bs) warning = RadioSetting("settings.warning", "Warning Alerts", RadioSettingValueBoolean(_mem.settings.warning)) basic.append(warning) monitor = RadioSetting("settings.monitor", "Monitor key", RadioSettingValueBoolean(_mem.settings.monitor)) basic.append(monitor) # Work mode settings wmset = RadioSetting("settings.wmem", "VFO/MR Mode", RadioSettingValueList( W_MODE, W_MODE[_mem.settings.wmem])) work.append(wmset) power = RadioSetting("settings.power", "Actual Power", RadioSettingValueList(POWER_LEVELS, POWER_LEVELS[ _mem.settings.power])) work.append(power) active_ch = RadioSetting("settings.active_ch", "Work Channel", RadioSettingValueList(ACTIVE_CH, ACTIVE_CH[ _mem.settings.active_ch])) work.append(active_ch) # vfo rx validation if _mem.vfo.vrx_freq.get_raw(asbytes=False)[0] == "\xFF": # if the vfo is not set, the UI cares about the # length of the field, so set a default LOG.debug("Setting VFO to default %s" % self._VFO_DEFAULT) vfo = self._VFO_DEFAULT else: vfo = int(_mem.vfo.vrx_freq) * 10 # frequency apply_callback def apply_freq(setting, obj): """Setting is the UI returned value, obj is the memmap object""" value = chirp_common.parse_freq(str(setting.value)) obj.set_value(value / 10) # preparing for callback on vrxfreq (handled also in a special ) vf_freq = RadioSetting("none.vrx_freq", "VFO frequency", RadioSettingValueString(0, 10, chirp_common. format_freq(vfo))) vf_freq.set_apply_callback(apply_freq, _mem.vfo.vrx_freq) work.append(vf_freq) # shift works # VSHIFT = ["None", "-", "+"] sset = 0 if bool(_mem.vfo.shift_minus) is True: sset = 1 elif bool(_mem.vfo.shift_plus) is True: sset = 2 shift = RadioSetting("none.shift", "VFO Shift", RadioSettingValueList(VSHIFT, VSHIFT[sset])) work.append(shift) # vfo shift validation if none set it to ZERO if _mem.settings.vfo_shift.get_raw(asbytes=False)[0] == "\xFF": # if the shift is not set, the UI cares about the # length of the field, so set to zero LOG.debug("VFO shift not set, setting it to zero") vfo_shift = 0 else: vfo_shift = int(_mem.settings.vfo_shift) * 10 offset = RadioSetting("none.vfo_shift", "VFO Offset", RadioSettingValueString(0, 9, chirp_common. format_freq(vfo_shift))) work.append(offset) step = RadioSetting("settings", "VFO step", RadioSettingValueList(STEPF, STEPF[ _mem.settings.step])) work.append(step) # FD-288 Family ANI settings if "FD-288" in self.MODEL: ani_mode = RadioSetting("ani_mode", "ANI ID", RadioSettingValueList(ANI, ANI[ _mem.settings.ani_mode])) work.append(ani_mode) # it can't be \xFF ani_value = str(_mem.settings.ani) if ani_value == "\xFF\xFF\xFF": ani_value = "200" ani_value = "".join(x for x in ani_value if (int(x) >= 2 and int(x) <= 9)) ani = RadioSetting("ani", "ANI (200-999)", RadioSettingValueString(0, 3, ani_value)) work.append(ani) return top def set_settings(self, settings): """Set settings in the Chirp way.""" # special case: shift handling def handle_shift(_vfo, settings): """_vfo is mmap obj for vfo, settings is for all UI settings""" # reset the shift in the memmap _vfo.shift_minus = 0 _vfo.shift_plus = 0 # parse and set if needed rx = chirp_common.parse_freq( str(settings["none.vrx_freq"]).split(":")[1]) offset = chirp_common.parse_freq( str(settings["none.vfo_shift"]).split(":")[1]) shift = str(settings["none.shift"]).split(":")[1] if shift == "None" or shift == "": # no shift _vfo.vtx_freq = rx / 10 if shift == "-": # minus shift _vfo.vtx_freq = (rx - offset) / 10 if shift == "+": # plus shift _vfo.vtx_freq = (rx + offset) / 10 # special case: narrow/wide at radio level and display icon def handle_width(_settings, settings): """_settings is mmap obj for settings, settings is all the UI settings""" value = str(settings["settings.bw"]).split(":")[1] # set bw in settings if value == "Wide": _settings.bw.set_value(1) _settings.bw1.set_value(0) else: _settings.bw.set_value(0) _settings.bw1.set_value(1) # special case: battery save and display icon def handle_bsave(_settings, settings): """_settings is mmap obj for settings, settings is all the UI settings""" value = str(settings["settings.bs"]).split(":")[1] # set bs in settings if value == "True": _settings.bs.set_value(1) _settings.bs1.set_value(0) else: _settings.bs.set_value(0) _settings.bs1.set_value(1) # special case: warning tones and display icon def handle_warning(_settings, settings): """_settings is mmap obj for settings, settings is all the UI settings""" value = str(settings["settings.warning"]).split(":")[1] # set warning in settings if value == "True": _settings.warning.set_value(1) _settings.warning1.set_value(0) else: _settings.warning.set_value(0) _settings.warning1.set_value(1) _mem = self._memobj for element in settings: name = element.get_name() if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue sett, name = name.split(".") try: # special cases if name in ["vrx_freq", "vfo_shift", "shift"]: # call local callback print("Calling local callback for shift handling") handle_shift(self._memobj.vfo, settings) continue if name == "bw": # call local callback print("Calling local callback for bw handling") handle_width(self._memobj.settings, settings) continue if name == "bs": # call local callback print("Calling local callback for bs handling") handle_bsave(self._memobj.settings, settings) continue if name == "warning": # call local callback print("Calling local callback for warning handling") handle_warning(self._memobj.settings, settings) continue if element.has_apply_callback(): try: element.run_apply_callback() continue except NotImplementedError: raise elif sett == "none": LOG.debug("Setting %sett.%s is ignored" % (sett, name)) continue elif element.value.get_mutable(): # value is mutable, find it on the mem space LOG.debug("Setting %s.%s = %s" % (sett, name, str( element.value))) # process it try: obj = getattr(_mem, sett) setattr(obj, name, element.value) except AttributeError: m = "Setting %s is not in this setting block" % name LOG.debug(m) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == MEM_SIZE: match_size = True # testing the firmware fingerprint, this experimental match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False # ##########################################################################3 # FD-268 family: this are the original tested models, FD-268B UHF # was tested "remotely" with images thanks to AG5M # I just have the 268A in hand to test @directory.register class FD268ARadio(FeidaxinFD2x8yRadio): """Feidaxin FD-268A Radio""" MODEL = "FD-268A" _range = (136000000, 174000000) _VFO_DEFAULT = 145000000 _IDENT = b"\xFF\xEE\x46\xFF" @directory.register class FD268BRadio(FeidaxinFD2x8yRadio): """Feidaxin FD-268B Radio""" MODEL = "FD-268B" _range = (400000000, 470000000) _VFO_DEFAULT = 439000000 _IDENT = b"\xFF\xEE\x47\xFF" # ##################################################################### # FD-288 Family: the only difference from this family to the FD-268's # are the ANI settings # Tested hacking the FD-268A memory @directory.register class FD288ARadio(FeidaxinFD2x8yRadio): """Feidaxin FD-288A Radio""" MODEL = "FD-288A" _range = (136000000, 174000000) _VFO_DEFAULT = 145000000 _IDENT = b"\xFF\xEE\x4B\xFF" @directory.register class FD288BRadio(FeidaxinFD2x8yRadio): """Feidaxin FD-288B Radio""" MODEL = "FD-288B" _range = (400000000, 470000000) _VFO_DEFAULT = 439000000 _IDENT = b"\xFF\xEE\x4C\xFF" # ##################################################################### # The following radios was tested hacking the FD-268A memory with # the software and found to be clones of FD-268 ones # please report any problems to driver author (see head of this file) @directory.register class FD150ARadio(FeidaxinFD2x8yRadio): """Feidaxin FD-150A Radio""" MODEL = "FD-150A" _range = (136000000, 174000000) _VFO_DEFAULT = 145000000 _IDENT = b"\xFF\xEE\x45\xFF" @directory.register class FD160ARadio(FeidaxinFD2x8yRadio): """Feidaxin FD-160A Radio""" MODEL = "FD-160A" _range = (136000000, 174000000) _VFO_DEFAULT = 145000000 _IDENT = b"\xFF\xEE\x48\xFF" @directory.register class FD450ARadio(FeidaxinFD2x8yRadio): """Feidaxin FD-450A Radio""" MODEL = "FD-450A" _range = (400000000, 470000000) _VFO_DEFAULT = 439000000 _IDENT = b"\xFF\xEE\x44\xFF" @directory.register class FD460ARadio(FeidaxinFD2x8yRadio): """Feidaxin FD-460A Radio""" MODEL = "FD-460A" _range = (400000000, 470000000) _VFO_DEFAULT = 439000000 _IDENT = b"\xFF\xEE\x4A\xFF" @directory.register class FD460UHRadio(FeidaxinFD2x8yRadio): """Feidaxin FD-460UH Radio""" MODEL = "FD-460UH" _range = (400000000, 480000000) _VFO_DEFAULT = 439000000 _IDENT = b"\xFF\xF4\x44\xFF" chirp-20240224/chirp/drivers/ftm7250d.py0000644000175000017500000001512114443346220016443 0ustar hibbyhibby# Copyright 2010 Dan Smith # Copyright 2017 Wade Simmons # FTM-7250D driver cloned from the FTM-3200 and modified by Iain White # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import yaesu_clone, ft1d from chirp import chirp_common, directory, bitwise from chirp.settings import RadioSettings LOG = logging.getLogger(__name__) POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=25), chirp_common.PowerLevel("Hi", watts=50)] TMODES = ["", "Tone", "TSQL", "DTCS", "TSQL-R", None, None, "Pager", "Cross"] CROSS_MODES = [None, "DTCS->", "Tone->DTCS", "DTCS->Tone"] MODES = ["FM", "NFM"] STEPS = [0, 5, 6.25, 10, 12.5, 15, 20, 25, 50, 100] # 0 = auto RFSQUELCH = ["OFF", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8"] # Charset is subset of ASCII + some unknown chars \x80-\x86 VALID_CHARS = ["%i" % int(x) for x in range(0, 10)] + \ list(":>=After clicking OK, press the [GM(AMS)] key\n" " to send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to MIC Jack.\n" "3. Press and hold in the [MHz(SETUP)] key while turning the" " radio\n" " on (\"CLONE\" will appear on the display).\n" "4. Press the [MHz(SETUP)] key\n" " (\"-WAIT-\" will appear on the LCD).\n") return rp def process_mmap(self): mem_format = ft1d.MEM_FORMAT + MEM_FORMAT self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.valid_modes = list(MODES) rf.valid_tmodes = [x for x in TMODES if x is not None] rf.valid_cross_modes = [x for x in CROSS_MODES if x is not None] rf.valid_duplexes = list(ft1d.DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(108000000, 580000000)] # rf.valid_skips = SKIPS rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(VALID_CHARS) rf.valid_name_length = 8 rf.memory_bounds = (1, 199) rf.can_odd_split = True rf.has_ctone = False rf.has_bank = False rf.has_bank_names = False # disable until implemented rf.has_settings = False return rf def _decode_label(self, mem): # TODO preserve the unknown \x80-x86 chars? return str(mem.label).rstrip("\xFF") def _encode_label(self, mem): label = mem.name.rstrip().encode('ascii', 'ignore') return self._add_ff_pad(label, 16) def _encode_charsetbits(self, mem): # TODO this is a setting to decide if the memory should be displayed # as a name or frequency. Should we expose this setting to the user # instead of autoselecting it (and losing their preference)? if mem.name.rstrip() == '': return 0x00 return 0x00 def _decode_power_level(self, mem): return POWER_LEVELS[mem.power - 1] def _encode_power_level(self, mem): if mem.power is None: return 3 else: return 3 - POWER_LEVELS.index(mem.power) def _decode_mode(self, mem): return MODES[mem.mode_alt] def _encode_mode(self, mem): return MODES.index(mem.mode) def _get_tmode(self, mem, _mem): if _mem.tone_mode > 8: tmode = "Cross" mem.cross_mode = CROSS_MODES[_mem.tone_mode - 8] else: tmode = TMODES[_mem.tone_mode] if tmode == "Pager": # TODO chirp_common does not allow 'Pager' # Expose as a different setting? mem.tmode = "" else: mem.tmode = tmode def _set_tmode(self, _mem, mem): if mem.tmode == "Cross": _mem.tone_mode = 8 + CROSS_MODES.index(mem.cross_mode) else: _mem.tone_mode = TMODES.index(mem.tmode) def _set_mode(self, _mem, mem): _mem.mode_alt = self._encode_mode(mem) def get_bank_model(self): return None def _debank(self, mem): return def _checksums(self): return [yaesu_clone.YaesuChecksum(0x064A, 0x06C8), yaesu_clone.YaesuChecksum(0x06CA, 0x0748), yaesu_clone.YaesuChecksum(0x074A, 0x07C8), yaesu_clone.YaesuChecksum(0x07CA, 0x0848), yaesu_clone.YaesuChecksum(0x0000, 0xFEC9)] def _get_settings(self): # TODO top = RadioSettings() return top @classmethod def _wipe_memory(cls, mem): mem.set_raw("\x00" * (mem.size() // 8)) def sync_out(self): # Need to give enough time for the radio to ACK after writes self.pipe.timeout = 1 return super(FTM7250Radio, self).sync_out() chirp-20240224/chirp/drivers/baofeng_uv17.py0000644000175000017500000003373414566340166017501 0ustar hibbyhibby# Copyright 2023: # * Sander van der Wel, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import chirp_common, directory from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettings, RadioSettingValueString import struct from chirp.drivers import baofeng_common, baofeng_uv17Pro from chirp import errors, util LOG = logging.getLogger(__name__) LIST_DTMFST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SCANMODE = ["Time", "Carrier", "Search"] # Radios seem to have different memory sizes def _get_memory_size(radio): response = baofeng_uv17Pro._sendmagic(radio, radio._magic_memsize[0][0], radio._magic_memsize[0][1]) mem_size = struct.unpack("> 4 & 0xf) * 10 + (blocknr & 0xf) memory_map += [blocknr] baofeng_uv17Pro._sendmagic(radio, b"\x06", 1) return memory_map def _download(radio): """Get the memory map""" baofeng_uv17Pro._do_ident(radio) data = b"" memory_map = _get_memory_map(radio) status = chirp_common.Status() status.cur = 0 status.max = radio.MEM_TOTAL // radio.BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) for block_number in radio.BLOCK_ORDER: if block_number not in memory_map: # Memory block not found. raise errors.RadioError('Radio memory is corrupted. ' + 'Fix this by uploading a backup image ' + 'to the radio.') block_index = memory_map.index(block_number) + 1 start_addr = block_index * 0x1000 for addr in range(start_addr, start_addr + 0x1000, radio.BLOCK_SIZE): frame = radio._make_read_frame(addr, radio.BLOCK_SIZE) # DEBUG LOG.debug("Frame=" + util.hexprint(frame)) baofeng_common._rawsend(radio, frame) d = baofeng_common._rawrecv(radio, radio.BLOCK_SIZE + 5) LOG.debug("Response Data= " + util.hexprint(d)) data += d[5:] status.cur = len(data) // radio.BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) baofeng_uv17Pro._sendmagic(radio, b"\x06", 1) return data def _upload(radio): """Upload procedure""" baofeng_uv17Pro._do_ident(radio) memory_map = _get_memory_map(radio) status = chirp_common.Status() status.cur = 0 status.max = radio.WRITE_MEM_TOTAL // radio.BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) for block_number in radio.BLOCK_ORDER: # Choose a block number if memory map is corrupt # This can happen when the upload process was interrupted if block_number not in memory_map: memory_map[memory_map.index(165)] = block_number block_index = memory_map.index(block_number) + 1 start_addr = block_index * 0x1000 data_start_addr = radio.BLOCK_ORDER.index(block_number) * 0x1000 for addr in range(start_addr, start_addr + 0x1000, radio.BLOCK_SIZE): # sending the data data_addr = data_start_addr + addr - start_addr data = radio.get_mmap()[data_addr:data_addr + radio.BLOCK_SIZE] frame = radio._make_frame(b"W", addr, radio.BLOCK_SIZE, data) baofeng_common._rawsend(radio, frame) # receiving the response ack = baofeng_common._rawrecv(radio, 1) if ack != b"\x06": msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) # UI Update status.cur = (data_addr) // radio.BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) @directory.register class UV17(baofeng_uv17Pro.UV17Pro): """Baofeng UV-17""" VENDOR = "Baofeng" MODEL = "UV-17" NEEDS_COMPAT_SERIAL = False download_function = _download upload_function = _upload MODES = ["FM", "NFM"] BLOCK_ORDER = [16, 17, 18, 19, 24, 25, 26, 4, 6] MEM_TOTAL = 0x9000 WRITE_MEM_TOTAL = 0x9000 BLOCK_SIZE = 0x40 BAUD_RATE = 57600 _magic = b"PSEARCH" _magics = [(b"PASSSTA", 3), (b"SYSINFO", 1), (b"\x56\x00\x00\x0A\x0D", 13), (b"\x06", 1), (b"\x56\x00\x10\x0A\x0D", 13), (b"\x06", 1), (b"\x56\x00\x20\x0A\x0D", 13), (b"\x06", 1)] _magic_memsize = [(b"\x56\x00\x00\x00\x0A", 11)] _radio_memsize = 0xffff _magics2 = [(b"\x06", 1), (b"\xFF\xFF\xFF\xFF\x0C\x55\x56\x31\x35\x39\x39\x39", 1), (b"\02", 8), (b"\x06", 1)] _fingerprint = b"\x06" + b"UV15999" _scode_offset = 1 _tri_band = False POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("High", watts=5.00)] LENGTH_NAME = 11 VALID_BANDS = [baofeng_uv17Pro.UV17Pro._vhf_range, baofeng_uv17Pro.UV17Pro._uhf_range] SCODE_LIST = ["%s" % x for x in range(1, 16)] SQUELCH_LIST = ["Off"] + list("123456789") LIST_POWERON_DISPLAY_TYPE = ["Full", "Message", "Voltage"] LIST_TIMEOUT = ["Off"] + ["%s sec" % x for x in range(15, 615, 15)] LIST_VOICE = ["Chinese", "English"] LIST_BACKLIGHT_TIMER = ["Always On"] + ["%s sec" % x for x in range(1, 11)] LIST_MODE = ["Name", "Frequency"] CHANNELS = 999 MEM_FORMAT = """ #seekto 0x0030; struct channel { lbcd rxfreq[4]; lbcd txfreq[4]; u8 unused1; ul16 rxtone; ul16 txtone; u8 unknown1:1, bcl:1, pttid:2, unknown2:1, wide:1, lowpower:1, unknown:1; u8 scode:4, unknown3:3, scan:1; u8 unknown4; }; struct { struct channel mem[252]; } mem1; #seek 0x10; struct { struct channel mem[255]; } mem2; #seek 0x10; struct { struct channel mem[255]; } mem3; #seek 0x10; struct { struct channel mem[237]; } mem4; #seekto 0x7000; struct { u8 powerondistype; u8 unknown0[15]; char boottext1[10]; u8 unknown1[6]; char boottext2[10]; u8 unknown2[22]; u8 tot; u8 squelch; u8 vox; u8 powersave: 4, unknown3:2, voice: 1, voicesw: 1; u8 backlight; u8 beep:1, autolock:1, unknown4:1, tail:1, scanmode:2, dtmfst:2; u8 unknown5:1, dualstandby:1, roger:1, unknown6:3, fmenable:1, unknown7:1; u8 unknown8[9]; u8 unknown9:6, chbdistype:1, chadistype:1; } settings; struct vfo { lbcd rxfreq[4]; lbcd txfreq[4]; u8 unused1; ul16 rxtone; ul16 txtone; u8 unknown1:1, bcl:1, pttid:2, unknown2:1, wide:1, lowpower:1, unknown:1; u8 scode:4, unknown3:3, scan:1; u8 unknown4; }; #seekto 0x0010; struct { struct vfo a; struct vfo b; } vfo; #seekto 0x4000; struct { char name[11]; } names[999]; #seekto 0x8000; struct { u8 code[5]; } pttid[15]; struct { u8 unknown[5]; u8 code[5]; } ani; """ def _make_frame(self, cmd, addr, length, data=""): """Pack the info in the header format""" frame = struct.pack("B", length) # add the data if set if len(data) != 0: frame += data # return the data return frame def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") top = RadioSettings(basic, dtmfe) self.get_settings_common_basic(basic, _mem) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered rs = RadioSetting("settings.boottext1", "Power-On Message 1", RadioSettingValueString( 0, 10, _filter(self._memobj.settings.boottext1))) basic.append(rs) rs = RadioSetting("settings.boottext2", "Power-On Message 2", RadioSettingValueString( 0, 10, _filter(self._memobj.settings.boottext2))) basic.append(rs) if _mem.settings.powersave > 0x04: val = 0x00 else: val = _mem.settings.powersave rs = RadioSetting("settings.powersave", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) rs = RadioSetting("settings.scanmode", "Scan Mode", RadioSettingValueList( LIST_SCANMODE, LIST_SCANMODE[_mem.settings.scanmode])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) rs = RadioSetting("settings.fmenable", "Enable FM radio", RadioSettingValueBoolean(_mem.settings.fmenable)) basic.append(rs) self.get_settings_common_dtmf(dtmfe, _mem) return top def decode_tone(self, val): pol = "N" mode = "" if val in [0, 0xFFFF]: xval = 0 elif (val & 0x8000) > 0: mode = "DTCS" xval = (val & 0x0f) + (val >> 4 & 0xf)\ * 10 + (val >> 8 & 0xf) * 100 if (val & 0xC000) == 0xC000: pol = "R" else: mode = "Tone" xval = int((val & 0x0f) + (val >> 4 & 0xf) * 10 + (val >> 8 & 0xf) * 100 + (val >> 12 & 0xf) * 1000) / 10.0 return mode, xval, pol def get_raw_memory(self, number): # The flash memory contains page_numbers # This is probably to do wear leveling on the memory # These numbers are needed, but make the channel memory # not continuous. number = number - 1 if number >= 762: _mem = self._memobj.mem4.mem[number - 762] return _mem if number >= 507: _mem = self._memobj.mem3.mem[number - 507] return _mem if number >= 252: _mem = self._memobj.mem2.mem[number - 252] return _mem _mem = self._memobj.mem1.mem[number] return _mem def get_memory(self, number): _mem = self.get_raw_memory(number) _nam = self._memobj.names[number - 1] mem = chirp_common.Memory() mem.number = number self.get_memory_common(_mem, _nam.name, mem) return mem def encode_tone(self, memtone, mode, tone, pol): if mode == "Tone": xtone = '%04i' % (tone * 10) memtone.set_value((int(xtone[0]) << 12) + (int(xtone[1]) << 8) + (int(xtone[2]) << 4) + int(xtone[3])) elif mode == "TSQL": xtone = '%04i' % (tone * 10) memtone.set_value((int(tone[0]) << 12) + (int(xtone[1]) << 8) + (int(xtone[2]) << 4) + int(xtone[3])) elif mode == "DTCS": xtone = str(int(tone)).rjust(4, '0') memtone.set_value((0x8000 + (int(xtone[0]) << 12) + (int(xtone[1]) << 8) + (int(xtone[2]) << 4) + int(xtone[3]))) else: memtone.set_value(0) if mode == "DTCS" and pol == "R": memtone.set_value(memtone + 0x4000) def set_memory(self, mem): _mem = self.get_raw_memory(mem.number) _nam = self._memobj.names[mem.number - 1] if mem.empty: _mem.set_raw(b"\xff" * 16) return _mem.set_raw(b"\x00" * 16) _namelength = self.get_features().valid_name_length _nam.name = mem.name.ljust(_namelength, '\x00') self.set_memory_common(mem, _mem) @directory.register class UV13Pro(UV17): VENDOR = "Baofeng" MODEL = "UV-13Pro" _radio_memsize = 0x31fff chirp-20240224/chirp/drivers/kyd.py0000644000175000017500000003701014566340166015774 0ustar hibbyhibby# Copyright 2014 Jim Unroe # Copyright 2014 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rx_tone; ul16 tx_tone; u8 unknown1:3, bcl:2, // Busy Lock unknown2:3; u8 unknown3:2, highpower:1, // Power Level wide:1, // Bandwidth unknown4:4; u8 unknown5[2]; } memory[16]; #seekto 0x012F; struct { u8 voice; // Voice Annunciation u8 tot; // Time-out Timer u8 totalert; // Time-out Timer Pre-alert u8 unknown1[2]; u8 squelch; // Squelch Level u8 save; // Battery Saver u8 beep; // Beep u8 unknown2[3]; u8 vox; // VOX Gain u8 voxdelay; // VOX Delay } settings; #seekto 0x017E; u8 skipflags[2]; // SCAN_ADD """ CMD_ACK = "\x06" NC630A_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("High", watts=5.00)] NC630A_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) BCL_LIST = ["Off", "Carrier", "QT/DQT"] TIMEOUTTIMER_LIST = [""] + ["%s seconds" % x for x in range(15, 615, 15)] TOTALERT_LIST = ["", "Off"] + ["%s seconds" % x for x in range(1, 11)] VOICE_LIST = ["Off", "Chinese", "English"] VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 17)] VOXDELAY_LIST = ["0.3", "0.5", "1.0", "1.5", "2.0", "3.0"] def _nc630a_enter_programming_mode(radio): serial = radio.pipe try: serial.write("PROGRAM") ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if not ack: raise errors.RadioError("No response from radio") elif ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") try: serial.write("\x02") ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") if not ident.startswith(radio._fileid): LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _nc630a_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", 'R', block_addr, block_size) expectedresponse = "W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Failed to read block at %04x" % block_addr) if ack != CMD_ACK: raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _nc630a_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", 'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _nc630a_enter_programming_mode(radio) data = "" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio._block_size): status.cur = addr + radio._block_size radio.status_fn(status) block = _nc630a_read_block(radio, addr, radio._block_size) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) return memmap.MemoryMap(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _nc630a_enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio._block_size): status.cur = addr + radio._block_size radio.status_fn(status) _nc630a_write_block(radio, addr, radio._block_size) class MT700Alias(chirp_common.Alias): VENDOR = "Plant-Tours" MODEL = "MT-700" @directory.register class NC630aRadio(chirp_common.CloneModeRadio): """KYD NC-630A""" VENDOR = "KYD" MODEL = "NC-630A" ALIASES = [MT700Alias] BAUD_RATE = 9600 _ranges = [ (0x0000, 0x0330), ] _memsize = 0x03C8 _block_size = 0x08 _fileid = b"P32073" def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = NC630A_POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["NFM", "FM"] # 12.5 kHz, 25 kHz. rf.memory_bounds = (1, 16) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] rf.valid_bands = [(400000000, 520000000)] rf.valid_dtcs_codes = NC630A_DTCS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): self._mmap = do_download(self) self.process_mmap() def sync_out(self): do_upload(self) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2800: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" elif _mem.tx_tone != 0xFFFF: mem.rtone = _mem.tx_tone / 10.0 txmode = "Tone" else: txmode = "" if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2800: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rx_tone != 0xFFFF: mem.ctone = _mem.rx_tone / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) if mem.tmode == "DTCS": mem.dtcs_polarity = "%s%s" % (tpol, rpol) LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.tx_tone, rxmode, _mem.rx_tone)) def get_memory(self, number): bitpos = (1 << ((number - 1) % 8)) bytepos = ((number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) _mem = self._memobj.memory[number - 1] _skp = self._memobj.skipflags[bytepos] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = _mem.wide and "FM" or "NFM" self._get_tone(_mem, mem) mem.power = NC630A_POWER_LEVELS[_mem.highpower] mem.skip = "" if (_skp & bitpos) else "S" LOG.debug("mem.skip %s" % mem.skip) mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueList( BCL_LIST, BCL_LIST[_mem.bcl])) mem.extra.append(rs) return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0x8000 return val rx_mode = tx_mode = None rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None tx_tone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = int(mem.rtone * 10) if rx_mode == "DTCS": rx_tone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = int(mem.ctone * 10) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.tx_tone, rx_mode, _mem.rx_tone)) def set_memory(self, mem): bitpos = (1 << ((mem.number - 1) % 8)) bytepos = ((mem.number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) _mem = self._memobj.memory[mem.number - 1] _skp = self._memobj.skipflags[bytepos] if mem.empty: _mem.fill_raw(b"\xFF") return _mem.set_raw(b"\x00" * 14 + b"\xFF" * 2) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq.fill_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.wide = mem.mode == "FM" self._set_tone(mem, _mem) _mem.highpower = mem.power == NC630A_POWER_LEVELS[1] if mem.skip != "S": _skp |= bitpos else: _skp &= ~bitpos LOG.debug("_skp %s" % _skp) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) rs = RadioSetting("tot", "Time-out timer", RadioSettingValueList( TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[_settings.tot])) basic.append(rs) rs = RadioSetting("totalert", "TOT Pre-alert", RadioSettingValueList( TOTALERT_LIST, TOTALERT_LIST[_settings.totalert])) basic.append(rs) rs = RadioSetting("vox", "VOX Gain", RadioSettingValueList( VOX_LIST, VOX_LIST[_settings.vox])) basic.append(rs) rs = RadioSetting("voice", "Voice Annumciation", RadioSettingValueList( VOICE_LIST, VOICE_LIST[_settings.voice])) basic.append(rs) rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("voxdelay", "VOX Delay", RadioSettingValueList( VOXDELAY_LIST, VOXDELAY_LIST[_settings.voxdelay])) basic.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) rs = RadioSetting("save", "Battery Saver", RadioSettingValueBoolean(_settings.save)) basic.append(rs) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = match_model = False # testing the file data size if len(filedata) in [0x338, 0x3C8]: match_size = True # testing model fingerprint if filedata[0x01B8:0x01BE] == cls._fileid: match_model = True if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/ftm350.py0000644000175000017500000003115614533322706016222 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, errors, bitwise, memmap from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings from chirp.settings import RadioSettingValueInteger, RadioSettingValueString LOG = logging.getLogger(__name__) mem_format = """ struct mem { u8 used:1, skip:2, unknown1:4, visible:1; u8 unknown2:1, mode:3, unknown8:1, oddsplit:1, duplex:2; bbcd freq[3]; u8 unknownA:1, tmode:3, unknownB:4; bbcd split[3]; u8 power:2, tone:6; u8 unknownC:1, dtcs:7; u8 showalpha:1, unknown5:7; u8 unknown6; u8 offset; u8 unknown7[2]; }; struct lab { u8 string[8]; }; #seekto 0x0508; struct { char call[6]; u8 ssid; } aprs_my_callsign; #seekto 0x0480; struct mem left_memory_zero; #seekto 0x04A0; struct lab left_label_zero; #seekto 0x04C0; struct mem right_memory_zero; #seekto 0x04E0; struct lab right_label_zero; #seekto 0x0800; struct mem left_memory[500]; #seekto 0x2860; struct mem right_memory[500]; #seekto 0x48C0; struct lab left_label[518]; struct lab right_label[518]; """ _TMODES = ["", "Tone", "TSQL", "-RVT", "DTCS", "-PR", "-PAG"] TMODES = ["", "Tone", "TSQL", "", "DTCS", "", ""] MODES = ["FM", "AM", "NFM", "", "WFM"] DUPLEXES = ["", "", "-", "+", "split", "off"] # TODO: add Japanese characters (viewable in special menu, scroll backwards) CHARSET = \ ('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"' + '#$%&`()*+,-./:;<=>?@[\\]^_`{|}~?????? ' + '?' * 91) POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=50), chirp_common.PowerLevel("Mid", watts=20), chirp_common.PowerLevel("Low", watts=5)] SKIPS = ["", "S", "P"] def aprs_call_to_str(_call): call = "" for i in str(_call): if i == "\xca": break call += i return call def _safe_read(radio, length): data = "" while len(data) < length: data += radio.pipe.read(length - len(data)) return data def _clone_in(radio): data = "" radio.pipe.timeout = 1 attempts = 30 data = memmap.MemoryMapBytes(b"\x00" * (radio._memsize + 128)) length = 0 last_addr = 0 while length < radio._memsize: frame = radio.pipe.read(131) if length and not frame: raise errors.RadioError("Radio not responding") if not frame: attempts -= 1 if attempts <= 0: raise errors.RadioError("Radio not responding") if frame: addr, = struct.unpack(">H", frame[0:2]) checksum = frame[130] block = frame[2:130] cs = 0 for i in frame[:-1]: cs = (cs + i) % 256 if cs != checksum: LOG.debug("Calc: %02x Real: %02x Len: %i" % (cs, checksum, len(block))) raise errors.RadioError("Block failed checksum") radio.pipe.write(b"\x06") time.sleep(0.05) if (last_addr + 128) != addr: LOG.debug("Gap, expecting %04x, got %04x" % (last_addr+128, addr)) last_addr = addr data[addr] = block length += len(block) status = chirp_common.Status() status.cur = length status.max = radio._memsize status.msg = "Cloning from radio" radio.status_fn(status) return data def _clone_out(radio): radio.pipe.timeout = 1 # Seriously, WTF Yaesu? ranges = [ (0x0000, 0x0000), (0x0100, 0x0380), (0x0480, 0xFF80), (0x0080, 0x0080), (0xFFFE, 0xFFFE), ] for start, end in ranges: for i in range(start, end+1, 128): block = radio._mmap[i:i + 128] frame = struct.pack(">H", i) + block cs = 0 for byte in frame: cs += byte frame += bytes([cs % 256]) radio.pipe.write(frame) ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio refused block %i" % (i / 128)) time.sleep(0.05) status = chirp_common.Status() status.cur = i + 128 status.max = radio._memsize status.msg = "Cloning to radio" radio.status_fn(status) def get_freq(rawfreq): """Decode a frequency that may include a fractional step flag""" # Ugh. The 0x80 and 0x40 indicate values to add to get the # real frequency. Gross. if rawfreq > 8000000000: rawfreq = (rawfreq - 8000000000) + 5000 if rawfreq > 4000000000: rawfreq = (rawfreq - 4000000000) + 2500 if rawfreq > 2000000000: rawfreq = (rawfreq - 2000000000) + 1250 return rawfreq def set_freq(freq, obj, field): """Encode a frequency with any necessary fractional step flags""" obj[field] = freq / 10000 frac = freq % 10000 if frac >= 5000: frac -= 5000 obj[field][0].set_bits(0x80) if frac >= 2500: frac -= 2500 obj[field][0].set_bits(0x40) if frac >= 1250: frac -= 1250 obj[field][0].set_bits(0x20) return freq @directory.register class FTM350Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FTM-350""" BAUD_RATE = 48000 VENDOR = "Yaesu" MODEL = "FTM-350" NEEDS_COMPAT_SERIAL = False _model = "" _memsize = 65536 _vfo = "" def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_ctone = False rf.has_settings = self._vfo == "left" rf.has_tuning_step = False rf.has_dtcs_polarity = False rf.has_sub_devices = self.VARIANT == "" rf.valid_skips = [] # FIXME: Finish this rf.valid_tmodes = [""] + [x for x in TMODES if x] rf.valid_modes = [x for x in MODES if x] rf.valid_duplexes = DUPLEXES rf.valid_skips = SKIPS rf.valid_name_length = 8 rf.valid_characters = CHARSET rf.memory_bounds = (0, 500) rf.valid_power_levels = POWER_LEVELS rf.valid_bands = [(500000, 1800000), (76000000, 250000000), (30000000, 1000000000)] rf.can_odd_split = True rf.valid_tuning_steps = [5.0, 6.25, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0, 200.0] return rf def get_sub_devices(self): return [FTM350RadioLeft(self._mmap), FTM350RadioRight(self._mmap)] def sync_in(self): try: self._mmap = _clone_in(self) except errors.RadioError: raise except Exception as e: LOG.exception('Failed to read: %s', e) raise errors.RadioError("Failed to download from radio (%s)" % e) self.process_mmap() def sync_out(self): try: _clone_out(self) except errors.RadioError: raise except Exception as e: LOG.exception('Failed to write: %s', e) raise errors.RadioError("Failed to upload to radio (%s)" % e) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): def identity(o): return o def indexed(o): return o[number - 1] if number == 0: suffix = "_zero" fn = identity else: suffix = "" fn = indexed return (repr(fn(self._memory_obj(suffix))) + repr(fn(self._label_obj(suffix)))) def _memory_obj(self, suffix=""): return getattr(self._memobj, "%s_memory%s" % (self._vfo, suffix)) def _label_obj(self, suffix=""): return getattr(self._memobj, "%s_label%s" % (self._vfo, suffix)) def get_memory(self, number): if number == 0: _mem = self._memory_obj("_zero") _lab = self._label_obj("_zero") else: _mem = self._memory_obj()[number - 1] _lab = self._label_obj()[number - 1] mem = chirp_common.Memory() mem.number = number if not _mem.used: mem.empty = True return mem if _mem.offset == 0xFF: # TX disabled mem.duplex = "off" elif _mem.oddsplit: mem.duplex = "split" mem.offset = get_freq(int(_mem.split) * 10000) else: mem.duplex = DUPLEXES[_mem.duplex] mem.offset = int(_mem.offset) * 50000 mem.freq = get_freq(int(_mem.freq) * 10000) if mem.duplex != "off": mem.rtone = chirp_common.TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.power = POWER_LEVELS[_mem.power] mem.tmode = TMODES[_mem.tmode] mem.mode = MODES[_mem.mode] mem.skip = SKIPS[_mem.skip] for char in _lab.string: if char == 0xCA: break try: mem.name += CHARSET[char] except IndexError: mem.name += "?" mem.name = mem.name.rstrip() return mem def set_memory(self, mem): if mem.number == 0: _mem = self._memory_obj("_zero") _lab = self._label_obj("_zero") else: _mem = self._memory_obj()[mem.number - 1] _lab = self._label_obj()[mem.number - 1] _mem.used = not mem.empty _mem.visible = not mem.empty if mem.empty: return set_freq(mem.freq, _mem, 'freq') _mem.oddsplit = 0 _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEXES.index(mem.duplex) if mem.duplex == "off": _mem.tone = 0x3F _mem.dtcs = 0x7F _mem.offset = 0xFF _mem.power = 0x03 _mem.tmode = 0x00 _mem.duplex = 0x00 elif mem.duplex == "split": set_freq(mem.offset, _mem, 'split') _mem.oddsplit = 1 else: _mem.offset = mem.offset / 50000 _mem.mode = MODES.index(mem.mode) _mem.skip = SKIPS.index(mem.skip) if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 for i in range(0, 8): try: char = CHARSET.index(mem.name[i]) except IndexError: char = 0xCA _lab.string[i] = char _mem.showalpha = mem.name.strip() != "" @classmethod def match_model(self, filedata, filename): return filedata.startswith(b"AH033$") def get_settings(self): top = RadioSettings() aprs = RadioSettingGroup("aprs", "APRS") top.append(aprs) myc = self._memobj.aprs_my_callsign rs = RadioSetting("aprs_my_callsign.call", "APRS My Callsign", RadioSettingValueString(0, 6, aprs_call_to_str(myc.call))) aprs.append(rs) rs = RadioSetting("aprs_my_callsign.ssid", "APRS My SSID", RadioSettingValueInteger(0, 15, myc.ssid)) aprs.append(rs) return top def set_settings(self, settings): for setting in settings: if not isinstance(setting, RadioSetting): self.set_settings(setting) continue # Quick hack to make these work if setting.get_name() == "aprs_my_callsign.call": self._memobj.aprs_my_callsign.call = \ setting.value.get_value().upper().replace(" ", "\xCA") elif setting.get_name() == "aprs_my_callsign.ssid": self._memobj.aprs_my_callsign.ssid = setting.value class FTM350RadioLeft(FTM350Radio): VARIANT = "Left" _vfo = "left" class FTM350RadioRight(FTM350Radio): VARIANT = "Right" _vfo = "right" chirp-20240224/chirp/drivers/lt725uv.py0000644000175000017500000015750714522657251016451 0ustar hibbyhibby# Copyright 2016-2023: # * Jim Unroe KC9HI, # Modified for Baojie BJ-218: 2018 # Rick DeWitt (RJD), # Modified for Baojie BJ-318: April 2021 # Mark Hartong, AJ4YI # Modified for Baojie BJ-318: January 2023 # Mark Hartong, AJ4YI # 1. Removed Experimental Warning # 2. Added Brown & Yellow as Color Selections # 3. Max VFO Volume Setting to 15 ( vice 10) # Modified UHF band limits: February 2023 # Jim Unroe, KC9HI # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings, InvalidValueError LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0200; struct { u8 init_bank; // determines which VFO is primary A or B u8 volume; // not used BJ-318, band volume is controlled vfo u8 bvol u16 fm_freq; // not used BJ-318, freq is controlled hello_lims u16 fm_318 u8 wtled; // not used BJ-318 u8 rxled; // not used BJ-318 u8 txled; // not used BJ-318 u8 ledsw; u8 beep; u8 ring; u8 bcl; u8 tot; u16 sig_freq; u16 dtmf_txms; u8 init_sql; // not used BJ-318, band squelch is controlled vfo u8 sql u8 rptr_mode; } settings; #seekto 0x0240; struct { u8 dtmf1_cnt; u8 dtmf1[7]; u8 dtmf2_cnt; u8 dtmf2[7]; u8 dtmf3_cnt; u8 dtmf3[7]; u8 dtmf4_cnt; u8 dtmf4[7]; u8 dtmf5_cnt; u8 dtmf5[7]; u8 dtmf6_cnt; u8 dtmf6[7]; u8 dtmf7_cnt; u8 dtmf7[7]; u8 dtmf8_cnt; u8 dtmf8[7]; } dtmf_tab; #seekto 0x0280; struct { u8 native_id_cnt; u8 native_id_code[7]; u8 master_id_cnt; u8 master_id_code[7]; u8 alarm_cnt; u8 alarm_code[5]; u8 id_disp_cnt; u8 id_disp_code[5]; u8 revive_cnt; u8 revive_code[5]; u8 stun_cnt; u8 stun_code[5]; u8 kill_cnt; u8 kill_code[5]; u8 monitor_cnt; u8 monitor_code[5]; u8 state_now; } codes; #seekto 0x02d0; struct { u8 hello1_cnt; // not used in BJ-318, is set in memory map char hello1[7]; // not used in BJ-318, is set in memory map u8 hello2_cnt; // not used in BJ-318, is set in memory map char hello2[7]; // not used in BJ-318, is set in memory map u32 vhf_low; u32 vhf_high; u32 uhf_low; u32 uhf_high; u8 lims_on; // first byte @ at address 0x02f0; u8 unknown_1; // use in BJ-318 unknown u8 lang; // BJ-318 Display language // 02 = English 00 and 01 are Asian u8 up_scr_color; // BJ-318 upper screen character color u8 dn_scr_color; // BJ-318 lower screen character color // purple=00, red=01, emerald=02, blue=03, // sky_blue=04, black=05, brown=06, yellow=07 required // hex values for color // Note sky_blue and black look the same on the // BJ-318 screen u16 fm_318; // FM stored Frequency in BJ-318 } hello_lims; struct vfo { u8 frq_chn_mode; u8 chan_num; u32 rxfreq; u16 is_rxdigtone:1, rxdtcs_pol:1, rx_tone:14; u8 rx_mode; u8 unknown_ff; u16 is_txdigtone:1, txdtcs_pol:1, tx_tone:14; u8 launch_sig; u8 tx_end_sig; u8 bpower; // sets power Hi=02h, Medium=01h, Low=00 // sets power for entire vfo band u8 fm_bw; u8 cmp_nder; u8 scrm_blr; u8 shift; u32 offset; u16 step; u8 sql; // squelch for entire vfo band // integer values 0 (low) to 9 (high) u8 bvol; // sets volume for vfo band // integer values 0 (low) TO 15 (high) }; #seekto 0x0300; struct { struct vfo vfoa; } upper; #seekto 0x0380; struct { struct vfo vfob; } lower; struct mem { u32 rxfreq; u16 is_rxdigtone:1, rxdtcs_pol:1, rxtone:14; u8 recvmode; u32 txfreq; u16 is_txdigtone:1, txdtcs_pol:1, txtone:14; u8 botsignal; u8 eotsignal; u8 power:1, // binary value for // individual channel power // set to "High" or "Low" // BJ-318 band power overrides any // individual channel power setting wide:1, compander:1, scrambler:1, unknown:4; u8 namelen; u8 name[7]; }; #seekto 0x0400; struct mem upper_memory[128]; #seekto 0x1000; struct mem lower_memory[128]; #seekto 0x1C00; struct { char mod_num[6]; } mod_id; """ MEM_SIZE = 0x1C00 BLOCK_SIZE = 0x40 STIMEOUT = 2 LIST_RECVMODE = ["QT/DQT", "QT/DQT + Signaling"] LIST_SIGNAL = ["Off"] + ["DTMF%s" % x for x in range(1, 9)] + \ ["DTMF%s + Identity" % x for x in range(1, 9)] + \ ["Identity code"] # Band Power settings, can be different than channel power LIST_BPOWER = ["Low", "Mid", "High"] # Tri-power models # Screen Color Settings # BJ-218 Colors LIST_COLOR = ["Off", "Orange", "Blue", "Purple"] # BJ-318 Colors LIST_COLOR318 = ["Purple", "Red", "Emerald", "Blue", "Sky_Blue", "Black", "Brown", "Yellow"] LIST_LEDSW = ["Auto", "On"] LIST_RING = ["Off"] + ["%s" % x for x in range(1, 10)] LIST_TDR_DEF = ["A-Upper", "B-Lower"] LIST_TIMEOUT = ["Off"] + ["%s" % x for x in range(30, 630, 30)] LIST_VFOMODE = ["Frequency Mode", "Channel Mode"] # Tones are numeric, Defined in \chirp\chirp_common.py TONES_CTCSS = sorted(chirp_common.TONES) # Converted to strings LIST_CTCSS = ["Off"] + [str(x) for x in TONES_CTCSS] # Now append the DxxxN and DxxxI DTCS codes from chirp_common for x in chirp_common.DTCS_CODES: LIST_CTCSS.append("D{:03d}N".format(x)) for x in chirp_common.DTCS_CODES: LIST_CTCSS.append("D{:03d}R".format(x)) LIST_BW = ["Narrow", "Wide"] LIST_SHIFT = ["Off", " + ", " - "] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] LIST_STEPS = [str(x) for x in STEPS] LIST_STATE = ["Normal", "Stun", "Kill"] LIST_SSF = ["1000", "1450", "1750", "2100"] LIST_DTMFTX = ["50", "100", "150", "200", "300", "500"] def _clean_buffer(radio): radio.pipe.timeout = 0.005 junk = radio.pipe.read(256) radio.pipe.timeout = STIMEOUT if junk: LOG.debug("Got %i bytes of junk before starting" % len(junk)) def _rawrecv(radio, amount): """Raw read from the radio device""" data = b"" try: data = radio.pipe.read(amount) except: _exit_program_mode(radio) msg = "Generic error reading data from radio; check your cable." raise errors.RadioError(msg) if len(data) != amount: _exit_program_mode(radio) msg = "Error reading from radio: not the amount of data we want." raise errors.RadioError(msg) return data def _rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) except: raise errors.RadioError("Error sending data to radio") def _make_frame(cmd, addr, length, data=""): """Pack the info in the header format""" frame = struct.pack(">4sHH", cmd, addr, length) # Add the data if set if len(data) != 0: frame += data # Return the data return frame def _recv(radio, addr, length): """Get data from the radio """ data = _rawrecv(radio, length) # DEBUG LOG.info("Response:") LOG.debug(util.hexprint(data)) return data def _do_ident(radio): """Put the radio in PROGRAM mode & identify it""" # Set the serial discipline radio.pipe.baudrate = 19200 radio.pipe.parity = "N" radio.pipe.timeout = STIMEOUT # Flush input buffer _clean_buffer(radio) magic = b"PROM_LIN" _rawsend(radio, magic) ack = _rawrecv(radio, 1) if ack != b"\x06": _exit_program_mode(radio) if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond") return True def _exit_program_mode(radio): endframe = b"EXIT" _rawsend(radio, endframe) def _download(radio): """Get the memory map""" # Put radio in program mode and identify it _do_ident(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data = b"" for addr in range(0, MEM_SIZE, BLOCK_SIZE): frame = _make_frame(b"READ", addr, BLOCK_SIZE) # DEBUG LOG.info("Request sent:") LOG.debug(util.hexprint(frame)) # Sending the read request _rawsend(radio, frame) # Now we read d = _recv(radio, addr, BLOCK_SIZE) # Aggregate the data data += d # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) _exit_program_mode(radio) return data def _upload(radio): """Upload procedure""" # Put radio in program mode and identify it _do_ident(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) # The fun starts here for addr in range(0, MEM_SIZE, BLOCK_SIZE): # Sending the data data = radio.get_mmap()[addr:addr + BLOCK_SIZE] frame = _make_frame(b"WRIE", addr, BLOCK_SIZE, data) _rawsend(radio, frame) # Receiving the response ack = _rawrecv(radio, 1) if ack != b"\x06": _exit_program_mode(radio) msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) _exit_program_mode(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" if len(data) == 0x1C08: rid = data[0x1C00:0x1C08] return rid.startswith(cls.MODEL.encode()) else: return False def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # Determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # If the two freqs are on the same Band this is not a split return False # If you get here is because the freq pairs are split return True @directory.register class LT725UV(chirp_common.CloneModeRadio): """LUITON LT-725UV Radio""" VENDOR = "LUITON" MODEL = "LT-725UV" NEEDS_COMPAT_SERIAL = False MODES = ["NFM", "FM"] TONES = chirp_common.TONES DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) NAME_LENGTH = 7 DTMF_CHARS = list("0123456789ABCD*#") # Channel Power: 2 levels # BJ-318 uses 3 power levels for each VFO "Band" # Low = 5W, Med = 10W, High = 25W # The band power selection in a VFO applies to the VFO and overrides # the stored channel power selection # The firmware channel memory structure provides only 1 bit for # individual channel power settings, limiting potential channel # power selection options to 2 levels: Low or High. POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5.00), chirp_common.PowerLevel("High", watts=30.00)] VALID_BANDS = [(136000000, 176000000), (400000000, 490000000)] # Valid chars on the LCD VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`{|}!\"#$%&'()*+,-./:;<=>?@[]^_" @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() if cls.MODEL == "BJ-318": msg = \ ('\n' 'The individual BJ-318 channel power settings set in CHIRP' ' are ignored by \n' 'the radio. They are allowed to be set in hopes of a future' ' firmware \n' 'change by the manufacturer. While the CHIRP driver will' ' allow setting \n' 'the individual VFO power to High (25W), Med (10W) or Low' ' (5W) they \n' 'are converted to just Low (5W) and High (25W) on upload. The' ' Med setting \n' 'reverts to Low. \n' '\n' 'Changing a channel power setting must be done manually using' ' the front \n' 'panel menu control (or the microphone controls while in VFO' ' mode.)' ) else: msg = \ ('Some notes about POWER settings:\n' '- The individual channel power settings are ignored' ' by the radio.\n' ' They are allowed to be set (and downloaded) in hopes of' ' a future firmware update.\n' '- Power settings done \'Live\' in the radio apply to the' ' entire upper or lower band.\n' '- Tri-power radio models will set and download the three' ' band-power' ' levels, but they are converted to just Low and High at' ' upload.' ' The Mid setting reverts to Low.' ) rp.info = msg rp.pre_download = _( "Follow this instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.has_sub_devices = self.VARIANT == "" rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = [] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = self.NAME_LENGTH rf.valid_dtcs_codes = self.DTCS_CODES rf.valid_bands = self.VALID_BANDS rf.memory_bounds = (1, 128) rf.valid_tuning_steps = STEPS return rf def get_sub_devices(self): return [LT725UVUpper(self._mmap), LT725UVLower(self._mmap)] def sync_in(self): """Download from radio""" try: data = _download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _memory_obj(self, suffix=""): return getattr(self._memobj, "%s_memory%s" % (self._vfo, suffix)) def _get_dcs(self, val): return int(str(val)[2:-18]) def _set_dcs(self, val): return int(str(val), 16) def get_memory(self, number): _mem = self._memory_obj()[number - 1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif _split(self.get_features(), mem.freq, int(_mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _mem.name[0:_mem.namelen]: mem.name += chr(char) dtcs_pol = ["N", "N"] if _mem.rxtone == 0x3FFF: rxmode = "" elif _mem.is_rxdigtone == 0: # CTCSS rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 else: # Digital rxmode = "DTCS" mem.rx_dtcs = self._get_dcs(_mem.rxtone) if _mem.rxdtcs_pol == 1: dtcs_pol[1] = "R" if _mem.txtone == 0x3FFF: txmode = "" elif _mem.is_txdigtone == 0: # CTCSS txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 else: # Digital txmode = "DTCS" mem.dtcs = self._get_dcs(_mem.txtone) if _mem.txdtcs_pol == 1: dtcs_pol[0] = "R" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) mem.mode = _mem.wide and "FM" or "NFM" mem.power = self.POWER_LEVELS[_mem.power] # Extra mem.extra = RadioSettingGroup("extra", "Extra") if _mem.recvmode == 0xFF: val = 0x00 else: val = _mem.recvmode recvmode = RadioSetting("recvmode", "Receiving mode", RadioSettingValueList(LIST_RECVMODE, LIST_RECVMODE[val])) mem.extra.append(recvmode) if _mem.botsignal == 0xFF: val = 0x00 else: val = _mem.botsignal botsignal = RadioSetting("botsignal", "Launch signaling", RadioSettingValueList(LIST_SIGNAL, LIST_SIGNAL[val])) mem.extra.append(botsignal) if _mem.eotsignal == 0xFF: val = 0x00 else: val = _mem.eotsignal rx = RadioSettingValueList(LIST_SIGNAL, LIST_SIGNAL[val]) eotsignal = RadioSetting("eotsignal", "Transmit end signaling", rx) mem.extra.append(eotsignal) rx = RadioSettingValueBoolean(bool(_mem.compander)) compander = RadioSetting("compander", "Compander", rx) mem.extra.append(compander) rx = RadioSettingValueBoolean(bool(_mem.scrambler)) scrambler = RadioSetting("scrambler", "Scrambler", rx) mem.extra.append(scrambler) return mem def set_memory(self, mem): _mem = self._memory_obj()[mem.number - 1] if mem.empty: _mem.set_raw("\xff" * 24) _mem.namelen = 0 return _mem.set_raw("\xFF" * 15 + "\x00\x00" + "\xFF" * 7) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.namelen = len(mem.name.rstrip()) _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _mem.name[i] = ord(mem.name[i]) except IndexError: _mem.name[i] = 0xFF rxmode = "" txmode = "" if mem.tmode == "Tone": txmode = "Tone" elif mem.tmode == "TSQL": rxmode = "Tone" txmode = "TSQL" elif mem.tmode == "DTCS": rxmode = "DTCSSQL" txmode = "DTCS" elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if rxmode == "": _mem.rxdtcs_pol = 1 _mem.is_rxdigtone = 1 _mem.rxtone = 0x3FFF elif rxmode == "Tone": _mem.rxdtcs_pol = 0 _mem.is_rxdigtone = 0 _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCSSQL": _mem.rxdtcs_pol = 1 if mem.dtcs_polarity[1] == "R" else 0 _mem.is_rxdigtone = 1 _mem.rxtone = self._set_dcs(mem.dtcs) elif rxmode == "DTCS": _mem.rxdtcs_pol = 1 if mem.dtcs_polarity[1] == "R" else 0 _mem.is_rxdigtone = 1 _mem.rxtone = self._set_dcs(mem.rx_dtcs) if txmode == "": _mem.txdtcs_pol = 1 _mem.is_txdigtone = 1 _mem.txtone = 0x3FFF elif txmode == "Tone": _mem.txdtcs_pol = 0 _mem.is_txdigtone = 0 _mem.txtone = int(mem.rtone * 10) elif txmode == "TSQL": _mem.txdtcs_pol = 0 _mem.is_txdigtone = 0 _mem.txtone = int(mem.ctone * 10) elif txmode == "DTCS": _mem.txdtcs_pol = 1 if mem.dtcs_polarity[0] == "R" else 0 _mem.is_txdigtone = 1 _mem.txtone = self._set_dcs(mem.dtcs) _mem.wide = self.MODES.index(mem.mode) _mem.power = mem.power == self.POWER_LEVELS[1] # Extra settings for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" # Define mem struct write-back shortcuts _sets = self._memobj.settings _vfoa = self._memobj.upper.vfoa _vfob = self._memobj.lower.vfob _lims = self._memobj.hello_lims _codes = self._memobj.codes _dtmf = self._memobj.dtmf_tab basic = RadioSettingGroup("basic", "Basic Settings") a_band = RadioSettingGroup("a_band", "VFO A-Upper Settings") b_band = RadioSettingGroup("b_band", "VFO B-Lower Settings") codes = RadioSettingGroup("codes", "Codes & DTMF Groups") lims = RadioSettingGroup("lims", "PowerOn & Freq Limits") group = RadioSettings(basic, a_band, b_band, lims, codes) # Basic Settings bnd_mode = RadioSetting("settings.init_bank", "TDR Band Default", RadioSettingValueList(LIST_TDR_DEF, LIST_TDR_DEF[ _sets.init_bank])) basic.append(bnd_mode) # BJ-318 set by vfo, skip if self.MODEL != "BJ-318": rs = RadioSettingValueInteger(0, 20, _sets.volume) volume = RadioSetting("settings.volume", "Volume", rs) basic.append(volume) # BJ-318 set by vfo, skip if self.MODEL != "BJ-318": vala = _vfoa.bpower # 2bits values 0,1,2= Low, Mid, High rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[vala]) powera = RadioSetting("upper.vfoa.bpower", "Power (Upper)", rx) basic.append(powera) # BJ-318 set by vfo, skip if self.MODEL != "BJ-318": valb = _vfob.bpower rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[valb]) powerb = RadioSetting("lower.vfob.bpower", "Power (Lower)", rx) basic.append(powerb) def my_word2raw(setting, obj, atrb, mlt=10): """Callback function to convert UI floating value to u16 int""" if str(setting.value) == "Off": frq = 0x0FFFF else: frq = int(float(str(setting.value)) * float(mlt)) if frq == 0: frq = 0xFFFF setattr(obj, atrb, frq) return def my_adjraw(setting, obj, atrb, fix): """Callback: add or subtract fix from value.""" vx = int(str(setting.value)) value = vx + int(fix) if value < 0: value = 0 if atrb == "frq_chn_mode" and int(str(setting.value)) == 2: value = vx * 2 # Special handling for frq_chn_mode setattr(obj, atrb, value) return def my_dbl2raw(setting, obj, atrb, flg=1): """Callback: convert from freq 146.7600 to 14760000 U32.""" value = chirp_common.parse_freq(str(setting.value)) / 10 # flg=1 means 0 becomes ff, else leave as possible 0 if flg == 1 and value == 0: value = 0xFFFFFFFF setattr(obj, atrb, value) return def my_val_list(setting, obj, atrb): """Callback:from ValueList with non-sequential, actual values.""" value = int(str(setting.value)) # Get the integer value if atrb == "tot": value = int(value / 30) # 30 second increments setattr(obj, atrb, value) return def my_spcl(setting, obj, atrb): """Callback: Special handling based on atrb.""" if atrb == "frq_chn_mode": idx = LIST_VFOMODE.index(str(setting.value)) # Returns 0 or 1 value = idx * 2 # Set bit 1 setattr(obj, atrb, value) return def my_tone_strn(obj, is_atr, pol_atr, tone_atr): """Generate the CTCS/DCS tone code string.""" vx = int(getattr(obj, tone_atr)) if vx == 16383 or vx == 0: return "Off" # 16383 is all bits set if getattr(obj, is_atr) == 0: # Simple CTCSS code tstr = str(vx / 10.0) else: # DCS if getattr(obj, pol_atr) == 0: tstr = "D{:03x}R".format(vx) else: tstr = "D{:03x}N".format(vx) return tstr def my_set_tone(setting, obj, is_atr, pol_atr, tone_atr): """Callback- create the tone setting from string code.""" sx = str(setting.value) # '131.8' or 'D231N' or 'Off' if sx == "Off": isx = 1 polx = 1 tonx = 0x3FFF elif sx[0] == "D": # DCS isx = 1 if sx[4] == "N": polx = 1 else: polx = 0 tonx = int(sx[1:4], 16) else: # CTCSS isx = 0 polx = 0 tonx = int(float(sx) * 10.0) setattr(obj, is_atr, isx) setattr(obj, pol_atr, polx) setattr(obj, tone_atr, tonx) return # not used by BJ-318 skip if self.MODEL != "BJ-318": val = _sets.fm_freq / 10.0 if val == 0: val = 88.9 # 0 is not valid rx = RadioSettingValueFloat(65, 108.0, val, 0.1, 1) rs = RadioSetting("settings.fm_freq", "FM Broadcast Freq (MHz)", rx) rs.set_apply_callback(my_word2raw, _sets, "fm_freq") basic.append(rs) # BJ-318 fm frequency if self.MODEL == "BJ-318": val = _lims.fm_318 / 10.0 if val == 0: val = 88.9 # 0 is not valid rx = RadioSettingValueFloat(65, 108.0, val, 0.1, 1) rs = RadioSetting("hello_lims.fm_318", "FM Broadcast Freq (MHz)", rx) rs.set_apply_callback(my_word2raw, _lims, "fm_318") basic.append(rs) # not used in BJ-318, skip if self.MODEL != "BJ-318": rs = RadioSettingValueList(LIST_COLOR, LIST_COLOR[_sets.wtled]) wtled = RadioSetting("settings.wtled", "Standby LED Color", rs) basic.append(wtled) # not used in BJ-318, skip if self.MODEL != "BJ-318": rs = RadioSettingValueList(LIST_COLOR, LIST_COLOR[_sets.rxled]) rxled = RadioSetting("settings.rxled", "RX LED Color", rs) basic.append(rxled) # not used in BJ-318, skip if self.MODEL != "BJ-318": rs = RadioSettingValueList(LIST_COLOR, LIST_COLOR[_sets.txled]) txled = RadioSetting("settings.txled", "TX LED Color", rs) basic.append(txled) ledsw = RadioSetting("settings.ledsw", "Back light mode", RadioSettingValueList(LIST_LEDSW, LIST_LEDSW[ _sets.ledsw])) basic.append(ledsw) beep = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean(bool(_sets.beep))) basic.append(beep) ring = RadioSetting("settings.ring", "Ring", RadioSettingValueList(LIST_RING, LIST_RING[ _sets.ring])) basic.append(ring) bcl = RadioSetting("settings.bcl", "Busy channel lockout", RadioSettingValueBoolean(bool(_sets.bcl))) basic.append(bcl) # squelch for non-BJ-318 models # BJ-318 squelch set by VFO basis if self.MODEL != "BJ-318": if _vfoa.sql == 0xFF: val = 0x04 else: val = _vfoa.sql sqla = RadioSetting("upper.vfoa.sql", "Squelch (Upper)", RadioSettingValueInteger(0, 9, val)) basic.append(sqla) if _vfob.sql == 0xFF: val = 0x04 else: val = _vfob.sql sqlb = RadioSetting("lower.vfob.sql", "Squelch (Lower)", RadioSettingValueInteger(0, 9, val)) basic.append(sqlb) tmp = str(int(_sets.tot) * 30) # 30 sec step counter rs = RadioSetting("settings.tot", "Transmit Timeout (Secs)", RadioSettingValueList(LIST_TIMEOUT, tmp)) rs.set_apply_callback(my_val_list, _sets, "tot") basic.append(rs) tmp = str(int(_sets.sig_freq)) rs = RadioSetting("settings.sig_freq", "Single Signaling Tone (Hz)", RadioSettingValueList(LIST_SSF, tmp)) rs.set_apply_callback(my_val_list, _sets, "sig_freq") basic.append(rs) tmp = str(int(_sets.dtmf_txms)) rs = RadioSetting("settings.dtmf_txms", "DTMF Tx Duration (mSecs)", RadioSettingValueList(LIST_DTMFTX, tmp)) rs.set_apply_callback(my_val_list, _sets, "dtmf_txms") basic.append(rs) rs = RadioSetting("settings.rptr_mode", "Repeater Mode", RadioSettingValueBoolean(bool(_sets.rptr_mode))) basic.append(rs) # UPPER BAND SETTINGS # Freq Mode, convert bit 1 state to index pointer val = _vfoa.frq_chn_mode // 2 rx = RadioSettingValueList(LIST_VFOMODE, LIST_VFOMODE[val]) rs = RadioSetting("upper.vfoa.frq_chn_mode", "Default Mode", rx) rs.set_apply_callback(my_spcl, _vfoa, "frq_chn_mode") a_band.append(rs) val = _vfoa.chan_num + 1 # Add 1 for 1-128 displayed rs = RadioSetting("upper.vfoa.chan_num", "Initial Chan", RadioSettingValueInteger(1, 128, val)) rs.set_apply_callback(my_adjraw, _vfoa, "chan_num", -1) a_band.append(rs) val = _vfoa.rxfreq / 100000.0 if (val < 136.0 or val > 176.0): val = 146.520 # 2m calling rs = RadioSetting("upper.vfoa.rxfreq ", "Default Recv Freq (MHz)", RadioSettingValueFloat(136.0, 176.0, val, 0.001, 5)) rs.set_apply_callback(my_dbl2raw, _vfoa, "rxfreq") a_band.append(rs) tmp = my_tone_strn(_vfoa, "is_rxdigtone", "rxdtcs_pol", "rx_tone") rs = RadioSetting("rx_tone", "Default Recv CTCSS (Hz)", RadioSettingValueList(LIST_CTCSS, tmp)) rs.set_apply_callback(my_set_tone, _vfoa, "is_rxdigtone", "rxdtcs_pol", "rx_tone") a_band.append(rs) rx = RadioSettingValueList(LIST_RECVMODE, LIST_RECVMODE[_vfoa.rx_mode]) rs = RadioSetting("upper.vfoa.rx_mode", "Default Recv Mode", rx) a_band.append(rs) tmp = my_tone_strn(_vfoa, "is_txdigtone", "txdtcs_pol", "tx_tone") rs = RadioSetting("tx_tone", "Default Xmit CTCSS (Hz)", RadioSettingValueList(LIST_CTCSS, tmp)) rs.set_apply_callback(my_set_tone, _vfoa, "is_txdigtone", "txdtcs_pol", "tx_tone") a_band.append(rs) rs = RadioSetting("upper.vfoa.launch_sig", "Launch Signaling", RadioSettingValueList(LIST_SIGNAL, LIST_SIGNAL[_vfoa.launch_sig])) a_band.append(rs) rx = RadioSettingValueList(LIST_SIGNAL, LIST_SIGNAL[_vfoa.tx_end_sig]) rs = RadioSetting("upper.vfoa.tx_end_sig", "Xmit End Signaling", rx) a_band.append(rs) rx = RadioSettingValueList(LIST_BW, LIST_BW[_vfoa.fm_bw]) rs = RadioSetting("upper.vfoa.fm_bw", "Wide/Narrow Band", rx) a_band.append(rs) rx = RadioSettingValueBoolean(bool(_vfoa.cmp_nder)) rs = RadioSetting("upper.vfoa.cmp_nder", "Compander", rx) a_band.append(rs) rs = RadioSetting("upper.vfoa.scrm_blr", "Scrambler", RadioSettingValueBoolean(bool(_vfoa.scrm_blr))) a_band.append(rs) rx = RadioSettingValueList(LIST_SHIFT, LIST_SHIFT[_vfoa.shift]) rs = RadioSetting("upper.vfoa.shift", "Xmit Shift", rx) a_band.append(rs) val = _vfoa.offset / 100000.0 rs = RadioSetting("upper.vfoa.offset", "Xmit Offset (MHz)", RadioSettingValueFloat(0, 100.0, val, 0.001, 3)) # Allow zero value rs.set_apply_callback(my_dbl2raw, _vfoa, "offset", 0) a_band.append(rs) tmp = str(_vfoa.step / 100.0) rs = RadioSetting("step", "Freq step (kHz)", RadioSettingValueList(LIST_STEPS, tmp)) rs.set_apply_callback(my_word2raw, _vfoa, "step", 100) a_band.append(rs) # BJ-318 upper band squelch if self.MODEL == "BJ-318": if _vfoa.sql == 0xFF: valq = 0x04 # setting default squelch to 04 else: valq = _vfoa.sql sqla = RadioSetting("upper.vfoa.sql", "Squelch", RadioSettingValueInteger(0, 9, valq)) a_band.append(sqla) # BJ-318 upper band volume if self.MODEL == "BJ-318": bvolume_u = RadioSetting("upper.vfoa.bvol", "Volume", RadioSettingValueInteger( 0, 15, _vfoa.bvol)) a_band.append(bvolume_u) # BJ-318 Upper Screen Color if self.MODEL == "BJ-318": rs_u = RadioSettingValueList(LIST_COLOR318, LIST_COLOR318[_lims.up_scr_color]) up_scr_color = RadioSetting("hello_lims.up_scr_color", "Screen Color", rs_u) a_band.append(up_scr_color) # BJ-318 Upper band power if self.MODEL == "BJ-318": val_b = _vfoa.bpower # 2bits values 0,1,2= Low, Mid, High rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[val_b]) power_u = RadioSetting("upper.vfoa.bpower", "Power", rx) a_band.append(power_u) # LOWER BAND SETTINGS val = _vfob.frq_chn_mode // 2 rx = RadioSettingValueList(LIST_VFOMODE, LIST_VFOMODE[val]) rs = RadioSetting("lower.vfob.frq_chn_mode", "Default Mode", rx) rs.set_apply_callback(my_spcl, _vfob, "frq_chn_mode") b_band.append(rs) val = _vfob.chan_num + 1 rs = RadioSetting("lower.vfob.chan_num", "Initial Chan", RadioSettingValueInteger(1, 128, val)) rs.set_apply_callback(my_adjraw, _vfob, "chan_num", -1) b_band.append(rs) val = _vfob.rxfreq / 100000.0 if (val < 400.0 or val > 490.0): val = 446.0 # UHF calling rs = RadioSetting("lower.vfob.rxfreq ", "Default Recv Freq (MHz)", RadioSettingValueFloat(400.0, 490.0, val, 0.001, 5)) rs.set_apply_callback(my_dbl2raw, _vfob, "rxfreq") b_band.append(rs) tmp = my_tone_strn(_vfob, "is_rxdigtone", "rxdtcs_pol", "rx_tone") rs = RadioSetting("rx_tone", "Default Recv CTCSS (Hz)", RadioSettingValueList(LIST_CTCSS, tmp)) rs.set_apply_callback(my_set_tone, _vfob, "is_rxdigtone", "rxdtcs_pol", "rx_tone") b_band.append(rs) rx = RadioSettingValueList(LIST_RECVMODE, LIST_RECVMODE[_vfob.rx_mode]) rs = RadioSetting("lower.vfob.rx_mode", "Default Recv Mode", rx) b_band.append(rs) tmp = my_tone_strn(_vfob, "is_txdigtone", "txdtcs_pol", "tx_tone") rs = RadioSetting("tx_tone", "Default Xmit CTCSS (Hz)", RadioSettingValueList(LIST_CTCSS, tmp)) rs.set_apply_callback(my_set_tone, _vfob, "is_txdigtone", "txdtcs_pol", "tx_tone") b_band.append(rs) rx = RadioSettingValueList(LIST_SIGNAL, LIST_SIGNAL[_vfob.launch_sig]) rs = RadioSetting("lower.vfob.launch_sig", "Launch Signaling", rx) b_band.append(rs) rx = RadioSettingValueList(LIST_SIGNAL, LIST_SIGNAL[_vfob.tx_end_sig]) rs = RadioSetting("lower.vfob.tx_end_sig", "Xmit End Signaling", rx) b_band.append(rs) rx = RadioSettingValueList(LIST_BW, LIST_BW[_vfob.fm_bw]) rs = RadioSetting("lower.vfob.fm_bw", "Wide/Narrow Band", rx) b_band.append(rs) rs = RadioSetting("lower.vfob.cmp_nder", "Compander", RadioSettingValueBoolean(bool(_vfob.cmp_nder))) b_band.append(rs) rs = RadioSetting("lower.vfob.scrm_blr", "Scrambler", RadioSettingValueBoolean(bool(_vfob.scrm_blr))) b_band.append(rs) rx = RadioSettingValueList(LIST_SHIFT, LIST_SHIFT[_vfob.shift]) rs = RadioSetting("lower.vfob.shift", "Xmit Shift", rx) b_band.append(rs) val = _vfob.offset / 100000.0 rs = RadioSetting("lower.vfob.offset", "Xmit Offset (MHz)", RadioSettingValueFloat(0, 100.0, val, 0.001, 3)) rs.set_apply_callback(my_dbl2raw, _vfob, "offset", 0) b_band.append(rs) tmp = str(_vfob.step / 100.0) rs = RadioSetting("step", "Freq step (kHz)", RadioSettingValueList(LIST_STEPS, tmp)) rs.set_apply_callback(my_word2raw, _vfob, "step", 100) b_band.append(rs) # BJ-318 lower band squelch if self.MODEL == "BJ-318": if _vfob.sql == 0xFF: val_l = 0x04 # setting default squelch to 04 else: val_l = _vfob.sql sql_b = RadioSetting("lower.vfob.sql", "Squelch", RadioSettingValueInteger(0, 9, val_l)) b_band.append(sql_b) # BJ-318 lower band volume if self.MODEL == "BJ-318": bvolume_l = RadioSetting("lower.vfob.bvol", "Volume", RadioSettingValueInteger( 0, 15, _vfob.bvol)) b_band.append(bvolume_l) # BJ-318 Lower Screen Color if self.MODEL == "BJ-318": rs_l = RadioSettingValueList(LIST_COLOR318, LIST_COLOR318[_lims.dn_scr_color]) dn_scr_color = RadioSetting("hello_lims.dn_scr_color", "Screen Color", rs_l) b_band.append(dn_scr_color) # BJ-318 lower band power if self.MODEL == "BJ-318": val_l = _vfoa.bpower # 2bits values 0,1,2= Low, Mid, High rx = RadioSettingValueList(LIST_BPOWER, LIST_BPOWER[val_l]) powera = RadioSetting("lower.vfob.bpower", "Power", rx) b_band.append(powera) # PowerOn & Freq Limits Settings def chars2str(cary, knt): """Convert raw memory char array to a string: NOT a callback.""" stx = "" for char in cary[0:knt]: stx += chr(int(char)) return stx def my_str2ary(setting, obj, atrba, atrbc): """Callback: convert 7-char string to char array with count.""" ary = "" knt = 7 for j in range(6, -1, -1): # Strip trailing spaces if str(setting.value)[j] == "" or str(setting.value)[j] == " ": knt = knt - 1 else: break for j in range(0, 7, 1): if j < knt: ary += str(setting.value)[j] else: ary += chr(0xFF) setattr(obj, atrba, ary) setattr(obj, atrbc, knt) return # not used in BJ-318 startup screen if self.MODEL != "BJ-318": tmp = chars2str(_lims.hello1, _lims.hello1_cnt) rs = RadioSetting("hello_lims.hello1", "Power-On Message 1", RadioSettingValueString(0, 7, tmp)) rs.set_apply_callback(my_str2ary, _lims, "hello1", "hello1_cnt") lims.append(rs) # not used in BJ-318 startup screen if self.MODEL != "BJ-318": tmp = chars2str(_lims.hello2, _lims.hello2_cnt) rs = RadioSetting("hello_lims.hello2", "Power-On Message 2", RadioSettingValueString(0, 7, tmp)) rs.set_apply_callback(my_str2ary, _lims, "hello2", "hello2_cnt") lims.append(rs) # VALID_BANDS = [(136000000, 176000000),400000000, 490000000)] lval = _lims.vhf_low / 100000.0 uval = _lims.vhf_high / 100000.0 if lval >= uval: lval = 144.0 uval = 158.0 rs = RadioSetting("hello_lims.vhf_low", "Lower VHF Band Limit (MHz)", RadioSettingValueFloat(136.0, 176.0, lval, 0.001, 3)) rs.set_apply_callback(my_dbl2raw, _lims, "vhf_low") lims.append(rs) rs = RadioSetting("hello_lims.vhf_high", "Upper VHF Band Limit (MHz)", RadioSettingValueFloat(136.0, 176.0, uval, 0.001, 3)) rs.set_apply_callback(my_dbl2raw, _lims, "vhf_high") lims.append(rs) lval = _lims.uhf_low / 100000.0 uval = _lims.uhf_high / 100000.0 if lval >= uval: lval = 420.0 uval = 470.0 rs = RadioSetting("hello_lims.uhf_low", "Lower UHF Band Limit (MHz)", RadioSettingValueFloat(400.0, 490.0, lval, 0.001, 3)) rs.set_apply_callback(my_dbl2raw, _lims, "uhf_low") lims.append(rs) rs = RadioSetting("hello_lims.uhf_high", "Upper UHF Band Limit (MHz)", RadioSettingValueFloat(400.0, 490.0, uval, 0.001, 3)) rs.set_apply_callback(my_dbl2raw, _lims, "uhf_high") lims.append(rs) # Codes and DTMF Groups Settings def make_dtmf(ary, knt): """Generate the DTMF code 1-8, NOT a callback.""" tmp = "" if knt > 0 and knt != 0xff: for val in ary[0:knt]: if val > 0 and val <= 9: tmp += chr(val + 48) elif val == 0x0a: tmp += "0" elif val == 0x0d: tmp += "A" elif val == 0x0e: tmp += "B" elif val == 0x0f: tmp += "C" elif val == 0x00: tmp += "D" elif val == 0x0b: tmp += "*" elif val == 0x0c: tmp += "#" else: msg = ("Invalid Character. Must be: 0-9,A,B,C,D,*,#") raise InvalidValueError(msg) return tmp def my_dtmf2raw(setting, obj, atrba, atrbc, syz=7): """Callback: DTMF Code; sends 5 or 7-byte string.""" draw = [] knt = syz for j in range(syz - 1, -1, -1): # Strip trailing spaces if str(setting.value)[j] == "" or str(setting.value)[j] == " ": knt = knt - 1 else: break for j in range(0, syz): bx = str(setting.value)[j] obx = ord(bx) dig = 0x0ff if j < knt and knt > 0: # (Else) is pads if bx == "0": dig = 0x0a elif bx == "A": dig = 0x0d elif bx == "B": dig = 0x0e elif bx == "C": dig = 0x0f elif bx == "D": dig = 0x00 elif bx == "*": dig = 0x0b elif bx == "#": dig = 0x0c elif obx >= 49 and obx <= 57: dig = obx - 48 else: msg = ("Must be: 0-9,A,B,C,D,*,#") raise InvalidValueError(msg) # - End if/elif/else for bx # - End if J<=knt draw.append(dig) # Generate string of bytes # - End for j setattr(obj, atrba, draw) setattr(obj, atrbc, knt) return tmp = make_dtmf(_codes.native_id_code, _codes.native_id_cnt) rs = RadioSetting("codes.native_id_code", "Native ID Code", RadioSettingValueString(0, 7, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "native_id_code", "native_id_cnt", 7) codes.append(rs) tmp = make_dtmf(_codes.master_id_code, _codes.master_id_cnt) rs = RadioSetting("codes.master_id_code", "Master Control ID Code", RadioSettingValueString(0, 7, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "master_id_code", "master_id_cnt", 7) codes.append(rs) tmp = make_dtmf(_codes.alarm_code, _codes.alarm_cnt) rs = RadioSetting("codes.alarm_code", "Alarm Code", RadioSettingValueString(0, 5, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "alarm_code", "alarm_cnt", 5) codes.append(rs) tmp = make_dtmf(_codes.id_disp_code, _codes.id_disp_cnt) rs = RadioSetting("codes.id_disp_code", "Identify Display Code", RadioSettingValueString(0, 5, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "id_disp_code", "id_disp_cnt", 5) codes.append(rs) tmp = make_dtmf(_codes.revive_code, _codes.revive_cnt) rs = RadioSetting("codes.revive_code", "Revive Code", RadioSettingValueString(0, 5, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "revive_code", "revive_cnt", 5) codes.append(rs) tmp = make_dtmf(_codes.stun_code, _codes.stun_cnt) rs = RadioSetting("codes.stun_code", "Remote Stun Code", RadioSettingValueString(0, 5, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "stun_code", "stun_cnt", 5) codes.append(rs) tmp = make_dtmf(_codes.kill_code, _codes.kill_cnt) rs = RadioSetting("codes.kill_code", "Remote KILL Code", RadioSettingValueString(0, 5, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "kill_code", "kill_cnt", 5) codes.append(rs) tmp = make_dtmf(_codes.monitor_code, _codes.monitor_cnt) rs = RadioSetting("codes.monitor_code", "Monitor Code", RadioSettingValueString(0, 5, tmp)) rs.set_apply_callback(my_dtmf2raw, _codes, "monitor_code", "monitor_cnt", 5) codes.append(rs) val = _codes.state_now if val > 2: val = 0 rx = RadioSettingValueList(LIST_STATE, LIST_STATE[val]) rs = RadioSetting("codes.state_now", "Current State", rx) codes.append(rs) dtm = make_dtmf(_dtmf.dtmf1, _dtmf.dtmf1_cnt) rs = RadioSetting("dtmf_tab.dtmf1", "DTMF1 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf1", "dtmf1_cnt") codes.append(rs) dtm = make_dtmf(_dtmf.dtmf2, _dtmf.dtmf2_cnt) rs = RadioSetting("dtmf_tab.dtmf2", "DTMF2 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf2", "dtmf2_cnt") codes.append(rs) dtm = make_dtmf(_dtmf.dtmf3, _dtmf.dtmf3_cnt) rs = RadioSetting("dtmf_tab.dtmf3", "DTMF3 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf3", "dtmf3_cnt") codes.append(rs) dtm = make_dtmf(_dtmf.dtmf4, _dtmf.dtmf4_cnt) rs = RadioSetting("dtmf_tab.dtmf4", "DTMF4 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf4", "dtmf4_cnt") codes.append(rs) dtm = make_dtmf(_dtmf.dtmf5, _dtmf.dtmf5_cnt) rs = RadioSetting("dtmf_tab.dtmf5", "DTMF5 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf5", "dtmf5_cnt") codes.append(rs) dtm = make_dtmf(_dtmf.dtmf6, _dtmf.dtmf6_cnt) rs = RadioSetting("dtmf_tab.dtmf6", "DTMF6 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf6", "dtmf6_cnt") codes.append(rs) dtm = make_dtmf(_dtmf.dtmf7, _dtmf.dtmf7_cnt) rs = RadioSetting("dtmf_tab.dtmf7", "DTMF7 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf7", "dtmf7_cnt") codes.append(rs) dtm = make_dtmf(_dtmf.dtmf8, _dtmf.dtmf8_cnt) rs = RadioSetting("dtmf_tab.dtmf8", "DTMF8 String", RadioSettingValueString(0, 7, dtm)) rs.set_apply_callback(my_dtmf2raw, _dtmf, "dtmf8", "dtmf8_cnt") codes.append(rs) return group # END get_settings() def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # Testing the file data size if len(filedata) == MEM_SIZE + 8: match_size = True # Testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False class LT725UVUpper(LT725UV): VARIANT = "Upper" _vfo = "upper" class LT725UVLower(LT725UV): VARIANT = "Lower" _vfo = "lower" class Zastone(chirp_common.Alias): """Declare BJ-218 alias for Zastone BJ-218.""" VENDOR = "Zastone" MODEL = "BJ-218" class Hesenate(chirp_common.Alias): """Declare BJ-218 alias for Hesenate BJ-218.""" VENDOR = "Hesenate" MODEL = "BJ-218" class Baojie218Upper(LT725UVUpper): VENDOR = "Baojie" MODEL = "BJ-218" class Baojie218Lower(LT725UVLower): VENDOR = "Baojie" MODEL = "BJ-218" @directory.register class Baojie218(LT725UV): """Baojie BJ-218""" VENDOR = "Baojie" MODEL = "BJ-218" ALIASES = [Zastone, Hesenate, ] def get_sub_devices(self): return [Baojie218Upper(self._mmap), Baojie218Lower(self._mmap)] class Baojie318Upper(LT725UVUpper): VENDOR = "Baojie" MODEL = "BJ-318" class Baojie318Lower(LT725UVLower): VENDOR = "Baojie" MODEL = "BJ-318" @directory.register class Baojie318(LT725UV): """Baojie BJ-318""" VENDOR = "Baojie" MODEL = "BJ-318" def get_sub_devices(self): return [Baojie318Upper(self._mmap), Baojie318Lower(self._mmap)] chirp-20240224/chirp/drivers/icx90.py0000644000175000017500000011107714446523722016145 0ustar hibbyhibby# -*- coding: utf-8 -*- # Copyright 2018-2020 Jaroslav Х karvada # Based on various code from the CHIRP # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import icf from chirp import chirp_common, bitwise, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings import argparse ICX90_MEM_FORMAT = """ struct mem_item { ul24 freq; u8 dtcs_polarity:2, unknown_1:2, offset_freq_mult:1, unknown_2:2, freq_mult:1; u8 unknown_3:1, duplex:2, mode:2, tone_mode:3; ul16 offset_freq; u8 dtcs; u8 tx_tone_lo:4, tune_step:4; u8 rx_tone:6, tx_tone_hi:2; char name[6]; }; struct bank_item { u8 invisible_channel:1, prog_skip:1, mem_skip:1, bank_index:5; u8 bank_channel; }; struct tv_mem_item { u8 fixed:7, mode:1; ul24 freq; char name[4]; }; struct mem_item memory[500]; struct mem_item scan_edges[50]; struct bank_item banks[500]; u8 unknown_4[120]; struct mem_item vfo_a_band[10]; struct mem_item vfo_b_band[10]; struct mem_item call_channels[5]; struct tv_mem_item tv_memory[68]; u8 unknown_5[35]; ul16 mem_channel; u8 autodial; u8 unknown_6[8]; u8 unknown_7:6, skip_scan:1, unknown_8:1; u8 squelch_level; struct { char dtmf_digits[16]; } dtmf_codes[10]; u8 tv_channel_skip[68]; u8 unknown_9[128]; u8 scan_resume; u8 scan_pause; u8 unknown_10; u8 beep_volume; u8 beep; u8 backlight; u8 busy_led; u8 auto_power_off; u8 power_save; u8 monitor; u8 dial_speedup; u8 unknown_11; u8 auto_repeater; u8 dtmf_speed; u8 hm_75a_function; u8 wx_alert; u8 expand_1; u8 scan_stop_beep; u8 scan_stop_light; u8 unknown_12; u8 light_position; u8 light_color; u8 unknown_13; u8 band_edge_beep; u8 auto_power_on; u8 key_lock; u8 ptt_lock; u8 lcd_contrast; u8 opening_message; u8 expand_2; u8 unknown_14; u8 busy_lockout; u8 timeout_timer; u8 active_band; u8 split; u8 fm_narrow; u8 morse_code_enable; u8 morse_code_speed; u8 unknown_15[22]; char opening_message_text[6]; u8 unknown_16[186]; u8 unknown_17:4, tune_step:4; u8 unknown_18[4]; u8 band_selected; u8 unknown_19[2]; u8 unknown_20:2, attenuator:1, vfo:1, power:1, dial_select:1, memory_name:1, memory_display:1; u8 unknown_21[2]; u8 mode:4, unknown_22:4; u8 unknown_23[9]; char alpha_tag[6]; u8 vfo_scan; u8 memory_scan; u8 unknown_24; u8 tv_channel; u8 wx_channel; char comment[16]; """ LOG = logging.getLogger(__name__) # in bytes MEM_ITEM_SIZE = 16 TV_MEM_ITEM_SIZE = 8 BANK_INDEX = ["A", "B", "C", "D", "E", "F", "G", "H", "J", "L", "N", "O", "P", "Q", "R", "T", "U", "Y"] MEM_NUM = 500 BANKS = 18 BANK_NUM = 100 BANK_INDEX_NUM = len(BANK_INDEX) DTMF_AUTODIAL_NUM = 10 DTMF_DIGITS_NUM = 16 OPENING_MESSAGE_LEN = 6 COMMENT_LEN = 16 BANDS = 10 TV_CHANNELS = 68 CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789()*+-,/|= " NAME_LENGTH = 6 TV_NAME_LENGTH = 4 DUPLEX = ["", "-", "+", ""] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] TONE_MODE = ["", "Tone", "TSQL", "DTCS"] TUNE_STEP = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 200.0] TUNE_STEP_STR = [str(x) for x in TUNE_STEP] MODE = ["FM", "WFM", "AM"] TV_MODE = ["WFM", "AM"] SQUELCH_LEVEL = ["Open", "Auto", "Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9"] AUTODIAL = ["Tone call", "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7", "D8", "D9"] DTMF_SPEED = ["100 ms", "200 ms", "300 ms", "400 ms"] SCAN_RESUME = ["0 s", "1 s", "2 s", "3 s", "4 s", "5 s", "Hold"] SCAN_PAUSE = ["2 s", "4 s", "6 s", "8 s", "10 s", "12 s", "14 s", "16 s", "18 s", "20 s", "Hold"] BEEP_VOLUME = ["Volume", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"] BACKLIGHT = ["Off", "On", "Auto"] AUTO_POWER_OFF = ["Off", "30 min", "60 min", "90 min", "120 min"] POWER_SAVE = ["Off", "1:1", "1:4", "1:8", "1:16", "Auto"] MONITOR = ["Push", "Hold"] AUTO_REPEATER = ["Off", "Duplex only", "Duplex & tone"] HM_75A_FUNCTION = ["Simple", "Normal 1", "Normal 2"] LIGHT_POSITION = ["LCD", "Key", "All"] LIGHT_COLOR = ["Green", "Orange", "Red"] AUTO_POWER_ON = ["Off", "00:30", "01:00", "01:30", "02:00", "02:30", "03:00", "03:30", "04:00", "04:30", "05:00", "05:30", "06:00", "06:30", "07:00", "07:30", "08:00", "08:30", "09:00", "09:30", "10:00", "10:30", "11:00", "11:30", "12:00", "12:30", "13:00", "13:30", "14:00", "14:30", "15:00", "15:30", "16:00", "16:30", "17:00", "17:30", "18:00", "18:30", "19:00", "19:30", "20:00", "20:30", "21:00", "21:30", "22:00", "22:30", "23:00", "23:30", "24:00"] KEY_LOCK = ["Normal", "No squelch", "No volume", "All"] LCD_CONTRAST = ["1", "2", "3", "4"] TIMEOUT_TIMER = ["Off", "1 min", "3 min", "5 min", "10 min"] ACTIVE_BAND = ["All", "Single"] MORSE_CODE_SPEED = ["10 WPM", "15 WPM", "20 WPM", "25 WPM"] WX_CHANNEL = ["WX01", "WX02", "WX03", "WX04", "WX05", "WX06", "WX07", "WX08", "WX09", "WX10"] MEMORY_DISPLAY = ["Channel", "Bank"] DIAL_SELECT = ["Normal", "Volume"] POWER = ["High", "Low"] VFO = ["A", "B"] OPERATION_MODE = ["VFO", "Memory", "Call channel", "TV"] VFO_SCAN = ["All", "Band", "P0", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10", "P11", "P12", "P13", "P14", "P15", "P16", "P17", "P18", "P19", "P20", "P21", "P22", "P23", "P24"] MEMORY_SCAN = ["All", "Bank", "Sel BC", "Sel 5 MHz", "Sel 50 MHz", "Sel WFM", "Sel Air", "Sel 144 MHz", "Sel 220 MHz", "Sel 300 MHz", "Sel 440 MHz", "Sel 800 MHz"] class ICx90BankModel(icf.IcomIndexedBankModel): bank_index = BANK_INDEX def get_mappings(self): banks = [] if (self._radio._num_banks != len(type(self).bank_index)): raise Exception("Invalid number of banks %d, supported only %d banks" % (self._radio._num_banks, len(type(self).bank_index))) for i in range(0, self._radio._num_banks): index = type(self).bank_index[i] bank = self._radio._bank_class(self, index, "BANK-%s" % index) bank.index = i banks.append(bank) return banks class ICT90_Alias(chirp_common.Alias): VENDOR = "Icom" MODEL = "IC-T90" @directory.register class ICx90Radio(icf.IcomCloneModeRadio): """Icom IC-E/T90""" VENDOR = "Icom" MODEL = "IC-E90" ALIASES = [ICT90_Alias] _model = "\x25\x07\x00\x01" _memsize = 0x2d40 _endframe = "Icom Inc." _ranges = [(0x0000, 0x2d40, 32)] _num_banks = BANKS _bank_index_bounds = (0, BANK_NUM - 1) _can_hispeed = False def __init__(self, pipe): icf.IcomCloneModeRadio.__init__(self, pipe) def special_add(self, key, item_type, num, unique_idx): item = {} item["item_type"] = item_type item["num"] = num item["uidx"] = unique_idx self.special[key] = item def init_special(self): self.special = {} i = 0 # program scan edges for x in range(25): self.special_add("Scan edge: %02dA" % x, "scan_edge", x * 2, i) self.special_add("Scan edge: %02dB" % x, "scan_edge", x * 2 + 1, i + 1) i += 2 # call channels for x in range(5): self.special_add("Call ch: %d" % x, "call_chan", x, i) i += 1 # VFO A for x in range(10): self.special_add("VFO A: %d" % x, "vfo_a", x, i) i += 1 # VFO B for x in range(10): self.special_add("VFO B: %d" % x, "vfo_b", x, i) i += 1 def get_sub_devices(self): return [ICx90Radio_ham(self._mmap), ICx90Radio_tv(self._mmap)] def clear_bank(self, loc): # it seems that empty invisible channel which isn't in bank is defined in bank_item by bytes 0x9f 0x00, # i.e. it has invisible_channel == 1 # it seems that non-empty visible channel which isn't in bank is defined in bank_item by bytes 0x1f 0x00, # i.e. it has invisible_channel == 0 # so do not touch the invisible_channel (the bit 7 of the first byte) here and only # set the rest of the bits self.memobj.banks[loc].bank_index = 0x1f self.memobj.banks[loc].prog_skip = 0 self.memobj.banks[loc].mem_skip = 0 self.memobj.banks[loc].bank_channel = 0 # it seems the bank driver has different terminology about bank number and index # so in fact _get_bank and _set_bank are about indexes (i.e index in the array # of bank names - A .. Y # and _get_bank_index and _set_bank_index are about positions in the bank (0..99) def _get_bank(self, loc): i = self.memobj.banks[loc].bank_index return i if i < BANK_INDEX_NUM else None def _set_bank(self, loc, bank): if bank is None: self.clear_bank(loc) else: self.memobj.banks[loc].bank_index = bank # it seems if invisible_channel == 1 the channel is invisible (deleted) # so set it explicitly as visible self.memobj.banks[loc].invisible_channel = 0 def _get_bank_index(self, loc): i = self.memobj.banks[loc].bank_channel return i if i < BANK_NUM else None def _set_bank_index(self, loc, index): self.memobj.banks[loc].bank_channel = index def get_features(self): self.init_special() rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_name = True rf.has_bank = True rf.has_bank_index = True rf.has_bank_names = False rf.can_delete = True rf.has_ctone = True rf.has_dtcs = True rf.has_dtcs_polarity = True rf.has_tuning_step = True rf.has_comment = False rf.memory_bounds = (0, MEM_NUM - 1) rf.has_sub_devices = True rf.valid_characters = CHARSET rf.valid_modes = list(MODE) rf.valid_tmodes = list(TONE_MODE) rf.valid_duplexes = list(DUPLEX)[:-1] rf.valid_tuning_steps = list(TUNE_STEP) rf.valid_bands = [(495000, 999990000)] rf.valid_skips = ["", "S", "P"] rf.valid_name_length = NAME_LENGTH rf.valid_special_chans = sorted(self.special.keys()) return rf def map_dtmf_chirp2icom(self, item): item = str(item).upper() if item == "*": item = "E" elif item == "#": item = "F" elif item == " ": return 0xff try: ret = int(item, 16) except ValueError: raise errors.InvalidDataError("invalid DTMF number '%s'" % item) return ret def dtmf_chirp2icom(self, dtmf): return "".join(map(self.map_dtmf_chirp2icom, str(dtmf).rjust(DTMF_DIGITS_NUM))) def map_dtmf_icom2chirp(self, item): item = ord(item) if item == 0xff: return " " else: item &= 0x0f if item < 10: return str(item) else: return ["A", "B", "C", "D", "*", "#"][item - 10] def dtmf_icom2chirp(self, dtmf): return "".join(map(self.map_dtmf_icom2chirp, str(dtmf))) def apply_dtmf_autodial(self, setting, obj): obj = self.dtmf_chirp2icom(setting.value) def get_settings(self): try: _squelch = 1 basic = RadioSettingGroup("basic", "Basic") expand_1 = RadioSettingGroup("expand_1", "Expand 1") expand_2 = RadioSettingGroup("expand_2", "Expand 2") dtmf_autodial = RadioSettingGroup("dtmf_autodial", "DTMF autodial") group = RadioSettings(basic, expand_1, expand_2, dtmf_autodial) # basic basic.append(RadioSetting("mem_channel", "Current memory channel", RadioSettingValueInteger(0, MEM_NUM - 1, self.memobj.mem_channel))) basic.append(RadioSetting("squelch_level", "Squelch level", RadioSettingValueList(SQUELCH_LEVEL, SQUELCH_LEVEL[self.memobj.squelch_level]))) basic.append(RadioSetting("scan_resume", "Scan resume", RadioSettingValueList(SCAN_RESUME, SCAN_RESUME[self.memobj.scan_resume]))) basic.append(RadioSetting("scan_pause", "Scan pause", RadioSettingValueList(SCAN_PAUSE, SCAN_PAUSE[self.memobj.scan_pause]))) basic.append(RadioSetting("beep_volume", "Beep audio", RadioSettingValueList(BEEP_VOLUME, BEEP_VOLUME[self.memobj.beep_volume]))) basic.append(RadioSetting("beep", "Operation beep", RadioSettingValueBoolean(self.memobj.beep))) basic.append(RadioSetting("backlight", "LCD backlight", RadioSettingValueList(BACKLIGHT, BACKLIGHT[self.memobj.backlight]))) basic.append(RadioSetting("busy_led", "Busy LED", RadioSettingValueBoolean(self.memobj.busy_led))) basic.append(RadioSetting("auto_power_off", "Auto power off", RadioSettingValueList(AUTO_POWER_OFF, AUTO_POWER_OFF[self.memobj.auto_power_off]))) basic.append(RadioSetting("power_save", "Power save", RadioSettingValueList(POWER_SAVE, POWER_SAVE[self.memobj.power_save]))) basic.append(RadioSetting("monitor", "Monitor", RadioSettingValueList(MONITOR, MONITOR[self.memobj.monitor]))) basic.append(RadioSetting("dial_speedup", "Dial speedup", RadioSettingValueBoolean(self.memobj.dial_speedup))) basic.append(RadioSetting("auto_repeater", "Auto repeater", RadioSettingValueList(AUTO_REPEATER, AUTO_REPEATER[self.memobj.auto_repeater]))) basic.append(RadioSetting("hm_75a_function", "HM-75A function", RadioSettingValueList(HM_75A_FUNCTION, HM_75A_FUNCTION[self.memobj.hm_75a_function]))) basic.append(RadioSetting("wx_alert", "WX alert", RadioSettingValueBoolean(self.memobj.wx_alert))) basic.append(RadioSetting("wx_channel", "Current WX channel", RadioSettingValueList(WX_CHANNEL, WX_CHANNEL[self.memobj.wx_channel]))) basic.append(RadioSetting("comment", "Comment", RadioSettingValueString(0, COMMENT_LEN, str(self.memobj.comment), autopad=True))) basic.append(RadioSetting("tune_step", "Current tune step", RadioSettingValueList(TUNE_STEP_STR, TUNE_STEP_STR[self.memobj.tune_step]))) basic.append(RadioSetting("band_selected", "Selected band", RadioSettingValueInteger(0, BANDS - 1, self.memobj.band_selected))) basic.append(RadioSetting("memory_display", "Memory display", RadioSettingValueList(MEMORY_DISPLAY, MEMORY_DISPLAY[self.memobj.memory_display]))) basic.append(RadioSetting("memory_name", "Memory name", RadioSettingValueBoolean(self.memobj.memory_name))) basic.append(RadioSetting("dial_select", "Dial select", RadioSettingValueList(DIAL_SELECT, DIAL_SELECT[self.memobj.dial_select]))) basic.append(RadioSetting("power", "RF power", RadioSettingValueList(POWER, POWER[self.memobj.power]))) basic.append(RadioSetting("vfo", "Current VFO", RadioSettingValueList(VFO, VFO[self.memobj.vfo]))) basic.append(RadioSetting("attenuator", "RF attenuator", RadioSettingValueBoolean(self.memobj.attenuator))) basic.append(RadioSetting("skip_scan", "Skip scan", RadioSettingValueBoolean(self.memobj.skip_scan))) # TODO: this needs to be reverse engineered, because the following commented # code does not seem correct # basic.append(RadioSetting("mode", "Current mode", # RadioSettingValueList(OPERATION_MODE, # OPERATION_MODE[self.memobj.mode]))) basic.append(RadioSetting("vfo_scan", "VFO scan", RadioSettingValueList(VFO_SCAN, VFO_SCAN[self.memobj.vfo_scan]))) basic.append(RadioSetting("memory_scan", "Memory scan", RadioSettingValueList(MEMORY_SCAN, MEMORY_SCAN[self.memobj.memory_scan]))) basic.append(RadioSetting("tv_channel", "Current TV channel", RadioSettingValueInteger(0, TV_CHANNELS - 1, self.memobj.tv_channel))) # DTMF auto dial dtmf_autodial.append(RadioSetting("autodial", "Autodial", RadioSettingValueList(AUTODIAL, AUTODIAL[self.memobj.autodial]))) dtmf_autodial.append(RadioSetting("dtmf_speed", "Speed", RadioSettingValueList(DTMF_SPEED, DTMF_SPEED[self.memobj.dtmf_speed]))) for x in range(DTMF_AUTODIAL_NUM): rs = RadioSetting("dtmf_codes[%d].dtmf_digits" % x, "DTMF autodial: %d" % x, RadioSettingValueString(0, DTMF_DIGITS_NUM, self.dtmf_icom2chirp(self.memobj.dtmf_codes[x].dtmf_digits), autopad=True, charset="0123456789ABCD*#abcd ")) rs.set_apply_callback(self.apply_dtmf_autodial, self.memobj.dtmf_codes[x].dtmf_digits) dtmf_autodial.append(rs) # expand 1 expand_1.append(RadioSetting("expand_1", "Expand 1", RadioSettingValueBoolean(self.memobj.expand_1))) expand_1.append(RadioSetting("scan_stop_beep", "Scan stop beep", RadioSettingValueBoolean(self.memobj.scan_stop_beep))) expand_1.append(RadioSetting("scan_stop_light", "Scan stop light", RadioSettingValueBoolean(self.memobj.scan_stop_light))) expand_1.append(RadioSetting("light_postion", "Light position", RadioSettingValueList(LIGHT_POSITION, LIGHT_POSITION[self.memobj.light_position]))) expand_1.append(RadioSetting("light_color", "Light color", RadioSettingValueList(LIGHT_COLOR, LIGHT_COLOR[self.memobj.light_color]))) expand_1.append(RadioSetting("band_edge_beep", "Band edge beep", RadioSettingValueBoolean(self.memobj.band_edge_beep))) expand_1.append(RadioSetting("auto_power_on", "Auto power on", RadioSettingValueList(AUTO_POWER_ON, AUTO_POWER_ON[self.memobj.auto_power_on]))) expand_1.append(RadioSetting("key_lock", "Key lock", RadioSettingValueList(KEY_LOCK, KEY_LOCK[self.memobj.key_lock]))) expand_1.append(RadioSetting("ptt_lock", "PTT lock", RadioSettingValueBoolean(self.memobj.ptt_lock))) expand_1.append(RadioSetting("lcd_contrast", "LCD contrast", RadioSettingValueList(LCD_CONTRAST, LCD_CONTRAST[self.memobj.lcd_contrast]))) expand_1.append(RadioSetting("opening_message", "Opening message", RadioSettingValueBoolean(self.memobj.opening_message))) expand_1.append(RadioSetting("opening_message_text", "Opening message", RadioSettingValueString(0, OPENING_MESSAGE_LEN, str(self.memobj.opening_message_text), autopad=True, charset=CHARSET))) # expand 2 expand_2.append(RadioSetting("expand_2", "Expand 2", RadioSettingValueBoolean(self.memobj.expand_2))) expand_2.append(RadioSetting("busy_lockout", "Busy lock out", RadioSettingValueBoolean(self.memobj.busy_lockout))) expand_2.append(RadioSetting("timeout_timer", "Timeout timer", RadioSettingValueList(TIMEOUT_TIMER, TIMEOUT_TIMER[self.memobj.timeout_timer]))) expand_2.append(RadioSetting("active_band", "Active band", RadioSettingValueList(ACTIVE_BAND, ACTIVE_BAND[self.memobj.active_band]))) expand_2.append(RadioSetting("fm_narrow", "FM narrow", RadioSettingValueBoolean(self.memobj.fm_narrow))) expand_2.append(RadioSetting("split", "Split", RadioSettingValueBoolean(self.memobj.split))) expand_2.append(RadioSetting("morse_code_enable", "Morse code synthesizer", RadioSettingValueBoolean(self.memobj.morse_code_enable))) expand_2.append(RadioSetting("morse_code_speed", "Morse code speed", RadioSettingValueList(MORSE_CODE_SPEED, MORSE_CODE_SPEED[self.memobj.morse_code_speed]))) return group except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: if element.has_apply_callback(): LOG.debug("Using apply callback") try: element.run_apply_callback() except NotImplementedError as e: LOG.error("icx90: %s", e) continue # Find the object containing setting. obj = self.memobj bits = element.get_name().split(".") setting = bits[-1] for name in bits[:-1]: if name.endswith("]"): name, index = name.split("[") index = int(index[:-1]) obj = getattr(obj, name)[index] else: obj = getattr(obj, name) try: old_val = getattr(obj, setting) LOG.debug("Setting %s(%r) <= %s" % ( element.get_name(), old_val, element.value)) setattr(obj, setting, element.value) except AttributeError as e: LOG.error("Setting %s is not in the memory map: %s" % (element.get_name(), e)) except Exception: LOG.debug(element.get_name()) raise def process_mmap(self): self.memobj = bitwise.parse(ICX90_MEM_FORMAT, self._mmap) def sync_in(self): icf.IcomCloneModeRadio.sync_in(self) self.process_mmap() def sync_out(self): icf.IcomCloneModeRadio.sync_out(self) def freq_chirp2icom(self, freq): if chirp_common.is_fractional_step(freq): mult = 6250 multr = 1 else: mult = 5000 multr = 0 return (freq / mult, multr) def freq_icom2chirp(self, freq, mult): return freq * (6250 if mult else 5000) def get_skip(self, number): bank_item = self.memobj.banks[number] if bank_item.prog_skip: return "P" elif bank_item.mem_skip: return "S" return "" def set_skip(self, number, skip): bank_item = self.memobj.banks[number] if skip == "P": bank_item.prog_skip = 1 bank_item.mem_skip = 1 elif skip == "S": bank_item.prog_skip = 0 bank_item.mem_skip = 1 elif skip == "": bank_item.prog_skip = 0 bank_item.mem_skip = 0 else: raise errors.InvalidDataError("skip '%s' not supported" % skip) # returns (memobj.mem_item, is_special_channel, unique_idx) def get_mem_item(self, number): try: item_type = self.special[number]["item_type"] num = self.special[number]["num"] unique_idx = self.special[number]["uidx"] if item_type == "scan_edge": return (self.memobj.scan_edges[num], True, unique_idx) elif item_type == "call_chan": return (self.memobj.call_channels[num], True, unique_idx) elif item_type == "vfo_a": return (self.memobj.vfo_a_band[num], True, unique_idx) elif item_type == "vfo_b": return (self.memobj.vfo_b_band[num], True, unique_idx) else: raise errors.InvalidDataError("unknown special channel type '%s'" % item_type) except KeyError: return (self.memobj.memory[number], False, number) def get_raw_memory(self, number): (mem_item, special, unique_idx) = self.get_mem_item(number) return repr(mem_item) def get_memory(self, number): mem = chirp_common.Memory() (mem_item, special, unique_idx) = self.get_mem_item(number) freq = self.freq_icom2chirp(mem_item.freq, mem_item.freq_mult) if freq == 0: mem.empty = True else: mem.empty = False mem.freq = freq if special: mem.name = " " * NAME_LENGTH else: mem.name = str(mem_item.name).rstrip("\x00 ") mem.rtone = chirp_common.TONES[(mem_item.tx_tone_hi << 4) + mem_item.tx_tone_lo] mem.ctone = chirp_common.TONES[mem_item.rx_tone] mem.dtcs = chirp_common.DTCS_CODES[mem_item.dtcs] mem.dtcs_polarity = DTCS_POLARITY[mem_item.dtcs_polarity] mem.offset = self.freq_icom2chirp(mem_item.offset_freq, mem_item.offset_freq_mult) mem.duplex = DUPLEX[mem_item.duplex] mem.tmode = TONE_MODE[mem_item.tone_mode] mem.tuning_step = TUNE_STEP[mem_item.tune_step] mem.mode = MODE[mem_item.mode] if not special: mem.skip = self.get_skip(number) if special: mem.extd_number = number mem.number = -len(self.special) + unique_idx else: mem.number = number return mem def set_memory(self, memory): (mem_item, special, unique_idx) = self.get_mem_item( memory.extd_number or memory.number) if memory.empty: mem_item.set_raw("\x00" * MEM_ITEM_SIZE) self.clear_bank(memory.number) self.memobj.banks[memory.number].invisible_channel = 1 else: (mem_item.freq, mem_item.freq_mult) = self.freq_chirp2icom(memory.freq) if special: mem_item.name = " " * NAME_LENGTH else: self.memobj.banks[memory.number].invisible_channel = 0 for x in range(NAME_LENGTH): try: mem_item.name[x] = str(memory.name[x]) except IndexError: mem_item.name[x] = " " mem_item.tx_tone_hi = chirp_common.TONES.index(memory.rtone) >> 4 mem_item.tx_tone_lo = chirp_common.TONES.index(memory.rtone) & 0x0f mem_item.rx_tone = chirp_common.TONES.index(memory.ctone) mem_item.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs) mem_item.dtcs_polarity = DTCS_POLARITY.index(memory.dtcs_polarity) (mem_item.offset_freq, mem_item.offset_freq_mult) = self.freq_chirp2icom(memory.offset) mem_item.duplex = DUPLEX.index(memory.duplex) mem_item.tone_mode = TONE_MODE.index(memory.tmode) mem_item.tune_step = TUNE_STEP.index(memory.tuning_step) mem_item.mode = MODE.index(memory.mode) if not special: self.set_skip(memory.number, memory.skip) def get_bank_model(self): return ICx90BankModel(self) class ICx90Radio_ham(ICx90Radio): VARIANT = 'Radio' def get_features(self): rf = ICx90Radio.get_features(self) rf.has_sub_devices = False return rf class ICx90Radio_tv(ICx90Radio): VARIANT = "TV" def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_name = True rf.has_bank = False rf.has_bank_index = False rf.has_bank_names = False rf.can_delete = True rf.has_ctone = False rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_tuning_step = False rf.has_comment = False rf.has_sub_devices = False rf.memory_bounds = (0, TV_CHANNELS - 1) rf.valid_characters = CHARSET rf.valid_modes = list(TV_MODE) rf.valid_tmodes = [] rf.valid_duplexes = [""] rf.valid_tuning_steps = [] rf.valid_bands = [(46750000, 957750000)] rf.valid_skips = ["", "S"] rf.valid_name_length = TV_NAME_LENGTH rf.valid_special_chans = [] return rf def get_bank_model(self): return None def freq_chirp2icom(self, freq): return freq / 5000 def freq_icom2chirp(self, freq): return freq * 5000 def get_skip(self, number): if self.memobj.tv_channel_skip[number] == 2: return "S" return "" def set_skip(self, number, skip): if skip == "S": self.memobj.tv_channel_skip[number] = 2 elif skip == "": self.memobj.tv_channel_skip[number] = 0 else: raise errors.InvalidDataError("skip '%s' not supported" % skip) def get_raw_memory(self, number): return repr(self.memobj.tv_memory[number]) def get_memory(self, number): mem = chirp_common.Memory() mem_item = self.memobj.tv_memory[number] mem.freq = self.freq_icom2chirp(mem_item.freq) if self.memobj.tv_channel_skip[number] == 1: mem.empty = True mem.mode = TV_MODE[0] else: mem.empty = False mem.name = str(mem_item.name).rstrip("\x00 ") mem.mode = TV_MODE[mem_item.mode] mem.skip = self.get_skip(number) mem.number = number return mem def set_memory(self, memory): mem_item = self.memobj.tv_memory[memory.number] if memory.empty: self.memobj.tv_channel_skip[memory.number] = 1 mem_item.set_raw("\x00" * TV_MEM_ITEM_SIZE) else: mem_item.freq = self.freq_chirp2icom(memory.freq) for x in range(TV_NAME_LENGTH): try: mem_item.name[x] = str(memory.name[x]) except IndexError: mem_item.name[x] = " " mem_item.mode = TV_MODE.index(memory.mode) self.set_skip(memory.number, memory.skip) def dump_banks(icx90, template_file): mb = icx90.get_features().memory_bounds with open(template_file, "w") as f: for mi in range(mb[0], mb[1] + 1): mem = icx90.get_memory(mi) bank = icx90._get_bank(mi) if bank is not None: bank = BANK_INDEX[bank] bank_pos = icx90._get_bank_index(mi) if not mem.empty and bank is not None and bank_pos is not None: f.write("%s;%s;%d\n" % (mem.name, bank, bank_pos)) def read_template_file(template_file): banks_templ = {} with open(template_file, "r") as f: for line in f: l = line.split(";") l[1] = BANK_INDEX.index(l[1]) banks_templ[l[0]] = l[1:] return banks_templ def reorder_banks(icx90, preserve_position, preserve_unknown, banks_templ): banks_cnt = [] mb = icx90.get_features().memory_bounds for i in range(0, BANKS): banks_cnt.append(0) for mi in range(mb[0], mb[1] + 1): mem = icx90.get_memory(mi) if preserve_unknown: bank = icx90._get_bank(mi) bank_pos = icx90._get_bank_index(mi) else: bank = None bank_pos = 0 if not mem.empty: if mem.name in banks_templ: bank = int(banks_templ[mem.name][0]) if preserve_position: bank_pos = int(banks_templ[mem.name][1]) else: bank_pos = banks_cnt[bank] banks_cnt[bank] += 1 print("%s\t-> %s, %02d" % (mem.name, BANK_INDEX[bank], bank_pos)) # explicitly set non empty channel as visible icx90.memobj.banks[mi].invisible_channel = 0 if bank >= BANKS or bank_pos >= BANK_NUM: bank = None bank_pos = 0 icx90._set_bank(mi, bank) icx90._set_bank_index(mi, bank_pos) if __name__ == "__main__": parser = argparse.ArgumentParser(description="Icom IC-E90 banks handling helper.") parser.add_argument("icx90_img_file", help="IC-X90 IMG file.") parser.add_argument("template_file", help="Banks template file.") parser.add_argument("-r", "--read-banks", action="store_true", help="Read banks content and store it to template file.") parser.add_argument("-f", "--fix-banks", action="store_true", help="Fix banks content, reorder channels in banks according to the provided template file and write it to IMG file.") parser.add_argument("-p", "--preserve-position", action="store_true", help="Preserve bank position as in the template file if possible, otherwise put channels to banks according their position in the memory.") parser.add_argument("-u", "--preserve-unknown", action="store_true", help="Preserve channels in banks if they aren't in the template file and don't conflicts with the template file, otherwise remove them from the banks.") parser.add_argument("-b", "--backup_img", action="store_true", help="Backup IMG file before changing it.") args = vars(parser.parse_args()) options_ok = True try: icx90_img_file = str(args.pop("icx90_img_file")) template_file = str(args.pop("template_file")) except KeyError: options_ok = False if options_ok and (args["read_banks"] or args["fix_banks"]): icx90 = ICx90Radio(icx90_img_file) if args["read_banks"]: dump_banks(icx90, template_file) elif args["fix_banks"]: banks_templ = read_template_file(template_file) if args["backup_img"]: icx90.save_mmap(icx90_img_file + ".bak") reorder_banks(icx90, args["preserve_position"], args["preserve_unknown"], banks_templ) icx90.save_mmap(icx90_img_file) else: parser.print_help() chirp-20240224/chirp/drivers/ft2d.py0000644000175000017500000001524314446523722016046 0ustar hibbyhibby# Copyright 2010 Dan Smith # Portions Copyright 2017 Wade Simmons # Copyright 2017 Declan Rieb # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import ft1d from chirp import chirp_common, directory from chirp import errors from chirp import memmap from chirp.settings import RadioSetting from chirp.settings import RadioSettingValueString from chirp import util # Differences from Yaesu FT1D # Text in memory and memory bank structures is ASCII encoded # Expanded modes # Slightly different clone-mode instructions LOG = logging.getLogger(__name__) TMODES = ["", "Tone", "TSQL", "DTCS", "RTone", "JRfrq", "PRSQL", "Pager"] class FT2Bank(chirp_common.NamedBank): # Like FT1D except for name in ASCII def get_name(self): _bank = self._model._radio._memobj.bank_info[self.index] name = "" for i in _bank.name: if i == 0xff: break name += chr(i & 0xFF) return name.rstrip() def set_name(self, name): _bank = self._model._radio._memobj.bank_info[self.index] _bank.name = [ord(x) for x in name.ljust(16, chr(0xFF))[:16]] class FT2BankModel(ft1d.FT1BankModel): # Just need this one to launch FT2Bank """A FT1D bank model""" def __init__(self, radio, name='Banks'): super(FT2BankModel, self).__init__(radio, name) _banks = self._radio._memobj.bank_info self._bank_mappings = [] for index, _bank in enumerate(_banks): bank = FT2Bank(self, "%i" % index, "BANK-%i" % index) bank.index = index self._bank_mappings.append(bank) @directory.register class FT2D(ft1d.FT1Radio): """Yaesu FT-2D""" BAUD_RATE = 38400 VENDOR = "Yaesu" MODEL = "FT2D" # Yaesu doesn't use a hyphen in its documents VARIANT = "R" _model = b"AH60M" # Get this from chirp .img file after saving once _has_vibrate = True MAX_MEM_SLOTS = 900 _mem_params = { "memnum": 900, # size of memories array "flgnum": 900, # size of flags array "dtmadd": 0x94A, # address of DTMF strings } _adms_ext = '.ft2d' _APRS_HIGH_SPEED_MAX = 90 FORMATS = [directory.register_format('FT2D ADMS-8', '*.ft2d')] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to DATA terminal.\n" "3. Press and hold [DISP] key while turning on radio\n" " (\"CLONE\" will appear on the display).\n" "4. After clicking OK here in chirp,\n" " press the [Send] screen button.\n") rp.pre_upload = _( " 1. Turn radio off.\n" " 2. Connect cable to DATA terminal.\n" " 3. Press and hold in [DISP] key while turning on radio\n" " (\"CLONE\" will appear on radio LCD).\n" " 4. Press [RECEIVE] screen button\n" " (\"-WAIT-\" will appear on radio LCD).\n" "5. Finally, press OK button below.\n") return rp def get_features(self): # AFAICT only TMODES & memory bounds are different rf = super(FT2D, self).get_features() rf.valid_tmodes = list(TMODES) rf.memory_bounds = (1, self.MAX_MEM_SLOTS) return rf def get_bank_model(self): # here only to launch the bank model return FT2BankModel(self) def _decode_label(self, mem): return str(mem.label).rstrip("\xFF") def _encode_label(self, mem): label = mem.name.rstrip().encode('ascii', 'ignore') return self._add_ff_pad(label, 16) def _decode_opening_message(self, opening_message): msg = "" for i in opening_message.message.padded_yaesu: if i == 0xFF: break msg += chr(int(i)) val = RadioSettingValueString(0, 16, msg) rs = RadioSetting("opening_message.message.padded_yaesu", "Opening Message", val) rs.set_apply_callback(self._apply_opening_message, opening_message.message.padded_yaesu) return rs def _apply_opening_message(self, setting, obj): data = self._add_ff_pad(setting.value.get_value().rstrip(), 16) val = [] for i in data: val.append(ord(i)) self._memobj.opening_message.message.padded_yaesu = val @directory.register class FT2Dv2(FT2D): """Yaesu FT-2D v2 firmware""" VARIANT = "Rv2" _model = b"AH60G" @directory.register class FT3D(FT2D): """Yaesu FT-3D""" MODEL = "FT3D" VARIANT = "R" _model = b"AH72M" FORMATS = [directory.register_format('FT3D ADMS-11', '*.ft3d')] def load_mmap(self, filename): if filename.lower().endswith('.ft3d'): with open(filename, 'rb') as f: self._adms_header = f.read(0x18C) if b'ADMS11, Version=1.0.0.0' not in self._adms_header: raise errors.ImageDetectFailed( 'Unsupported version found in ADMS file') LOG.debug('ADMS Header:\n%s', util.hexprint(self._adms_header)) self._mmap = memmap.MemoryMapBytes(f.read()) LOG.info('Loaded ADMS-11 file at offset 0x18C') self.process_mmap() else: chirp_common.CloneModeRadio.load_mmap(self, filename) def save_mmap(self, filename): if filename.lower().endswith('.ft3d'): if not hasattr(self, '_adms_header'): raise Exception('Unable to save .img to .ft3d') with open(filename, 'wb') as f: f.write(self._adms_header) f.write(self._mmap.get_packed()) LOG.info('Wrote ADMS-11 file') else: chirp_common.CloneModeRadio.save_mmap(self, filename) @classmethod def match_model(cls, filedata, filename): if filename.endswith('.ft3d'): return True else: return super().match_model(filedata, filename) chirp-20240224/chirp/drivers/ts850.py0000644000175000017500000002025314430171343016056 0ustar hibbyhibby# Copyright 2018 Antony Jordan # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import chirp_common, directory, errors from chirp.drivers.kenwood_live import KenwoodLiveRadio, \ command, iserr, NOCACHE LOG = logging.getLogger(__name__) TS850_DUPLEX = ["off", "split"] TS850_TMODES = ["", "Tone"] TS850_SKIP = ["", "S"] TS850_MODES = { "N/A0": " ", "N/A1": "0", "LSB": "1", "USB": "2", "CW": "3", "FM": "4", "AM": "5", "FSK": "6", "CW-R": "7", "FSK-R": "9", } TS850_MODES_REV = {val: mode for mode, val in TS850_MODES.items()} TS850_TONES = list(chirp_common.OLD_TONES) TS850_TONES.remove(69.3) TS850_BANDS = [ (1800000, 2000000), # 160M Band (3500000, 4000000), # 80M Band (7000000, 7300000), # 40M Band (10100000, 10150000), # 30M Band (14000000, 14350000), # 20M Band (18068000, 18168000), # 17M Band (21000000, 21450000), # 15M Band (24890000, 24990000), # 12M Band (28000000, 29700000) # 10M Band ] @directory.register class TS850Radio(KenwoodLiveRadio): """Kenwood TS-850""" MODEL = "TS-850" BAUD_RATE = 4800 _upper = 99 _kenwood_valid_tones = list(TS850_TONES) def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = True rf.has_bank = False rf.has_ctone = False rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_name = False rf.has_tuning_step = False rf.memory_bounds = (0, self._upper) rf.valid_bands = TS850_BANDS rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC rf.valid_duplexes = TS850_DUPLEX rf.valid_modes = list(TS850_MODES.keys()) rf.valid_skips = TS850_SKIP rf.valid_tmodes = TS850_TMODES return rf def get_memory(self, number): if number < 0 or number > self._upper: raise errors.InvalidMemoryLocation( "Number must be between 0 and %i" % self._upper) if number in self._memcache and not NOCACHE: return self._memcache[number] result = command(self.pipe, *self._cmd_get_memory(number)) if result == "N": mem = chirp_common.Memory() mem.number = number mem.empty = True self._memcache[mem.number] = mem return mem mem = self._parse_mem_spec(result) self._memcache[mem.number] = mem # check for split frequency operation result = command(self.pipe, *self._cmd_get_split(number)) self._parse_split_spec(mem, result) return mem def set_memory(self, memory): if memory.number < 0 or memory.number > self._upper: raise errors.InvalidMemoryLocation( "Number must be between 0 and %i" % self._upper) if memory.number > 90: if memory.duplex == TS850_DUPLEX[0]: memory.duplex = TS850_DUPLEX[1] memory.offset = memory.freq else: if memory.freq > memory.offset: temp = memory.freq memory.freq = memory.offset memory.offset = temp # Clear out memory contents to prevent errors spec = self._make_base_spec(memory, 0) spec = "".join(spec) result = command(self.pipe, *self._cmd_set_memory(memory.number, spec)) if iserr(result): raise errors.InvalidDataError("Radio refused %i" % memory.number) # If we have a split set the transmit frequency first. if memory.duplex == TS850_DUPLEX[1]: spec = "".join(self._make_split_spec(memory)) result = command(self.pipe, *self._cmd_set_split(memory.number, spec)) if iserr(result): raise errors.InvalidDataError("Radio refused %i" % memory.number) spec = self._make_mem_spec(memory) spec = "".join(spec) result = command(self.pipe, *self._cmd_set_memory(memory.number, spec)) if iserr(result): raise errors.InvalidDataError("Radio refused %i" % memory.number) def erase_memory(self, number): if number not in self._memcache: return resp = command(self.pipe, *self._cmd_erase_memory(number)) if iserr(resp): raise errors.RadioError("Radio refused delete of %i" % number) del self._memcache[number] def _cmd_get_memory(self, number): return "MR", "0 %02i" % number def _cmd_get_split(self, number): return "MR", "1 %02i" % number def _cmd_get_memory_name(self, number): LOG.error("TS-850 does not support memory channel names") return "" def _cmd_set_memory(self, number, spec): return "MW", "0 %02i%s" % (number, spec) def _cmd_set_split(self, number, spec): return "MW", "1 %02i%s" % (number, spec) def _cmd_set_memory_name(self, number, name): LOG.error("TS-850 does not support memory channel names") return "" def _cmd_erase_memory(self, number): return "MW0 %02i%014i " % (number, 0) def _parse_mem_spec(self, spec): mem = chirp_common.Memory() # pad string so indexes match Kenwood docs spec = " " + spec # Param Format Function _p1 = spec[3] # P1 9 Split Specification # _p2 = spec[4] # P2 - Blank _p3 = spec[5:7] # P3 7 Memory Channel _p4 = spec[7:18] # P4 4 Frequency _p5 = spec[18] # P5 2 Mode _p6 = spec[19] # P6 10 Memory Lockout _p7 = spec[20] # P7 1 Tone On/Off _p8 = spec[21:23] # P8 14 Tone Frequency # _p9 = spec[23] # P9 - Blank mem.duplex = TS850_DUPLEX[int(_p1)] mem.number = int(_p3) mem.freq = int(_p4) mem.mode = TS850_MODES_REV[_p5] mem.skip = TS850_SKIP[int(_p6)] mem.tmode = TS850_TMODES[int(_p7)] if mem.tmode == TS850_TMODES[1]: mem.rtone = TS850_TONES[int(_p8)-1] return mem def _parse_split_spec(self, mem, spec): # pad string so indexes match Kenwood docs spec = " " + spec split_freq = int(spec[7:18]) # P4 if mem.freq != 0: mem.duplex = "split" mem.offset = split_freq return mem def _make_base_spec(self, mem, freq): if mem.mode == "FM" \ and mem.duplex == TS850_DUPLEX[1] \ and mem.tmode == TS850_TMODES[1]: tmode = "1" tone = "%02i" % (TS850_TONES.index(mem.rtone)+1) else: tmode = "0" tone = " " spec = ( # Param Format Function "%011i" % freq, # P4 4 Frequency TS850_MODES[mem.mode], # P5 2 Mode # (Except Tune) "%i" % (mem.skip == TS850_SKIP[1]), # P6 10 Memory Lockout tmode, # P7 1 Tone On/Off tone, # P8 1 Tone Frequency " " # P9 14 Padding ) return spec def _make_mem_spec(self, mem): return self._make_base_spec(mem, mem.freq) def _make_split_spec(self, mem): return self._make_base_spec(mem, mem.offset) chirp-20240224/chirp/drivers/ic2730.py0000644000175000017500000013616014547737342016127 0ustar hibbyhibby# Copyright 2018 Rhett Robinson Vers 1.0 # 6/2019: Vers 1.1 Added Settings support, Rick DeWitt # 7/2020: Vers 1.2 Fixed reversed E:* / F:# DTMF codes Issue #8159 # 9/2020: Vers 1.3 Expanded tone mode support and added py3 HAS_FUTURE # bytes() per issue #8233. (icf.py is NOT updated) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import icf from chirp import chirp_common, directory, bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { u24 freq_flags:6, freq:18; u16 offset; u8 tune_step:4, unknown5:2, mode:2; u8 unknown6:2, rtone:6; u8 unknown7:2, ctone:6; u8 unknown8; u8 dtcs; u8 tmode:4, duplex:2, dtcs_polarity:2; char name[6]; } memory[1002]; #seekto 0x42c0; u8 used_flags[125]; #seekto 0x433e; u8 skip_flags[125]; u8 pskip_flags[125]; #seekto 0x4440; struct { u8 bank; u8 index; } bank_info[1000]; #seekto 0x4c40; struct { char com[16]; } comment; #seekto 0x4c50; struct { char name[6]; } bank_names[10]; #seekto 0x4cc8; struct{ u8 codes[24]; } dtmfcode[16]; #seekto 0x4c8c; struct { char nam[6]; } pslnam[10]; #seekto 0x4e80; struct { u24 loflags:6, lofreq:18; u24 hiflags:6, hifreq:18; u8 flag:4, mode:4; u8 tstp; char name[6]; } pgmscanedge[25]; #seekto 0x5000; struct { u8 aprichn; u8 bprichn; u8 autopwr; u8 unk5003; u8 autorptr; u8 rmtmic; // 0x05005 u8 pttlock; u8 bcl; u8 tot; u8 actband; u8 unk500a; u8 dialspdup; u8 toneburst; u8 micgain; u8 unk500e; u8 civaddr; u8 civbaud; u8 civtcvr; u8 sqlatt; u8 sqldly; u8 unk5014a:4, fanspeed:4; u8 unk5015; u8 bthvox; u8 bthvoxlvl; u8 bthvoxdly; u8 bthvoxtot; // 0x05019 u8 btoothon; u8 btoothauto; u8 bthdset; u8 bthhdpsav; u8 bth1ptt; // 0x0501e u8 bthpttbeep; u8 bthcustbeep; // 0x05020 u8 ascanpause; u8 bscanpause; u8 ascanresume; u8 bscanresume; u8 dtmfspd; u8 unk5026; u8 awxalert; u8 bwxalert; u8 aprgskpscn; u8 bprgskpscn; u8 memname; u8 contrast; u8 autodimtot; u8 autodim; u8 unk502f; u8 backlight; u8 unk5031; u8 unk5032; u8 openmsg; u8 beeplvl; // 0x05034 u8 keybeep; u8 scanstpbeep; u8 bandedgbeep; u8 subandmute; u8 atmpskiptym; u8 btmpskiptym; u32 vfohome; u8 vfohomeset; u16 homech; u8 mickyrxf1; u8 mickyrxf2; u8 mickyrxup; u8 mickyrxdn; // 0x05045 u8 bthplaykey; u8 bthfwdkey; u8 bthrwdkey; u8 mickytxf1; u8 mickytxf2; u8 mickytxup; u8 mickytxdn; u8 unk504d; u8 unk504e; u8 unk504f; u8 homebeep; u8 bthfctn; u8 unk5052; u8 unk5053; u8 ifxchg; u8 airbandch; u8 vhfpower; u8 uhfpower; u8 unk5058; u8 unk5059; u8 unk505a; u8 unk505b; u8 unk505c; u8 unk505d; u8 unk505e:6, rpthangup:1, unk505e2:1; u8 unk505f; } settings; #seekto 0x5220; struct { u16 left_memory; u16 right_memory; } initmem; #seekto 0x523e; struct { u8 awxchan; u8 bwxchan; } abwx; #seekto 0x5250; struct { u8 alnk[2]; u16 unk5252; u8 blnk[2]; } banklink; #seekto 0x5258; struct { u8 msk[4]; } pslgrps[25]; #seekto 0x5280; u16 mem_writes_count; """ MDUPLEX = ["", "-", "+"] MSKIPS = ["", "S", "P"] MMODES = ["FM", "NFM", "AM", "NAM"] MTONE_MODES = chirp_common.TONE_MODES MTMODES = ["", "Tone", "TonePoc", "TSQL", "DTCSPoc", "DTCS", "TSQL-R", "DTCS-R", "DTC.OFF", "TON.DTC", "DTC.TSQ", "TON.TSQ"] MCROSS_MODES = ["Tone->Tone", "DTCS->", "Tone->DTCS", "DTCS->Tone"] MDTCSP = ["NN", "NR", "RN", "RR"] MDTMF_CHARS = list("0123456789ABCD*#") MBANKLINK_CHARS = list("ABCDEFGHIJ") AUTOREPEATER = ["OFF", "DUP", "DUP.TON"] MICKEYOPTS = ["Off", "Up", "Down", "Vol Up", "Vol Down", "SQL Up", "SQL Down", "Monitor", "Call", "MR (Ch 0)", "MR (Ch 1)", "VFO/MR", "Home Chan", "Band/Bank", "Scan", "Temp Skip", "Main", "Mode", "Low", "Dup", "Priority", "Tone", "MW", "Mute", "T-Call", "DTMF Direct"] class IC2730Bank(icf.IcomNamedBank): """An IC2730 bank""" def get_name(self): _banks = self._model._radio._memobj.bank_names return str(_banks[self.index].name).rstrip() def set_name(self, name): _banks = self._model._radio._memobj.bank_names _banks[self.index].name = str(name).ljust(6)[:6] def _get_special(): special = {"C0": -2, "C1": -1} return special def _resolve_memory_number(number): if isinstance(number, str): return _get_special()[number] else: return number def _wipe_memory(mem, char): mem.set_raw(char * (mem.size() // 8)) @directory.register class IC2730Radio(icf.IcomCloneModeRadio): """Icom IC-2730A""" VENDOR = "Icom" MODEL = "IC-2730A" _model = "\x35\x98\x00\x01" _memsize = 21312 # 0x5340 _endframe = "Icom Inc\x2e4E" _ranges = [(0x0000, 0x5300, 64), (0x5300, 0x5310, 16), (0x5310, 0x5340, 48)] _num_banks = 10 _bank_class = IC2730Bank _can_hispeed = True _raw_frames = True _highbit_flip = True _icf_data = { 'MapRev': 1, 'EtcData': 0, # This might be wrong 'Comment': '', 'recordsize': 32, } @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = ('Click the Special Channels tab on the main screen to ' 'access the C0 and C1 frequencies.\n' 'The Pocket Beep tone/dtcs modes are not supported by ' 'CHIRP. Set those manually.\n') rp.pre_download = _( "Follow these instructions to download your config:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable to the Speaker-2 jack\n" "3 - Turn on your radio\n" "4 - Radio > Download from radio\n" "5 - Disconnect the interface cable! Otherwise there will be\n" " no right-side audio!\n") rp.pre_upload = _( "Follow these instructions to upload your config:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable to the Speaker-2 jack\n" "3 - Turn on your radio\n" "4 - Radio > Upload to radio\n" "5 - Disconnect the interface cable, otherwise there will be\n" " no right-side audio!\n" "6 - Cycle power on the radio to exit clone mode\n") return rp def _get_bank(self, loc): _bank = self._memobj.bank_info[loc] _bank.bank = _bank.bank & 0x1F # Bad index filter, fix issue #7031 if _bank.bank == 0x1F: return None else: return _bank.bank def _set_bank(self, loc, bank): _bank = self._memobj.bank_info[loc] if bank is None: _bank.bank = 0x1F else: _bank.bank = bank def _get_bank_index(self, loc): _bank = self._memobj.bank_info[loc] return _bank.index def _set_bank_index(self, loc, index): _bank = self._memobj.bank_info[loc] _bank.index = index def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank_index = True rf.has_bank_names = True rf.has_cross = True rf.has_ctone = True rf.has_dtcs = True rf.has_rx_dtcs = False rf.has_dtcs_polarity = True rf.requires_call_lists = False rf.memory_bounds = (0, 999) rf.valid_modes = MMODES rf.valid_tmodes = MTONE_MODES rf.valid_duplexes = MDUPLEX rf.valid_tuning_steps = list(chirp_common.TUNING_STEPS[0:9]) rf.valid_bands = [(118000000, 174000000), (375000000, 550000000)] rf.valid_skips = MSKIPS rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_cross_modes = MCROSS_MODES rf.valid_name_length = 6 rf.valid_special_chans = sorted(_get_special().keys()) return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_memory(self, number): mem = chirp_common.Memory() mem.number = _resolve_memory_number(number) if mem.number >= 0: _mem = self._memobj.memory[mem.number] bitpos = (1 << (number % 8)) bytepos = number / 8 _used = self._memobj.used_flags[bytepos] is_used = ((_used & bitpos) == 0) _skip = self._memobj.skip_flags[bytepos] _pskip = self._memobj.pskip_flags[bytepos] if _skip & bitpos: mem.skip = MSKIPS[1] # "S" elif _pskip & bitpos: mem.skip = MSKIPS[2] # "P" if not is_used: mem.empty = True return mem else: # C0, C1 specials _mem = self._memobj.memory[1002 + mem.number] # _mem.freq is stored as a multiple of a tuning step frequency_flags = int(_mem.freq_flags) frequency_multiplier = 5000 offset_multiplier = 5000 if frequency_flags & 0x08: frequency_multiplier = 6250 if frequency_flags & 0x01: offset_multiplier = 6250 if frequency_flags & 0x10: frequency_multiplier = 8333 if frequency_flags & 0x02: offset_multiplier = 8333 if frequency_flags & 0x10: # fix underflow val = int(_mem.freq) * frequency_multiplier mem.freq = round(val) else: mem.freq = int(_mem.freq) * frequency_multiplier if frequency_flags & 0x02: val = int(_mem.offset) * offset_multiplier mem.offset = round(val) else: mem.offset = int(_mem.offset) * offset_multiplier mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] tmx = 0 # MTONE_MODES index default cmx = 0 # MCROSS_MODES index if _mem.tmode == 1: # Tone tmx = 1 elif _mem.tmode == 3: # TSQL tmx = 2 elif _mem.tmode == 5: # DTCS tmx = 3 elif _mem.tmode == 6: # TSQL-R tmx = 5 elif _mem.tmode == 7: # DTCS-R tmx = 4 elif _mem.tmode == 8: # DTC.OFF tmx = 6 # Real Cross modes now cmx = 1 elif _mem.tmode == 9: # TON.DTC tmx = 6 cmx = 2 elif _mem.tmode == 10: # DTC.TSQ tmx = 6 cmx = 3 elif _mem.tmode == 11: # TON.TSQ tmx = 6 cmx = 0 mem.tmode = MTONE_MODES[tmx] mem.cross_mode = MCROSS_MODES[cmx] mem.duplex = MDUPLEX[_mem.duplex] mem.mode = MMODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = MDTCSP[_mem.dtcs_polarity] if _mem.tune_step > 8: mem.tuning_step = 5.0 # Sometimes TS is garbage? else: mem.tuning_step = chirp_common.TUNING_STEPS[_mem.tune_step] mem.name = str(_mem.name).rstrip() if mem.number == -2: mem.name = "C0" mem.extd_number = "C0" if mem.number == -1: mem.name = "C1" mem.extd_number = "C1" return mem def set_memory(self, mem): if mem.number >= 0: # Normal bitpos = (1 << (mem.number % 8)) bytepos = mem.number / 8 _mem = self._memobj.memory[mem.number] _used = self._memobj.used_flags[bytepos] was_empty = _used & bitpos skip = self._memobj.skip_flags[bytepos] pskip = self._memobj.pskip_flags[bytepos] if mem.skip == "S": skip |= bitpos else: skip &= ~bitpos if mem.skip == "P": pskip |= bitpos else: pskip &= ~bitpos if mem.empty: _used |= bitpos _wipe_memory(_mem, "\xFF") self._set_bank(mem.number, None) return _used &= ~bitpos if was_empty: _wipe_memory(_mem, "\x00") _mem.name = mem.name.ljust(6) else: # Specials: -2 and -1 _mem = self._memobj.memory[1002 + mem.number] # Common to both types frequency_flags = 0x00 frequency_multiplier = 5000 offset_multiplier = 5000 if mem.freq % 5000 != 0 and mem.freq % 6250 == 0: frequency_flags |= 0x08 frequency_multiplier = 6250 elif mem.freq % 8333 == 0: frequency_flags |= 0x10 frequency_multiplier = 8333 if mem.offset % 5000 != 0 and mem.offset % 6250 == 0: frequency_flags |= 0x01 offset_multiplier = 6250 elif mem.offset % 8333 == 0: frequency_flags |= 0x02 offset_multiplier = 8333 _mem.freq = mem.freq / frequency_multiplier _mem.offset = mem.offset / offset_multiplier _mem.freq_flags = frequency_flags _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) tmx = MTONE_MODES.index(mem.tmode) cmx = MCROSS_MODES.index(mem.cross_mode) if tmx != 6: # Not Cross if tmx < 2: # "", Tone _mem.tmode = tmx if tmx == 2: # TSQL _mem.tmode = 3 if tmx == 3: # DTCS _mem.tmode = 5 if tmx == 4: # DTCS-R _mem.tmode = 7 if tmx == 5: # TSQL-R _mem.tmode = 6 else: # Cross modes if cmx == 0: # Tone->Tone _mem.tmode = 11 if cmx == 1: # DTCS-> _mem.tmode = 8 if cmx == 2: # Tone->DTCS _mem.tmode = 9 if cmx == 3: # DTCS->Tone _mem.tmode = 10 _mem.duplex = MDUPLEX.index(mem.duplex) _mem.mode = MMODES.index(mem.mode) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = MDTCSP.index(mem.dtcs_polarity) _mem.tune_step = chirp_common.TUNING_STEPS.index(mem.tuning_step) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_settings(self): """Translate the MEM_FORMAT structs into settings in the UI""" # Define mem struct write-back shortcuts _sets = self._memobj.settings _cmnt = self._memobj.comment _wxch = self._memobj.abwx _dtm = self._memobj.dtmfcode _pses = self._memobj.pgmscanedge _bklk = self._memobj.banklink basic = RadioSettingGroup("basic", "Basic Settings") mickey = RadioSettingGroup("mickey", "Microphone Keys") bluet = RadioSettingGroup("bluet", "Bluetooth") disp = RadioSettingGroup("disp", "Display") sound = RadioSettingGroup("sound", "Sounds") dtmf = RadioSettingGroup("dtmf", "DTMF Codes") abset = RadioSettingGroup("abset", "A/B Band Settings") edges = RadioSettingGroup("edges", "Program Scan Edges") pslnk = RadioSettingGroup("pslnk", "Program Scan Links") other = RadioSettingGroup("other", "Other Settings") group = RadioSettings(basic, disp, sound, mickey, dtmf, abset, bluet, edges, pslnk, other) def mic_keys(setting, obj, atrb): """ Callback to set subset of mic key options """ stx = str(setting.value) value = MICKEYOPTS.index(stx) setattr(obj, atrb, value) return def hex_val(setting, obj, atrb): """ Callback to store string as hex values """ value = int(str(setting.value), 16) setattr(obj, atrb, value) return def unpack_str(codestr): """Convert u8 DTMF array to a string: NOT a callback.""" stx = "" for i in range(0, 24): # unpack up to ff if codestr[i] != 0xff: # Issue 8159 fix if codestr[i] == 0x0E: stx += "*" elif codestr[i] == 0x0F: stx += "#" else: stx += format(int(codestr[i]), '0X') return stx def pack_chars(setting, obj, atrb, ndx): """Callback to build 0-9,A-D,*# nibble array from string""" # String will be f padded to 24 bytes # Chars are stored as hex values ary = [] stx = str(setting.value).upper() stx = stx.strip() # trim spaces # Remove illegal characters first sty = "" for j in range(0, len(stx)): if stx[j] in MDTMF_CHARS: sty += stx[j] for j in range(0, 24): if j < len(sty): # Issue 8159 fix if sty[j] == "*": chrv = 0xE elif sty[j] == "#": chrv = 0xF else: chrv = int(sty[j], 16) else: # pad to 24 bytes chrv = 0xFF ary.append(chrv) # append byte setattr(obj[ndx], atrb, ary) return def myset_comment(setting, obj, atrb, knt): """ Callback to create space-padded char array""" stx = str(setting.value) for i in range(0, knt): if i > len(stx): str.append(0x20) setattr(obj, atrb, stx) return def myset_psnam(setting, obj, ndx, atrb, knt): """ Callback to generate space-padded, uppercase char array """ # This sub also is specific to object arrays stx = str(setting.value).upper() for i in range(0, knt): if i > len(stx): str.append(0x20) setattr(obj[ndx], atrb, stx) return def myset_frqflgs(setting, obj, ndx, flg, frq): """ Callback to gen flag/freq pairs """ vfrq = float(str(setting.value)) vfrq = int(vfrq * 1000000) vflg = 0x10 if vfrq % 6250 == 0: vflg = 0x08 vfrq = int(vfrq / 6250) elif vfrq % 5000 == 0: vflg = 0 vfrq = int(vfrq / 5000) else: vfrq = int(vfrq / 8333) setattr(obj[ndx], flg, vflg) setattr(obj[ndx], frq, vfrq) return def banklink(ary): """ Sub to generate A-J string from 2-byte bit pattern """ stx = "" for kx in range(0, 10): if kx < 8: val = ary[0] msk = 1 << kx else: val = ary[1] msk = 1 << (kx - 8) if val & msk: stx += chr(kx + 65) else: stx += "_" return stx def myset_banklink(setting, obj, atrb): """Callback to create 10-bit, u8[2] array from 10 char string""" stx = str(setting.value).upper() ary = [0, 0] for kx in range(0, 10): if stx[kx] == chr(kx + 65): if kx < 8: ary[0] = ary[0] + (1 << kx) else: ary[1] = ary[1] + (1 << (kx - 8)) setattr(obj, atrb, ary) return def myset_tsopt(setting, obj, ndx, atrb, bx): """ Callback to set scan Edge tstep """ stx = str(setting.value) flg = 0 if stx == "-": val = 0xff else: if bx == 1: # Air band if stx == "Auto": val = 0xe elif stx == "25k": val = 8 elif stx == "8.33k": val = 2 else: # VHF or UHF optx = ["-", "5k", "6.25k", "10k", "12.5k", "15k", "20k", "25k", "30k", "50k"] val = optx.index(stx) + 1 setattr(obj[ndx], atrb, val) # and set flag setattr(obj[ndx], "flag", flg) return def myset_mdopt(setting, obj, ndx, atrb, bx): """ Callback to set Scan Edge mode """ stx = str(setting.value) if stx == "-": val = 0xf elif stx == "FM": val = 0 else: val = 1 setattr(obj[ndx], atrb, val) return def myset_bitmask(setting, obj, ndx, atrb, knt): """ Callback to generate byte-array bitmask from string""" # knt is BIT count to process lsx = str(setting.value).strip().split(",") for kx in range(0, len(lsx)): try: lsx[kx] = int(lsx[kx]) except Exception: lsx[kx] = -99 # will nop ary = [0, 0, 0, 0xfe] for kx in range(0, knt): if kx < 8: if kx in lsx: ary[0] += 1 << kx elif kx >= 8 and kx < 16: if kx in lsx: ary[1] += 1 << (kx - 8) elif kx >= 16 and kx < 24: if kx in lsx: ary[2] += 1 << (kx - 16) else: if kx in lsx: # only bit 25 ary[3] += 1 setattr(obj[ndx], atrb, ary) return # --- Basic options = ["Off", "S-Meter Squelch", "ATT"] rx = RadioSettingValueList(options, options[_sets.sqlatt]) rset = RadioSetting("settings.sqlatt", "Squelch/ATT", rx) basic.append(rset) options = ["Short", "Long"] rx = RadioSettingValueList(options, options[_sets.sqldly]) rset = RadioSetting("settings.sqldly", "Squelch Delay", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(_sets.pttlock)) rset = RadioSetting("settings.pttlock", "PTT Lockout", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bcl)) rset = RadioSetting("settings.bcl", "Busy Channel Lockout", rx) basic.append(rset) options = ["Off", "1m", "3m", "5m", "10m", "15m", "30m"] rx = RadioSettingValueList(options, options[_sets.tot]) rset = RadioSetting("settings.tot", "Tx Timeout", rx) basic.append(rset) val = int(_sets.vfohome) if val == 0xffff: val = 0 val = val / 1000000.0 rx = RadioSettingValueFloat(0.0, 550.0, val, 0.005, 4) rx.set_mutable(False) rset = RadioSetting("settings.vfohome", "Home VFO (Read-Only)", rx) basic.append(rset) val = _sets.homech if val == 0xffff: val = -1 rx = RadioSettingValueInteger(-1, 999, val) rx.set_mutable(False) rset = RadioSetting("settings.homech", "Home Channel (Read-Only)", rx) basic.append(rset) options = ["1", "2", "3", "4"] rx = RadioSettingValueList(options, options[_sets.micgain]) rset = RadioSetting("settings.micgain", "Microphone Gain", rx) basic.append(rset) _bmem = self._memobj.initmem rx = RadioSettingValueInteger(0, 999, _bmem.left_memory) rset = RadioSetting("initmem.left_memory", "Left Bank Initial Mem Chan", rx) basic.append(rset) rx = RadioSettingValueInteger(0, 999, _bmem.right_memory) rset = RadioSetting("initmem.right_memory", "Right Bank Initial Mem Chan", rx) basic.append(rset) stx = "" for i in range(0, 16): stx += chr(int(_cmnt.com[i])) stx = stx.rstrip() rx = RadioSettingValueString(0, 16, stx) rset = RadioSetting("comment.com", "Comment (16 chars)", rx) rset.set_apply_callback(myset_comment, _cmnt, "com", 16) basic.append(rset) # --- Other rset = RadioSetting("drv_clone_speed", "Use Hi-Speed Clone", RadioSettingValueBoolean(self._can_hispeed)) other.append(rset) options = ["Single", "All", "Ham"] rx = RadioSettingValueList(options, options[_sets.actband]) rset = RadioSetting("settings.actband", "Active Band", rx) other.append(rset) options = ["Slow", "Mid", "Fast", "Auto"] rx = RadioSettingValueList(options, options[_sets.fanspeed]) rset = RadioSetting("settings.fanspeed", "Fan Speed", rx) other.append(rset) rx = RadioSettingValueBoolean(bool(_sets.dialspdup)) rset = RadioSetting("settings.dialspdup", "Dial Speed-Up", rx) other.append(rset) options = ["Off", "On(Dup)", "On(Dup+Tone)"] rx = RadioSettingValueList(options, options[_sets.autorptr]) rset = RadioSetting("settings.autorptr", "Auto Repeater", rx) other.append(rset) rx = RadioSettingValueBoolean(bool(_sets.rmtmic)) rset = RadioSetting("settings.rmtmic", "One-Touch PTT (Remote Mic)", rx) other.append(rset) options = ["Low", "Mid", "High"] rx = RadioSettingValueList(options, options[_sets.vhfpower]) rset = RadioSetting("settings.vhfpower", "VHF Power Default", rx) other.append(rset) rx = RadioSettingValueList(options, options[_sets.uhfpower]) rset = RadioSetting("settings.uhfpower", "UHF Power Default", rx) other.append(rset) rx = RadioSettingValueBoolean(bool(_sets.toneburst)) rset = RadioSetting("settings.toneburst", "1750 Hz Tone Burst", rx) other.append(rset) rx = RadioSettingValueBoolean(bool(_sets.ifxchg)) rset = RadioSetting("settings.ifxchg", "IF Exchange", rx) other.append(rset) rx = RadioSettingValueBoolean(bool(_sets.rpthangup)) rset = RadioSetting("settings.rpthangup", "Repeater Hang up Timeout", rx) other.append(rset) stx = str(_sets.civaddr)[2:] # Hex value rx = RadioSettingValueString(1, 2, stx) rset = RadioSetting("settings.civaddr", "CI-V Address (90)", rx) rset.set_apply_callback(hex_val, _sets, "civaddr") other.append(rset) options = ["1200", "2400", "4800", "9600", "19200", "Auto"] rx = RadioSettingValueList(options, options[_sets.civbaud]) rset = RadioSetting("settings.civbaud", "CI-V Baud Rate (bps)", rx) other.append(rset) rx = RadioSettingValueBoolean(bool(_sets.civtcvr)) rset = RadioSetting("settings.civtcvr", "CI-V Transceive", rx) other.append(rset) # A/B Band Settings options = ["Off", "On", "Bell"] rx = RadioSettingValueList(options, options[_sets.aprichn]) rset = RadioSetting("settings.aprichn", "A Band: VFO Priority Watch Mode", rx) abset.append(rset) options = ["2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "Hold"] rx = RadioSettingValueList(options, options[_sets.ascanpause]) rset = RadioSetting("settings.ascanpause", "-- A Band: Scan Pause Time (Secs)", rx) abset.append(rset) options = ["0", "1", "2", "3", "4", "5", "Hold"] rx = RadioSettingValueList(options, options[_sets.ascanresume]) rset = RadioSetting("settings.ascanresume", "-- A Band: Scan Resume Time (Secs)", rx) abset.append(rset) options = ["5", "10", "15"] rx = RadioSettingValueList(options, options[_sets.atmpskiptym]) rset = RadioSetting("settings.atmpskiptym", "-- A Band: Temp Skip Time (Secs)", rx) abset.append(rset) rx = RadioSettingValueBoolean(bool(_sets.aprgskpscn)) rset = RadioSetting("settings.aprgskpscn", "-- A Band: Program Skip Scan", rx) abset.append(rset) rx = RadioSettingValueString(10, 10, banklink(_bklk.alnk)) rset = RadioSetting("banklink.alnk", "-- A Band Banklink (use _ to skip)", rx) rset.set_apply_callback(myset_banklink, _bklk, "alnk") abset.append(rset) rx = RadioSettingValueBoolean(bool(_sets.awxalert)) rset = RadioSetting("settings.awxalert", "-- A Band: Weather Alert", rx) abset.append(rset) # Use list for Wx chans since chan 1 = index 0 options = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] rx = RadioSettingValueList(options, options[_wxch.awxchan]) rset = RadioSetting("abwx.awxchan", "-- A Band: Weather Channel", rx) abset.append(rset) options = ["Off", "On", "Bell"] rx = RadioSettingValueList(options, options[_sets.bprichn]) rset = RadioSetting("settings.bprichn", "B Band: VFO Priority Watch Mode", rx) abset.append(rset) options = ["2", "4", "6", "8", "10", "12", "14", "16", "18", "20", "Hold"] rx = RadioSettingValueList(options, options[_sets.bscanpause]) rset = RadioSetting("settings.bscanpause", "-- B Band: Scan Pause Time (Secs)", rx) abset.append(rset) options = ["0", "1", "2", "3", "4", "5", "Hold"] rx = RadioSettingValueList(options, options[_sets.bscanresume]) rset = RadioSetting("settings.bscanresume", "-- B Band: Scan Resume Time (Secs)", rx) abset.append(rset) options = ["5", "10", "15"] rx = RadioSettingValueList(options, options[_sets.btmpskiptym]) rset = RadioSetting("settings.btmpskiptym", "-- B Band: Temp Skip Time (Secs)", rx) abset.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bprgskpscn)) rset = RadioSetting("settings.bprgskpscn", "-- B Band: Program Skip Scan", rx) abset.append(rset) rx = RadioSettingValueString(10, 10, banklink(_bklk.blnk)) rset = RadioSetting("banklink.blnk", "-- B Band Banklink (use _ to skip)", rx) rset.set_apply_callback(myset_banklink, _bklk, "blnk") abset.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bwxalert)) rset = RadioSetting("settings.bwxalert", "-- B Band: Weather Alert", rx) abset.append(rset) options = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] rx = RadioSettingValueList(options, options[_wxch.bwxchan]) rset = RadioSetting("abwx.bwxchan", "-- B Band: Weather Channel", rx) abset.append(rset) # --- Microphone Keys # The Mic keys get weird: stored values are indecis to the full # options list, but only a subset is valid... shortopts = ["Off", "Monitor", "MR (Ch 0)", "MR (Ch 1)", "Band/Bank", "Scan", "Temp Skip", "Mode", "Low", "Dup", "Priority", "Tone", "MW", "Mute", "DTMF Direct", "T-Call"] ptr = shortopts.index(MICKEYOPTS[_sets.mickyrxf1]) rx = RadioSettingValueList(shortopts, shortopts[ptr]) rset = RadioSetting("settings.mickyrxf1", "During Rx/Standby [F-1]", rx) rset.set_apply_callback(mic_keys, _sets, "mickyrxf1") mickey.append(rset) ptr = shortopts.index(MICKEYOPTS[_sets.mickyrxf2]) rx = RadioSettingValueList(shortopts, shortopts[ptr]) rset = RadioSetting("settings.mickyrxf2", "During Rx/Standby [F-2]", rx) rset.set_apply_callback(mic_keys, _sets, "mickyrxf2") mickey.append(rset) options = ["Off", "Low", "T-Call"] # NOT a subset of MICKEYOPTS rx = RadioSettingValueList(options, options[_sets.mickytxf1]) rset = RadioSetting("settings.mickytxf1", "During Tx [F-1]", rx) mickey.append(rset) rx = RadioSettingValueList(options, options[_sets.mickytxf2]) rset = RadioSetting("settings.mickytxf2", "During Tx [F-2]", rx) mickey.append(rset) # These next two get the full options list rx = RadioSettingValueList(MICKEYOPTS, MICKEYOPTS[_sets.mickyrxup]) rset = RadioSetting("settings.mickyrxup", "During Rx/Standby [Up]", rx) mickey.append(rset) rx = RadioSettingValueList(MICKEYOPTS, MICKEYOPTS[_sets.mickyrxdn]) rset = RadioSetting("settings.mickyrxdn", "During Rx/Standby [Down]", rx) mickey.append(rset) options = ["Off", "Low", "T-Call"] rx = RadioSettingValueList(options, options[_sets.mickytxup]) rset = RadioSetting("settings.mickytxup", "During Tx [Up]", rx) mickey.append(rset) rx = RadioSettingValueList(options, options[_sets.mickytxdn]) rset = RadioSetting("settings.mickytxdn", "During Tx [Down]", rx) mickey.append(rset) # --- Bluetooth rx = RadioSettingValueBoolean(bool(_sets.btoothon)) rset = RadioSetting("settings.btoothon", "Bluetooth", rx) bluet.append(rset) rx = RadioSettingValueBoolean(bool(_sets.btoothauto)) rset = RadioSetting("settings.btoothauto", "Auto Connect", rx) bluet.append(rset) options = ["Headset Only", "Headset & Speaker"] rx = RadioSettingValueList(options, options[_sets.bthdset]) rset = RadioSetting("settings.bthdset", "Headset Audio", rx) bluet.append(rset) options = ["Normal", "Microphone", "PTT (Audio:Main)", "PTT(Audio:Controller)"] rx = RadioSettingValueList(options, options[_sets.bthfctn]) rset = RadioSetting("settings.bthfctn", "Headset Function", rx) bluet.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bthvox)) rset = RadioSetting("settings.bthvox", "Vox", rx) bluet.append(rset) options = ["Off", "1.0", "2", "3", "4", "5", "6", "7", "8", "9", "10"] rx = RadioSettingValueList(options, options[_sets.bthvoxlvl]) rset = RadioSetting("settings.bthvoxlvl", "Vox Level", rx) bluet.append(rset) options = ["0.5", "1.0", "1.5", "2.0", "2.5", "3.0"] rx = RadioSettingValueList(options, options[_sets.bthvoxdly]) rset = RadioSetting("settings.bthvoxdly", "Vox Delay (Secs)", rx) bluet.append(rset) options = ["Off", "1", "2", "3", "4", "5", "10", "15"] rx = RadioSettingValueList(options, options[_sets.bthvoxtot]) rset = RadioSetting("settings.bthvoxtot", "Vox Time-Out (Mins)", rx) bluet.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bthhdpsav)) rset = RadioSetting("settings.bthhdpsav", "ICOM Headset Power-Save", rx) bluet.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bth1ptt)) rset = RadioSetting("settings.bth1ptt", "ICOM Headset One-Touch PTT", rx) bluet.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bthpttbeep)) rset = RadioSetting("settings.bthpttbeep", "ICOM Headset PTT Beep", rx) bluet.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bthcustbeep)) rset = RadioSetting("settings.bthcustbeep", "ICOM Headset Custom Key Beep", rx) bluet.append(rset) rx = RadioSettingValueList(MICKEYOPTS, MICKEYOPTS[_sets.bthplaykey]) rset = RadioSetting("settings.bthplaykey", "ICOM Headset Custom Key [Play]", rx) bluet.append(rset) rx = RadioSettingValueList(MICKEYOPTS, MICKEYOPTS[_sets.bthfwdkey]) rset = RadioSetting("settings.bthfwdkey", "ICOM Headset Custom Key [Fwd]", rx) bluet.append(rset) rx = RadioSettingValueList(MICKEYOPTS, MICKEYOPTS[_sets.bthrwdkey]) rset = RadioSetting("settings.bthrwdkey", "ICOM Headset Custom Key [Rwd]", rx) bluet.append(rset) # ---- Display options = ["1: Dark", "2", "3", "4: Bright"] rx = RadioSettingValueList(options, options[_sets.backlight]) rset = RadioSetting("settings.backlight", "Backlight Level", rx) disp.append(rset) options = ["Off", "Auto-Off", "Auto-1", "Auto-2", "Auto-3"] rx = RadioSettingValueList(options, options[_sets.autodim]) rset = RadioSetting("settings.autodim", "Auto Dimmer", rx) disp.append(rset) options = ["5", "10"] rx = RadioSettingValueList(options, options[_sets.autodimtot]) rset = RadioSetting("settings.autodimtot", "Auto-Dimmer Timeout (Secs)", rx) disp.append(rset) options = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] rx = RadioSettingValueList(options, options[_sets.contrast]) rset = RadioSetting("settings.contrast", "LCD Contrast", rx) disp.append(rset) rx = RadioSettingValueBoolean(bool(_sets.openmsg)) rset = RadioSetting("settings.openmsg", "Opening Message", rx) disp.append(rset) rx = RadioSettingValueBoolean(bool(_sets.memname)) rset = RadioSetting("settings.memname", "Memory Names", rx) disp.append(rset) options = ["CH ID", "Frequency"] rx = RadioSettingValueList(options, options[_sets.airbandch]) rset = RadioSetting("settings.airbandch", "Air Band Display", rx) disp.append(rset) # -- Sounds rx = RadioSettingValueInteger(0, 9, _sets.beeplvl) rset = RadioSetting("settings.beeplvl", "Beep Level", rx) sound.append(rset) rx = RadioSettingValueBoolean(bool(_sets.homebeep)) rset = RadioSetting("settings.homebeep", "Home Chan Beep", rx) sound.append(rset) rx = RadioSettingValueBoolean(bool(_sets.keybeep)) rset = RadioSetting("settings.keybeep", "Key Touch Beep", rx) sound.append(rset) rx = RadioSettingValueBoolean(bool(_sets.bandedgbeep)) rset = RadioSetting("settings.bandedgbeep", "Band Edge Beep", rx) sound.append(rset) rx = RadioSettingValueBoolean(bool(_sets.scanstpbeep)) rset = RadioSetting("settings.scanstpbeep", "Scan Stop Beep", rx) sound.append(rset) options = ["Off", "Mute", "Beep", "Mute & Beep"] rx = RadioSettingValueList(options, options[_sets.subandmute]) rset = RadioSetting("settings.subandmute", "Sub Band Mute", rx) sound.append(rset) # --- DTMF Codes options = ["100", "200", "300", "500"] rx = RadioSettingValueList(options, options[_sets.dtmfspd]) rset = RadioSetting("settings.dtmfspd", "DTMF Speed (mSecs)", rx) dtmf.append(rset) for kx in range(0, 16): stx = unpack_str(_dtm[kx].codes) rx = RadioSettingValueString(0, 24, stx) # NOTE the / to indicate indexed array rset = RadioSetting("dtmfcode/%d.codes" % kx, "DTMF Code %X" % kx, rx) rset.set_apply_callback(pack_chars, _dtm, "codes", kx) dtmf.append(rset) # --- Program Scan Edges for kx in range(0, 25): stx = "" for i in range(0, 6): stx += chr(int(_pses[kx].name[i])) stx = stx.rstrip() rx = RadioSettingValueString(0, 6, stx) rset = RadioSetting("pgmscanedge/%d.name" % kx, "Program Scan %d Name" % kx, rx) rset.set_apply_callback(myset_psnam, _pses, kx, "name", 6) edges.append(rset) # Freq's use the multiplier flags fmult = 5000.0 if _pses[kx].loflags == 0x10: fmult = 8333 if _pses[kx].loflags == 0x08: fmult = 6250.0 flow = (int(_pses[kx].lofreq) * fmult) / 1000000.0 flow = round(flow, 4) fmult = 5000.0 if _pses[kx].hiflags == 0x10: fmult = 8333 if _pses[kx].hiflags == 0x08: fmult = 6250.0 fhigh = (int(_pses[kx].hifreq) * fmult) / 1000000.0 fhigh = round(fhigh, 4) if (flow > 0) and (flow >= fhigh): # reverse em val = flow flow = fhigh fhigh = val rx = RadioSettingValueFloat(0, 550.0, flow, 0.010, 3) rset = RadioSetting("pgmscanedge/%d.lofreq" % kx, "-- Scan %d Low Limit" % kx, rx) rset.set_apply_callback(myset_frqflgs, _pses, kx, "loflags", "lofreq") edges.append(rset) rx = RadioSettingValueFloat(0, 550.0, fhigh, 0.010, 3) rset = RadioSetting("pgmscanedge/%d.hifreq" % kx, "-- Scan %d High Limit" % kx, rx) rset.set_apply_callback(myset_frqflgs, _pses, kx, "hiflags", "hifreq") edges.append(rset) # Tstep and Mode depend on the bands ndxt = 0 ndxm = 0 bxnd = 0 tsopt = ["-", "5k", "6.25k", "10k", "12.5k", "15k", "20k", "25k", "30k", "50k"] mdopt = ["-", "FM", "FM-N"] if fhigh > 0: if fhigh < 135.0: # Air band bxnd = 1 tsopt = ["-", "8.33k", "25k", "Auto"] ndxt = _pses[kx].tstp if ndxt == 0xe: # Auto ndxt = 3 elif ndxt == 8: # 25k ndxt = 2 elif ndxt == 2: # 8.33k ndxt = 1 else: ndxt = 0 mdopt = ["-"] elif (flow >= 137.0) and (fhigh <= 174.0): # VHF ndxt = _pses[kx].tstp - 1 ndxm = _pses[kx].mode + 1 bxnd = 2 elif (flow >= 375.0) and (fhigh <= 550.0): # UHF ndxt = _pses[kx].tstp - 1 ndxm = _pses[kx].mode + 1 bxnd = 3 else: # Mixed, ndx's = 0 default tsopt = ["-"] mdopt = ["-"] bxnd = 4 if (ndxt > 9) or (ndxt < 0): ndxt = 0 # trap ff if ndxm > 2: ndxm = 0 # end if fhigh > 0 rx = RadioSettingValueList(tsopt, tsopt[ndxt]) rset = RadioSetting("pgmscanedge/%d.tstp" % kx, "-- Scan %d Freq Step" % kx, rx) rset.set_apply_callback(myset_tsopt, _pses, kx, "tstp", bxnd) edges.append(rset) rx = RadioSettingValueList(mdopt, mdopt[ndxm]) rset = RadioSetting("pgmscanedge/%d.mode" % kx, "-- Scan %d Mode" % kx, rx) rset.set_apply_callback(myset_mdopt, _pses, kx, "mode", bxnd) edges.append(rset) # End for kx # --- Program Scan Links _psln = self._memobj.pslnam _pslg = self._memobj.pslgrps for kx in range(0, 10): stx = "" for i in range(0, 6): stx += chr(int(_psln[kx].nam[i])) stx = stx.rstrip() rx = RadioSettingValueString(0, 6, stx) rset = RadioSetting("pslnam/%d.nam" % kx, "Program Scan Link %d Name" % kx, rx) rset.set_apply_callback(myset_psnam, _psln, kx, "nam", 6) pslnk.append(rset) for px in range(0, 25): # Generate string numeric representation of 4-byte bitmask stx = "" for nx in range(0, 25): if nx < 8: if (_pslg[kx].msk[0] & (1 << nx)): stx += "%0d, " % nx elif (nx >= 8) and (nx < 16): if (_pslg[kx].msk[1] & (1 << (nx - 8))): stx += "%0d, " % nx elif (nx >= 16) and (nx < 24): if (_pslg[kx].msk[2] & (1 << (nx - 16))): stx += "%0d, " % nx elif (nx >= 24): if (_pslg[kx].msk[3] & (1 << (nx - 24))): stx += "%0d, " % nx rx = RadioSettingValueString(0, 80, stx) rset = RadioSetting("pslgrps/%d.msk" % kx, "--- Scan Link %d Scans" % kx, rx) rset.set_apply_callback(myset_bitmask, _pslg, kx, "msk", 25) pslnk.append(rset) # end for px # End for kx return group # END get_settings() def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.get_name() == "drv_clone_speed": val = element.value.get_value() self.__class__._can_hispeed = val elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/id880.py0000644000175000017500000002660514566340166016051 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, directory, bitwise MEM_FORMAT = """ struct { u24 rxmult:3, txmult:3, freq:18; u16 offset; u16 rtone:6, ctone:6, unknown1:1, mode:3; u8 dtcs; u8 tune_step:4, unknown2:4; u8 unknown3; u8 unknown4:1, tmode:3, duplex:2, dtcs_polarity:2; char name[8]; u8 unknwon5:1, digital_code:7; char urcall[7]; char r1call[7]; char r2call[7]; } memory[1000]; #seekto 0xAA80; u8 used_flags[132]; #seekto 0xAB04; u8 skip_flags[132]; u8 pskip_flags[132]; #seekto 0xAD00; struct { u8 bank; u8 index; } bank_info[1000]; #seekto 0xB550; struct { char name[6]; } bank_names[26]; #seekto 0xDE56; struct { char call[8]; char extension[4]; } mycall[6]; struct { char call[8]; } urcall[60]; struct { char call[8]; char extension[4]; } rptcall[99]; #seekto 0x0FB8; u8 name_flags[132]; """ TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS", "TSQL-R", "DTCS-R"] DUPLEX = ["", "-", "+", ""] DTCSP = ["NN", "NR", "RN", "RR"] MODES = ["FM", "NFM", "WFM", "AM", "NAM", "DV"] STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 125.0, 200.0] FREQ_MULTIPLIER = [5000, 6250, 6250, 8333, 9000] def decode_call(sevenbytes): """Decode a callsign from a packed region @sevenbytes""" if len(sevenbytes) != 7: raise Exception("%i (!=7) bytes to decode_call" % len(sevenbytes)) i = 0 rem = 0 call = "" for byte in [ord(x) for x in sevenbytes]: i += 1 # Mask is 0x01, 0x03, 0x07, etc mask = (1 << i) - 1 # Code gets the upper bits of remainder plus all but the i lower # bits of this byte code = (byte >> i) | rem call += chr(code) # Remainder for next time are the masked bits, moved to the high # places for the next round rem = (byte & mask) << 7 - i # After seven trips gathering overflow bits, we should have seven # left, which is the final character call += chr(rem) return call.rstrip() def encode_call(call): """Encode @call into a 7-byte region""" call = call.ljust(8) buf = [] for i in range(0, 8): byte = ord(call[i]) if i > 0: last = buf[i-1] himask = ~((1 << (7-i)) - 1) & 0x7F last |= (byte & himask) >> (7-i) buf[i-1] = last else: himask = 0 buf.append((byte & ~himask) << (i+1)) return "".join([chr(x) for x in buf[:7]]) def _decode_freq(freq, mult): return int(freq) * FREQ_MULTIPLIER[mult] def _encode_freq(freq): for i, step in list(enumerate(FREQ_MULTIPLIER)): if freq % step == 0: return freq / step, i raise ValueError("%d cannot be factored by multiplier table." % freq) def _wipe_memory(mem, char): mem.set_raw(char * (mem.size() // 8)) class ID880Bank(icf.IcomNamedBank): """ID880 Bank""" def get_name(self): _bank = self._model._radio._memobj.bank_names[self.index] return str(_bank.name).rstrip() def set_name(self, name): _bank = self._model._radio._memobj.bank_names[self.index] _bank.name = name.ljust(6)[:6] @directory.register class ID880Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): """Icom ID880""" VENDOR = "Icom" MODEL = "ID-880H" _model = "\x31\x67\x00\x01" _memsize = 62976 _endframe = "Icom Inc\x2eB1" _ranges = [(0x0000, 0xF5c0, 32), (0xF5c0, 0xf5e0, 16), (0xf5e0, 0xf600, 32)] _num_banks = 26 _bank_class = ID880Bank _can_hispeed = True MYCALL_LIMIT = (1, 7) URCALL_LIMIT = (1, 60) RPTCALL_LIMIT = (1, 99) def _get_bank(self, loc): _bank = self._memobj.bank_info[loc] if _bank.bank == 0xFF: return None else: return _bank.bank def _set_bank(self, loc, bank): _bank = self._memobj.bank_info[loc] if bank is None: _bank.bank = 0xFF else: _bank.bank = bank def _get_bank_index(self, loc): _bank = self._memobj.bank_info[loc] return _bank.index def _set_bank_index(self, loc, index): _bank = self._memobj.bank_info[loc] _bank.index = index def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.requires_call_lists = False rf.has_settings = True rf.has_bank = True rf.has_bank_index = True rf.has_bank_names = True rf.valid_modes = ["FM", "NFM", "AM", "NAM", "DV"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'TSQL-R', 'DTCS-R'] rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = STEPS rf.valid_bands = [(118000000, 173995000), (230000000, 549995000), (810000000, 823990000), (849000000, 868990000), (894000000, 999990000)] rf.valid_skips = ["", "S", "P"] rf.valid_name_length = 8 rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + \ r"!\"#$%&'()*+,-./:;<=>?@[\]^" rf.memory_bounds = (0, 999) return rf def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): bytepos = number / 8 bitpos = 1 << (number % 8) _mem = self._memobj.memory[number] _used = self._memobj.used_flags[bytepos] is_used = ((_used & bitpos) == 0) if is_used and MODES[_mem.mode] == "DV": mem = chirp_common.DVMemory() mem.dv_urcall = decode_call(str(_mem.urcall)) mem.dv_rpt1call = decode_call(str(_mem.r1call)) mem.dv_rpt2call = decode_call(str(_mem.r2call)) else: mem = chirp_common.Memory() mem.number = number if number < 1000: _skip = self._memobj.skip_flags[bytepos] _pskip = self._memobj.pskip_flags[bytepos] if _skip & bitpos: mem.skip = "S" elif _pskip & bitpos: mem.skip = "P" else: pass # FIXME: Special memories if not is_used: mem.empty = True return mem mem.freq = _decode_freq(_mem.freq, _mem.rxmult) mem.offset = _decode_freq(_mem.offset, _mem.txmult) mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.mode = MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCSP[_mem.dtcs_polarity] if _mem.tune_step >= len(STEPS): mem.tuning_step = 5.0 else: mem.tuning_step = STEPS[_mem.tune_step] mem.name = str(_mem.name).rstrip() return mem def set_memory(self, mem): bitpos = (1 << (mem.number % 8)) bytepos = mem.number / 8 _mem = self._memobj.memory[mem.number] _used = self._memobj.used_flags[bytepos] _namf = self._memobj.name_flags[bytepos] was_empty = _used & bitpos if mem.empty: _used |= bitpos _wipe_memory(_mem, "\xFF") self._set_bank(mem.number, None) return _used &= ~bitpos if was_empty: _wipe_memory(_mem, "\x00") _mem.freq, _mem.rxmult = _encode_freq(mem.freq) _mem.offset, _mem.txmult = _encode_freq(mem.offset) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.tmode = TMODES.index(mem.tmode) if mem.tmode == 'DTCS': # The first index of DTCS is "bell" mode _mem.tmode += 1 _mem.duplex = DUPLEX.index(mem.duplex) _mem.mode = MODES.index(mem.mode) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = DTCSP.index(mem.dtcs_polarity) _mem.tune_step = STEPS.index(mem.tuning_step) _mem.name = mem.name.ljust(8) if mem.name.strip(): _namf |= bitpos else: _namf &= ~bitpos if isinstance(mem, chirp_common.DVMemory): _mem.urcall = encode_call(mem.dv_urcall) _mem.r1call = encode_call(mem.dv_rpt1call) _mem.r2call = encode_call(mem.dv_rpt2call) if mem.number < 1000: skip = self._memobj.skip_flags[bytepos] pskip = self._memobj.pskip_flags[bytepos] if mem.skip == "S": skip |= bitpos else: skip &= ~bitpos if mem.skip == "P": pskip |= bitpos else: pskip &= ~bitpos def get_urcall_list(self): _calls = self._memobj.urcall calls = ["CQCQCQ"] for i in range(*self.URCALL_LIMIT): calls.append(str(_calls[i-1].call)) return calls def get_mycall_list(self): _calls = self._memobj.mycall calls = [] for i in range(*self.MYCALL_LIMIT): calls.append(str(_calls[i-1].call)) return calls def get_repeater_call_list(self): calls = ["*NOTUSE*"] for _i in range(*self.RPTCALL_LIMIT): # FIXME: Not sure where the repeater list actually is calls.append("UNSUPRTD") continue return calls @classmethod def match_model(cls, filedata, filename): if (super().match_model(filedata, filename) and filename.lower().endswith('.icf')): return True # This is a horrid hack, given that people can change the GPS-A # destination, but it should suffice in most cases until we get # a rich container file format return len(filedata) == cls._memsize and b"API880," in filedata # This radio isn't really supported yet and detects as a conflict with # the ID-880. So, don't register right now @directory.register class ID80Radio(ID880Radio): """Icom ID80""" MODEL = "ID-80H" _model = "\x31\x55\x00\x01" @classmethod def match_model(cls, filedata, filename): if (super().match_model(filedata, filename) and filename.lower().endswith('.icf')): return True # This is a horrid hack, given that people can change the GPS-A # destination, but it should suffice in most cases until we get # a rich container file format return len(filedata) == cls._memsize and b"API80," in filedata def get_features(self): rf = super().get_features() rf.valid_modes = ["FM", "NFM", "WFM", "AM", "NAM", "DV"] rf.valid_bands = [(495000, 1000000000)] return rf chirp-20240224/chirp/drivers/kenwood_d7.py0000644000175000017500000032156714466370044017257 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import math import os import threading from chirp import chirp_common, directory, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettingValueList, RadioSettingValueMap, \ RadioSettings, RadioSettingValueFloat LOG = logging.getLogger(__name__) class KenwoodD7Position(RadioSettingGroup): def __init__(self, name, shortname, radio, *args, **kwargs): super().__init__(name, shortname, *args, **kwargs) self._radio = radio if ' ' in name: index = name.split(" ", 1)[1] else: index = '' rs = RadioSetting("latd%s" % index, "Latitude degrees", RadioSettingValueInteger(0, 90, 0)) self.append(rs) rs = RadioSetting("latm%s" % index, "Latitude minutes", RadioSettingValueFloat(0, 59.99, 0, resolution=0.01, precision=2)) self.append(rs) rs = RadioSetting("south%s" % index, "South", RadioSettingValueBoolean(False)) self.append(rs) rs = RadioSetting("longd%s" % index, "Longitude degrees", RadioSettingValueInteger(0, 180, 0)) self.append(rs) rs = RadioSetting("longm%s" % index, "Longitude minutes", RadioSettingValueFloat(0, 59.99, 0, resolution=0.01, precision=2)) self.append(rs) rs = RadioSetting("west%s" % index, "West", RadioSettingValueBoolean(False)) self.append(rs) def kenwood_d7_read_value(self): index = self._get_index() name = self.get_name() rawval = self._radio._kenwood_get(name)[1] curr_value = int(rawval[0:2]) self["latd%s" % index].value.set_value(curr_value) curr_value = int(rawval[2:6]) / 100 self["latm%s" % index].value.set_value(curr_value) curr_value = int(rawval[6:8]) self["south%s" % index].value.set_value(curr_value) curr_value = int(rawval[8:11]) self["longd%s" % index].value.set_value(curr_value) curr_value = int(rawval[11:15]) / 100 self["longm%s" % index].value.set_value(curr_value) curr_value = int(rawval[15:17]) self["west%s" % index].value.set_value(curr_value) self['latd%s' % index].value._has_changed = False self['latm%s' % index].value._has_changed = False self['south%s' % index].value._has_changed = False self['longd%s' % index].value._has_changed = False self['longm%s' % index].value._has_changed = False self['west%s' % index].value._has_changed = False def _get_index(self): name = self.get_name() if ' ' in name: return name.split(" ", 1)[1] return '' def changed(self): index = self._get_index() if self['latd%s' % index].changed(): return True if self['latm%s' % index].changed(): return True if self['south%s' % index].changed(): return True if self['longd%s' % index].changed(): return True if self['longm%s' % index].changed(): return True if self['west%s' % index].changed(): return True return False def kenwood_d7_set_value(self): index = self._get_index() latd = self['latd%s' % index].value.get_value() latm = self['latm%s' % index].value.get_value() latmd = int(round(math.modf(latm)[0] * 100)) latm = int(round(latm)) south = int(self['south%s' % index].value.get_value()) longd = self['longd%s' % index].value.get_value() longm = self['longm%s' % index].value.get_value() longmd = int(round(math.modf(longm)[0] * 100)) longm = int(round(longm)) west = int(self['west%s' % index].value.get_value()) args = '%s%02d%02d%02d%02d%03d%02d%02d%02d' % (index, latd, latm, latmd, south, longd, longm, longmd, west) if index != '': index = ' ' + index self._radio._kenwood_set('MP%s' % index, args) # TODO: Hacking up _has_changed is bad... but we don't want # to re-send all the set commands each time either. self['latd%s' % index].value._has_changed = False self['latm%s' % index].value._has_changed = False self['south%s' % index].value._has_changed = False self['longd%s' % index].value._has_changed = False self['longm%s' % index].value._has_changed = False self['west%s' % index].value._has_changed = False class KenwoodD7DTMFMemory(RadioSettingGroup): DTMF_CHARSET = "ABCD#*0123456789 " def __init__(self, name, shortname, radio, *args, **kwargs): super().__init__(name, shortname, *args, **kwargs) self._radio = radio self._name = name index = self._get_index() rs = RadioSetting("DMN %s" % index, "Memory Name", RadioSettingValueString(0, 8, '', False)) self.append(rs) rs = RadioSetting("DM %s" % index, "Memory Value", RadioSettingValueString(0, 16, '', False, self.DTMF_CHARSET)) self.append(rs) def _get_index(self): return "%02d" % int(self._name.split(" ", 1)[1]) def kenwood_d7_read_value(self): index = self._get_index() value = self._radio._kenwood_get("DM %s" % index)[1] value = value.replace("E", "*").replace("F", "#") vname = self._radio._kenwood_get("DMN %s" % index)[1] self["DMN %s" % index].value.set_value(vname) self["DMN %s" % index].value._has_changed = False self["DM %s" % index].value.set_value(value) self["DM %s" % index].value._has_changed = False def changed(self): for element in self: if element.changed(): return True return False def kenwood_d7_set_value(self): for element in self: if not element.changed(): continue newval = element.value.get_value() newval = newval.replace("*", "E").replace("#", "F") self._radio._kenwood_set(element.get_name(), newval) element.value._has_changed = False class KenwoodD7ProgrammableVFOs(RadioSettingGroup): def __init__(self, name, shortname, radio, *args, **kwargs): self._radio = radio super().__init__(name, shortname, *args, **kwargs) for optname, index, minimum, maximum in self._radio._PROGRAMMABLE_VFOS: group = RadioSettingGroup("PV %d" % index, optname) self.append(group) rs = RadioSetting("PV %dL" % index, "Lower Limit", RadioSettingValueInteger(minimum, maximum, minimum)) group.append(rs) rs = RadioSetting("PV %dU" % index, "Upper Limit", RadioSettingValueInteger(minimum, maximum, maximum)) group.append(rs) def _get_index(self, element): name = element.get_name() return int(name.split(" ", 1)[1]) def kenwood_d7_read_value(self): for element in self: index = self._get_index(element) rv = self._radio._kenwood_get("PV %d" % index)[1] lower, upper = rv.split(',', 1) lower = int(lower) upper = int(upper) pvdl = "PV %dL" % index pvdu = "PV %dU" % index element[pvdl].value.set_value(lower) element[pvdl].value._has_changed = False element[pvdu].value.set_value(upper) element[pvdu].value._has_changed = False def changed(self): for element in self: for bound in element: if bound.changed(): return True return False # TODO: Custom validator things... def kenwood_d7_set_value(self): for element in self: index = self._get_index(element) pvdl = "PV %dL" % index pvdu = "PV %dU" % index if element[pvdl].changed() or element[pvdu].changed(): lower = element[pvdl].value.get_value() upper = element[pvdu].value.get_value() args = "%05d,%05d" % (lower, upper) self._radio._kenwood_set(element.get_name(), args) element[pvdl].value._has_changed = False element[pvdu].value._has_changed = False class KenwoodD7Family(chirp_common.LiveRadio): VENDOR = "Kenwood" MODEL = "" NEEDS_COMPAT_SERIAL = False HARDWARE_FLOW = False _ARG_DELIMITER = " " _BAUDS = [9600] _CMD_DELIMITER = "\r" _DISABLE_AI_CMD = ('AI', '0') _DUPLEX = {0: "", 1: "+", 2: "-"} _HAS_NAME = True _LOCK = threading.Lock() _MODES = {0: "FM", 1: "AM"} _NOCACHE = "CHIRP_NOCACHE" in os.environ _SPLIT = True _STEPS = (5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0) _TONES = chirp_common.OLD_TONES _LOWER = 0 _UPPER = 199 _CALL_CHANS = ("VHF Call", "UHF Call") _SPECIAL_CHANS = ("L0", "U0", "L1", "U1", "L2", "U2", "L3", "U3", "L4", "U4", "L5", "U5", "L6", "U6", "L7", "U7", "L8", "U8", "L9", "U9", *_CALL_CHANS) # These are used more than once in _COMMON_SETTINGS _BOOL = {'type': 'bool'} _DATA_BAND = {'type': 'list', 'values': ("A", "B", "A:TX/B:RX", "A:RX/B:TX")} _DTMF_MEMORY = {'type': KenwoodD7DTMFMemory} _ON_OFF_DUAL_MAP = {'type': 'map', 'map': (("Off", "0"), ("On", "1,0")), 'set_requires': (('DL', True),), 'get_requires': (('DL', True),)} _POSITION = {'type': KenwoodD7Position} _SSTV_CHARSET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 !?-/" _SSTV_COLOURS = {'type': 'list', 'values': ("Black", "Blue", "Red", "Magenta", "Green", "Cyan", "Yellow", "White")} _STATUS_TEXT = {'type': 'string', 'max_len': 32} _SQUELCH = {'type': 'list', 'digits': 2, 'values': ("Open", "1", "2", "3", "4", "5")} # Settings that are shared by at least two radios. # If a third radio does not have the setting at all, the presence # here won't matter. If it has it but with different parameters, # it can be overridden in the subclass _SETTINGS dict. _COMMON_SETTINGS = { "AIP": _BOOL, "ARL": {'type': 'map', 'map': (('Off', '0000'),) + tuple( [('%i' % x, '%04i' % x) for x in range(10, 2510, 10)])}, "ARLM": {'type': 'string', 'max_len': 45}, "AMGG": {'type': 'string', 'max_len': 45, 'charset': "ABCDEFGHIJKLMNOPQRSTUVWXYZ*,-0123456789"}, "AMR": _BOOL, "APO": {'type': 'list', 'values': ("Off", "30min", "60min")}, "ARO": _BOOL, # ASC x requires that the specified VFO is enabled on TH-D7G # (ie: dual is on or VFO is current) for both fetch and set # Easiest to just enable DL before set/read "ASC 0": _ON_OFF_DUAL_MAP, "ASC 1": _ON_OFF_DUAL_MAP, "BAL": {'type': 'list', 'values': ("4:0", "3:1", "2:2", "1:3", "0:4")}, "BC": {'type': 'list', 'values': ("A", "B")}, "BCN": _BOOL, # BEL x requires that the specified VFO is enabled on TH-D7G # (ie: dual is on or VFO is current) for both fetch and set # Easiest to just enable DL before set/read "BEL 0": _ON_OFF_DUAL_MAP, "BEL 1": _ON_OFF_DUAL_MAP, "BEP": {'type': 'list', 'values': ("Off", "Key", "Key+Data", "All")}, "BEPT": {'type': 'list', 'values': ("Off", "Mine", "All New", "All")}, "CH": _BOOL, "CKEY": {'type': 'list', 'values': ("Call", "1750 Hz")}, "CNT": {'type': 'integer', 'min': 1, 'max': 16}, "DL": _BOOL, "DS": {'type': 'list', 'values': ("Data Band", "Both Bands")}, "DTB": _DATA_BAND, "DTBA": _DATA_BAND, "dtmfmem 00": _DTMF_MEMORY, "dtmfmem 01": _DTMF_MEMORY, "dtmfmem 02": _DTMF_MEMORY, "dtmfmem 03": _DTMF_MEMORY, "dtmfmem 04": _DTMF_MEMORY, "dtmfmem 05": _DTMF_MEMORY, "dtmfmem 06": _DTMF_MEMORY, "dtmfmem 07": _DTMF_MEMORY, "dtmfmem 08": _DTMF_MEMORY, "dtmfmem 09": _DTMF_MEMORY, "DTX": {'type': 'list', 'values': ("Manual", "PTT", "Auto")}, "ELK": {'type': 'bool'}, "GU": {'type': 'list', 'values': ("Not Used", "NMEA", "NMEA96")}, # This isn't exactly shared, but each radio adds to this list "ICO": {'type': 'map', 'map': (('Kenwood', '0,0'), ('Runner', '0,1'), ('House ', '0,2'), ('Tent', '0,3'), ('Boat', '0,4'), ('SSTV', '0,5'), ('Plane', '0,6'), ('Speedboat', '0,7'), ('Car', '0,8'), ('Bicycle', '0,9'), ('TRIANGLE(DF station)', '0,A'), ('Jeep', '0,B'), ('Recreational Vehicle', '0,C'), ('Truck ', '0,D'), ('Van', '0,E'))}, "KILO": {'type': 'list', 'values': ("Miles", "Kilometers")}, "LK": _BOOL, "LMP": _BOOL, "MAC": _SSTV_COLOURS, "MES": {'type': 'string', 'max_len': 8}, # NOTE: Requires memory mode to be active "MNF": {'type': 'list', 'values': ("Name", "Frequency")}, "MP 1": _POSITION, "MP 2": _POSITION, "MP 3": _POSITION, "MYC": {'type': 'string', 'max_len': 9}, "PAMB": {'type': 'list', 'values': ("Off", "1 Digit", "2 Digits", "3 Digits", "4 Digits")}, "PKSA": {'type': 'list', 'values': ("1200", "9600")}, "POSC": {'type': 'list', 'values': ("Off Duty", "Enroute", "In Service", "Returning", "Committed", "Special", "Priority", "CUSTOM 0", "CUSTOM 1", "CUSTOM 2", "CUSTOM 4", "CUSTOM 5", "CUSTOM 6", "Emergency")}, "PP": {'type': 'string', 'max_len': 32}, "PT": {'type': 'list', 'values': ("100ms", "200ms", "500ms", "750ms", "1000ms", "1500ms", "2000ms")}, "PV": {'type': KenwoodD7ProgrammableVFOs}, "RSC": _SSTV_COLOURS, "RSV": {'type': 'string', 'max_len': 10, 'charset': _SSTV_CHARSET}, "SCC": {'type': 'string', 'max_len': 8}, "SCR": {'type': 'list', 'values': ("Time", "Carrier", "Seek")}, "SCT": {'type': 'string', 'max_len': 8}, "SKTN": {'type': 'map', 'map': tuple([(str(x), "%02d" % (ind + 1)) for ind, x in enumerate(_TONES) if x != 69.3])}, "SMC": _SSTV_COLOURS, "SMSG": {'type': 'string', 'max_len': 9, 'charset': _SSTV_CHARSET}, "SMY": {'type': 'string', 'max_len': 8, 'charset': _SSTV_CHARSET}, "SQ 0": _SQUELCH, "SQ 1": _SQUELCH, "STAT 1": _STATUS_TEXT, "STAT 2": _STATUS_TEXT, "STAT 3": _STATUS_TEXT, "STXR": {'type': 'list', 'values': ("Off", "1/1", "1/2", "1/3", "1/4", "1/5", "1/6", "1/7", "1/8")}, "SV": {'type': 'list', 'values': ("Off", "0.2s", "0.4s", "0.6s", "0.8s", "1.0s", "2s", "3s", "4s", "5s")}, "TEMP": {'type': 'list', 'values': ("ТАF", "ТАC")}, "TH": _BOOL, "TNC": _BOOL, "TSP": _BOOL, "TXD": {'type': 'map', 'map': (("100ms", "1"), ("200ms", "2"), ("300ms", "3"), ("400ms", "4"), ("500ms", "5"), ("750ms", "6"), ("1000ms", "7"))}, "TXH": _BOOL, "TXI": {'type': 'list', 'values': ("30sec", "1min", "2min", "3min", "4min", "5min", "10min", "20min", "30min")}, "TXS": _BOOL, "TZ": {'type': 'list', 'values': ("UTC - 12:00", "UTC - 11:30", "UTC - 11:00", "UTC - 10:30", "UTC - 10:00", "UTC - 9:30", "UTC - 9:00", "UTC - 8:30", "UTC - 8:00", "UTC - 7:30", "UTC - 7:00", "UTC - 6:30", "UTC - 6:00", "UTC - 5:30", "UTC - 5:00", "UTC - 4:30", "UTC - 4:00", "UTC - 3:30", "UTC - 3:00", "UTC - 2:30", "UTC - 2:00", "UTC - 1:30", "UTC - 1:00", "UTC - 0:30", "UTC", "UTC + 0:30", "UTC + 1:00", "UTC + 1:30", "UTC + 2:00", "UTC + 2:30", "UTC + 3:00", "UTC + 3:30", "UTC + 4:00", "UTC + 4:30", "UTC + 5:00", "UTC + 5:30", "UTC + 6:00", "UTC + 6:30", "UTC + 7:00", "UTC + 7:30", "UTC + 8:00", "UTC + 8:30", "UTC + 9:00", "UTC + 9:30", "UTC + 10:00", "UTC + 10:30", "UTC + 11:00", "UTC + 11:30", "UTC + 12:00")}, "UPR": {'type': 'string', 'max_len': 9, 'charset': "ABCDEFGHIJKLMNOPQRSTUVWXYZ-0123456789"}, "VCS": _BOOL, "WAY": {'type': 'list', 'values': ("Off", "6 digit NMEA", "7 digit NMEA", "8 digit NMEA", "9 digit NMEA", "6 digit Magellan", "DGPS")}} _PROGRAMMABLE_VFOS = ( ("Band A, 118 MHz Sub-Band", 1, 118, 135), ("Band A, VHF Sub-Band", 2, 136, 173), ("Band B, VHF Sub-Band", 3, 144, 147), ("Band B, UHF Sub-Band", 6, 400, 479)) def __init__(self, *args, **kwargs): chirp_common.LiveRadio.__init__(self, *args, **kwargs) # Clear the caches self._memcache = {} self._setcache = {} self._baud = 9600 self._cur_setting = 0 self._setting_count = 0 self._vfo = 0 if self.pipe: self.pipe.timeout = 0.5 radio_id = self._get_id() if hasattr(self, '_ID_STRING'): id_str = self._ID_STRING else: id_str = self.MODEL.split(" ")[0] if radio_id != id_str: raise Exception("Radio reports %s (not %s)" % (radio_id, id_str)) self._command(*self._DISABLE_AI_CMD) # This returns the index value for CR/CW commands, not the index # in the memory list grid def _call_index(self, memid_or_index): if isinstance(memid_or_index, int): memid = self._index_to_memid(memid_or_index) else: memid = memid_or_index return self._CALL_CHANS.index(memid) # This returns the memid from the index value in CR/CW commands, not # the index in the memory list grid def _call_index_to_memid(self, index): return self._CALL_CHANS[index] def _cmd_get_memory_name(self, memid): return "MNA", "%i,%s" % (self._vfo, memid) def _cmd_get_memory_or_split(self, memid, split): sd = split and 1 or 0 if self._is_call(memid): return "CR", "%d,%d" % (self._call_index(memid), split) return "MR", "%i,%d,%s" % (self._vfo, sd, memid) def _cmd_set_memory_name(self, memid, name): if self._is_call(memid): return None return "MNA", "%i,%s,%s" % (self._vfo, memid, name) def _cmd_set_memory_or_split(self, memid, memory, split): if not memory.empty: spec = "," + ",".join(self._make_mem_spec(memid, memory)) else: spec = '' sd = split and 1 or 0 if (self._is_call(memid)): return "CW", "%d,%d%s" % (self._call_index(memid), sd, spec) return "MW", "%i,%d,%s%s" % (self._vfo, sd, memid, spec) def _count_settings(self, entries): for entry in entries: if (type(entry[1]) is tuple): self._count_settings(entry[1]) else: self._setting_count += 1 def _create_group(self, entries, grp=None): if grp is None: grp = RadioSettings() for entry in entries: if (type(entry[1]) is tuple): subgrp = RadioSettingGroup(entry[0].lower(), entry[0]) grp.append(self._create_group(entry[1], subgrp)) else: setting = self._get_setting_data(entry[0]) if setting['type'] == 'undefined': continue if setting['type'] == 'list': rsvl = RadioSettingValueList(setting['values']) rs = RadioSetting(entry[0], entry[1], rsvl) elif setting['type'] == 'bool': rs = RadioSetting(entry[0], entry[1], RadioSettingValueBoolean(False)) elif setting['type'] == 'string': params = {} if 'charset' in setting: params['charset'] = setting['charset'] else: params['charset'] = chirp_common.CHARSET_ASCII minlen = 'min_len' in setting and setting['min_len'] or 0 dummy = params['charset'][0] * minlen rsvs = RadioSettingValueString(minlen, setting['max_len'], dummy, False, **params) rs = RadioSetting(entry[0], entry[1], rsvs) elif setting['type'] == 'integer': rs = RadioSetting(entry[0], entry[1], RadioSettingValueInteger(setting['min'], setting['max'], setting['min'])) elif setting['type'] == 'map': rsvs = RadioSettingValueMap(setting['map'], setting['map'][0][1]) rs = RadioSetting(entry[0], entry[1], rsvs) else: rs = setting['type'](entry[0], entry[1], self) rs.kenwood_d7_loaded = False grp.append(rs) self._setcache[entry[0]] = rs return grp def _do_prerequisite(self, cmd, get, do): if get: arg = 'get_requires' else: arg = 'set_requires' setting = self._get_setting_data(cmd) if arg not in setting: return # Undo prerequisites in the reverse order they were applied if not do: it = reversed(setting[arg]) else: it = iter(setting[arg]) for prereq, value in it: entry = self._setcache[prereq] if not entry.kenwood_d7_loaded: self._refresh_setting(entry) if do: entry.kenwood_d7_old_value = entry.value.get_value() entry.value.set_value(value) else: entry.value.set_value(entry.kenwood_d7_old_value) sdata = self._get_setting_data(prereq) self._set_setting(prereq, sdata, entry) def _drain_input(self): oldto = self.pipe.timeout self.pipe.timeout = 0 # Read until a timeout while len(self.pipe.read(1)): pass self.pipe.timeout = oldto def _empty_memory(self, memid): mem = chirp_common.Memory() if self._is_special(memid): mem.extd_number = memid mem.number = self._memid_to_index(memid) mem.empty = True mem.immutable = self._get_immutable(memid) return mem def _get_id(self): """Get the ID of the radio attached to @ser""" for i in self._BAUDS: LOG.info("Trying ID at baud %i" % i) self.pipe.baudrate = i # Try to force an error self.pipe.write(self._CMD_DELIMITER.encode('cp1252')) # Wait for it to be sent self.pipe.flush() self._drain_input() try: resp = self._command("ID") except UnicodeDecodeError: # If we got binary here, we are using the wrong rate # or not talking to a kenwood live radio. continue ret = self._parse_id_response(resp) if ret is not None: self._baud = i return ret # Radio responded in the right baud rate, # but threw an error because of all the crap # we have been hurling at it. Retry the ID at this # baud rate, which will almost definitely work. if "?" in resp: resp = self._command("ID") ret = self._parse_id_response(resp) if ret is not None: self._baud = i return ret raise errors.RadioError("No response from radio") def _get_immutable(self, memid_or_index): if self._is_call(memid_or_index): return ['name', 'skip'] if self._is_pscan(memid_or_index): return ['skip'] return [] def _get_setting_data(self, setting): if setting in self._SETTINGS: return self._SETTINGS[setting] if setting in self._COMMON_SETTINGS: return self._COMMON_SETTINGS[setting] if (setting.upper() == setting): LOG.debug("Undefined setting: %s" % setting) return {'type': 'undefined'} def _get_setting_digits(self, setting_data): if 'digits' in setting_data: return setting_data['digits'] if setting_data['type'] == 'integer': return len(str(setting_data['max'])) if setting_data['type'] == 'list': return len(str(len(setting_data['values']))) raise TypeError('Setting data should not have digits') def _get_tmode(self, tone, ctcss, dcs): """Get the tone mode based on the values of the tone, ctcss, dcs""" if dcs and int(dcs) == 1: return "DTCS" elif int(ctcss): return "TSQL" elif int(tone): return "Tone" else: return "" def _index_to_memid(self, index): if not isinstance(index, int): raise errors.RadioError("%s passed as memory index" % str(type(index))) if index <= self._UPPER: return "%03d" % index index -= self._UPPER index -= 1 return self._SPECIAL_CHANS[index] def _is_call(self, memid_or_index): if isinstance(memid_or_index, int): memid = self._index_to_memid(memid_or_index) else: memid = memid_or_index return memid in self._CALL_CHANS def _is_pscan(self, memid_or_index): if isinstance(memid_or_index, int): memid = self._index_to_memid(memid_or_index) else: memid = memid_or_index if memid[0] == 'L' or memid[0] == 'U': if memid[1:].isdigit(): return True return False def _is_special(self, memid_or_index): if isinstance(memid_or_index, str): index = self._memid_to_index(memid_or_index) else: index = memid_or_index return index > self._UPPER def _iserr(self, result): """Returns True if the @result from a radio is an error""" return result in ["N", "?"] def _keep_reading(self, result): return False def _kenwood_get(self, cmd): self._do_prerequisite(cmd, True, True) ret = None if " " in cmd: suffix = cmd.split(" ", 1)[1] resp = self._kenwood_simple_get(cmd) if resp[1][0:len(suffix)+1] == suffix + ',': resp = (cmd, resp[1][len(suffix)+1:]) ret = resp else: raise errors.RadioError("Command %s response value '%s' " "unusable" % (cmd, resp[1])) else: ret = self._kenwood_simple_get(cmd) self._do_prerequisite(cmd, True, False) return ret def _kenwood_get_bool(self, cmd): _cmd, result = self._kenwood_get(cmd) return result == "1" def _kenwood_get_int(self, cmd): _cmd, result = self._kenwood_get(cmd) return int(result) def _kenwood_set_success(self, cmd, modcmd, value, response): if response[:len(modcmd)] == modcmd: return True return False def _kenwood_set(self, cmd, value): self._do_prerequisite(cmd, False, True) if " " in cmd: resp = self._command(cmd + "," + value) modcmd = cmd.split(" ", 1)[0] else: resp = self._command(cmd, value) modcmd = cmd self._do_prerequisite(cmd, False, False) if self._kenwood_set_success(cmd, modcmd, value, resp): return raise errors.RadioError("Radio refused to set %s" % cmd) def _kenwood_set_bool(self, cmd, value): return self._kenwood_set(cmd, str(int(value))) def _kenwood_set_int(self, cmd, value, digits=1): return self._kenwood_set(cmd, ("%%0%ii" % digits) % value) def _kenwood_simple_get(self, cmd): resp = self._command(cmd) if " " in resp: return resp.split(" ", 1) else: if resp == cmd: return [resp, ""] else: raise errors.RadioError("Radio refused to return %s" % cmd) def _mem_spec_fixup(self, spec, memid, mem): pass def _make_mem_spec(self, memid, mem): if mem.duplex in " -+": duplex = util.get_dict_rev(self._DUPLEX, mem.duplex) offset = mem.offset else: duplex = 0 offset = 0 spec = [ "%011i" % mem.freq, "%X" % self._STEPS.index(mem.tuning_step), "%i" % duplex, "0", "%i" % (mem.tmode == "Tone"), "%i" % (mem.tmode == "TSQL"), "", # DCS Flag "%02i" % (self._TONES.index(mem.rtone) + 1), "", # DCS Code "%02i" % (self._TONES.index(mem.ctone) + 1), "%09i" % offset, "%i" % util.get_dict_rev(self._MODES, mem.mode)] if not self._is_call(memid): spec.append("%i" % ((mem.skip == "S") and 1 or 0)) self._mem_spec_fixup(spec, memid, mem) return tuple(spec) def _make_split_spec(self, mem): return ("%011i" % mem.offset, "0") def _memid_to_index(self, memid): if not isinstance(memid, str): raise errors.RadioError("%s passed as memory id" % str(type(memid))) if memid in self._SPECIAL_CHANS: return self._SPECIAL_CHANS.index(memid) + self._UPPER + 1 return int(memid) def _parse_id_response(self, resp): # most kenwood VHF+ radios if " " in resp: return resp.split(" ")[1] return None def _parse_mem_fixup(self, mem, spec): pass def _parse_mem(self, result): mem = chirp_common.Memory() value = result.split(" ")[1] spec = value.split(",") if len(spec) == 14: # This is a Call memory spec.insert(1, 0) # Add "bank" spec.insert(15, 0) # Add "skip" memid = self._call_index_to_memid(int(spec[0])) mem.extd_number = memid mem.number = self._memid_to_index(mem.extd_number) elif spec[2].isdigit(): # Normal memory mem.number = int(spec[2]) memid = self._index_to_memid(mem.number) else: # Program Scan memory memid = spec[2] mem.extd_number = memid mem.number = self._memid_to_index(mem.extd_number) mem.immutable = self._get_immutable(memid) mem.freq = int(spec[3], 10) mem.tuning_step = self._STEPS[int(spec[4], 16)] mem.duplex = self._DUPLEX[int(spec[5])] mem.tmode = self._get_tmode(spec[7], spec[8], spec[9]) mem.rtone = self._TONES[int(spec[10]) - 1] mem.ctone = self._TONES[int(spec[12]) - 1] if spec[13]: mem.offset = int(spec[13]) else: mem.offset = 0 mem.mode = self._MODES[int(spec[14])] if 'skip' not in mem.immutable: mem.skip = int(spec[15]) and "S" or "" self._parse_mem_fixup(mem, spec) return mem def _parse_split(self, mem, result): value = result.split(" ")[1] spec = value.split(",") mem.duplex = "split" # TODO: There's another parameter here... not sure what it is if len(spec) == 14: # Call memory mem.offset = int(spec[2]) else: mem.offset = int(spec[3]) def _refresh_setting(self, entry): name = entry.get_name() setting = self._get_setting_data(name) # TODO: It would be nice to bump_wait_dialog here... # Also, this is really only useful for the cli. :( if self.status_fn: status = chirp_common.Status() status.cur = self._cur_setting status.max = self._setting_count status.msg = "Fetching %-30s" % entry.get_shortname() # self.bump_wait_dialog(int(status.cur * 100 / status.max), # "Fetching %s" % entry[1]) self.status_fn(status) self._cur_setting += 1 if setting['type'] == 'list': value = self._kenwood_get_int(name) entry.value.set_index(value) elif setting['type'] == 'bool': value = self._kenwood_get_bool(name) entry.value.set_value(value) elif setting['type'] == 'string': value = self._kenwood_get(name)[1] entry.value.set_value(value) elif setting['type'] == 'integer': value = self._kenwood_get_int(name) entry.value.set_value(value) elif setting['type'] == 'map': value = self._kenwood_get(name)[1] entry.value.set_mem_val(value) else: entry.kenwood_d7_read_value() if hasattr(entry, 'value'): if hasattr(entry.value, '_has_changed'): entry.value._has_changed = False entry.kenwood_d7_loaded = True def _refresh_settings(self): for entry in self._setcache.values(): if not entry.kenwood_d7_loaded: self._refresh_setting(entry) def _validate_memid(self, memid_or_index): if isinstance(memid_or_index, int): index = memid_or_index memid = self._index_to_memid(memid_or_index) else: memid = memid_or_index index = self._memid_to_index(memid_or_index) if memid in self._SPECIAL_CHANS: pass elif index < self._LOWER or index > self._UPPER: raise errors.InvalidMemoryLocation( "Number must be between %i and %i" % (self._LOWER, self._UPPER)) return index, memid def _validate_memory(self, memory): if memory.number is None: return self._validate_memid(memory.extd_number) return self._validate_memid(memory.number) def _set_setting(self, name, sdata, element): if sdata['type'] == 'bool': value = element.value.get_value() self._kenwood_set_bool(name, value) element.value._has_changed = False elif sdata['type'] == 'integer': value = element.value.get_value() digits = self._get_setting_digits(sdata) self._kenwood_set_int(name, value, digits) element.value._has_changed = False elif sdata['type'] == 'string': value = element.value.get_value() self._kenwood_set(name, value) element.value._has_changed = False elif sdata['type'] == 'list': value = element.value.get_value() digits = self._get_setting_digits(sdata) self._kenwood_set_int(name, sdata['values'].index(value), digits) element.value._has_changed = False elif sdata['type'] == 'map': self._kenwood_set(name, element.value.get_mem_val()) element.value._has_changed = False # TODO: I would like to have tried this first then fetched # value, but we can't use hasattr() on settings due to the # Magic foo.value attribute in chirp/settings.py. Instead, # I need to get_value() each time. :( elif hasattr(element, 'kenwood_d7_set_value'): element.kenwood_d7_set_value() else: raise TypeError('No way to set %s value' % name) def _command(self, cmd, *args): """Send @cmd to radio via @ser""" # This lock is needed to allow clicking the settings tab while # the memories are still loading. Most important with the TH-D7A # and TH-D7A(G) with the 9600bps maximum. with self._LOCK: if args: cmd += self._ARG_DELIMITER + self._ARG_DELIMITER.join(args) cmd += self._CMD_DELIMITER self._drain_input() LOG.debug("PC->RADIO: %s" % cmd.strip()) self.pipe.write(cmd.encode('cp1252')) cd = self._CMD_DELIMITER.encode('cp1252') keep_reading = True while keep_reading: result = self.pipe.read_until(cd).decode('cp1252') if result.endswith(self._CMD_DELIMITER): keep_reading = self._keep_reading(result) LOG.debug("RADIO->PC: %r" % result.strip()) result = result[:-1] else: keep_reading = False LOG.error("Timeout waiting for data") return result.strip() def erase_memory(self, memid_or_index): index, memid = self._validate_memid(memid_or_index) if memid not in self._memcache: return # TODO: Can't disable the menu item? if self._is_call(memid): # Raising an error just makes the memory errored return cmd = self._cmd_set_memory_or_split(memid, self._empty_memory(memid), False) resp = self._command(*cmd) if self._iserr(resp): raise errors.RadioError("Radio refused delete of %s" % memid) del self._memcache[memid] def get_features(self, *args, **kwargs): rf = chirp_common.RadioFeatures(*args, **kwargs) rf.valid_tones = tuple([x for x in self._TONES if x != 69.3]) rf.has_settings = True rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_mode = True rf.has_tuning_step = True rf.can_odd_split = True rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split"] rf.valid_modes = list(self._MODES.values()) rf.valid_tmodes = ["", "Tone", "TSQL"] rf.valid_characters = \ chirp_common.CHARSET_ALPHANUMERIC + "/.-+*)('&%$#! ~}|{" rf.valid_tuning_steps = self._STEPS rf.memory_bounds = (self._LOWER, self._UPPER) rf.valid_special_chans = self._SPECIAL_CHANS return rf def get_memory(self, memid_or_index): index, memid = self._validate_memid(memid_or_index) if memid in self._memcache and not self._NOCACHE: return self._memcache[memid] result = self._command(*self._cmd_get_memory_or_split(memid, False)) if result == "N": mem = self._empty_memory(memid) self._memcache[memid] = mem return mem elif self._ARG_DELIMITER not in result: LOG.error("Not sure what to do with this: `%s'" % result) raise errors.RadioError("Unexpected result returned from radio") mem = self._parse_mem(result) self._memcache[memid] = mem if self._HAS_NAME: cmd = self._cmd_get_memory_name(memid) if cmd is not None: result = self._command(*cmd) if " " in result: value = result.split(" ", 1)[1] mem.name = value.split(",", 2)[2] if mem.duplex == "" and self._SPLIT: cmd = self._cmd_get_memory_or_split(memid, True) if cmd is not None: result = self._command(*cmd) if " " in result: self._parse_split(mem, result) return mem def get_settings(self): if self._setting_count == 0: self._count_settings(self._SETTINGS_MENUS) ret = self._create_group(self._SETTINGS_MENUS) self._cur_setting = 0 self._refresh_settings() status = chirp_common.Status() status.cur = self._setting_count status.max = self._setting_count status.msg = "%-40s" % "Done" self.status_fn(status) return ret def set_memory(self, memory): index, memid = self._validate_memory(memory) if memory.empty: self.erase_memory(memid) LOG.debug("set_memory passed an empty memory, perhaps " "you wanted erase_memory()?") return r1 = self._command(*self._cmd_set_memory_or_split(memid, memory, False)) if self._iserr(r1): raise errors.InvalidDataError("Radio refused %s" % memid) self._memcache[memid] = memory.dupe() if self._HAS_NAME: r2cmd = self._cmd_set_memory_name(memid, memory.name) if r2cmd is not None: r2 = self._command(*r2cmd) if self._iserr(r2): raise errors.InvalidDataError("Radio refused name %s: %s" % (memid, repr(memory.name))) if memory.duplex == "split" and self._SPLIT: result = self._command(*self._cmd_set_memory_or_split(memid, memory, True)) if self._iserr(result): raise errors.InvalidDataError("Radio refused %s" % memid) def set_settings(self, settings): for element in settings: name = element.get_name() sdata = self._get_setting_data(name) if sdata['type'] == 'undefined': if isinstance(element, RadioSettingGroup): self.set_settings(element) continue if not element.changed(): continue self._set_setting(name, sdata, element) @directory.register class THD7Radio(KenwoodD7Family): """Kenwood TH-D7""" MODEL = "TH-D7" _SETTINGS = { "BEPT": {'type': 'list', 'values': ("Off", "Mine", "All New")}, "DTB": {'type': 'list', 'values': ("A", "B")}, "DTBA": {'type': 'list', 'values': ("A", "B", "A:TX/B:RX", "A:RX/B:TX")}, "GU": {'type': 'list', 'values': ("Not Used", "NMEA")}, "MP": {'type': 'position'}, "STAT": {'type': 'string', 'max_len': 20}, "TEMP": {'type': 'list', 'values': ("Miles / ТАF", "Kilometers / ТАC")}} _SETTINGS_MENUS = ( ('Main', (("ASC 0", "Automatic Simplex Check Band A"), ("ASC 1", "Automatic Simplex Check Band B"), ("BAL", "Balance"), ("BC", "Band"), ("BEL 0", "Tone Alert Band A"), ("BEL 1", "Tone Alert Band B"), ("CH", "Channel Mode Display"), ("DL", "Dual"), ("LMP", "Lamp"), ("LK", "Lock"), # MNF requires that the *current* VFO be in MR mode # Also, it has a direct key # ("MNF", "Memory Display Mode"), ("SQ 0", "Band A Squelch"), ("SQ 1", "Band B Squelch"), # We likely don't want to enable this from Chirp... # ("TNC", "Packet Mode"))), )), ('Radio', (('Display', (("MES", "Power-ON Message"), ("CNT", "Contrast"))), ('Save', (("SV", "Battery Saver Interval"), ("APO", "Automatic Power Off (APO)"))), ('DTMF', (("dtmfmem 00", "Number Store #0"), ("dtmfmem 01", "Number Store #1"), ("dtmfmem 02", "Number Store #2"), ("dtmfmem 03", "Number Store #3"), ("dtmfmem 04", "Number Store #4"), ("dtmfmem 05", "Number Store #5"), ("dtmfmem 06", "Number Store #6"), ("dtmfmem 07", "Number Store #7"), ("dtmfmem 08", "Number Store #8"), ("dtmfmem 09", "Number Store #9"), ("TSP", "TX Speed"), ("TXH", "TX Hold"), ("PT", "Pause"))), ('TNC', (("DTB", "Data band select"), ("DS", "DCD sense"))), ('AUX', (("ARO", "Automatic Repeater Offset"), ("SCR", "Scan Resume"), ("BEP", "Key Beep"), ("ELK", "Tuning Enable"), ("TXS", "TX Inhibit"), ("AIP", "Advanced Intercept Point"), ("TH", "TX Hold, 1750 Hz"), ("XXX", "VHF band narrow TX deviation"))))), ('APRS', (("MYC", "My call sign"), ("GU", "GPS receiver"), # Untested... D7G and D700 take an index, but since D7A only has # one position and is older, it may not. # ("MP", "Latitude / longitude data"), ("POSC", "Position comment"), ("ICO", "Station icon"), ("STAT", "Status text"), ("TXI", "Beacon transmit interval"), ("PP", "Packet path"), ("DTX", "Beacon transmit method"), ("UPR", "Group code"), ("ARL", "Reception restriction distance"), ("TEMP", "Unit for temperature"))), ('SSTV', (("SMY", "My call sign"), ("MAC", "Color for call sign"), ("SMSG", "Message"), ("SMC", "Color for message"), ("RSV", "RSV report"), ("RSC", "Color for RSV report"), ("VCS", "VC-H1 Control"))), ('SkyCommand', (("SCC", "Commander call sign"), ("SCT", "Transporter call sign"), ("SKTN", "Tone frequency select")))) @directory.register class THD7GRadio(KenwoodD7Family): """Kenwood TH-D7G""" MODEL = "TH-D7G" _APRS_EXTRA = (('WEATHER Station (blue)', '1,/#'), ('House QTH (VHF)', '1,/-'), ('Boy Scouts', '1,/,'), ('Campground (Portable ops)', '1,/;'), ('FIRE', '1,/:'), ('Police, Sheriff', '1,/!'), ('SERVER for Files', '1,/?'), ('X', '1,/.'), ('Small AIRCRAFT (SSID-11)', "1,/'"), ('reserved (was rain)', '1,/"'), ('Mobile Satellite Station', '1,/('), ('Wheelchair (handicapped)', '1,/)'), ('Human/Person (SSID-7)', '1,/['), ('MAIL/PostOffice(was PBBS)', '1,/]'), ('/{ (J1)', '1,/{'), ('/} (J3)', '1,/}'), ('HC FUTURE predict (dot)', '1,/@'), ('SnowMobile', '1,/*'), ('Red Dot', '1,//'), ('TRIANGLE(DF station)', '1,/\\'), ('HF GATEway', '1,/&'), ('DIGI (white center)', '1,/#'), ('DX CLUSTER', '1,/%'), ('Dish Antenna', '1,/`'), ('LARGE AIRCRAFT', '1,/^'), ('Red Cross', '1,/+'), ('Motorcycle (SSID-10)', '1,/<'), ('RAILROAD ENGINE', '1,/='), ('CAR (SSID-9)', '1,/>'), ('TNC Stream Switch', '1,/|'), ('TNC Stream Switch', '1,/~'), ('PHONE', '1,/$'), ('# circle (obsolete)', '1,/0'), ('TBD (these were numbered)', '1,/1'), ('TBD (circles like pool)', '1,/2'), ('TBD (balls. But with)', '1,/3'), ('TBD (overlays, we can)', '1,/4'), ("TBD (put all #'s on one)", '1,/5'), ('TBD (So 1-9 are available)', '1,/6'), ('TBD (for new uses?)', '1,/7'), ('TBD (They are often used)', '1,/8'), ('TBD (as mobiles at events)', '1,/9'), ('Aid Station', '1,/A'), ('AMBULANCE (SSID-1)', '1,/a'), ('BBS or PBBS', '1,/B'), ('BIKE (SSID-4)', '1,/b'), ('Canoe', '1,/C'), ('Incident Command Post', '1,/c'), ('/D (PD)', '1,/D'), ('Fire dept', '1,/d'), ('EYEBALL (Events, etc!)', '1,/E'), ('HORSE (equestrian)', '1,/e'), ('Farm Vehicle (tractor)', '1,/F'), ('FIRE TRUCK (SSID-3)', '1,/f'), ('Grid Square (6 digit)', '1,/G'), ('Glider', '1,/g'), ('HOTEL (blue bed symbol)', '1,/H'), ('HOSPITAL', '1,/h'), ('TcpIp on air network stn', '1,/I'), ('IOTA (islands on the air)', '1,/i'), ('/J (PJ)', '1,/J'), ('JEEP (SSID-12)', '1,/j'), ('School', '1,/K'), ('TRUCK (SSID-14)', '1,/k'), ('PC user (Jan 03)', '1,/L'), ('Laptop (Jan 03) (Feb 07)', '1,/l'), ('MacAPRS', '1,/M'), ('Mic-E Repeater', '1,/m'), ('NTS Station', '1,/N'), ('Node (black bulls-eye)', '1,/n'), ('BALLOON (SSID-11)', '1,/O'), ('EOC', '1,/o'), ('Police', '1,/P'), ('ROVER (puppy, or dog)', '1,/p'), ('TBD', '1,/Q'), ('GRID SQ shown above 128 m', '1,/q'), ('REC. VEHICLE (SSID-13)', '1,/R'), ('Repeater (Feb 07)', '1,/r'), ('SHUTTLE', '1,/S'), ('SHIP (pwr boat) (SSID-8)', '1,/s'), ('SSTV', '1,/T'), ('TRUCK STOP', '1,/t'), ('BUS (SSID-2)', '1,/U'), ('TRUCK (18 wheeler)', '1,/u'), ('ATV', '1,/V'), ('VAN (SSID-15)', '1,/v'), ('National WX Service Site', '1,/W'), ('WATER station', '1,/w'), ('HELO (SSID-6)', '1,/X'), ('xAPRS (Unix)', '1,/x'), ('YACHT (sail) (SSID-5)', '1,/Y'), ('YAGI @ QTH', '1,/y'), ('WinAPRS', '1,/Z'), ('TBD', '1,/z'), ('# WX site (green digi)', '1,\\_'), ('# WX site (green digi) with Zero overlaid', '1,0_'), ('# WX site (green digi) with One overlaid', '1,1_'), ('# WX site (green digi) with Two overlaid', '1,2_'), ('# WX site (green digi) with Three overlaid', '1,3_'), ('# WX site (green digi) with Four overlaid', '1,4_'), ('# WX site (green digi) with Five overlaid', '1,5_'), ('# WX site (green digi) with Six overlaid', '1,6_'), ('# WX site (green digi) with Seven overlaid', '1,7_'), ('# WX site (green digi) with Eight overlaid', '1,8_'), ('# WX site (green digi) with Nine overlaid', '1,9_'), ('# WX site (green digi) with Letter A overlaid', '1,A_'), ('# WX site (green digi) with Letter B overlaid', '1,B_'), ('# WX site (green digi) with Letter C overlaid', '1,C_'), ('# WX site (green digi) with Letter D overlaid', '1,D_'), ('# WX site (green digi) with Letter E overlaid', '1,E_'), ('# WX site (green digi) with Letter F overlaid', '1,F_'), ('# WX site (green digi) with Letter G overlaid', '1,G_'), ('# WX site (green digi) with Letter H overlaid', '1,H_'), ('# WX site (green digi) with Letter I overlaid', '1,I_'), ('# WX site (green digi) with Letter J overlaid', '1,J_'), ('# WX site (green digi) with Letter K overlaid', '1,K_'), ('# WX site (green digi) with Letter L overlaid', '1,L_'), ('# WX site (green digi) with Letter M overlaid', '1,M_'), ('# WX site (green digi) with Letter N overlaid', '1,N_'), ('# WX site (green digi) with Letter O overlaid', '1,O_'), ('# WX site (green digi) with Letter P overlaid', '1,P_'), ('# WX site (green digi) with Letter Q overlaid', '1,Q_'), ('# WX site (green digi) with Letter R overlaid', '1,R_'), ('# WX site (green digi) with Letter S overlaid', '1,S_'), ('# WX site (green digi) with Letter T overlaid', '1,T_'), ('# WX site (green digi) with Letter U overlaid', '1,U_'), ('# WX site (green digi) with Letter V overlaid', '1,V_'), ('# WX site (green digi) with Letter W overlaid', '1,W_'), ('# WX site (green digi) with Letter X overlaid', '1,X_'), ('# WX site (green digi) with Letter Y overlaid', '1,Y_'), ('# WX site (green digi) with Letter Z overlaid', '1,Z_'), ('House (H=HF) (O = Op Present)', '1,\\-'), ('Girl Scouts', '1,\\,'), ('Park/Picnic + overlay events', '1,\\;'), ('AVAIL (Hail ==> ` ovly H)', '1,\\:'), ('EMERGENCY (and overlays)', '1,\\!'), ('INFO Kiosk (Blue box with ?)', '1,\\?'), ('Ambiguous (Big Question mark)', '1,\\.'), ('Crash (& now Incident sites)', "1,\\'"), ('reserved', '1,\\"'), ('CLOUDY (other clouds w ovrly)', '1,\\('), ('Firenet MEO, MODIS Earth Obs.', '1,\\)'), ('W.Cloud (& humans w Ovrly)', '1,\\['), ('AVAIL', '1,\\]'), ('AVAIL? (Fog ==> E ovly F)', '1,\\{'), ('AVAIL? (maybe)', '1,\\}'), ('HURICANE/Trop-Storm', '1,\\@'), ('AVAIL (SNOW moved to ` ovly S)', '1,\\*'), ('Waypoint Destination See APRSdos MOBILE.txt', '1,\\/'), ('New overlayable GPS symbol', '1,\\\\'), ('I=Igte R=RX T=1hopTX 2=2hopTX', '1,\\&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Zero overlaid', '1,0&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with One overlaid', '1,1&'), ('TX igate with path set to 2 hops', '1,2&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Three overlaid', '1,3&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Four overlaid', '1,4&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Five overlaid', '1,5&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Six overlaid', '1,6&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Seven overlaid', '1,7&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Eight overlaid', '1,8&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Nine overlaid', '1,9&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter A overlaid', '1,A&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter B overlaid', '1,B&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter C overlaid', '1,C&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter D overlaid', '1,D&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter E overlaid', '1,E&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter F overlaid', '1,F&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter G overlaid', '1,G&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter H overlaid', '1,H&'), ('Igate Generic', '1,I&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter J overlaid', '1,J&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter K overlaid', '1,K&'), ('Lora Igate', '1,L&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter M overlaid', '1,M&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter N overlaid', '1,N&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter O overlaid', '1,O&'), ('PSKmail node', '1,P&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter Q overlaid', '1,Q&'), ('Receive only Igate', '1,R&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter S overlaid', '1,S&'), ('TX igate with path set to 1 hop only', '1,T&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter U overlaid', '1,U&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter V overlaid', '1,V&'), ('WIRES-X', '1,W&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter X overlaid', '1,X&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter Y overlaid', '1,Y&'), ('I=Igte R=RX T=1hopTX 2=2hopTX with Letter Z overlaid', '1,Z&'), ('OVERLAY DIGI (green star)', '1,\\#'), ('OVERLAY DIGI (green star) with Zero overlaid', '1,0#'), ('OVERLAY DIGI (green star) with One overlaid', '1,1#'), ('OVERLAY DIGI (green star) with Two overlaid', '1,2#'), ('OVERLAY DIGI (green star) with Three overlaid', '1,3#'), ('OVERLAY DIGI (green star) with Four overlaid', '1,4#'), ('OVERLAY DIGI (green star) with Five overlaid', '1,5#'), ('OVERLAY DIGI (green star) with Six overlaid', '1,6#'), ('OVERLAY DIGI (green star) with Seven overlaid', '1,7#'), ('OVERLAY DIGI (green star) with Eight overlaid', '1,8#'), ('OVERLAY DIGI (green star) with Nine overlaid', '1,9#'), ('OVERLAY DIGI (green star) with Letter A overlaid', '1,A#'), ('OVERLAY DIGI (green star) with Letter B overlaid', '1,B#'), ('OVERLAY DIGI (green star) with Letter C overlaid', '1,C#'), ('OVERLAY DIGI (green star) with Letter D overlaid', '1,D#'), ('OVERLAY DIGI (green star) with Letter E overlaid', '1,E#'), ('OVERLAY DIGI (green star) with Letter F overlaid', '1,F#'), ('OVERLAY DIGI (green star) with Letter G overlaid', '1,G#'), ('OVERLAY DIGI (green star) with Letter H overlaid', '1,H#'), ('OVERLAY DIGI (green star) with Letter I overlaid', '1,I#'), ('OVERLAY DIGI (green star) with Letter J overlaid', '1,J#'), ('OVERLAY DIGI (green star) with Letter K overlaid', '1,K#'), ('OVERLAY DIGI (green star) with Letter L overlaid', '1,L#'), ('OVERLAY DIGI (green star) with Letter M overlaid', '1,M#'), ('OVERLAY DIGI (green star) with Letter N overlaid', '1,N#'), ('OVERLAY DIGI (green star) with Letter O overlaid', '1,O#'), ('OVERLAY DIGI (green star) with Letter P overlaid', '1,P#'), ('OVERLAY DIGI (green star) with Letter Q overlaid', '1,Q#'), ('OVERLAY DIGI (green star) with Letter R overlaid', '1,R#'), ('OVERLAY DIGI (green star) with Letter S overlaid', '1,S#'), ('OVERLAY DIGI (green star) with Letter T overlaid', '1,T#'), ('OVERLAY DIGI (green star) with Letter U overlaid', '1,U#'), ('OVERLAY DIGI (green star) with Letter V overlaid', '1,V#'), ('OVERLAY DIGI (green star) with Letter W overlaid', '1,W#'), ('OVERLAY DIGI (green star) with Letter X overlaid', '1,X#'), ('OVERLAY DIGI (green star) with Letter Y overlaid', '1,Y#'), ('OVERLAY DIGI (green star) with Letter Z overlaid', '1,Z#'), ('Power Plant with overlay', '1,\\%'), ('Rain (all types w ovrly)', '1,\\`'), ('other Aircraft ovrlys (2014)', '1,\\^'), ('other Aircraft ovrlys (2014) with Zero overlaid', '1,0^'), ('other Aircraft ovrlys (2014) with One overlaid', '1,1^'), ('other Aircraft ovrlys (2014) with Two overlaid', '1,2^'), ('other Aircraft ovrlys (2014) with Three overlaid', '1,3^'), ('other Aircraft ovrlys (2014) with Four overlaid', '1,4^'), ('other Aircraft ovrlys (2014) with Five overlaid', '1,5^'), ('other Aircraft ovrlys (2014) with Six overlaid', '1,6^'), ('other Aircraft ovrlys (2014) with Seven overlaid', '1,7^'), ('other Aircraft ovrlys (2014) with Eight overlaid', '1,8^'), ('other Aircraft ovrlys (2014) with Nine overlaid', '1,9^'), ('Autonomous', '1,A^'), ('other Aircraft ovrlys (2014) with Letter B overlaid', '1,B^'), ('other Aircraft ovrlys (2014) with Letter C overlaid', '1,C^'), ('Drone', '1,D^'), ('Electric aircraft', '1,E^'), ('other Aircraft ovrlys (2014) with Letter F overlaid', '1,F^'), ('other Aircraft ovrlys (2014) with Letter G overlaid', '1,G^'), ('Hovercraft', '1,H^'), ('other Aircraft ovrlys (2014) with Letter I overlaid', '1,I^'), ('JET', '1,J^'), ('other Aircraft ovrlys (2014) with Letter K overlaid', '1,K^'), ('other Aircraft ovrlys (2014) with Letter L overlaid', '1,L^'), ('Missle', '1,M^'), ('other Aircraft ovrlys (2014) with Letter N overlaid', '1,N^'), ('other Aircraft ovrlys (2014) with Letter O overlaid', '1,O^'), ('Prop', '1,P^'), ('other Aircraft ovrlys (2014) with Letter Q overlaid', '1,Q^'), ('Remotely Piloted', '1,R^'), ('Solar Powered', '1,S^'), ('other Aircraft ovrlys (2014) with Letter T overlaid', '1,T^'), ('other Aircraft ovrlys (2014) with Letter U overlaid', '1,U^'), ('Vertical takeoff', '1,V^'), ('other Aircraft ovrlys (2014) with Letter W overlaid', '1,W^'), ('Experimental', '1,X^'), ('other Aircraft ovrlys (2014) with Letter Y overlaid', '1,Y^'), ('other Aircraft ovrlys (2014) with Letter Z overlaid', '1,Z^'), ('Church', '1,\\+'), ('ADVISORY (one WX flag)', '1,\\<'), ('avail. symbol overlay group', '1,\\='), ('OVERLAYED CARs & Vehicles', '1,\\>'), ('OVERLAYED CARs & Vehicles with Zero overlaid', '1,0>'), ('OVERLAYED CARs & Vehicles with One overlaid', '1,1>'), ('OVERLAYED CARs & Vehicles with Two overlaid', '1,2>'), ('Model 3 (Tesla)', '1,3>'), ('OVERLAYED CARs & Vehicles with Four overlaid', '1,4>'), ('OVERLAYED CARs & Vehicles with Five overlaid', '1,5>'), ('OVERLAYED CARs & Vehicles with Six overlaid', '1,6>'), ('OVERLAYED CARs & Vehicles with Seven overlaid', '1,7>'), ('OVERLAYED CARs & Vehicles with Eight overlaid', '1,8>'), ('OVERLAYED CARs & Vehicles with Nine overlaid', '1,9>'), ('OVERLAYED CARs & Vehicles with Letter A overlaid', '1,A>'), ('BEV - Battery EV', '1,B>'), ('OVERLAYED CARs & Vehicles with Letter C overlaid', '1,C>'), ('DIY - Do it yourself ', '1,D>'), ('Ethanol (was electric)', '1,E>'), ('Fuelcell or hydrogen', '1,F>'), ('OVERLAYED CARs & Vehicles with Letter G overlaid', '1,G>'), ('Hybrid', '1,H>'), ('OVERLAYED CARs & Vehicles with Letter I overlaid', '1,I>'), ('OVERLAYED CARs & Vehicles with Letter J overlaid', '1,J>'), ('OVERLAYED CARs & Vehicles with Letter K overlaid', '1,K>'), ('Leaf', '1,L>'), ('OVERLAYED CARs & Vehicles with Letter M overlaid', '1,M>'), ('OVERLAYED CARs & Vehicles with Letter N overlaid', '1,N>'), ('OVERLAYED CARs & Vehicles with Letter O overlaid', '1,O>'), ('PHEV - Plugin-hybrid', '1,P>'), ('OVERLAYED CARs & Vehicles with Letter Q overlaid', '1,Q>'), ('OVERLAYED CARs & Vehicles with Letter R overlaid', '1,R>'), ('Solar powered', '1,S>'), ('Tesla (temporary)', '1,T>'), ('OVERLAYED CARs & Vehicles with Letter U overlaid', '1,U>'), ('Volt (temporary)', '1,V>'), ('OVERLAYED CARs & Vehicles with Letter W overlaid', '1,W>'), ('Model X', '1,X>'), ('OVERLAYED CARs & Vehicles with Letter Y overlaid', '1,Y>'), ('OVERLAYED CARs & Vehicles with Letter Z overlaid', '1,Z>'), ('TNC Stream Switch', '1,\\|'), ('TNC Stream Switch', '1,\\~'), ('Bank or ATM (green box)', '1,\\$'), ('CIRCLE (IRLP/Echolink/WIRES)', '1,\\0'), ('CIRCLE (IRLP/Echolink/WIRES) with Zero overlaid', '1,00'), ('CIRCLE (IRLP/Echolink/WIRES) with One overlaid', '1,10'), ('CIRCLE (IRLP/Echolink/WIRES) with Two overlaid', '1,20'), ('CIRCLE (IRLP/Echolink/WIRES) with Three overlaid', '1,30'), ('CIRCLE (IRLP/Echolink/WIRES) with Four overlaid', '1,40'), ('CIRCLE (IRLP/Echolink/WIRES) with Five overlaid', '1,50'), ('CIRCLE (IRLP/Echolink/WIRES) with Six overlaid', '1,60'), ('CIRCLE (IRLP/Echolink/WIRES) with Seven overlaid', '1,70'), ('CIRCLE (IRLP/Echolink/WIRES) with Eight overlaid', '1,80'), ('CIRCLE (IRLP/Echolink/WIRES) with Nine overlaid', '1,90'), ('Allstar Node', '1,A0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter B overlaid', '1,B0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter C overlaid', '1,C0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter D overlaid', '1,D0'), ('Echolink Node', '1,E0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter F overlaid', '1,F0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter G overlaid', '1,G0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter H overlaid', '1,H0'), ('IRLP repeater', '1,I0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter J overlaid', '1,J0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter K overlaid', '1,K0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter L overlaid', '1,L0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter M overlaid', '1,M0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter N overlaid', '1,N0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter O overlaid', '1,O0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter P overlaid', '1,P0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter Q overlaid', '1,Q0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter R overlaid', '1,R0'), ('Staging Area', '1,S0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter T overlaid', '1,T0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter U overlaid', '1,U0'), ('Echolink and IRLP', '1,V0'), ('WIRES (Yaesu VOIP)', '1,W0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter X overlaid', '1,X0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter Y overlaid', '1,Y0'), ('CIRCLE (IRLP/Echolink/WIRES) with Letter Z overlaid', '1,Z0'), ('AVAIL', '1,\\1'), ('AVAIL', '1,\\2'), ('AVAIL', '1,\\3'), ('AVAIL', '1,\\4'), ('AVAIL', '1,\\5'), ('AVAIL', '1,\\6'), ('AVAIL', '1,\\7'), ('802.11 or other network node', '1,\\8'), ('Gas Station (blue pump)', '1,\\9'), ('overlayBOX DTMF & RFID & XO', '1,\\A'), ('overlayBOX DTMF & RFID & XO with Zero overlaid', '1,0A'), ('overlayBOX DTMF & RFID & XO with One overlaid', '1,1A'), ('overlayBOX DTMF & RFID & XO with Two overlaid', '1,2A'), ('overlayBOX DTMF & RFID & XO with Three overlaid', '1,3A'), ('overlayBOX DTMF & RFID & XO with Four overlaid', '1,4A'), ('overlayBOX DTMF & RFID & XO with Five overlaid', '1,5A'), ('overlayBOX DTMF & RFID & XO with Six overlaid', '1,6A'), ('HT DTMF user', '1,7A'), ('overlayBOX DTMF & RFID & XO with Eight overlaid', '1,8A'), ('Mobile DTMF user', '1,9A'), ('AllStar DTMF report', '1,AA'), ('overlayBOX DTMF & RFID & XO with Letter B overlaid', '1,BA'), ('overlayBOX DTMF & RFID & XO with Letter C overlaid', '1,CA'), ('D-Star report', '1,DA'), ('Echolink DTMF report', '1,EA'), ('overlayBOX DTMF & RFID & XO with Letter F overlaid', '1,FA'), ('overlayBOX DTMF & RFID & XO with Letter G overlaid', '1,GA'), ('House DTMF user', '1,HA'), ('IRLP DTMF report', '1,IA'), ('overlayBOX DTMF & RFID & XO with Letter J overlaid', '1,JA'), ('overlayBOX DTMF & RFID & XO with Letter K overlaid', '1,KA'), ('overlayBOX DTMF & RFID & XO with Letter L overlaid', '1,LA'), ('overlayBOX DTMF & RFID & XO with Letter M overlaid', '1,MA'), ('overlayBOX DTMF & RFID & XO with Letter N overlaid', '1,NA'), ('overlayBOX DTMF & RFID & XO with Letter O overlaid', '1,OA'), ('overlayBOX DTMF & RFID & XO with Letter P overlaid', '1,PA'), ('overlayBOX DTMF & RFID & XO with Letter Q overlaid', '1,QA'), ('RFID report', '1,RA'), ('overlayBOX DTMF & RFID & XO with Letter S overlaid', '1,SA'), ('overlayBOX DTMF & RFID & XO with Letter T overlaid', '1,TA'), ('overlayBOX DTMF & RFID & XO with Letter U overlaid', '1,UA'), ('overlayBOX DTMF & RFID & XO with Letter V overlaid', '1,VA'), ('overlayBOX DTMF & RFID & XO with Letter W overlaid', '1,WA'), ('OLPC Laptop XO', '1,XA'), ('overlayBOX DTMF & RFID & XO with Letter Y overlaid', '1,YA'), ('overlayBOX DTMF & RFID & XO with Letter Z overlaid', '1,ZA'), ('ARRL,ARES,WinLINK,Dstar, etc', '1,\\a'), ('AVAIL (BlwngSnow ==> E ovly B', '1,\\B'), ('AVAIL (Blwng Dst/Snd => E ovly)', '1,\\b'), ('Coast Guard', '1,\\C'), ('CD triangle RACES/SATERN/etc', '1,\\c'), ('DX spot by callsign', '1,\\d'), ("DEPOTS (Drizzle ==> ' ovly D)", '1,\\D A'), ('Smoke (& other vis codes)', '1,\\E'), ('Sleet (& future ovrly codes)', '1,\\e'), ('AVAIL (FrzngRain ==> `F)', '1,\\F'), ('Funnel Cloud', '1,\\f'), ('AVAIL (Snow Shwr ==> I ovly S)', '1,\\G'), ('Gale Flags', '1,\\g'), ('\\Haze (& Overlay Hazards)', '1,\\H'), ('Store. or HAMFST Hh=HAM store', '1,\\h'), ('Rain Shower', '1,\\I'), ('BOX or points of Interest', '1,\\i'), ('AVAIL (Lightning ==> I ovly L)', '1,\\J'), ('WorkZone (Steam Shovel)', '1,\\j'), ('Kenwood HT (W)', '1,\\K'), ('Special Vehicle SUV,ATV,4x4', '1,\\k'), ('Lighthouse', '1,\\L'), ('Areas (box,circles,etc)', '1,\\l'), ('MARS (A=Army,N=Navy,F=AF)', '1,\\M'), ('Value Sign (3 digit display)', '1,\\m'), ('Navigation Buoy', '1,\\N'), ('OVERLAY TRIANGLE', '1,\\n'), ('OVERLAY TRIANGLE with Zero overlaid', '1,0n'), ('OVERLAY TRIANGLE with One overlaid', '1,1n'), ('OVERLAY TRIANGLE with Two overlaid', '1,2n'), ('OVERLAY TRIANGLE with Three overlaid', '1,3n'), ('OVERLAY TRIANGLE with Four overlaid', '1,4n'), ('OVERLAY TRIANGLE with Five overlaid', '1,5n'), ('OVERLAY TRIANGLE with Six overlaid', '1,6n'), ('OVERLAY TRIANGLE with Seven overlaid', '1,7n'), ('OVERLAY TRIANGLE with Eight overlaid', '1,8n'), ('OVERLAY TRIANGLE with Nine overlaid', '1,9n'), ('OVERLAY TRIANGLE with Letter A overlaid', '1,An'), ('OVERLAY TRIANGLE with Letter B overlaid', '1,Bn'), ('OVERLAY TRIANGLE with Letter C overlaid', '1,Cn'), ('OVERLAY TRIANGLE with Letter D overlaid', '1,Dn'), ('OVERLAY TRIANGLE with Letter E overlaid', '1,En'), ('OVERLAY TRIANGLE with Letter F overlaid', '1,Fn'), ('OVERLAY TRIANGLE with Letter G overlaid', '1,Gn'), ('OVERLAY TRIANGLE with Letter H overlaid', '1,Hn'), ('OVERLAY TRIANGLE with Letter I overlaid', '1,In'), ('OVERLAY TRIANGLE with Letter J overlaid', '1,Jn'), ('OVERLAY TRIANGLE with Letter K overlaid', '1,Kn'), ('OVERLAY TRIANGLE with Letter L overlaid', '1,Ln'), ('OVERLAY TRIANGLE with Letter M overlaid', '1,Mn'), ('OVERLAY TRIANGLE with Letter N overlaid', '1,Nn'), ('OVERLAY TRIANGLE with Letter O overlaid', '1,On'), ('OVERLAY TRIANGLE with Letter P overlaid', '1,Pn'), ('OVERLAY TRIANGLE with Letter Q overlaid', '1,Qn'), ('OVERLAY TRIANGLE with Letter R overlaid', '1,Rn'), ('OVERLAY TRIANGLE with Letter S overlaid', '1,Sn'), ('OVERLAY TRIANGLE with Letter T overlaid', '1,Tn'), ('OVERLAY TRIANGLE with Letter U overlaid', '1,Un'), ('OVERLAY TRIANGLE with Letter V overlaid', '1,Vn'), ('OVERLAY TRIANGLE with Letter W overlaid', '1,Wn'), ('OVERLAY TRIANGLE with Letter X overlaid', '1,Xn'), ('OVERLAY TRIANGLE with Letter Y overlaid', '1,Yn'), ('OVERLAY TRIANGLE with Letter Z overlaid', '1,Zn'), ('Overlay Balloon (Rocket = \\O)', '1,\\O'), ('small circle', '1,\\o'), ('Parking', '1,\\P'), ('AVAIL (PrtlyCldy => ( ovly P', '1,\\p'), ('QUAKE', '1,\\Q'), ('AVAIL', '1,\\q'), ('Restaurant', '1,\\R'), ('Restrooms', '1,\\r'), ('Satellite/Pacsat', '1,\\S'), ('OVERLAY SHIP/boats', '1,\\s'), ('OVERLAY SHIP/boats with Zero overlaid', '1,0s'), ('OVERLAY SHIP/boats with One overlaid', '1,1s'), ('OVERLAY SHIP/boats with Two overlaid', '1,2s'), ('OVERLAY SHIP/boats with Three overlaid', '1,3s'), ('OVERLAY SHIP/boats with Four overlaid', '1,4s'), ('OVERLAY SHIP/boats with Five overlaid', '1,5s'), ('Shipwreck ("deep6")', '1,6s'), ('OVERLAY SHIP/boats with Seven overlaid', '1,7s'), ('OVERLAY SHIP/boats with Eight overlaid', '1,8s'), ('OVERLAY SHIP/boats with Nine overlaid', '1,9s'), ('OVERLAY SHIP/boats with Letter A overlaid', '1,As'), ('Pleasure Boat', '1,Bs'), ('Cargo', '1,Cs'), ('Diving', '1,Ds'), ('Emergency or Medical transport', '1,Es'), ('Fishing', '1,Fs'), ('OVERLAY SHIP/boats with Letter G overlaid', '1,Gs'), ('High-speed Craft', '1,Hs'), ('OVERLAY SHIP/boats with Letter I overlaid', '1,Is'), ('Jet Ski', '1,Js'), ('OVERLAY SHIP/boats with Letter K overlaid', '1,Ks'), ('Law enforcement', '1,Ls'), ('Miltary', '1,Ms'), ('OVERLAY SHIP/boats with Letter N overlaid', '1,Ns'), ('Oil Rig', '1,Os'), ('Pilot Boat', '1,Ps'), ('Torpedo', '1,Qs'), ('OVERLAY SHIP/boats with Letter R overlaid', '1,Rs'), ('Search and Rescue', '1,Ss'), ('Tug', '1,Ts'), ('Underwater ops or submarine', '1,Us'), ('OVERLAY SHIP/boats with Letter V overlaid', '1,Vs'), ('Wing-in-Ground effect (or Hovercraft)', '1,Ws'), ('Passenger (paX)(ferry)', '1,Xs'), ('Sailing (large ship)', '1,Ys'), ('OVERLAY SHIP/boats with Letter Z overlaid', '1,Zs'), ('Thunderstorm', '1,\\T'), ('Tornado', '1,\\t'), ('SUNNY', '1,\\U'), ('OVERLAYED TRUCK', '1,\\u'), ('OVERLAYED TRUCK with Zero overlaid', '1,0u'), ('OVERLAYED TRUCK with One overlaid', '1,1u'), ('OVERLAYED TRUCK with Two overlaid', '1,2u'), ('OVERLAYED TRUCK with Three overlaid', '1,3u'), ('OVERLAYED TRUCK with Four overlaid', '1,4u'), ('OVERLAYED TRUCK with Five overlaid', '1,5u'), ('OVERLAYED TRUCK with Six overlaid', '1,6u'), ('OVERLAYED TRUCK with Seven overlaid', '1,7u'), ('OVERLAYED TRUCK with Eight overlaid', '1,8u'), ('OVERLAYED TRUCK with Nine overlaid', '1,9u'), ('OVERLAYED TRUCK with Letter A overlaid', '1,Au'), ('Buldozer/construction/Backhoe', '1,Bu'), ('Chlorine Tanker', '1,Cu'), ('OVERLAYED TRUCK with Letter D overlaid', '1,Du'), ('OVERLAYED TRUCK with Letter E overlaid', '1,Eu'), ('OVERLAYED TRUCK with Letter F overlaid', '1,Fu'), ('Gas', '1,Gu'), ('Hazardous', '1,Hu'), ('OVERLAYED TRUCK with Letter I overlaid', '1,Iu'), ('OVERLAYED TRUCK with Letter J overlaid', '1,Ju'), ('OVERLAYED TRUCK with Letter K overlaid', '1,Ku'), ('OVERLAYED TRUCK with Letter L overlaid', '1,Lu'), ('OVERLAYED TRUCK with Letter M overlaid', '1,Mu'), ('OVERLAYED TRUCK with Letter N overlaid', '1,Nu'), ('OVERLAYED TRUCK with Letter O overlaid', '1,Ou'), ('Plow or SnowPlow', '1,Pu'), ('OVERLAYED TRUCK with Letter Q overlaid', '1,Qu'), ('OVERLAYED TRUCK with Letter R overlaid', '1,Ru'), ('OVERLAYED TRUCK with Letter S overlaid', '1,Su'), ('Tanker', '1,Tu'), ('OVERLAYED TRUCK with Letter U overlaid', '1,Uu'), ('OVERLAYED TRUCK with Letter V overlaid', '1,Vu'), ('OVERLAYED TRUCK with Letter W overlaid', '1,Wu'), ('OVERLAYED TRUCK with Letter X overlaid', '1,Xu'), ('OVERLAYED TRUCK with Letter Y overlaid', '1,Yu'), ('OVERLAYED TRUCK with Letter Z overlaid', '1,Zu'), ('VORTAC Nav Aid', '1,\\V'), ('OVERLAYED Van', '1,\\v'), ('OVERLAYED Van with Zero overlaid', '1,0v'), ('OVERLAYED Van with One overlaid', '1,1v'), ('OVERLAYED Van with Two overlaid', '1,2v'), ('OVERLAYED Van with Three overlaid', '1,3v'), ('OVERLAYED Van with Four overlaid', '1,4v'), ('OVERLAYED Van with Five overlaid', '1,5v'), ('OVERLAYED Van with Six overlaid', '1,6v'), ('OVERLAYED Van with Seven overlaid', '1,7v'), ('OVERLAYED Van with Eight overlaid', '1,8v'), ('OVERLAYED Van with Nine overlaid', '1,9v'), ('OVERLAYED Van with Letter A overlaid', '1,Av'), ('OVERLAYED Van with Letter B overlaid', '1,Bv'), ('OVERLAYED Van with Letter C overlaid', '1,Cv'), ('OVERLAYED Van with Letter D overlaid', '1,Dv'), ('OVERLAYED Van with Letter E overlaid', '1,Ev'), ('OVERLAYED Van with Letter F overlaid', '1,Fv'), ('OVERLAYED Van with Letter G overlaid', '1,Gv'), ('OVERLAYED Van with Letter H overlaid', '1,Hv'), ('OVERLAYED Van with Letter I overlaid', '1,Iv'), ('OVERLAYED Van with Letter J overlaid', '1,Jv'), ('OVERLAYED Van with Letter K overlaid', '1,Kv'), ('OVERLAYED Van with Letter L overlaid', '1,Lv'), ('OVERLAYED Van with Letter M overlaid', '1,Mv'), ('OVERLAYED Van with Letter N overlaid', '1,Nv'), ('OVERLAYED Van with Letter O overlaid', '1,Ov'), ('OVERLAYED Van with Letter P overlaid', '1,Pv'), ('OVERLAYED Van with Letter Q overlaid', '1,Qv'), ('OVERLAYED Van with Letter R overlaid', '1,Rv'), ('OVERLAYED Van with Letter S overlaid', '1,Sv'), ('OVERLAYED Van with Letter T overlaid', '1,Tv'), ('OVERLAYED Van with Letter U overlaid', '1,Uv'), ('OVERLAYED Van with Letter V overlaid', '1,Vv'), ('OVERLAYED Van with Letter W overlaid', '1,Wv'), ('OVERLAYED Van with Letter X overlaid', '1,Xv'), ('OVERLAYED Van with Letter Y overlaid', '1,Yv'), ('OVERLAYED Van with Letter Z overlaid', '1,Zv'), ('# NWS site (NWS options)', '1,\\W'), ('# NWS site (NWS options) with Zero overlaid', '1,0W'), ('# NWS site (NWS options) with One overlaid', '1,1W'), ('# NWS site (NWS options) with Two overlaid', '1,2W'), ('# NWS site (NWS options) with Three overlaid', '1,3W'), ('# NWS site (NWS options) with Four overlaid', '1,4W'), ('# NWS site (NWS options) with Five overlaid', '1,5W'), ('# NWS site (NWS options) with Six overlaid', '1,6W'), ('# NWS site (NWS options) with Seven overlaid', '1,7W'), ('# NWS site (NWS options) with Eight overlaid', '1,8W'), ('# NWS site (NWS options) with Nine overlaid', '1,9W'), ('# NWS site (NWS options) with Letter A overlaid', '1,AW'), ('# NWS site (NWS options) with Letter B overlaid', '1,BW'), ('# NWS site (NWS options) with Letter C overlaid', '1,CW'), ('# NWS site (NWS options) with Letter D overlaid', '1,DW'), ('# NWS site (NWS options) with Letter E overlaid', '1,EW'), ('# NWS site (NWS options) with Letter F overlaid', '1,FW'), ('# NWS site (NWS options) with Letter G overlaid', '1,GW'), ('# NWS site (NWS options) with Letter H overlaid', '1,HW'), ('# NWS site (NWS options) with Letter I overlaid', '1,IW'), ('# NWS site (NWS options) with Letter J overlaid', '1,JW'), ('# NWS site (NWS options) with Letter K overlaid', '1,KW'), ('# NWS site (NWS options) with Letter L overlaid', '1,LW'), ('# NWS site (NWS options) with Letter M overlaid', '1,MW'), ('# NWS site (NWS options) with Letter N overlaid', '1,NW'), ('# NWS site (NWS options) with Letter O overlaid', '1,OW'), ('# NWS site (NWS options) with Letter P overlaid', '1,PW'), ('# NWS site (NWS options) with Letter Q overlaid', '1,QW'), ('# NWS site (NWS options) with Letter R overlaid', '1,RW'), ('# NWS site (NWS options) with Letter S overlaid', '1,SW'), ('# NWS site (NWS options) with Letter T overlaid', '1,TW'), ('# NWS site (NWS options) with Letter U overlaid', '1,UW'), ('# NWS site (NWS options) with Letter V overlaid', '1,VW'), ('# NWS site (NWS options) with Letter W overlaid', '1,WW'), ('# NWS site (NWS options) with Letter X overlaid', '1,XW'), ('# NWS site (NWS options) with Letter Y overlaid', '1,YW'), ('# NWS site (NWS options) with Letter Z overlaid', '1,ZW'), ('Flooding (Avalanches/Slides)', '1,\\w'), ('Pharmacy Rx (Apothecary)', '1,\\X'), ('Wreck or Obstruction ->X<-', '1,\\x'), ('Radios and devices', '1,\\Y'), ('Skywarn', '1,\\y'), ('AVAIL', '1,\\Z'), ('OVERLAYED Shelter', '1,\\z')) _SETTINGS = { "DS": {'type': 'list', 'values': ("Data Band", "Both Bands", "Ignore DCD")}, "DSPA": {'type': 'list', 'values': ("Entire Display", "One Line")}, "ICO": {'type': 'map', 'map': (KenwoodD7Family._COMMON_SETTINGS["ICO"]["map"] + _APRS_EXTRA)}} _SETTINGS_MENUS = ( ('Main', (("ASC 0", "Automatic Simplex Check Band A"), ("ASC 1", "Automatic Simplex Check Band B"), ("BAL", "Balance"), ("BC", "Band"), ("BEL 0", "Tone Alert Band A"), ("BEL 1", "Tone Alert Band B"), ("CH", "Channel Mode Display"), ("DL", "Dual"), ("LK", "Lock"), ("LMP", "Lamp"), # MNF requires that the *current* VFO be in MR mode # Also, it has a direct key # ("MNF", "Memory Display Mode"), ("PV", "Programmable VFOs"), ("SQ 0", "Band A Squelch"), ("SQ 1", "Band B Squelch"), # We likely don't want to enable this from Chirp... # ("TNC", "Packet Mode"))), )), ('Radio', (('Display', (("MES", "Power-ON Message"), ("CNT", "Contrast"))), ('Save', (("SV", "Battery Saver Interval"), ("APO", "Automatic Power Off (APO)"))), ('DTMF', (("dtmfmem 00", "Number Store #0"), ("dtmfmem 01", "Number Store #1"), ("dtmfmem 02", "Number Store #2"), ("dtmfmem 03", "Number Store #3"), ("dtmfmem 04", "Number Store #4"), ("dtmfmem 05", "Number Store #5"), ("dtmfmem 06", "Number Store #6"), ("dtmfmem 07", "Number Store #7"), ("dtmfmem 08", "Number Store #8"), ("dtmfmem 09", "Number Store #9"), ("TSP", "TX Speed"), ("TXH", "TX Hold"), ("PT", "Pause"))), ('TNC', (("DTB", "Data band select"), ("DS", "DCD sense"))), ('AUX', (("ARO", "Automatic Repeater Offset"), ("SCR", "Scan Resume"), ("BEP", "Key Beep"), ("ELK", "Tuning Enable"), ("TXS", "TX Inhibit"), ("AIP", "Advanced Intercept Point"), ("CKEY", "Call Key function"), ("TH", "TX Hold, 1750 Hz"))))), ('APRS', (("MYC", "My call sign"), ("GU", "GPS receiver"), ("WAY", "Waypoint"), ("MP 1", "My position #1"), ("MP 2", "My position #2"), ("MP 3", "My position #3"), ("PAMB", "Position Ambiguity"), ("POSC", "Position comment"), ("ARL", "Reception restriction distance"), ("ICO", "Station icon"), ("STAT 1", "Status text #1"), ("STAT 2", "Status text #2"), ("STAT 3", "Status text #3"), ("STXR", "Status text transmit rate"), ("PP", "Packet path"), ("DTX", "Packet transmit method"), ("TXI", "Packet transmit interval"), ("UPR", "Group code"), ("BEPT", "Beep"), ("DSPA", "Display area"), ("KILO", "Unit for distance"), ("TEMP", "Unit for temperature"), ("AMR", "Auto Answer Reply"), ("ARLM", "Reply message"), ("AMGG", "Message group"), ("DTBA", "Data band"), ("PKSA", "Packet transfer rate"), ("TZ", "Time Zone"), ("TXD", "Packet transmit delay"))), ('SSTV', (("SMY", "My call sign"), ("MAC", "Color for call sign"), ("SMSG", "Message"), ("SMC", "Color for message"), ("RSV", "RSV report"), ("RSC", "Color for RSV report"), ("VCS", "VC-H1 Control"))), ('SkyCommand', (("SCC", "Commander call sign"), ("SCT", "Transporter call sign"), ("SKTN", "Tone frequency select")))) @directory.register class TMD700Radio(KenwoodD7Family): """Kenwood TH-D700""" MODEL = "TM-D700" HARDWARE_FLOW = True # Details taken from https://www.qsl.net/k7jar/pages/D700Cmds.html # And https://www.qsl.net/k/kb9rku/aprs/ (continued on next line) # PC%20Command%20Specifications%20for%20TM-D700_Rev1.pdf _BAUDS = [57600, 38400, 19200, 9600] _LOWER = 1 _UPPER = 200 _BOOL = {'type': 'bool'} _PKEY_FUNCTION = {'type': 'list', 'values': ('Power', 'A/B', 'Monitor', 'Enter', 'Voice', '1750', 'PM', 'Menu', 'VFO', 'MR', 'CALL', 'MHz', 'Tone', 'Rev', 'Low', 'Mute', 'Ctrl', 'PM.In', 'A.B.C', 'M>V', 'M.In', 'C.In', 'Lock', 'T.Sel', 'Shift', 'Step', 'Visual', 'Dim', 'Sub-Band Select', 'DX', 'TNC', 'List', 'P.Mon', 'BCon', 'Msg', 'Pos')} _VOLUME = {'type': 'list', 'values': ('Off', '1', '2', '3', '4', '5', '6', 'Maximum')} _SETTINGS = { "ABLG": {'type': 'string', 'max_len': 29}, "AD": _BOOL, "BEP": {'type': 'list', 'values': ("Off", "Key")}, "BVOL": _VOLUME, "CP": {'type': 'list', 'values': ('9600bps', '19200bps', '38400bps', '57600bps')}, "DATP": {'type': 'list', 'values': ('1200bps', '9600bps')}, "DIG": _BOOL, "DTM": _BOOL, "FUNC": {'type': 'map', 'map': (("Mode 1", "1"), ("Mode 2", "2"), ("Mode 3", "3"))}, "ICO": {'type': 'map', 'map': (KenwoodD7Family._COMMON_SETTINGS["ICO"]["map"] + (('Digipeater', '0,F'),) + THD7GRadio._APRS_EXTRA)}, "MCL 0": _BOOL, "MCL 1": _BOOL, "MCNT": _BOOL, "MD": {'type': 'list', 'values': ('FM', 'AM')}, "NP": _BOOL, "OS": {'type': 'integer', 'min': -99999999, 'max': 999999999, 'digits': 9}, "PF 1": _PKEY_FUNCTION, "PF 2": _PKEY_FUNCTION, "PF 3": _PKEY_FUNCTION, "PF 4": _PKEY_FUNCTION, "PMM": _BOOL, "RCA": _BOOL, "RC": _BOOL, "RCC": {'type': 'integer', 'min': 0, 'max': 999}, "REP": {'type': 'list', 'values': ('Off', 'Locked-Band', 'Cross-Band')}, "REPL": _BOOL, "SHT": {'type': 'list', 'values': ('Off', '125ms', '250ms', '500ms')}, "SSEL": {'type': 'map', 'map': (("MODE1", "1"), ("MODE2", "2"))}, "SSQ 0": _BOOL, "SSQ 1": _BOOL, "TOT": {'type': 'list', 'values': ('3 minutes', '5 minutes', '10 minutes')}, "UDIG": {'type': 'string', 'max_len': 39, 'charset': '0123456789' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ,-'}, "VOM": {'type': 'list', 'values': ('Off', 'English', 'APRS only', 'Japanese')}, "VS3": _VOLUME, "VSM": {'type': 'map', 'map': (('31 Channels', '1'), ('61 Channels', '2'), ('91 Channels', '3'), ('181 Channels', '4'))}} _PROGRAMMABLE_VFOS = ( ("Band A 118 MHz Sub-Band", 1, 118, 135), ("Band A VHF Sub-Band", 2, 136, 199), ("Band B VHF Sub-Band", 3, 136, 174), ("Band A 220 MHz Sub-Band", 4, 200, 299), ("Band B 300 MHz Sub-Band", 5, 300, 399), ("Band A 300 MHz Sub-Band", 6, 300, 399), ("Band B UHF Sub-Band", 7, 400, 523), ("Band A UHF Sub-Band", 8, 400, 469), ("Band B 1.2 GHz Sub-Band", 9, 800, 1299)) _SETTINGS_MENUS = ( ('Main', (("ASC 0", "Automatic Simplex Check Band A"), ("ASC 1", "Automatic Simplex Check Band B"), ("DL", "Dual"), ("LK", "Lock"), # MNF requires that the *current* VFO be in MR mode # ("MNF", "Memory Display Mode"), # We likely don't want to enable this from Chirp... # ("TNC", "Packet Mode"))), )), ('Radio', (('Display', (("MES", "Power-ON Message"), ("CNT", "Contrast"), ("NP", "Reverse mode"), ("AD", "Auto Dimmer Change"), ("FUNC", "Multi-function button"))), ('Audio', (("BVOL", "Beep volume"), ("BEP", "Key Beep"), ("SSEL", "Speaker configuration"), ("VOM", "Voice Synthesizer"), ("VS3", "Voice volume"))), ('TX/RX', (("PV", "Programmable VFO"), ("SSQ 0", "Band A S-meter Squelch"), ("SSQ 1", "Band B S-meter Squelch"), ("SHT", "Squelch hang time"), ("MD", "FM / AM mode"), ("AIP", "Advanced Intercept Point"), ("XXX", "TX/ RX deviation"))), ('Memory', (("PMM", "Auto PM Channel Store"), ("CH", "Channel Display"), ("MCL 0", "Band A Memory Channel Lockout"), ("MCL 1", "Band B Memory Channel Lockout"), ("XXX", "Memory channel name"))), ('DTMF', (("dtmfmem 00", "Number Store #0"), ("dtmfmem 01", "Number Store #1"), ("dtmfmem 02", "Number Store #2"), ("dtmfmem 03", "Number Store #3"), ("dtmfmem 04", "Number Store #4"), ("dtmfmem 05", "Number Store #5"), ("dtmfmem 06", "Number Store #6"), ("dtmfmem 07", "Number Store #7"), ("dtmfmem 08", "Number Store #8"), ("dtmfmem 09", "Number Store #9"), ("TSP", "TX Speed"), ("PT", "Pause"))), ('TNC', (("DTB", "Data band"), ("DS", "DCD sense"), ("XXX", "Time"), ("XXX", "Date"), ("TZ", "Time zone"))), ('Repeater', (("OS", "Offset frequency"), ("ARO", "Automatic Repeater Offset"), ("CKEY", "Call Button Function"), ("TH", "TX Hold"), ("REPH", "Repeater Hold"), ("REP", "Repeater function"))), ('Mic', (("PF 1", "Mic PF Key"), ("PF 2", "Mic MR Key"), ("PF 3", "Mic VFO Key"), ("PF 4", "Mic CALL Key"), ("MCNT", "Microphone Control"), ("DTM", "DTMF Monitor"))), ('Aux', (("SCR", "Scan Resume"), ("VSM", "Number of Channels for Visual Scan"), ("APO", "Automatic Power Off (APO)"), ("TOT", "Time-Out Timer (TOT)"), ("CP", "COM port"), ("DATP", "Data port"))), ('Remote Control', (("RCC", "Secret code"), ("RCA", "Acknowledgement"), ("RC", "Remote Control"))))), ('SSTV', (("SMY", "My call sign"), ("MAC", "Color for call sign"), ("SMSG", "Message"), ("SMC", "Color for message"), ("RSV", "RSV report"), ("RSC", "Color for RSV report"), ("VCS", "VC-H1 Control"))), ('APRS', (("MYC", "My call sign"), ("GU", "GPS receiver"), ("WAY", "Waypoint"), ("MP 1", "My position #1"), ("MP 2", "My position #2"), ("MP 3", "My position #3"), ("PAMB", "Position Ambiguity"), ("POSC", "Position comment"), ("ARL", "Reception restriction distance"), ("ICO", "Station icon"), ("STAT 1", "Status text #1"), ("STAT 2", "Status text #2"), ("STAT 3", "Status text #3"), ("STXR", "Status text transmit rate"), ("PP", "Packet path"), ("DTX", "Packet transmit method"), ("TXI", "Packet transmit interval"), ("UPR", "Group code"), ("BEPT", "Beep"), ("KILO", "Unit for distance"), ("TEMP", "Unit for temperature"), ("DTBA", "Data band"), ("PKSA", "Packet transfer rate"), ("DIG", "Digipeater"), ("UDIG", "Digipeating path"), ("AMR", "Auto Answer Reply"), ("ARLM", "Reply message"), ("ABLG", "Bulletin group"))), ('SkyCommand', (("SCC", "Commander call sign"), ("SCT", "Transporter call sign"), ("SKTN", "Tone frequency select")))) # Apparently, when sent "CH 1", the radio will return "SM 0,00" # which is the current value of the Band A S-Meter. We'll ignore that # and read the next line (which is hopefully "CH 1") def _keep_reading(self, result): if result[0:3] == 'SM ': return True return False # It also seems that "CH 1" can return "N" when the current memory # is invalid (but still enters CH mode) def _kenwood_set_success(self, cmd, modcmd, value, response): if cmd == 'CH' and value == "1": if response == 'N': return True return super()._kenwood_set_success(cmd, modcmd, value, response) def _mem_spec_fixup(self, spec, memid, mem): spec[6] = "%i" % (mem.tmode == "DTCS") spec[8] = "%03i0" % (chirp_common.DTCS_CODES.index(mem.dtcs) + 1) def _parse_mem_fixup(self, mem, spec): if spec[11] and spec[11].isdigit(): mem.dtcs = chirp_common.DTCS_CODES[int(spec[11][:-1]) - 1] else: LOG.warn("Unknown or invalid DCS: %s" % spec[11]) def get_features(self, *args, **kwargs): rf = super().get_features(*args, **kwargs) rf.has_dtcs = True rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] return rf chirp-20240224/chirp/drivers/vx7.py0000644000175000017500000002562414466370044015736 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, bitwise import logging LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0611; u8 checksum1; #seekto 0x0691; u8 checksum2; #seekto 0x0742; struct { u16 in_use; } bank_used[9]; #seekto 0x0EA2; struct { u16 members[48]; } bank_members[9]; #seekto 0x3F52; u8 checksum3; #seekto 0x1202; struct { u8 even_pskip:1, even_skip:1, even_valid:1, even_masked:1, odd_pskip:1, odd_skip:1, odd_valid:1, odd_masked:1; } flags[225]; #seekto 0x1322; struct { u8 unknown1; u8 power:2, duplex:2, tune_step:4; bbcd freq[3]; u8 zeros1:2, ones:2, zeros2:2, mode:2; u8 name[8]; u8 zero; bbcd offset[3]; u8 zeros3:2, tone:6; u8 zeros4:1, dcs:7; u8 zeros5:5, is_split_tone:1, tmode:2; u8 charset; } memory[450]; """ DUPLEX = ["", "-", "+", "split"] MODES = ["FM", "AM", "WFM", "Auto"] TMODES = ["", "Tone", "TSQL", "DTCS", "Cross"] CROSS_MODES = ["DTCS->", "Tone->DTCS", "DTCS->Tone"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0, 9.0] CHARSET = ["%i" % int(x) for x in range(0, 10)] + \ [" "] + \ [chr(x) for x in range(ord("A"), ord("Z")+1)] + \ [chr(x) for x in range(ord("a"), ord("z")+1)] + \ list(".,:;!\"#$%&'()*+-.=<>?@[?]^_\\{|}") + \ list("\x00" * 100) POWER_LEVELS = [chirp_common.PowerLevel("L1", watts=0.05), chirp_common.PowerLevel("L2", watts=1.00), chirp_common.PowerLevel("L3", watts=2.50), chirp_common.PowerLevel("Hi", watts=5.00) ] POWER_LEVELS_220 = [chirp_common.PowerLevel("L1", watts=0.05), chirp_common.PowerLevel("L2", watts=0.30)] def _is220(freq): return freq >= 222000000 and freq <= 225000000 class VX7BankModel(chirp_common.BankModel): """A VX-7 Bank model""" def get_num_mappings(self): return 9 def get_mappings(self): banks = [] for i in range(0, self.get_num_mappings()): bank = chirp_common.Bank(self, "%i" % (i+1), "MG%i" % (i+1)) bank.index = i banks.append(bank) return banks def add_memory_to_mapping(self, memory, bank): _members = self._radio._memobj.bank_members[bank.index] _bank_used = self._radio._memobj.bank_used[bank.index] for i in range(0, 48): if _members.members[i] == 0xFFFF: _members.members[i] = memory.number - 1 _bank_used.in_use = 0x0000 break def remove_memory_from_mapping(self, memory, bank): _members = self._radio._memobj.bank_members[bank.index].members _bank_used = self._radio._memobj.bank_used[bank.index] found = False remaining_members = 0 for i in range(0, len(_members)): if _members[i] == (memory.number - 1): _members[i] = 0xFFFF found = True elif _members[i] != 0xFFFF: remaining_members += 1 if not found: raise Exception("Memory {num} is not in bank {bank}".format( num=memory.number, bank=bank)) if not remaining_members: _bank_used.in_use = 0xFFFF def get_mapping_memories(self, bank): memories = [] _members = self._radio._memobj.bank_members[bank.index].members _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xFFFF: return memories for number in _members: if number == 0xFFFF: continue memories.append(self._radio.get_memory(number+1)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in [x.number for x in self.get_mapping_memories(bank)]: banks.append(bank) return banks def _wipe_memory(mem): mem.set_raw("\x00" * (mem.size() // 8)) mem.unknown1 = 0x05 mem.ones = 0x03 @directory.register class VX7Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu VX-7""" BAUD_RATE = 19200 VENDOR = "Yaesu" MODEL = "VX-7" _model = "" _memsize = 16211 _block_lengths = [10, 8, 16193] _block_size = 8 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [MON-F] key while turning the radio" " on\n" " (\"CLONE\" will appear on the display).\n" "4. After clicking OK, press the [BAND] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [MON-F] key while turning the radio" " on\n" " (\"CLONE\" will appear on the display).\n" "4. Press the [V/M] key (\"CLONE WAIT\" will appear on the" " LCD).\n") return rp def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0592, 0x0610), yaesu_clone.YaesuChecksum(0x0612, 0x0690), yaesu_clone.YaesuChecksum(0x0000, 0x3F51), ] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = True rf.has_dtcs_polarity = False rf.valid_modes = list(set(MODES)) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(500000, 999000000)] rf.valid_skips = ["", "S", "P"] rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 8 rf.memory_bounds = (1, 450) rf.can_odd_split = True rf.has_ctone = False rf.has_cross = True rf.valid_cross_modes = list(CROSS_MODES) return rf def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def get_memory(self, number): _mem = self._memobj.memory[number-1] _flag = self._memobj.flags[(number-1)/2] nibble = ((number-1) % 2) and "even" or "odd" used = _flag["%s_masked" % nibble] valid = _flag["%s_valid" % nibble] pskip = _flag["%s_pskip" % nibble] skip = _flag["%s_skip" % nibble] mem = chirp_common.Memory() mem.number = number if not used: mem.empty = True if not valid: mem.empty = True mem.power = POWER_LEVELS[0] return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = int(_mem.offset) * 1000 mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] if not _mem.is_split_tone: mem.tmode = TMODES[_mem.tmode] mem.cross_mode = CROSS_MODES[0] else: mem.tmode = "Cross" mem.cross_mode = CROSS_MODES[int(_mem.tmode)] mem.duplex = DUPLEX[_mem.duplex] if mem.duplex == "split": mem.offset = chirp_common.fix_rounded_step(mem.offset) mem.mode = MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] mem.tuning_step = STEPS[_mem.tune_step] mem.skip = pskip and "P" or skip and "S" or "" if _is220(mem.freq): levels = POWER_LEVELS_220 else: levels = POWER_LEVELS try: mem.power = levels[_mem.power] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.power, levels)) mem.power = levels[0] for i in _mem.name: if i == "\xFF": break mem.name += CHARSET[i] mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] _flag = self._memobj.flags[(mem.number-1)/2] nibble = ((mem.number-1) % 2) and "even" or "odd" valid = _flag["%s_valid" % nibble] used = _flag["%s_masked" % nibble] if not mem.empty and not valid: _wipe_memory(_mem) self._wipe_memory_banks(mem) if mem.empty and valid and not used: _flag["%s_valid" % nibble] = False return _flag["%s_masked" % nibble] = not mem.empty if mem.empty: return _flag["%s_valid" % nibble] = True _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 1000 _mem.tone = chirp_common.TONES.index(mem.rtone) if mem.tmode != "Cross": _mem.is_split_tone = 0 _mem.tmode = TMODES.index(mem.tmode) else: _mem.is_split_tone = 1 _mem.tmode = CROSS_MODES.index(mem.cross_mode) _mem.duplex = DUPLEX.index(mem.duplex) _mem.mode = MODES.index(mem.mode) _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tune_step = STEPS.index(mem.tuning_step) if mem.power: if _is220(mem.freq): levels = [str(l) for l in POWER_LEVELS_220] _mem.power = levels.index(str(mem.power)) else: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 _flag["%s_pskip" % nibble] = mem.skip == "P" _flag["%s_skip" % nibble] = mem.skip == "S" for i in range(0, 8): _mem.name[i] = CHARSET.index(mem.name.ljust(8)[i]) def validate_memory(self, mem): msgs = yaesu_clone.YaesuCloneModeRadio.validate_memory(self, mem) if _is220(mem.freq): if str(mem.power) not in [str(l) for l in POWER_LEVELS_220]: msgs.append(chirp_common.ValidationError( "Power level %s not supported on 220 MHz band" % mem.power)) return msgs @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize def get_bank_model(self): return VX7BankModel(self) chirp-20240224/chirp/drivers/uvk5_egzumer.py0000644000175000017500000017022414566340166017642 0ustar hibbyhibby# Quansheng UV-K5 driver (c) 2023 Jacek Lipkowski # Adapted For UV-K5 EGZUMER custom software By EGZUMER, JOC2 # # based on template.py Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import chirp_common, directory, bitwise from chirp.drivers import uvk5 from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettings, InvalidValueError, RadioSettingSubGroup LOG = logging.getLogger(__name__) MEM_FORMAT = """ //#seekto 0x0000; struct { ul32 freq; ul32 offset; // 0x08 u8 rxcode; u8 txcode; // 0x0A u8 txcodeflag:4, rxcodeflag:4; // 0x0B u8 modulation:4, shift:4; // 0x0C u8 __UNUSED1:3, bclo:1, txpower:2, bandwidth:1, freq_reverse:1; // 0x0D u8 __UNUSED2:4, dtmf_pttid:3, dtmf_decode:1; // 0x0E u8 step; u8 scrambler; } channel[214]; //#seekto 0xd60; struct { u8 is_scanlist1:1, is_scanlist2:1, compander:2, is_free:1, band:3; } channel_attributes[207]; #seekto 0xe40; ul16 fmfreq[20]; #seekto 0xe70; u8 call_channel; u8 squelch; u8 max_talk_time; u8 noaa_autoscan; u8 key_lock; u8 vox_switch; u8 vox_level; u8 mic_gain; u8 backlight_min:4, backlight_max:4; u8 channel_display_mode; u8 crossband; u8 battery_save; u8 dual_watch; u8 backlight_time; u8 ste; u8 freq_mode_allowed; #seekto 0xe80; u8 ScreenChannel_A; u8 MrChannel_A; u8 FreqChannel_A; u8 ScreenChannel_B; u8 MrChannel_B; u8 FreqChannel_B; u8 NoaaChannel_A; u8 NoaaChannel_B; #seekto 0xe90; u8 keyM_longpress_action:7, button_beep:1; u8 key1_shortpress_action; u8 key1_longpress_action; u8 key2_shortpress_action; u8 key2_longpress_action; u8 scan_resume_mode; u8 auto_keypad_lock; u8 power_on_dispmode; ul32 password; #seekto 0xea0; u8 voice; u8 s0_level; u8 s9_level; #seekto 0xea8; u8 alarm_mode; u8 roger_beep; u8 rp_ste; u8 TX_VFO; u8 Battery_type; #seekto 0xeb0; char logo_line1[16]; char logo_line2[16]; //#seekto 0xed0; struct { u8 side_tone; char separate_code; char group_call_code; u8 decode_response; u8 auto_reset_time; u8 preload_time; u8 first_code_persist_time; u8 hash_persist_time; u8 code_persist_time; u8 code_interval_time; u8 permit_remote_kill; #seekto 0xee0; char local_code[3]; #seek 5; char kill_code[5]; #seek 3; char revive_code[5]; #seek 3; char up_code[16]; char down_code[16]; } dtmf; //#seekto 0xf18; u8 slDef; u8 sl1PriorEnab; u8 sl1PriorCh1; u8 sl1PriorCh2; u8 sl2PriorEnab; u8 sl2PriorCh1; u8 sl2PriorCh2; #seekto 0xf40; u8 int_flock; u8 int_350tx; u8 int_KILLED; u8 int_200tx; u8 int_500tx; u8 int_350en; u8 int_scren; u8 backlight_on_TX_RX:2, AM_fix:1, mic_bar:1, battery_text:2, live_DTMF_decoder:1, unknown:1; #seekto 0xf50; struct { char name[16]; } channelname[200]; #seekto 0x1c00; struct { char name[8]; char number[3]; #seek 5; } dtmfcontact[16]; struct { struct { #seekto 0x1E00; u8 openRssiThr[10]; #seekto 0x1E10; u8 closeRssiThr[10]; #seekto 0x1E20; u8 openNoiseThr[10]; #seekto 0x1E30; u8 closeNoiseThr[10]; #seekto 0x1E40; u8 closeGlitchThr[10]; #seekto 0x1E50; u8 openGlitchThr[10]; } sqlBand4_7; struct { #seekto 0x1E60; u8 openRssiThr[10]; #seekto 0x1E70; u8 closeRssiThr[10]; #seekto 0x1E80; u8 openNoiseThr[10]; #seekto 0x1E90; u8 closeNoiseThr[10]; #seekto 0x1EA0; u8 closeGlitchThr[10]; #seekto 0x1EB0; u8 openGlitchThr[10]; } sqlBand1_3; #seekto 0x1EC0; struct { ul16 level1; ul16 level2; ul16 level4; ul16 level6; } rssiLevelsBands3_7; struct { ul16 level1; ul16 level2; ul16 level4; ul16 level6; } rssiLevelsBands1_2; struct { struct { u8 lower; u8 center; u8 upper; } low; struct { u8 lower; u8 center; u8 upper; } mid; struct { u8 lower; u8 center; u8 upper; } hi; #seek 7; } txp[7]; #seekto 0x1F40; ul16 batLvl[6]; #seekto 0x1F50; ul16 vox1Thr[10]; #seekto 0x1F68; ul16 vox0Thr[10]; #seekto 0x1F80; u8 micLevel[5]; #seekto 0x1F88; il16 xtalFreqLow; #seekto 0x1F8E; u8 volumeGain; u8 dacGain; } cal; #seekto 0x1FF0; struct { u8 ENABLE_DTMF_CALLING:1, ENABLE_PWRON_PASSWORD:1, ENABLE_TX1750:1, ENABLE_ALARM:1, ENABLE_VOX:1, ENABLE_VOICE:1, ENABLE_NOAA:1, ENABLE_FMRADIO:1; u8 __UNUSED:2, ENABLE_SPECTRUM:1, ENABLE_AM_FIX:1, ENABLE_BLMIN_TMP_OFF:1, ENABLE_RAW_DEMODULATORS:1, ENABLE_WIDE_RX:1, ENABLE_FLASHLIGHT:1; } BUILD_OPTIONS; """ # power UVK5_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1.50), chirp_common.PowerLevel("Med", watts=3.00), chirp_common.PowerLevel("High", watts=5.00), ] # scrambler SCRAMBLER_LIST = ["Off", "2600Hz", "2700Hz", "2800Hz", "2900Hz", "3000Hz", "3100Hz", "3200Hz", "3300Hz", "3400Hz", "3500Hz"] # compander COMPANDER_LIST = ["Off", "TX", "RX", "TX/RX"] # rx mode RXMODE_LIST = ["Main only", "Dual RX, respond", "Crossband", "Dual RX, TX on main"] # channel display mode CHANNELDISP_LIST = ["Frequency", "Channel Number", "Name", "Name + Frequency"] # TalkTime TALK_TIME_LIST = ["30 sec", "1 min", "2 min", "3 min", "4 min", "5 min", "6 min", "7 min", "8 min", "9 min", "15 min"] # battery save BATSAVE_LIST = ["Off", "1:1", "1:2", "1:3", "1:4"] # battery type BATTYPE_LIST = ["1600 mAh", "2200 mAh"] # bat txt BAT_TXT_LIST = ["None", "Voltage", "Percentage"] # Backlight auto mode BACKLIGHT_LIST = ["Off", "5s", "10s", "20s", "1min", "2min", "4min", "Always On"] # Backlight LVL BACKLIGHT_LVL_LIST = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] # Backlight _TX_RX_LIST BACKLIGHT_TX_RX_LIST = ["Off", "TX", "RX", "TX/RX"] # flock list extended FLOCK_LIST = ["Default+ (137-174, 400-470 + Tx200, Tx350, Tx500)", "FCC HAM (144-148, 420-450)", "CE HAM (144-146, 430-440)", "GB HAM (144-148, 430-440)", "137-174, 400-430", "137-174, 400-438", "Disable All", "Unlock All"] SCANRESUME_LIST = ["Listen 5 seconds and resume", "Listen until carrier disappears", "Stop scanning after receiving a signal"] WELCOME_LIST = ["Full screen test", "User message", "Battery voltage", "None"] VOICE_LIST = ["Off", "Chinese", "English"] # ACTIVE CHANNEL TX_VFO_LIST = ["A", "B"] ALARMMODE_LIST = ["Site", "Tone"] ROGER_LIST = ["Off", "Roger beep", "MDC data burst"] RTE_LIST = ["Off", "100ms", "200ms", "300ms", "400ms", "500ms", "600ms", "700ms", "800ms", "900ms", "1000ms"] VOX_LIST = ["Off", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] # fm radio supported frequencies FMMIN = 76.0 FMMAX = 108.0 # bands supported by the UV-K5 BANDS_STANDARD = { 0: [50.0, 76.0], 1: [108.0, 136.9999], 2: [137.0, 173.9999], 3: [174.0, 349.9999], 4: [350.0, 399.9999], 5: [400.0, 469.9999], 6: [470.0, 600.0] } BANDS_WIDE = { 0: [18.0, 108.0], 1: [108.0, 136.9999], 2: [137.0, 173.9999], 3: [174.0, 349.9999], 4: [350.0, 399.9999], 5: [400.0, 469.9999], 6: [470.0, 1300.0] } SCANLIST_SELECT_LIST = ["List 1", "List 2", "All channels"] DTMF_CHARS = "0123456789ABCD*# " DTMF_CHARS_ID = "0123456789ABCDabcd" DTMF_CHARS_KILL = "0123456789ABCDabcd" DTMF_CHARS_UPDOWN = "0123456789ABCDabcd#* " DTMF_CODE_CHARS = "ABCD*# " DTMF_DECODE_RESPONSE_LIST = ["Do nothing", "Local ringing", "Replay response", "Local ringing + reply response"] KEYACTIONS_LIST = ["None", "Flashlight", "TX power", "Monitor", "Scan", "VOX", "Alarm", "FM broadcast radio", "1750Hz tone", "Lock keypad", "Switch main VFO", "Switch frequency/memory mode", "Switch demodulation", "Min backlight temporary off", "Spectrum analyzer" ] MIC_GAIN_LIST = ["+1.1dB", "+4.0dB", "+8.0dB", "+12.0dB", "+15.1dB"] def min_max_def(value, min_val, max_val, default): """returns value if in bounds or default otherwise""" if min_val is not None and value < min_val: return default if max_val is not None and value > max_val: return default return value def list_def(value, lst, default): """return value if is in the list, default otherwise""" if isinstance(default, str): default = lst.index(default) if value < 0 or value >= len(lst): return default return value @directory.register @directory.detected_by(uvk5.UVK5Radio) class UVK5RadioEgzumer(uvk5.UVK5RadioBase): """Quansheng UV-K5 (egzumer)""" VENDOR = "Quansheng" MODEL = "UV-K5" VARIANT = "egzumer" BAUD_RATE = 38400 NEEDS_COMPAT_SERIAL = False FIRMWARE_VERSION = "" _cal_start = 0x1E00 # calibration memory start address _pttid_list = ["Off", "Up code", "Down code", "Up+Down code", "Apollo Quindar"] _steps = [2.5, 5, 6.25, 10, 12.5, 25, 8.33, 0.01, 0.05, 0.1, 0.25, 0.5, 1, 1.25, 9, 15, 20, 30, 50, 100, 125, 200, 250, 500] @classmethod def k5_approve_firmware(cls, firmware): return firmware.startswith('EGZUMER ') def _get_bands(self): is_wide = self._memobj.BUILD_OPTIONS.ENABLE_WIDE_RX \ if self._memobj is not None else True bands = BANDS_WIDE if is_wide else BANDS_STANDARD return bands def _find_band(self, hz): mhz = hz/1000000.0 bands = self._get_bands() for bnd, rng in bands.items(): if rng[0] <= mhz <= rng[1]: return bnd return False def _get_vfo_channel_names(self): """generates VFO_CHANNEL_NAMES""" bands = self._get_bands() names = [] for bnd, rng in bands.items(): name = f"F{bnd + 1}({round(rng[0])}M-{round(rng[1])}M)" names.append(name + "A") names.append(name + "B") return names def _get_specials(self): """generates SPECIALS""" specials = {} for idx, name in enumerate(self._get_vfo_channel_names()): specials[name] = 200 + idx return specials # Return information about this radio's features, including # how many memories it has, what bands it supports, etc def get_features(self): rf = super().get_features() rf.valid_special_chans = self._get_vfo_channel_names() rf.valid_modes = ["FM", "NFM", "AM", "NAM", "USB"] rf.valid_bands = [] bands = self._get_bands() for _, rng in bands.items(): rf.valid_bands.append( (int(rng[0]*1000000), int(rng[1]*1000000))) return rf # Convert the raw byte array into a memory object structure def process_mmap(self): self._check_firmware_at_load() self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def _get_mem_mode(self, _mem): temp_modes = self.get_features().valid_modes temp_modul = _mem.modulation * 2 + _mem.bandwidth if temp_modul < len(temp_modes): return temp_modes[temp_modul] elif temp_modul == 5: # USB with narrow setting return temp_modes[4] elif temp_modul >= len(temp_modes): LOG.error('Mode %i unsupported', temp_modul) return "FM" def get_memory(self, number): mem = super().get_memory(number) try: number = self._get_specials()[number] except KeyError: number -= 1 if number < 200: comp = list_def(self._memobj.channel_attributes[number].compander, COMPANDER_LIST, 0) else: comp = 0 val = RadioSettingValueList(COMPANDER_LIST, None, comp) rs = RadioSetting("compander", "Compander (Compnd)", val) mem.extra.append(rs) return mem def _set_mem_mode(self, _mem, mode): tmp_mode = self.get_features().valid_modes.index(mode) _mem.modulation = tmp_mode / 2 _mem.bandwidth = tmp_mode % 2 if mode == "USB": _mem.bandwidth = 1 # narrow def set_memory(self, mem): super().set_memory(mem) try: number = self._get_specials()[mem.number] except KeyError: number = mem.number - 1 if number < 200 and 'compander' in mem.extra: self._memobj.channel_attributes[number].compander = ( COMPANDER_LIST.index(str(mem.extra['compander'].value))) def set_settings(self, settings): _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue elname = element.get_name() # basic settings # VFO_A e80 ScreenChannel_A if elname == "VFO_A_chn": _mem.ScreenChannel_A = element.value if _mem.ScreenChannel_A < 200: _mem.MrChannel_A = _mem.ScreenChannel_A elif _mem.ScreenChannel_A < 207: _mem.FreqChannel_A = _mem.ScreenChannel_A else: _mem.NoaaChannel_A = _mem.ScreenChannel_A # VFO_B e83 elif elname == "VFO_B_chn": _mem.ScreenChannel_B = element.value if _mem.ScreenChannel_B < 200: _mem.MrChannel_B = _mem.ScreenChannel_B elif _mem.ScreenChannel_B < 207: _mem.FreqChannel_B = _mem.ScreenChannel_B else: _mem.NoaaChannel_B = _mem.ScreenChannel_B # TX_VFO channel selected A,B elif elname == "TX_VFO": _mem.TX_VFO = element.value # call channel elif elname == "call_channel": _mem.call_channel = element.value # squelch elif elname == "squelch": _mem.squelch = element.value # TOT elif elname == "tot": _mem.max_talk_time = element.value # NOAA autoscan elif elname == "noaa_autoscan": _mem.noaa_autoscan = element.value # VOX elif elname == "vox": voxvalue = int(element.value) _mem.vox_switch = voxvalue > 0 _mem.vox_level = (voxvalue - 1) if _mem.vox_switch else 0 # mic gain elif elname == "mic_gain": _mem.mic_gain = element.value # Channel display mode elif elname == "channel_display_mode": _mem.channel_display_mode = element.value # RX Mode elif elname == "rx_mode": tmptxmode = int(element.value) tmpmainvfo = _mem.TX_VFO + 1 _mem.crossband = tmpmainvfo * bool(tmptxmode & 0b10) _mem.dual_watch = tmpmainvfo * bool(tmptxmode & 0b01) # Battery Save elif elname == "battery_save": _mem.battery_save = element.value # Backlight auto mode elif elname == "backlight_time": _mem.backlight_time = element.value # Backlight min elif elname == "backlight_min": _mem.backlight_min = element.value # Backlight max elif elname == "backlight_max": _mem.backlight_max = element.value # Backlight TX_RX elif elname == "backlight_on_TX_RX": _mem.backlight_on_TX_RX = element.value # AM_fix elif elname == "AM_fix": _mem.AM_fix = element.value # mic_bar elif elname == "mem.mic_bar": _mem.mic_bar = element.value # Batterie txt elif elname == "_mem.battery_text": _mem.battery_text = element.value # Tail tone elimination elif elname == "ste": _mem.ste = element.value # VFO Open elif elname == "freq_mode_allowed": _mem.freq_mode_allowed = element.value # Beep control elif elname == "button_beep": _mem.button_beep = element.value # Scan resume mode elif elname == "scan_resume_mode": _mem.scan_resume_mode = element.value # Keypad lock elif elname == "key_lock": _mem.key_lock = element.value # Auto keypad lock elif elname == "auto_keypad_lock": _mem.auto_keypad_lock = element.value # Power on display mode elif elname == "welcome_mode": _mem.power_on_dispmode = element.value # Keypad Tone elif elname == "voice": _mem.voice = element.value elif elname == "s0_level": _mem.s0_level = element.value * -1 elif elname == "s9_level": _mem.s9_level = element.value * -1 elif elname == "password": if element.value.get_value() is None or element.value == "": _mem.password = 0xFFFFFFFF else: _mem.password = element.value # Alarm mode elif elname == "alarm_mode": _mem.alarm_mode = element.value # Reminding of end of talk elif elname == "roger_beep": _mem.roger_beep = element.value # Repeater tail tone elimination elif elname == "rp_ste": _mem.rp_ste = element.value # Logo string 1 elif elname == "logo1": bts = str(element.value).rstrip("\x20\xff\x00")+"\x00" * 12 _mem.logo_line1 = bts[0:12] + "\x00\xff\xff\xff" # Logo string 2 elif elname == "logo2": bts = str(element.value).rstrip("\x20\xff\x00")+"\x00" * 12 _mem.logo_line2 = bts[0:12] + "\x00\xff\xff\xff" # unlock settings # FLOCK elif elname == "int_flock": _mem.int_flock = element.value # 350TX elif elname == "int_350tx": _mem.int_350tx = element.value # KILLED elif elname == "int_KILLED": _mem.int_KILLED = element.value # 200TX elif elname == "int_200tx": _mem.int_200tx = element.value # 500TX elif elname == "int_500tx": _mem.int_500tx = element.value # 350EN elif elname == "int_350en": _mem.int_350en = element.value # SCREN elif elname == "int_scren": _mem.int_scren = element.value # battery type elif elname == "Battery_type": _mem.Battery_type = element.value # fm radio for i in range(1, 21): freqname = "FM_%i" % i if elname == freqname: val = str(element.value).strip() try: val2 = int(float(val) * 10) except Exception: val2 = 0xffff if val2 < FMMIN * 10 or val2 > FMMAX * 10: val2 = 0xffff # raise errors.InvalidValueError( # "FM radio frequency should be a value " # "in the range %.1f - %.1f" % (FMMIN , FMMAX)) _mem.fmfreq[i-1] = val2 # dtmf settings if elname == "dtmf_side_tone": _mem.dtmf.side_tone = element.value elif elname == "dtmf_separate_code": _mem.dtmf.separate_code = element.value elif elname == "dtmf_group_call_code": _mem.dtmf.group_call_code = element.value elif elname == "dtmf_decode_response": _mem.dtmf.decode_response = element.value elif elname == "dtmf_auto_reset_time": _mem.dtmf.auto_reset_time = element.value elif elname == "dtmf_preload_time": _mem.dtmf.preload_time = element.value // 10 elif elname == "dtmf_first_code_persist_time": _mem.dtmf.first_code_persist_time = element.value // 10 elif elname == "dtmf_hash_persist_time": _mem.dtmf.hash_persist_time = element.value // 10 elif elname == "dtmf_code_persist_time": _mem.dtmf.code_persist_time = element.value // 10 elif elname == "dtmf_code_interval_time": _mem.dtmf.code_interval_time = element.value // 10 elif elname == "dtmf_permit_remote_kill": _mem.dtmf.permit_remote_kill = element.value elif elname == "dtmf_dtmf_local_code": k = str(element.value).rstrip("\x20\xff\x00") + "\x00" * 3 _mem.dtmf.local_code = k[0:3] elif elname == "dtmf_dtmf_up_code": k = str(element.value).strip("\x20\xff\x00") + "\x00" * 16 _mem.dtmf.up_code = k[0:16] elif elname == "dtmf_dtmf_down_code": k = str(element.value).rstrip("\x20\xff\x00") + "\x00" * 16 _mem.dtmf.down_code = k[0:16] elif elname == "dtmf_kill_code": k = str(element.value).strip("\x20\xff\x00") + "\x00" * 5 _mem.dtmf.kill_code = k[0:5] elif elname == "dtmf_revive_code": k = str(element.value).strip("\x20\xff\x00") + "\x00" * 5 _mem.dtmf.revive_code = k[0:5] elif elname == "live_DTMF_decoder": _mem.live_DTMF_decoder = element.value # dtmf contacts for i in range(1, 17): varname = "DTMF_%i" % i if elname == varname: k = str(element.value).rstrip("\x20\xff\x00") + "\x00" * 8 _mem.dtmfcontact[i-1].name = k[0:8] varnumname = "DTMFNUM_%i" % i if elname == varnumname: k = str(element.value).rstrip("\x20\xff\x00") + "\xff" * 3 _mem.dtmfcontact[i-1].number = k[0:3] # scanlist stuff if elname == "slDef": _mem.slDef = element.value elif elname == "sl1PriorEnab": _mem.sl1PriorEnab = element.value elif elname == "sl2PriorEnab": _mem.sl2PriorEnab = element.value elif elname in ["sl1PriorCh1", "sl1PriorCh2", "sl2PriorCh1", "sl2PriorCh2"]: val = int(element.value) if val > 200 or val < 1: val = 0xff else: val -= 1 _mem[elname] = val if elname == "key1_shortpress_action": _mem.key1_shortpress_action = \ KEYACTIONS_LIST.index(element.value) elif elname == "key1_longpress_action": _mem.key1_longpress_action = \ KEYACTIONS_LIST.index(element.value) elif elname == "key2_shortpress_action": _mem.key2_shortpress_action = \ KEYACTIONS_LIST.index(element.value) elif elname == "key2_longpress_action": _mem.key2_longpress_action = \ KEYACTIONS_LIST.index(element.value) elif elname == "keyM_longpress_action": _mem.keyM_longpress_action = \ KEYACTIONS_LIST.index(element.value) elif elname == "upload_calibration": self._upload_calibration = bool(element.value) elif element.changed() and elname.startswith("cal."): _mem.get_path(elname).set_value(element.value) def get_settings(self): _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") keya = RadioSettingGroup("keya", "Programmable Keys") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") dtmfc = RadioSettingGroup("dtmfc", "DTMF Contacts") scanl = RadioSettingGroup("scn", "Scan Lists") unlock = RadioSettingGroup("unlock", "Unlock Settings") fmradio = RadioSettingGroup("fmradio", "FM Radio") calibration = RadioSettingGroup("calibration", "Calibration") roinfo = RadioSettingGroup("roinfo", "Driver Information") top = RadioSettings() top.append(basic) top.append(advanced) top.append(keya) top.append(dtmf) if _mem.BUILD_OPTIONS.ENABLE_DTMF_CALLING: top.append(dtmfc) top.append(scanl) top.append(unlock) if _mem.BUILD_OPTIONS.ENABLE_FMRADIO: top.append(fmradio) top.append(roinfo) top.append(calibration) # helper function def append_label(radio_setting, label, descr=""): if not hasattr(append_label, 'idx'): append_label.idx = 0 val = RadioSettingValueString(len(descr), len(descr), descr) val.set_mutable(False) rs = RadioSetting("label%s" % append_label.idx, label, val) append_label.idx += 1 radio_setting.append(rs) # Programmable keys def get_action(action_num): """"get actual key action""" lst = KEYACTIONS_LIST.copy() if not self._memobj.BUILD_OPTIONS.ENABLE_ALARM: lst.remove("Alarm") if not self._memobj.BUILD_OPTIONS.ENABLE_TX1750: lst.remove("1750Hz tone") if not self._memobj.BUILD_OPTIONS.ENABLE_FLASHLIGHT: lst.remove("Flashlight") if not self._memobj.BUILD_OPTIONS.ENABLE_VOX: lst.remove("VOX") if not self._memobj.BUILD_OPTIONS.ENABLE_FMRADIO: lst.remove("FM broadcast radio") if not self._memobj.BUILD_OPTIONS.ENABLE_BLMIN_TMP_OFF: lst.remove("Min backlight temporary off") if not self._memobj.BUILD_OPTIONS.ENABLE_SPECTRUM: lst.remove("Spectrum analyzer") action_num = int(action_num) if action_num >= len(KEYACTIONS_LIST) or \ KEYACTIONS_LIST[action_num] not in lst: action_num = 0 return lst, KEYACTIONS_LIST[action_num] val = RadioSettingValueList(*get_action(_mem.key1_shortpress_action)) rs = RadioSetting("key1_shortpress_action", "Side key 1 short press (F1Shrt)", val) keya.append(rs) val = RadioSettingValueList(*get_action(_mem.key1_longpress_action)) rs = RadioSetting("key1_longpress_action", "Side key 1 long press (F1Long)", val) keya.append(rs) val = RadioSettingValueList(*get_action(_mem.key2_shortpress_action)) rs = RadioSetting("key2_shortpress_action", "Side key 2 short press (F2Shrt)", val) keya.append(rs) val = RadioSettingValueList(*get_action(_mem.key2_longpress_action)) rs = RadioSetting("key2_longpress_action", "Side key 2 long press (F2Long)", val) keya.append(rs) val = RadioSettingValueList(*get_action(_mem.keyM_longpress_action)) rs = RadioSetting("keyM_longpress_action", "Menu key long press (M Long)", val) keya.append(rs) # ----------------- DTMF settings tmpval = str(_mem.dtmf.separate_code) if tmpval not in DTMF_CODE_CHARS: tmpval = '*' val = RadioSettingValueString(1, 1, tmpval) val.set_charset(DTMF_CODE_CHARS) sep_code_setting = RadioSetting("dtmf_separate_code", "Separate Code", val) tmpval = str(_mem.dtmf.group_call_code) if tmpval not in DTMF_CODE_CHARS: tmpval = '#' val = RadioSettingValueString(1, 1, tmpval) val.set_charset(DTMF_CODE_CHARS) group_code_setting = RadioSetting("dtmf_group_call_code", "Group Call Code", val) tmpval = min_max_def(_mem.dtmf.first_code_persist_time * 10, 30, 1000, 300) val = RadioSettingValueInteger(30, 1000, tmpval, 10) first_code_per_setting = \ RadioSetting("dtmf_first_code_persist_time", "First code persist time (ms)", val) tmpval = min_max_def(_mem.dtmf.hash_persist_time * 10, 30, 1000, 300) val = RadioSettingValueInteger(30, 1000, tmpval, 10) spec_per_setting = RadioSetting("dtmf_hash_persist_time", "#/* persist time (ms)", val) tmpval = min_max_def(_mem.dtmf.code_persist_time * 10, 30, 1000, 300) val = RadioSettingValueInteger(30, 1000, tmpval, 10) code_per_setting = RadioSetting("dtmf_code_persist_time", "Code persist time (ms)", val) tmpval = min_max_def(_mem.dtmf.code_interval_time * 10, 30, 1000, 300) val = RadioSettingValueInteger(30, 1000, tmpval, 10) code_int_setting = RadioSetting("dtmf_code_interval_time", "Code interval time (ms)", val) tmpval = str(_mem.dtmf.local_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_ID: continue tmpval = "103" break val = RadioSettingValueString(3, 3, tmpval) val.set_charset(DTMF_CHARS_ID) ani_id_setting = \ RadioSetting("dtmf_dtmf_local_code", "Local code (ANI ID)", val) ani_id_setting.set_doc('3 chars 0-9 ABCD') tmpval = str(_mem.dtmf.up_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_UPDOWN or i == "": continue else: tmpval = "123" break val = RadioSettingValueString(1, 16, tmpval) val.set_charset(DTMF_CHARS_UPDOWN) up_code_setting = \ RadioSetting("dtmf_dtmf_up_code", "Up code", val) up_code_setting.set_doc('1-16 chars 0-9 ABCD*#') tmpval = str(_mem.dtmf.down_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_UPDOWN: continue else: tmpval = "456" break val = RadioSettingValueString(1, 16, tmpval) val.set_charset(DTMF_CHARS_UPDOWN) dw_code_setting = \ RadioSetting("dtmf_dtmf_down_code", "Down code", val) dw_code_setting.set_doc('1-16 chars 0-9 ABCD*#') val = RadioSettingValueBoolean(_mem.dtmf.side_tone) dtmf_side_tone_setting = \ RadioSetting("dtmf_side_tone", "DTMF Sidetone on speaker when sent (D ST)", val) tmpval = list_def(_mem.dtmf.decode_response, DTMF_DECODE_RESPONSE_LIST, 0) val = RadioSettingValueList(DTMF_DECODE_RESPONSE_LIST, None, tmpval) dtmf_resp_setting = RadioSetting("dtmf_decode_response", "Decode Response (D Resp)", val) tmpval = min_max_def(_mem.dtmf.auto_reset_time, 5, 60, 10) val = RadioSettingValueInteger(5, 60, tmpval) d_hold_setting = RadioSetting("dtmf_auto_reset_time", "Auto reset time (s) (D Hold)", val) # D Prel tmpval = min_max_def(_mem.dtmf.preload_time * 10, 30, 990, 300) val = RadioSettingValueInteger(30, 990, tmpval, 10) d_prel_setting = RadioSetting("dtmf_preload_time", "Pre-load time (ms) (D Prel)", val) # D LIVE val = RadioSettingValueBoolean(_mem.live_DTMF_decoder) d_live_setting = \ RadioSetting("live_DTMF_decoder", "Displays DTMF codes" " received in the middle of the screen (D Live)", val) val = RadioSettingValueBoolean(_mem.dtmf.permit_remote_kill) perm_kill_setting = RadioSetting("dtmf_permit_remote_kill", "Permit remote kill", val) tmpval = str(_mem.dtmf.kill_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_KILL: continue else: tmpval = "77777" break if not len(tmpval) == 5: tmpval = "77777" val = RadioSettingValueString(5, 5, tmpval) val.set_charset(DTMF_CHARS_KILL) kill_code_setting = RadioSetting("dtmf_kill_code", "Kill code", val) kill_code_setting.set_doc('5 chars 0-9 ABCD') tmpval = str(_mem.dtmf.revive_code).upper().strip( "\x00\xff\x20") for i in tmpval: if i in DTMF_CHARS_KILL: continue else: tmpval = "88888" break if not len(tmpval) == 5: tmpval = "88888" val = RadioSettingValueString(5, 5, tmpval) val.set_charset(DTMF_CHARS_KILL) rev_code_setting = RadioSetting("dtmf_revive_code", "Revive code", val) rev_code_setting.set_doc('5 chars 0-9 ABCD') val = RadioSettingValueBoolean(_mem.int_KILLED) killed_setting = RadioSetting("int_KILLED", "DTMF kill lock", val) # ----------------- DTMF Contacts for i in range(1, 17): varname = "DTMF_"+str(i) varnumname = "DTMFNUM_"+str(i) vardescr = "DTMF Contact "+str(i)+" name" varinumdescr = "DTMF Contact "+str(i)+" number" cntn = str(_mem.dtmfcontact[i-1].name).strip("\x20\x00\xff") cntnum = str(_mem.dtmfcontact[i-1].number).strip("\x20\x00\xff") val = RadioSettingValueString(0, 8, cntn) rs = RadioSetting(varname, vardescr, val) dtmfc.append(rs) val = RadioSettingValueString(0, 3, cntnum) val.set_charset(DTMF_CHARS) rs = RadioSetting(varnumname, varinumdescr, val) rs.set_doc("DTMF Contacts are 3 codes (valid: 0-9 * # ABCD), " "or an empty string") dtmfc.append(rs) # ----------------- Scan Lists tmpscanl = list_def(_mem.slDef, SCANLIST_SELECT_LIST, 0) val = RadioSettingValueList(SCANLIST_SELECT_LIST, None, tmpscanl) rs = RadioSetting("slDef", "Default scanlist (SList)", val) scanl.append(rs) val = RadioSettingValueBoolean(_mem.sl1PriorEnab) rs = RadioSetting("sl1PriorEnab", "List 1 priority channel scan", val) scanl.append(rs) ch_list = ["None"] for ch in range(1, 201): ch_list.append("Channel M%i" % ch) tmpch = list_def(_mem.sl1PriorCh1 + 1, ch_list, 0) val = RadioSettingValueList(ch_list, None, tmpch) rs = RadioSetting("sl1PriorCh1", "List 1 priority channel 1", val) scanl.append(rs) tmpch = list_def(_mem.sl1PriorCh2 + 1, ch_list, 0) val = RadioSettingValueList(ch_list, None, tmpch) rs = RadioSetting("sl1PriorCh2", "List 1 priority channel 2", val) scanl.append(rs) val = RadioSettingValueBoolean(_mem.sl2PriorEnab) rs = RadioSetting("sl2PriorEnab", "List 2 priority channel scan", val) scanl.append(rs) tmpch = list_def(_mem.sl2PriorCh1 + 1, ch_list, 0) val = RadioSettingValueList(ch_list, None, tmpch) rs = RadioSetting("sl2PriorCh1", "List 2 priority channel 1", val) scanl.append(rs) tmpch = list_def(_mem.sl2PriorCh2 + 1, ch_list, 0) val = RadioSettingValueList(ch_list, None, tmpch) rs = RadioSetting("sl2PriorCh2", "List 2 priority channel 2", val) scanl.append(rs) # ----------------- Basic settings ch_list = [] for ch in range(1, 201): ch_list.append("Channel M%i" % ch) for bnd in range(1, 8): ch_list.append("Band F%i" % bnd) if _mem.BUILD_OPTIONS.ENABLE_NOAA: for bnd in range(1, 11): ch_list.append("NOAA N%i" % bnd) tmpfreq0 = list_def(_mem.ScreenChannel_A, ch_list, 0) val = RadioSettingValueList(ch_list, None, tmpfreq0) freq0_setting = RadioSetting("VFO_A_chn", "VFO A current channel/band", val) tmpfreq1 = list_def(_mem.ScreenChannel_B, ch_list, 0) val = RadioSettingValueList(ch_list, None, tmpfreq1) freq1_setting = RadioSetting("VFO_B_chn", "VFO B current channel/band", val) tmptxvfo = list_def(_mem.TX_VFO, TX_VFO_LIST, 0) val = RadioSettingValueList(TX_VFO_LIST, None, tmptxvfo) tx_vfo_setting = RadioSetting("TX_VFO", "Main VFO", val) tmpsq = min_max_def(_mem.squelch, 0, 9, 1) val = RadioSettingValueInteger(0, 9, tmpsq) squelch_setting = RadioSetting("squelch", "Squelch (Sql)", val) ch_list = [] for ch in range(1, 201): ch_list.append("Channel M%i" % ch) tmpc = list_def(_mem.call_channel, ch_list, 0) val = RadioSettingValueList(ch_list, None, tmpc) call_channel_setting = RadioSetting("call_channel", "One key call channel (1 Call)", val) val = RadioSettingValueBoolean(_mem.key_lock) keypad_cock_setting = RadioSetting("key_lock", "Keypad locked", val) val = RadioSettingValueBoolean(_mem.auto_keypad_lock) auto_keypad_lock_setting = \ RadioSetting("auto_keypad_lock", "Auto keypad lock (KeyLck)", val) tmptot = list_def(_mem.max_talk_time, TALK_TIME_LIST, 1) val = RadioSettingValueList(TALK_TIME_LIST, None, tmptot) tx_t_out_setting = RadioSetting("tot", "Max talk, TX Time Out (TxTOut)", val) tmpbatsave = list_def(_mem.battery_save, BATSAVE_LIST, 4) val = RadioSettingValueList(BATSAVE_LIST, None, tmpbatsave) bat_save_setting = RadioSetting("battery_save", "Battery save (BatSav)", val) val = RadioSettingValueBoolean(_mem.noaa_autoscan) noaa_auto_scan_setting = RadioSetting("noaa_autoscan", "NOAA Autoscan (NOAA-S)", val) tmpmicgain = list_def(_mem.mic_gain, MIC_GAIN_LIST, 2) val = RadioSettingValueList(MIC_GAIN_LIST, None, tmpmicgain) mic_gain_setting = RadioSetting("mic_gain", "Mic Gain (Mic)", val) val = RadioSettingValueBoolean(_mem.mic_bar) mic_bar_setting = RadioSetting("mic_bar", "Microphone Bar display (MicBar)", val) tmpchdispmode = list_def(_mem.channel_display_mode, CHANNELDISP_LIST, 0) val = RadioSettingValueList(CHANNELDISP_LIST, None, tmpchdispmode) ch_disp_setting = RadioSetting("channel_display_mode", "Channel display mode (ChDisp)", val) tmpdispmode = list_def(_mem.power_on_dispmode, WELCOME_LIST, 0) val = RadioSettingValueList(WELCOME_LIST, None, tmpdispmode) p_on_msg_setting = RadioSetting("welcome_mode", "Power ON display message (POnMsg)", val) logo1 = str(_mem.logo_line1).strip("\x20\x00\xff") + "\x00" logo1 = uvk5._getstring(logo1.encode('ascii', errors='ignore'), 0, 12) val = RadioSettingValueString(0, 12, logo1) logo1_setting = RadioSetting("logo1", "Message line 1", val) logo2 = str(_mem.logo_line2).strip("\x20\x00\xff") + "\x00" logo2 = uvk5._getstring(logo2.encode('ascii', errors='ignore'), 0, 12) val = RadioSettingValueString(0, 12, logo2) logo2_setting = RadioSetting("logo2", "Message line 2", val) tmpbattxt = list_def(_mem.battery_text, BAT_TXT_LIST, 2) val = RadioSettingValueList(BAT_TXT_LIST, None, tmpbattxt) bat_txt_setting = RadioSetting("battery_text", "Battery Level Display (BatTXT)", val) tmpback = list_def(_mem.backlight_time, BACKLIGHT_LIST, 0) val = RadioSettingValueList(BACKLIGHT_LIST, None, tmpback) back_lt_setting = RadioSetting("backlight_time", "Backlight time (BackLt)", val) tmpback = list_def(_mem.backlight_min, BACKLIGHT_LVL_LIST, 0) val = RadioSettingValueList(BACKLIGHT_LVL_LIST, None, tmpback) bl_min_setting = RadioSetting("backlight_min", "Backlight level min (BLMin)", val) tmpback = list_def(_mem.backlight_max, BACKLIGHT_LVL_LIST, 10) val = RadioSettingValueList(BACKLIGHT_LVL_LIST, None, tmpback) bl_max_setting = RadioSetting("backlight_max", "Backlight level max (BLMax)", val) tmpback = list_def(_mem.backlight_on_TX_RX, BACKLIGHT_TX_RX_LIST, 0) val = RadioSettingValueList(BACKLIGHT_TX_RX_LIST, None, tmpback) blt_trx_setting = RadioSetting("backlight_on_TX_RX", "Backlight on TX/RX (BltTRX)", val) val = RadioSettingValueBoolean(_mem.button_beep) beep_setting = RadioSetting("button_beep", "Key press beep sound (Beep)", val) tmpalarmmode = list_def(_mem.roger_beep, ROGER_LIST, 0) val = RadioSettingValueList(ROGER_LIST, None, tmpalarmmode) roger_setting = RadioSetting("roger_beep", "End of transmission beep (Roger)", val) val = RadioSettingValueBoolean(_mem.ste) ste_setting = RadioSetting("ste", "Squelch tail elimination (STE)", val) tmprte = list_def(_mem.rp_ste, RTE_LIST, 0) val = RadioSettingValueList(RTE_LIST, None, tmprte) rp_ste_setting = \ RadioSetting("rp_ste", "Repeater squelch tail elimination (RP STE)", val) val = RadioSettingValueBoolean(_mem.AM_fix) am_fix_setting = RadioSetting("AM_fix", "AM reception fix (AM Fix)", val) tmpvox = min_max_def((_mem.vox_level + 1) * _mem.vox_switch, 0, 10, 0) val = RadioSettingValueList(VOX_LIST, None, tmpvox) vox_setting = RadioSetting("vox", "Voice-operated switch (VOX)", val) tmprxmode = list_def((bool(_mem.crossband) << 1) + bool(_mem.dual_watch), RXMODE_LIST, 0) val = RadioSettingValueList(RXMODE_LIST, None, tmprxmode) rx_mode_setting = RadioSetting("rx_mode", "RX Mode (RxMode)", val) val = RadioSettingValueBoolean(_mem.freq_mode_allowed) freq_mode_allowed_setting = RadioSetting("freq_mode_allowed", "Frequency mode allowed", val) tmpscanres = list_def(_mem.scan_resume_mode, SCANRESUME_LIST, 0) val = RadioSettingValueList(SCANRESUME_LIST, None, tmpscanres) scn_rev_setting = RadioSetting("scan_resume_mode", "Scan resume mode (ScnRev)", val) tmpvoice = list_def(_mem.voice, VOICE_LIST, 0) val = RadioSettingValueList(VOICE_LIST, None, tmpvoice) voice_setting = RadioSetting("voice", "Voice", val) tmpalarmmode = list_def(_mem.alarm_mode, ALARMMODE_LIST, 0) val = RadioSettingValueList(ALARMMODE_LIST, None, tmpalarmmode) alarm_setting = RadioSetting("alarm_mode", "Alarm mode", val) # ----------------- Extra settings # S-meter tmp_s0 = -int(_mem.s0_level) tmp_s9 = -int(_mem.s9_level) if tmp_s0 not in range(-200, -91) or tmp_s9 not in range(-160, -51) \ or tmp_s9 < tmp_s0+9: tmp_s0 = -130 tmp_s9 = -76 val = RadioSettingValueInteger(-200, -90, tmp_s0) s0_level_setting = RadioSetting("s0_level", "S-meter S0 level [dBm]", val) val = RadioSettingValueInteger(-160, -50, tmp_s9) s9_level_setting = RadioSetting("s9_level", "S-meter S9 level [dBm]", val) # Battery Type tmpbtype = list_def(_mem.Battery_type, BATTYPE_LIST, 0) val = RadioSettingValueList(BATTYPE_LIST, BATTYPE_LIST[tmpbtype]) bat_type_setting = RadioSetting("Battery_type", "Battery Type (BatTyp)", val) # Power on password def validate_password(value): value = value.strip(" ") if value.isdigit(): return value.zfill(6) if value != "": raise InvalidValueError("Power on password " "can only have digits") return "" pswd_str = str(int(_mem.password)).zfill(6) \ if _mem.password < 1000000 else "" val = RadioSettingValueString(0, 6, pswd_str) val.set_validate_callback(validate_password) pswd_setting = RadioSetting("password", "Power on password", val) # ----------------- FM radio for i in range(1, 21): fmfreq = _mem.fmfreq[i-1] / 10.0 freq_name = str(fmfreq) if fmfreq < FMMIN or fmfreq > FMMAX: freq_name = "" rs = RadioSetting("FM_%i" % i, "Ch %i" % i, RadioSettingValueString(0, 5, freq_name)) fmradio.append(rs) rs.set_doc('Frequency in MHz') # ----------------- Unlock settings # F-LOCK def validate_int_flock(value): mem_val = self._memobj.int_flock if mem_val != 7 and value == FLOCK_LIST[7]: msg = "%r can only be enabled from radio menu" % value raise InvalidValueError(msg) return value tmpflock = list_def(_mem.int_flock, FLOCK_LIST, 0) val = RadioSettingValueList(FLOCK_LIST, None, tmpflock) val.set_validate_callback(validate_int_flock) f_lock_setting = RadioSetting("int_flock", "TX Frequency Lock (F Lock)", val) val = RadioSettingValueBoolean(_mem.int_200tx) tx200_setting = RadioSetting("int_200tx", "Unlock 174-350MHz TX (Tx 200)", val) val = RadioSettingValueBoolean(_mem.int_350tx) tx350_setting = RadioSetting("int_350tx", "Unlock 350-400MHz TX (Tx 350)", val) val = RadioSettingValueBoolean(_mem.int_500tx) tx500_setting = RadioSetting("int_500tx", "Unlock 500-600MHz TX (Tx 500)", val) val = RadioSettingValueBoolean(_mem.int_350en) en350_setting = RadioSetting("int_350en", "Unlock 350-400MHz RX (350 En)", val) val = RadioSettingValueBoolean(_mem.int_scren) en_scrambler_setting = RadioSetting("int_scren", "Scrambler enabled (ScraEn)", val) # ----------------- Driver Info firmware = self.metadata.get('uvk5_firmware', 'UNKNOWN') append_label(roinfo, "Firmware Version", firmware) # ----------------- Calibration val = RadioSettingValueBoolean(False) radio_setting = RadioSetting("upload_calibration", "Upload calibration", val) radio_setting.set_warning( _('This option may break your radio! ' 'Each radio has a unique set of calibration data ' 'and uploading the data from the image will cause ' 'physical harm to the radio if it is from a ' 'different piece of hardware. Do not use this ' 'unless you know what you are doing and accept the ' 'risk of destroying your radio!'), safe_value=False) calibration.append(radio_setting) radio_setting_group = RadioSettingGroup("squelch_calibration", "Squelch") calibration.append(radio_setting_group) bands = {"sqlBand1_3": "Frequency Band 1-3", "sqlBand4_7": "Frequency Band 4-7"} for bnd, bndn in bands.items(): band_group_range = RadioSettingSubGroup(bnd, bndn) radio_setting_group.append(band_group_range) for sql in range(0, 10): band_group = RadioSettingSubGroup( '%s_%i' % (bnd, sql), "Squelch %i" % sql) band_group_range.append(band_group) name = 'cal.%s.openRssiThr[%i]' % (bnd, sql) tempval = min_max_def(_mem.get_path(name), 0, 255, 0) val = RadioSettingValueInteger(0, 255, tempval) radio_setting = RadioSetting(name, "RSSI threshold open", val) band_group.append(radio_setting) name = 'cal.%s.closeRssiThr[%i]' % (bnd, sql) tempval = min_max_def(_mem.get_path(name), 0, 255, 0) val = RadioSettingValueInteger(0, 255, tempval) radio_setting = RadioSetting(name, "RSSI threshold close", val) band_group.append(radio_setting) name = "cal.%s.openNoiseThr[%i]" % (bnd, sql) tempval = min_max_def(_mem.get_path(name), 0, 127, 0) val = RadioSettingValueInteger(0, 127, tempval) radio_setting = RadioSetting(name, "Noise threshold open", val) band_group.append(radio_setting) name = "cal.%s.closeNoiseThr[%i]" % (bnd, sql) tempval = min_max_def(_mem.get_path(name), 0, 127, 0) val = RadioSettingValueInteger(0, 127, tempval) radio_setting = RadioSetting(name, "Noise threshold close", val) band_group.append(radio_setting) name = "cal.%s.openGlitchThr[%i]" % (bnd, sql) tempval = min_max_def(_mem.get_path(name), 0, 255, 0) val = RadioSettingValueInteger(0, 255, tempval) radio_setting = RadioSetting(name, "Glitch threshold open", val) band_group.append(radio_setting) name = "cal.%s.closeGlitchThr[%i]" % (bnd, sql) tempval = min_max_def(_mem.get_path(name), 0, 255, 0) val = RadioSettingValueInteger(0, 255, tempval) radio_setting = RadioSetting(name, "Glitch threshold close", val) band_group.append(radio_setting) # radio_setting_group = RadioSettingGroup("rssi_level_calibration", "RSSI levels") calibration.append(radio_setting_group) bands = {"rssiLevelsBands1_2": "1-2 ", "rssiLevelsBands3_7": "3-7 "} for bnd, bndn in bands.items(): band_group = RadioSettingSubGroup(bnd, 'Frequency Band %s' % bndn) radio_setting_group.append(band_group) for lvl in [1, 2, 4, 6]: name = "cal.%s.level%i" % (bnd, lvl) value = int(_mem.get_path(name)) tempval = min_max_def(value, 0, 65535, 0) val = RadioSettingValueInteger(0, 65535, tempval) radio_setting = RadioSetting(name, "Level %i" % lvl, val) band_group.append(radio_setting) # radio_setting_group = RadioSettingGroup("tx_power_calibration", "TX power") calibration.append(radio_setting_group) for bnd in range(0, 7): band_group = RadioSettingSubGroup('txpower_band_%i' % bnd, 'Band %i' % (bnd + 1)) powers = {"low": "Low", "mid": "Medium", "hi": "High"} radio_setting_group.append(band_group) for pwr, pwrn in powers.items(): bounds = ["lower", "center", "upper"] subgroup = RadioSettingSubGroup('txpower_band_%i_%s' % ( bnd, pwr), pwrn) band_group.append(subgroup) for bound in bounds: name = f"cal.txp[{bnd}].{pwr}.{bound}" tempval = min_max_def(_mem.get_path(name), 0, 255, 0) val = RadioSettingValueInteger(0, 255, tempval) radio_setting = RadioSetting(name, bound.capitalize(), val) subgroup.append(radio_setting) # radio_setting_group = RadioSettingGroup("battery_calibration", "Battery") calibration.append(radio_setting_group) for lvl in range(0, 6): name = "cal.batLvl[%i]" % lvl temp_val = min_max_def(_mem.get_path(name), 0, 4999, 4999) val = RadioSettingValueInteger(0, 4999, temp_val) label = 'Level %i%s' % ( lvl, " (voltage calibration)" if lvl == 3 else "") radio_setting = RadioSetting(name, label, val) radio_setting_group.append(radio_setting) radio_setting_group = RadioSettingGroup("vox_calibration", "VOX") calibration.append(radio_setting_group) for lvl in range(0, 10): name = "cal.vox1Thr[%s]" % lvl val = RadioSettingValueInteger(0, 65535, _mem.get_path(name)) radio_setting = RadioSetting(name, "Level %i On" % (lvl + 1), val) radio_setting_group.append(radio_setting) name = "cal.vox0Thr[%s]" % lvl val = RadioSettingValueInteger(0, 65535, _mem.get_path(name)) radio_setting = RadioSetting(name, "Level %i Off" % (lvl + 1), val) radio_setting_group.append(radio_setting) radio_setting_group = RadioSettingGroup("mic_calibration", "Microphone sensitivity") calibration.append(radio_setting_group) for lvl in range(0, 5): name = "cal.micLevel[%s]" % lvl tempval = min_max_def(_mem.get_path(name), 0, 31, 31) val = RadioSettingValueInteger(0, 31, tempval) radio_setting = RadioSetting(name, "Level %i" % lvl, val) radio_setting_group.append(radio_setting) radio_setting_group = RadioSettingGroup("other_calibration", "Other") calibration.append(radio_setting_group) name = "cal.xtalFreqLow" temp_val = min_max_def(_mem.get_path(name), -1000, 1000, 0) val = RadioSettingValueInteger(-1000, 1000, temp_val) radio_setting = RadioSetting(name, "Xtal frequency low", val) radio_setting_group.append(radio_setting) name = "cal.volumeGain" temp_val = min_max_def(_mem.get_path(name), 0, 63, 58) val = RadioSettingValueInteger(0, 63, temp_val) radio_setting = RadioSetting(name, "Volume gain", val) radio_setting_group.append(radio_setting) name = "cal.dacGain" temp_val = min_max_def(_mem.get_path(name), 0, 15, 8) val = RadioSettingValueInteger(0, 15, temp_val) radio_setting = RadioSetting(name, "DAC gain", val) radio_setting_group.append(radio_setting) # -------- LAYOUT basic.append(squelch_setting) basic.append(rx_mode_setting) basic.append(call_channel_setting) basic.append(auto_keypad_lock_setting) basic.append(tx_t_out_setting) basic.append(bat_save_setting) basic.append(scn_rev_setting) if _mem.BUILD_OPTIONS.ENABLE_NOAA: basic.append(noaa_auto_scan_setting) if _mem.BUILD_OPTIONS.ENABLE_AM_FIX: basic.append(am_fix_setting) dispSubGrp = RadioSettingSubGroup("dispSubGrp", "Display settings") basic.append(dispSubGrp) dispSubGrp.append(bat_txt_setting) dispSubGrp.append(mic_bar_setting) dispSubGrp.append(ch_disp_setting) dispSubGrp.append(p_on_msg_setting) dispSubGrp.append(logo1_setting) dispSubGrp.append(logo2_setting) bcklSubGrp = RadioSettingSubGroup("bcklSubGrp", "Backlight settings") basic.append(bcklSubGrp) bcklSubGrp.append(back_lt_setting) bcklSubGrp.append(bl_min_setting) bcklSubGrp.append(bl_max_setting) bcklSubGrp.append(blt_trx_setting) audioSubGrp = RadioSettingSubGroup("audioSubGrp", "Audio related settings") basic.append(audioSubGrp) if _mem.BUILD_OPTIONS.ENABLE_VOX: audioSubGrp.append(vox_setting) audioSubGrp.append(mic_gain_setting) audioSubGrp.append(beep_setting) audioSubGrp.append(roger_setting) audioSubGrp.append(ste_setting) audioSubGrp.append(rp_ste_setting) if _mem.BUILD_OPTIONS.ENABLE_VOICE: audioSubGrp.append(voice_setting) if _mem.BUILD_OPTIONS.ENABLE_ALARM: audioSubGrp.append(alarm_setting) stateSubGrp = RadioSettingSubGroup("stateSubGrp", "Radio state") basic.append(stateSubGrp) stateSubGrp.append(freq0_setting) stateSubGrp.append(freq1_setting) stateSubGrp.append(tx_vfo_setting) stateSubGrp.append(keypad_cock_setting) advanced.append(freq_mode_allowed_setting) advanced.append(bat_type_setting) advanced.append(s0_level_setting) advanced.append(s9_level_setting) if _mem.BUILD_OPTIONS.ENABLE_PWRON_PASSWORD: advanced.append(pswd_setting) if _mem.BUILD_OPTIONS.ENABLE_DTMF_CALLING: dtmf.append(sep_code_setting) dtmf.append(group_code_setting) dtmf.append(first_code_per_setting) dtmf.append(spec_per_setting) dtmf.append(code_per_setting) dtmf.append(code_int_setting) if _mem.BUILD_OPTIONS.ENABLE_DTMF_CALLING: dtmf.append(ani_id_setting) dtmf.append(up_code_setting) dtmf.append(dw_code_setting) dtmf.append(d_prel_setting) dtmf.append(dtmf_side_tone_setting) if _mem.BUILD_OPTIONS.ENABLE_DTMF_CALLING: dtmf.append(dtmf_resp_setting) dtmf.append(d_hold_setting) dtmf.append(d_live_setting) dtmf.append(perm_kill_setting) dtmf.append(kill_code_setting) dtmf.append(rev_code_setting) dtmf.append(killed_setting) unlock.append(f_lock_setting) unlock.append(tx200_setting) unlock.append(tx350_setting) unlock.append(tx500_setting) unlock.append(en350_setting) unlock.append(en_scrambler_setting) return top chirp-20240224/chirp/drivers/tdh8.py0000644000175000017500000023603114535036544016056 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import time import logging from chirp import chirp_common, errors, util, directory, memmap from chirp import bitwise from chirp.settings import InvalidValueError, RadioSetting, \ RadioSettingGroup, RadioSettingValueFloat, \ RadioSettingValueList, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettings from textwrap import dedent from chirp import bandplan_na LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0008; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unused1; u8 pttid:2, freqhop:1, unused3:1, unused4:1, bcl:1, unused5:1, unused2:1; u8 unused6:1, unused7:1, lowpower:2, wide:1, unused8:1, offset:2; u8 unused10; } memory[200]; #seekto 0x0D38; struct { char name[8]; u8 unknown2[8]; } names[200]; #seekto 0x0CA8; struct { u8 txled:1, rxled:1, unused11:1, ham:1, gmrs:1, unused14:1, unused15:1, pritx:1; u8 scanmode:2, unused16:1, keyautolock:1, unused17:1, btnvoice:1, unknown18:1, voiceprompt:1; u8 fmworkmode:1, sync:1, tonevoice:2, fmrec:1, mdfa:1, aworkmode:2; u8 ponmsg:2, unused19:1, mdfb:1, unused20:1, dbrx:1, bworkmode:2; u8 ablock; u8 bblock; u8 fmroad; u8 unused21:1, tailclean:1, rogerprompt:1, unused23:1, unused24:1, voxgain:3; u8 astep:4, bstep:4; u8 squelch; u8 tot; u8 lang; u8 save; u8 ligcon; u8 voxdelay; u8 onlychmode:1, unused:6, alarm:1; } settings; #seekto 0x0CB8; struct { u8 ofseta[4]; u8 ununsed26[12]; } aoffset; #seekto 0x0CBC; struct { u8 ofsetb[4]; u8 ununsed27[12]; } boffset; #seekto 0x0CD8; struct{ u8 fmblock[4]; }fmmode[25]; #seekto 0x1A08; struct{ u8 block8:1, block7:1, block6:1, block5:1, block4:1, block3:1, block2:1, block1:1; } usedflags[25]; #seekto 0x1a28; struct{ u8 scan8:1, scan7:1, scan6:1, scan5:1, scan4:1, scan3:1, scan2:1, scan1:1; } scanadd[25]; #seekto 0x1B38; struct{ u8 vfo[4]; }fmvfo; #seekto 0x1B58; struct { lbcd rxfreqa[4]; lbcd txfreq[4]; u8 rxtone[2]; u8 txtone[2]; u8 unused1; u8 pttid:2, specialqta:1, unused3:1, unused4:1, bcl:1, unused5:1, unused2:1; u8 unused6:1, unused7:1, lowpower:2, wide:1, unused8:1, offset:2; u8 unused10; } vfoa; #seekto 0x1B68; struct { lbcd rxfreqb[4]; lbcd txfreq[4]; u8 rxtoneb[2]; u8 txtone[2]; u8 unused1; u8 pttid:2, specialqtb:1, unused3:1, unused4:1, bclb:1, unused5:1, unused2:1; u8 unused6:1, unused7:1, lowpowerb:2, wideb:1, unused8:1, offsetb:2; u8 unused10; } vfob; #seekto 0x1B78; struct{ u8 block8:1, block7:1, block6:1, block5:1, block4:1, block3:1, block2:1, block1:1; } fmusedflags[4]; #seekto 0x1c08; struct { char msg1[16]; char msg2[16]; char msg3[16]; } poweron_msg; #seekto 0x1CC8; struct{ u8 stopkey1; u8 ssidekey1; u8 ssidekey2; u8 ltopkey2; u8 lsidekey3; u8 lsidekey4; u8 unused25[10]; } press; #seekto 0x1E28; struct{ u8 idcode[3]; }icode; #seekto 0x1E31; struct{ u8 gcode; }groupcode; #seekto 0x1E38; struct{ u8 group1[7]; }group1; #seekto 0x1E48; struct{ u8 group2[7]; }group2; #seekto 0x1E58; struct{ u8 group3[7]; }group3; #seekto 0x1E68; struct{ u8 group4[7]; }group4; #seekto 0x1E78; struct{ u8 group5[7]; }group5; #seekto 0x1E88; struct{ u8 group6[7]; }group6; #seekto 0x1E98; struct{ u8 group7[7]; }group7; #seekto 0x1EA8; struct{ u8 group8[7]; }group8; #seekto 0x1EC8; struct{ u8 scode[7]; }startcode; #seekto 0x1ED8; struct{ u8 ecode[7]; }endcode; """ MEM_FORMAT_H3 = """ #seekto 0x0008; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unused1; u8 pttid:2, freqhop:1, unused3:1, unused4:1, bcl:1, unused5:1, unused2:1; u8 unused6:1, scramble:1, lowpower:2, wide:1, unused8:1, offset:2; u8 unused10; } memory[200]; #seekto 0x0C98; struct{ u8 stopkey1; u8 ssidekey1; u8 ssidekey2; u8 ltopkey2; u8 lsidekey3; u8 lsidekey4; } press; #seekto 0x0CA8; struct { u8 txled:1, rxled:1, unused11:1, ham:1, gmrs:1, unused14:1, unused15:1, pritx:1; u8 scanmode:2, unused16:1, keyautolock:1, unused17:1, btnvoice:1, unknown18:1, voiceprompt:1; u8 fmworkmode:1, sync:1, tonevoice:2, fmrec:1, mdfa:1, aworkmode:2; u8 ponmsg:2, unused19:1, mdfb:1, unused20:1, dbrx:1, bworkmode:2; u8 ablock; u8 bblock; u8 fmroad; u8 unused21:1, tailclean:1, rogerprompt_:1, kill:1, stun:1, voxgain:3; u8 astep:4, bstep:4; u8 squelch; u8 tot; u8 rogerprompt:2, unused11_4:4, lang:1, unused11_1:1; u8 save; u8 ligcon; u8 voxdelay; u8 onlychmode:1, breathled:3, unused:3, alarm:1; } settings; #seekto 0x0CB8; struct { u8 ofseta[4]; u8 ununsed26[12]; } aoffset; #seekto 0x0CBC; struct { u8 ofsetb[4]; u8 ununsed27[12]; } boffset; #seekto 0x0CD8; struct{ u8 fmblock[4]; }fmmode[25]; #seekto 0x0D48; struct { char name[8]; } names[200]; #seekto 0x1808; struct{ u8 stuncode[16]; u8 killcode[16]; }skcode; #seekto 0x1828; struct{ u8 idcode[3]; }icode; #seekto 0x1837; struct{ u8 gcode; }groupcode; #seekto 0x1838; struct{ u8 group1[7]; }group1; #seekto 0x1848; struct{ u8 group2[7]; }group2; #seekto 0x1858; struct{ u8 group3[7]; }group3; #seekto 0x1868; struct{ u8 group4[7]; }group4; #seekto 0x1878; struct{ u8 group5[7]; }group5; #seekto 0x1888; struct{ u8 group6[7]; }group6; #seekto 0x1898; struct{ u8 group7[7]; }group7; #seekto 0x18A8; struct{ u8 group8[7]; }group8; #seekto 0x18C8; struct{ u8 scode[7]; }startcode; #seekto 0x18D8; struct{ u8 ecode[7]; }endcode; #seekto 0x1908; struct{ u8 block8:1, block7:1, block6:1, block5:1, block4:1, block3:1, block2:1, block1:1; } usedflags[25]; #seekto 0x1928; struct{ u8 scan8:1, scan7:1, scan6:1, scan5:1, scan4:1, scan3:1, scan2:1, scan1:1; } scanadd[25]; #seekto 0x1948; struct{ u8 block8:1, block7:1, block6:1, block5:1, block4:1, block3:1, block2:1, block1:1; } fmusedflags[4]; #seekto 0x1958; struct { lbcd rxfreqa[4]; lbcd txfreq[4]; u8 rxtone[2]; u8 txtone[2]; u8 unused1; u8 pttid:2, specialqta:1, unused3:1, unused4:1, bcl:1, unused5:1, unused2:1; u8 unused6:1, unused7:1, lowpower:2, wide:1, unused8:1, offset:2; u8 unused10; } vfoa; #seekto 0x1968; struct { lbcd rxfreqb[4]; lbcd txfreq[4]; u8 rxtoneb[2]; u8 txtone[2]; u8 unused1; u8 pttid:2, specialqtb:1, unused3:1, unused4:1, bclb:1, unused5:1, unused2:1; u8 unused6:1, unused7:1, lowpowerb:2, wideb:1, unused8:1, offsetb:2; u8 unused10; } vfob; #seekto 0x1978; struct{ u8 vfo[4]; }fmvfo; #seekto 0x1c08; struct { char msg1[16]; char msg2[16]; char msg3[16]; } poweron_msg; #seekto 0x1f28; struct{ u8 micgain; } mic; """ # basic settings SQUELCH = ['%s' % x for x in range(0, 10)] LIGHT_LIST = ["CONT", "5s", "10s", "15s", "30s"] VOICE_PRMPT_LIST = ["OFF", "ON"] AUTOLOCK_LIST = ["OFF", "ON"] TIME_OUT_LIST = ["OFF", "60s", "120s", "180s"] MDFA_LIST = ["Frequency", "Name"] MDFB_LIST = ["Frequency", "Name"] SYNC_LIST = ["ON", "OFF"] LANG_LIST = ["Chinese", "English"] BTV_SAVER_LIST = ["OFF", "1:1", "1:2", "1:3", "1:4"] DBRX_LIST = ["OFF", "ON"] ASTEP_LIST = ["2.50K", "5.00K", "6.25K", "10.00K", "12.00K", "25.00K", "50.00K"] BSTEP_LIST = ["2.50K", "5.00K", "6.25K", "10.00K", "12.00K", "25.00K", "50.00K"] SCAN_MODE_LIST = ["TO", "CO", "SE"] PRIO_LIST = ["Edit", "Busy"] SHORT_KEY_LIST = ["None", "FM Radio", "Lamp", "Monitor", "TONE", "Alarm", "Weather"] LONG_KEY_LIST = ["None", "FM Radio", "Lamp", "Monitor", "TONE", "Alarm", "Weather"] BUSYLOCK_LIST = ["Off", "On"] PRESS_NAME = ["stopkey1", "ssidekey1", "ssidekey2", "ltopkey2", "lsidekey3", "lsidekey4"] VFOA_NAME = ["rxfreqa", "txfreq", "rxtone", "txtone", "pttid", "specialqta", "bcl", "lowpower", "wide", "offset"] VFOB_NAME = ["rxfreqb", "txfreq", "rxtoneb", "txtone", "pttid", "specialqtb", "bclb", "lowpowerb", "wideb", "offsetb"] # KEY VOX_GAIN = ["OFF", "1", "2", "3", "4", "5"] VOX_DELAY = ["1.05s", "2.0s", "3.0s"] PTTID_VALUES = ["Off", "BOT", "EOT", "BOTH"] BCLOCK_VALUES = ["Off", "On"] FREQHOP_VALUES = ["Off", "On"] SCAN_VALUES = ["Del", "Add"] # AB CHANNEL A_OFFSET = ["Off", "-", "+"] A_TX_POWER = ["Low", "Mid", "High"] A_BAND = ["Wide", "Narrow"] A_BUSYLOCK = ["Off", "On"] A_SPEC_QTDQT = ["Off", "On"] A_WORKMODE = ["VFO", "VFO+CH", "CH Mode"] B_OFFSET = ["Off", "-", "+"] B_TX_POWER = ["Low", "Mid", "High"] B_BAND = ["Wide", "Narrow"] B_BUSYLOCK = ["Off", "On"] B_SPEC_QTDQT = ["Off", "On"] B_WORKMODE = ["VFO", "VFO+CH", "CH Mode"] # FM FM_WORKMODE = ["CH", "VFO"] FM_CHANNEL = ['%s' % x for x in range(0, 26)] # DTMF GROUPCODE = ["", "Off", "*", "#", "A", "B", "C", "D"] AB_LIST = ["A", "B"] ALMOD_LIST = ["Site", "Tone", "Code"] BANDWIDTH_LIST = ["Wide", "Narrow"] COLOR_LIST = ["Off", "Blue", "Orange", "Purple"] DTMFSPEED_LIST = ["%s ms" % x for x in range(50, 2010, 10)] DTMFST_LIST = ["OFF", "DT-ST", "ANI-ST", "DT+ANI"] MODE_LIST = ["Channel", "Name", "Frequency"] PONMSG_LIST = ["Full", "Message", "Icon"] PTTID_LIST = ["Off", "BOT", "EOT", "Both"] PTTIDCODE_LIST = ["%s" % x for x in range(1, 16)] RTONE_LIST = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] RESUME_LIST = ["TO", "CO", "SE"] ROGERRX_LIST = ["Off"] + AB_LIST RPSTE_LIST = ["OFF"] + ["%s" % x for x in range(1, 11)] SAVE_LIST = ["Off", "1:1", "1:2", "1:3", "1:4"] SCODE_LIST = ["%s" % x for x in range(1, 16)] SHIFTD_LIST = ["Off", "+", "-"] STEDELAY_LIST = ["OFF"] + ["%s ms" % x for x in range(100, 1100, 100)] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0] STEP_LIST = [str(x) for x in STEPS] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] STEP291_LIST = [str(x) for x in STEPS] TDRAB_LIST = ["Off"] + AB_LIST TDRCH_LIST = ["CH%s" % x for x in range(1, 129)] TIMEOUT_LIST = ["%s sec" % x for x in range(15, 615, 15)] + \ ["Off (if supported by radio)"] TXPOWER_LIST = ["High", "Low"] TXPOWER3_LIST = ["High", "Mid", "Low"] VOICE_LIST = ["Off", "English", "Chinese"] VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 11)] WORKMODE_LIST = ["Frequency", "Channel"] # mic MIC_GAIN_LIST = ['%s' % x for x in range(0, 10)] MIC_GAIN_LIST_H8 = ['%s' % x for x in range(0, 33)] H8_LIST = ["TD-H8", "TD-H8-HAM", "TD-H8-GMRS"] GMRS_FREQS = bandplan_na.GMRS_HIRPT NOAA_FREQS = [162550000, 162400000, 162475000, 162425000, 162450000, 162500000, 162525000, 161650000, 161775000, 161750000, 162000000] HAM_GMRS_NAME = ["NOAA 1", "NOAA 2", "NOAA 3", "NOAA 4", "NOAA 5", "NOAA 6", "NOAA 7", "NOAA 8", "NOAA 9", "NOAA 10", "NOAA 11"] ALL_MODEL = ["TD-H8", "TD-H8-HAM", "TD-H8-GMRS", "TD-H3", "TD-H3-HAM", "TD-H3-GMRS"] TD_H8 = b"\x50\x56\x4F\x4A\x48\x1C\x14" TD_H3 = b"\x50\x56\x4F\x4A\x48\x5C\x14" def _do_status(radio, block): status = chirp_common.Status() status.msg = "Cloning" status.cur = block status.max = radio._memsize radio.status_fn(status) def _upper_band_from_data(data): return data[0x03:0x04] def _upper_band_from_image(radio): return _upper_band_from_data(radio.get_mmap()) def _firmware_version_from_data(data, version_start, version_stop): version_tag = data[version_start:version_stop] return version_tag def _firmware_version_from_image(radio): version = _firmware_version_from_data(radio.get_mmap(), radio._fw_ver_file_start, radio._fw_ver_file_stop) # LOG.debug("_firmware_version_from_image: " + util.hexprint(version)) return version def _do_ident(radio, magic, secondack=True): serial = radio.pipe serial.timeout = 1 LOG.info("Sending Magic: %s" % util.hexprint(magic)) serial.write(magic) ack = serial.read(1) if ack != b"\x06": if ack: # LOG.debug(repr(ack)) pass raise errors.RadioError("Radio did not respond") serial.write(b"\x02") response = b"" for i in range(1, 9): byte = serial.read(1) response += byte if byte == b"\xDD": break if len(response) in [8, 12]: # DEBUG LOG.info("Valid response, got this:") LOG.info(util.hexprint(response)) if len(response) == 12: ident = response[0] + response[3] + response[5] + response[7:] else: ident = response else: # bad response msg = "Unexpected response, got this:" msg += util.hexprint(response) LOG.debug(msg) raise errors.RadioError("Unexpected response from radio.") if secondack: serial.write(b"\x06") ack = serial.read(1) if ack != b"\x06": raise errors.RadioError("Radio refused clone") return ident def response_mode(mode): data = mode return data def _read_block(radio, start, size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', start, size) expectedresponse = b"W" + cmd[1:] try: serial.write(cmd) response = serial.read(5 + size) if response[:4] != expectedresponse: raise errors.RadioError("Error reading block %04x." % (start)) block_data = response[4:-1] except Exception: raise errors.RadioError("Failed to read block at %04x" % start) return block_data def _get_radio_firmware_version(radio): if radio.MODEL in ALL_MODEL: block = _read_block(radio, 0x1B40, 0x20) version = block[0:6] return version IDENT_BLACKLIST = { b"\x50\x56\x4F\x4A\x48\x1C\x14": "Radio identifies as TIDRADIO TD-H8", } def _ident_radio(radio): for magic in radio._idents: error = None try: data = _do_ident(radio, magic) return data except errors.RadioError as e: error = e time.sleep(2) if error: raise error raise errors.RadioError("Radio did not respond") def _do_download(radio): data = _ident_radio(radio) append_model = False # HAM OR GMRS # Determine the walkie-talkie mode # TDH8 have three mode:ham, gmrs and normal LOG.info("Radio mode is " + str(data)[2:8]) LOG.info("Chirp choose mode is " + str(data)[2:8]) # The Ham and GMRS modes are subclasses of this model TDH8. # We compare the radio identification to the value of that class to # make sure the user chose the model that matches # the radio we're talking to right now. If they do not match, # we refuse to talk to the radio until the user selects the correct model. if radio.ident_mode == data: LOG.info("Successful match.") else: msg = ("Model mismatch!") raise errors.RadioError(msg) # Main block LOG.info("Downloading...") for i in range(0, radio._memsize, 0x20): block = _read_block(radio, i, 0x20) data += block _do_status(radio, i) _do_status(radio, radio._memsize) LOG.info("done.") if append_model: data += radio.MODEL.ljust(8) return memmap.MemoryMapBytes(data) def _exit_write_block(radio): serial = radio.pipe try: serial.write(b"E") except Exception: raise errors.RadioError("Radio refused to exit programming mode") def _write_block(radio, addr, data): serial = radio.pipe cmd = struct.pack(">cHb", b'W', addr, 0x20) data = radio.get_mmap()[addr + 8: addr + 40] # The checksum needs to be in the last check_sum = bytes([sum(data) & 0xFF]) data += check_sum used_data = cmd + data serial.write(used_data) ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio refused to accept block 0x%04x" % addr) def _do_upload(radio): data = _ident_radio(radio) radio_version = _get_radio_firmware_version(radio) LOG.info("Radio Version is %s" % repr(radio_version)) if radio.ident_mode == data: LOG.info("Successful match.") else: msg = ("Model mismatch!") raise errors.RadioError(msg) # Main block LOG.debug("Uploading...") for start_addr, end_addr in radio._ranges_main: for addr in range(start_addr, end_addr, 0x20): _write_block(radio, addr, 0x20) _do_status(radio, addr) _exit_write_block(radio) LOG.debug("Upload all done.") TX_POWER = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("Mid", watts=4.00), chirp_common.PowerLevel("High", watts=8.00)] TDH8_CHARSET = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" @directory.register class TDH8(chirp_common.CloneModeRadio): """TIDRADIO TD-H8""" VENDOR = "TIDRADIO" MODEL = "TD-H8" ident_mode = b'P31183\xff\xff' BAUD_RATE = 38400 NEEDS_COMPAT_SERIAL = False _memsize = 0x1eef _ranges_main = [(0x0000, 0x1eef)] _idents = [TD_H8] _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 521000000) _aux_block = True _tri_power = True _gmrs = False _ham = False _mem_params = (0x1F2F) # offset of fw version in image file _fw_ver_file_start = 0x1838 _fw_ver_file_stop = 0x1846 _valid_chars = TDH8_CHARSET @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = (dedent("""\ 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to download image from device.""")) rp.pre_upload = (dedent("""\ 1. Turn radio off. 2. Connect cable to mic/spkr connector. 3. Make sure connector is firmly connected. 4. Turn radio on (volume may need to be set at 100%). 5. Ensure that the radio is tuned to channel with no activity. 6. Click OK to upload image to device.""")) return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_cross = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.has_ctone = True rf.can_odd_split = True rf.valid_name_length = 8 rf.valid_characters = self._valid_chars rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = TX_POWER rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["FM", "NFM"] rf.valid_tuning_steps = STEPS normal_bands = [self._vhf_range, self._uhf_range] if self._mmap is None: rf.valid_bands = [normal_bands[0], normal_bands[1]] else: rf.valid_bands = normal_bands rf.memory_bounds = (1, 199) return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = _do_download(self) self.process_mmap() except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def sync_out(self): try: _do_upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) # Encoding processing def _decode_tone(self, val): if val == 16665 or val == 0: return '', None, None elif val >= 12000: return 'DTCS', val - 12000, 'R' elif val >= 8000: return 'DTCS', val - 8000, 'N' else: return 'Tone', val / 10.0, None # Decoding processing def _encode_tone(self, memval, mode, value, pol): if mode == "": memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def _get_mem(self, number): return self._memobj.memory[number] def _get_nam(self, number): if self.MODEL in H8_LIST: return self._memobj.names[number] else: return self._memobj.names[number - 1] def _get_fm(self, number): return self._memobj.fmmode[number] def _get_get_scanvfo(self, number): return self._memobj.fmvfo[number] def _get_scan(self, number): return self._memobj.scanadd[number] def _get_block_data(self, number): return self._memobj.usedflags[number] def _get_fmblock_data(self, number): return self._memobj.fmusedflags[number] def get_memory(self, number): _mem = self._get_mem(number) _nam = self._get_nam(number) mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xff": mem.empty = True return mem # receiving frequency mem.freq = int(_mem.rxfreq) * 10 # narrow and wide mem.mode = _mem.wide and "NFM" or "FM" # power try: mem.power = TX_POWER[_mem.lowpower] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.lowpower, TX_POWER)) mem.power = TX_POWER[0] # Channel name for char in _nam.name: if "\x00" in str(char) or "\xFF" in str(char): char = "" mem.name += str(char) mem.name = mem.name.rstrip() if self.ident_mode != b'P31183\xff\xff' and \ (mem.number >= 189 and mem.number <= 199): mem.name = HAM_GMRS_NAME[mem.number - 200] # tmode lin2 = int(_mem.rxtone) rxtone = self._decode_tone(lin2) lin = int(_mem.txtone) txtone = self._decode_tone(lin) if txtone[0] == "Tone" and not rxtone[0]: mem.tmode = "Tone" elif txtone[0] == rxtone[0] and txtone[0] == "Tone" \ and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txtone[0] == rxtone[0] and txtone[0] == "DTCS" \ and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxtone[0] or txtone[0]: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txtone[0], rxtone[0]) chirp_common.split_tone_decode(mem, txtone, rxtone) # skip/scanadd scan_val_list = [] for x in range(25): a = self._get_scan(x) for i in range(0, 8): scan_val = (getattr(a, 'scan%i' % (i+1))) # print(str(scan_val)[3]) used_scan_val = str(scan_val)[3] scan_val_list.append(used_scan_val) if int(scan_val_list[number - 1]) == 0: mem.skip = 'S' elif int(scan_val_list[number - 1]) == 1: mem.skip = '' if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif int(_mem.txfreq) == 66666665 and int(_mem.rxfreq) != 66666665: mem.offset = 0 mem.duplex = 'off' else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 if self._gmrs: # mem.duplex = "" # mem.offset = 0 if mem.number >= 1 and mem.number <= 30: mem.immutable.append('freq') if mem.number >= 8 and mem.number <= 14: mem.mode = 'NFM' mem.power = TX_POWER[0] mem.immutable = ['freq', 'mode', 'power', 'duplex', 'offset'] elif mem.number >= 31 and mem.number <= 54: # mem.immutable = ['duplex', 'offset'] mem.duplex = '+' mem.offset = 5000000 elif mem.number >= 189 and mem.number <= 199: ham_freqs = NOAA_FREQS[mem.number - 189] mem.freq = ham_freqs mem.immutable = ['name', 'power', 'duplex', 'freq', 'rx_dtcs', 'vfo', 'tmode', 'empty', 'offset', 'rtone', 'ctone', 'dtcs', 'dtcs_polarity', 'cross_mode'] elif self._ham: if mem.number >= 189 and mem.number <= 199: ham_freqs = NOAA_FREQS[mem.number - 189] mem.freq = ham_freqs mem.immutable = ['name', 'power', 'freq', 'rx_dtcs', 'vfo', 'tmode', 'empty', 'offset', 'rtone', 'ctone', 'dtcs', 'dtcs_polarity', 'cross_mode'] # other function # pttid mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTTID_VALUES, PTTID_VALUES[_mem.pttid])) mem.extra.append(rs) # Busylock rs = RadioSetting("bcl", "Busy Lock", RadioSettingValueList(BCLOCK_VALUES, BCLOCK_VALUES[_mem.bcl])) mem.extra.append(rs) rs = RadioSetting( "freqhop", "Frequency Hop", RadioSettingValueList( FREQHOP_VALUES, FREQHOP_VALUES[_mem.freqhop])) mem.extra.append(rs) return mem def _set_mem(self, number): return self._memobj.memory[number] def _set_nam(self, number): if self.MODEL in H8_LIST: return self._memobj.names[number] else: return self._memobj.names[number - 1] def _get_scan_list(self, scan_data): # scan_val_list - Get all scans Add data 1-200 digits scan_val_list = [] for x in range(25): a = self._get_scan(x) for i in range(0, 8): scan_val = (getattr(a, 'scan%i' % (i+1))) used_scan_val = str(scan_val)[3] scan_val_list.append(used_scan_val) # used_scan_list - 25 structures, split the scan added # data into 25 groups of 8 bits each used_scan_list = [] count_num = 1 for i in range(0, len(scan_val_list), 8): used_scan_list.append(scan_val_list[i:i + 8]) count_num += 1 # Determine whether it is a standard number that can be divisible # Which group is the scan addition located in the modified channel if scan_data % 8 != 0: x_list = scan_data / 8 y_list = scan_data % 8 else: x_list = (scan_data / 8) - 1 y_list = 8 return ([x_list, y_list]) def get_block_xy(self, number): if number % 8 != 0: x_list = number / 8 y_list = number % 8 else: x_list = (number / 8) - 1 y_list = 8 return ([x_list, y_list]) def set_memory(self, mem): _mem = self._get_mem(mem.number) _nam = self._get_nam(mem.number) if mem.empty: _mem.set_raw("\xff" * 16) if self.MODEL in H8_LIST: _nam.set_raw("\xff" * 16) else: _nam.set_raw("\xff" * 8) return _mem.set_raw("\x00" * 16) # When the channel is empty, you need to set "usedflags" to 0, # which means it is empty.When the channel has a value, # you need to set "usedflags" to 0, # indicating that it contains a value. # The method "get_block_xy" is due to # the particularity of the structure, # x represents a certain structure group, # and y represents a certain byte of the structure group. if not mem.empty: block_xy = self.get_block_xy(mem.number) _usedflags = self._get_block_data(block_xy[0]) if block_xy[1] == 1: _usedflags.block1 = 1 elif block_xy[1] == 2: _usedflags.block2 = 1 elif block_xy[1] == 3: _usedflags.block3 = 1 elif block_xy[1] == 4: _usedflags.block4 = 1 elif block_xy[1] == 5: _usedflags.block5 = 1 elif block_xy[1] == 6: _usedflags.block6 = 1 elif block_xy[1] == 7: _usedflags.block7 = 1 elif block_xy[1] == 8: _usedflags.block8 = 1 else: block_xy = self.get_block_xy(mem.number) _usedflags = self._get_block_data(block_xy[0]) if block_xy[1] == 1: _usedflags.block1 = 0 elif block_xy[1] == 2: _usedflags.block2 = 0 elif block_xy[1] == 3: _usedflags.block3 = 0 elif block_xy[1] == 4: _usedflags.block4 = 0 elif block_xy[1] == 5: _usedflags.block5 = 0 elif block_xy[1] == 6: _usedflags.block6 = 0 elif block_xy[1] == 7: _usedflags.block7 = 0 elif block_xy[1] == 8: _usedflags.block8 = 0 if mem.duplex == "": _mem.rxfreq = _mem.txfreq = mem.freq / 10 elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 elif mem.duplex == 'off': _mem.txfreq = 166666665 else: _mem.txfreq = mem.freq / 10 _mem.rxfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" txtone, rxtone = chirp_common.split_tone_encode(mem) self._encode_tone(_mem.txtone, *txtone) self._encode_tone(_mem.rxtone, *rxtone) if mem.mode == "FM": _mem.wide = 0 else: _mem.wide = 1 if str(mem.power) == "Low": _mem.lowpower = 0 elif str(mem.power) == "Mid": _mem.lowpower = 1 elif str(mem.power) == "High": _mem.lowpower = 10 else: _mem.lowpower = 0 # Skip/Scanadd Setting scanlist = self._get_scan_list(mem.number) _scan = self._get_scan(scanlist[0]) if scanlist[1] == 1: _scan.scan1 = mem.skip != "S" elif scanlist[1] == 2: _scan.scan2 = mem.skip != "S" elif scanlist[1] == 3: _scan.scan3 = mem.skip != "S" elif scanlist[1] == 4: _scan.scan4 = mem.skip != "S" elif scanlist[1] == 5: _scan.scan5 = mem.skip != "S" elif scanlist[1] == 6: _scan.scan6 = mem.skip != "S" elif scanlist[1] == 7: _scan.scan7 = mem.skip != "S" elif scanlist[1] == 8: _scan.scan8 = mem.skip != "S" for setting in mem.extra: if (self.ident_mode == b'P31185\xff\xff' or self.ident_mode == b'P31184\xff\xff') and \ mem.number >= 189 and mem.number <= 199: if setting.get_name() == 'pttid': setting.value = 'Off' setattr(_mem, setting.get_name(), setting.value) elif setting.get_name() == 'bcl': setting.value = 'Off' setattr(_mem, setting.get_name(), setting.value) elif setting.get_name() == 'freqhop': setting.value = 'Off' setattr(_mem, setting.get_name(), setting.value) else: setattr(_mem, setting.get_name(), setting.value) def _is_orig(self): version_tag = _firmware_version_from_image(self) try: if b'BFB' in version_tag: idx = version_tag.index(b"BFB") + 3 version = int(version_tag[idx:idx + 3]) return version < 291 return False except Exception: pass raise errors.RadioError("Unable to parse version string %s" % version_tag) def _my_upper_band(self): band_tag = _upper_band_from_image(self) return band_tag def _get_settings(self): _settings = self._memobj.settings _press = self._memobj.press _aoffset = self._memobj.aoffset _boffset = self._memobj.boffset _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob _gcode = self._memobj.groupcode _msg = self._memobj.poweron_msg basic = RadioSettingGroup("basic", "Basic Settings") abblock = RadioSettingGroup("abblock", "A/B Channel") fmmode = RadioSettingGroup("fmmode", "FM") dtmf = RadioSettingGroup("dtmf", "DTMF") # group = RadioSettings(fmmode, dtmf) group = RadioSettings(basic, abblock, fmmode, dtmf) rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueList( SQUELCH, SQUELCH[_settings.squelch])) basic.append(rs) rs = RadioSetting("ligcon", "Light Control", RadioSettingValueList( LIGHT_LIST, LIGHT_LIST[_settings.ligcon])) basic.append(rs) rs = RadioSetting("voiceprompt", "Voice Prompt", RadioSettingValueList( VOICE_PRMPT_LIST, VOICE_PRMPT_LIST[ _settings.voiceprompt])) basic.append(rs) rs = RadioSetting("keyautolock", "Auto Lock", RadioSettingValueList( AUTOLOCK_LIST, AUTOLOCK_LIST[ _settings.keyautolock])) basic.append(rs) rs = RadioSetting("mdfa", "MDF-A", RadioSettingValueList( MDFA_LIST, MDFA_LIST[_settings.mdfa])) basic.append(rs) rs = RadioSetting("mdfb", "MDF-B", RadioSettingValueList( MDFB_LIST, MDFB_LIST[_settings.mdfb])) basic.append(rs) rs = RadioSetting("sync", "SYNC", RadioSettingValueList( SYNC_LIST, SYNC_LIST[_settings.sync])) basic.append(rs) rs = RadioSetting("save", "Battery Save", RadioSettingValueList( BTV_SAVER_LIST, BTV_SAVER_LIST[_settings.save])) basic.append(rs) rs = RadioSetting("dbrx", "Double Rx", RadioSettingValueList( DBRX_LIST, DBRX_LIST[_settings.dbrx])) basic.append(rs) rs = RadioSetting("astep", "A Step", RadioSettingValueList( ASTEP_LIST, ASTEP_LIST[_settings.astep])) basic.append(rs) rs = RadioSetting("bstep", "B Step", RadioSettingValueList( BSTEP_LIST, BSTEP_LIST[_settings.bstep])) basic.append(rs) rs = RadioSetting("scanmode", "Scan Mode", RadioSettingValueList( SCAN_MODE_LIST, SCAN_MODE_LIST[ _settings.scanmode])) basic.append(rs) rs = RadioSetting("pritx", "Priority TX", RadioSettingValueList( PRIO_LIST, PRIO_LIST[_settings.pritx])) basic.append(rs) rs = RadioSetting("btnvoice", "Beep", RadioSettingValueBoolean(_settings.btnvoice)) basic.append(rs) rs = RadioSetting("rogerprompt", "Roger", RadioSettingValueBoolean(_settings.rogerprompt)) basic.append(rs) rs = RadioSetting("txled", "Disp Lcd(TX)", RadioSettingValueBoolean(_settings.txled)) basic.append(rs) rs = RadioSetting("rxled", "Disp Lcd(RX)", RadioSettingValueBoolean(_settings.rxled)) basic.append(rs) rs = RadioSetting("onlychmode", "Only CH Mode", RadioSettingValueBoolean(_settings.onlychmode)) basic.append(rs) rs = RadioSetting("ssidekey1", "SHORT_KEY_PF1", RadioSettingValueList( SHORT_KEY_LIST, SHORT_KEY_LIST[ _press.ssidekey1])) basic.append(rs) rs = RadioSetting("lsidekey3", "LONG_KEY_PF1", RadioSettingValueList( LONG_KEY_LIST, LONG_KEY_LIST[_press.lsidekey3])) basic.append(rs) if self.MODEL in H8_LIST: rs = RadioSetting("stopkey1", "SHORT_KEY_TOP", RadioSettingValueList(SHORT_KEY_LIST, SHORT_KEY_LIST[0])) basic.append(rs) rs = RadioSetting("ltopkey2", "LONG_KEY_TOP", RadioSettingValueList( LONG_KEY_LIST, LONG_KEY_LIST[_press.ltopkey2])) basic.append(rs) rs = RadioSetting("ssidekey2", "SHORT_KEY_PF2", RadioSettingValueList( SHORT_KEY_LIST, SHORT_KEY_LIST[_press.ssidekey2])) basic.append(rs) rs = RadioSetting("lsidekey4", "LONG_KEY_PF2", RadioSettingValueList( LONG_KEY_LIST, LONG_KEY_LIST[_press.lsidekey4])) basic.append(rs) rs = RadioSetting("voxgain", "VOX Gain", RadioSettingValueList( VOX_GAIN, VOX_GAIN[_settings.voxgain])) basic.append(rs) rs = RadioSetting("voxdelay", "VOX Delay", RadioSettingValueList( VOX_DELAY, VOX_DELAY[_settings.voxdelay])) basic.append(rs) rs = RadioSetting("ponmsg", "Power-On Message", RadioSettingValueList( PONMSG_LIST, PONMSG_LIST[_settings.ponmsg])) basic.append(rs) # mic gain if self.MODEL not in H8_LIST: _mic = self._memobj.mic rs = RadioSetting("micgain", "MIC GAIN", RadioSettingValueList( MIC_GAIN_LIST, MIC_GAIN_LIST[_mic.micgain])) basic.append(rs) if self.MODEL not in H8_LIST: rs = RadioSetting("kill", "Kill", RadioSettingValueBoolean(_settings.kill)) basic.append(rs) rs = RadioSetting("stun", "Stun", RadioSettingValueBoolean(_settings.stun)) basic.append(rs) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered rs = RadioSetting("poweron_msg.msg1", "Power-On Message 1", RadioSettingValueString(0, 16, _filter(_msg.msg1))) basic.append(rs) rs = RadioSetting("poweron_msg.msg2", "Power-On Message 2", RadioSettingValueString(0, 16, _filter(_msg.msg2))) basic.append(rs) rs = RadioSetting("poweron_msg.msg3", "Power-On Message 3", RadioSettingValueString(0, 16, _filter(_msg.msg3))) basic.append(rs) # A channel a_freq = int(_vfoa.rxfreqa) freqa = "%i.%05i" % (a_freq / 100000, a_freq % 100000) if freqa == "0.00000": val1a = RadioSettingValueString(0, 7, '0.00000') else: val1a = RadioSettingValueFloat( 136, 520, float(freqa), 0.00001, 5) rs = RadioSetting("rxfreqa", "A Channel - Frequency", val1a) abblock.append(rs) # Offset # If the offset is 12.345 # Then the data obtained is [0x45, 0x23, 0x01, 0x00] a_set_val = _aoffset.ofseta a_set_list = len(_aoffset.ofseta) - 1 real_val = '' for i in range(a_set_list, -1, -1): real_val += str(a_set_val[i])[2:] if real_val == "FFFFFFFF": rs = RadioSetting("ofseta", "A Offset Frequency", RadioSettingValueString(0, 7, "")) else: real_val = int(real_val) real_val = "%i.%05i" % (real_val / 100000, real_val % 100000) rs = RadioSetting("ofseta", "A Offset Frequency", RadioSettingValueFloat( 0.00000, 59.99750, real_val, 0.00001, 5)) abblock.append(rs) rs = RadioSetting("offset", "A Offset", RadioSettingValueList( A_OFFSET, A_OFFSET[_vfoa.offset])) abblock.append(rs) rs = RadioSetting("lowpower", "A TX Power", RadioSettingValueList( A_TX_POWER, A_TX_POWER[_vfoa.lowpower])) abblock.append(rs) rs = RadioSetting("wide", "A Band", RadioSettingValueList( A_BAND, A_BAND[_vfoa.wide])) abblock.append(rs) rs = RadioSetting("bcl", "A Busy Lock", RadioSettingValueList( A_BUSYLOCK, A_BUSYLOCK[_vfoa.bcl])) abblock.append(rs) rs = RadioSetting("specialqta", "A Special QT/DQT", RadioSettingValueList( A_SPEC_QTDQT, A_SPEC_QTDQT[_vfoa.specialqta])) abblock.append(rs) rs = RadioSetting("aworkmode", "A Work Mode", RadioSettingValueList( A_WORKMODE, A_WORKMODE[_settings.aworkmode])) abblock.append(rs) # B channel b_freq = int(str(int(_vfob.rxfreqb)).ljust(8, '0')) freqb = "%i.%05i" % (b_freq / 100000, b_freq % 100000) if freqb == "0.00000": val1a = RadioSettingValueString(0, 7, '0.00000') else: val1a = RadioSettingValueFloat( 136, 520, float(freqb), 0.00001, 5) rs = RadioSetting("rxfreqb", "B Channel - Frequency", val1a) abblock.append(rs) # Offset frequency # If the offset is 12.345 # Then the data obtained is [0x45, 0x23, 0x01, 0x00] # Need to use the following anonymous function to process data b_set_val = _boffset.ofsetb b_set_list = len(_boffset.ofsetb) - 1 real_val = '' for i in range(b_set_list, -1, -1): real_val += str(b_set_val[i])[2:] if real_val == "FFFFFFFF": rs = RadioSetting("ofsetb", "B Offset Frequency", RadioSettingValueString(0, 7, " ")) else: real_val = int(real_val) real_val = "%i.%05i" % (real_val / 100000, real_val % 100000) rs = RadioSetting("ofsetb", "B Offset Frequency", RadioSettingValueFloat( 0.00000, 59.99750, real_val, 0.00001, 5)) abblock.append(rs) rs = RadioSetting("offsetb", "B Offset", RadioSettingValueList( B_OFFSET, B_OFFSET[_vfob.offsetb])) abblock.append(rs) rs = RadioSetting("lowpowerb", "B TX Power", RadioSettingValueList( B_TX_POWER, B_TX_POWER[_vfob.lowpowerb])) abblock.append(rs) rs = RadioSetting("wideb", "B Band", RadioSettingValueList( B_BAND, B_BAND[_vfob.wideb])) abblock.append(rs) rs = RadioSetting("bclb", "B Busy Lock", RadioSettingValueList( B_BUSYLOCK, B_BUSYLOCK[_vfob.bclb])) abblock.append(rs) rs = RadioSetting("specialqtb", "B Special QT/DQT", RadioSettingValueList( B_SPEC_QTDQT, B_SPEC_QTDQT[_vfob.specialqtb])) abblock.append(rs) rs = RadioSetting("bworkmode", "B Work Mode", RadioSettingValueList( B_WORKMODE, B_WORKMODE[_settings.bworkmode])) abblock.append(rs) rs = RadioSetting("fmworkmode", "Work Mode", RadioSettingValueList( FM_WORKMODE, FM_WORKMODE[_settings.fmworkmode])) fmmode.append(rs) rs = RadioSetting("fmroad", "Channel", RadioSettingValueList( FM_CHANNEL, FM_CHANNEL[_settings.fmroad])) fmmode.append(rs) rs = RadioSetting("fmrec", "Forbid Receive", RadioSettingValueBoolean(_settings.fmrec)) fmmode.append(rs) # FM for i in range(25): _fm = self._get_fm(i).fmblock _fm_len = len(_fm) - 1 _fm_temp = '' for x in range(_fm_len, -1, -1): _fm_temp += str(_fm[x])[2:] if _fm_temp == "00000000" or _fm_temp == 'FFFFFFFF': rs = RadioSetting('block' + str(i), "Channel" + " " + str(i+1), RadioSettingValueString(0, 5, "")) else: _fm_block = int(_fm_temp) _fm_block = '%i.%i' % (_fm_block / 10, _fm_block % 10) rs = RadioSetting('block' + str(i), "Channel" + " " + str(i+1), RadioSettingValueString(0, 5, _fm_block)) fmmode.append(rs) _fmv = self._memobj.fmvfo.vfo _fmv_len = len(_fmv) - 1 _fmv_temp = '' for x in range(_fmv_len, -1, -1): _fmv_temp += str(_fmv[x])[2:] _fmv_block = int(_fmv_temp) _fmv_block = '%i.%i' % (_fmv_block / 10, _fmv_block % 10) rs = RadioSetting( "fmvfo", "VFO", RadioSettingValueFloat( 76.0, 108.0, _fmv_block, 0.1, 1)) fmmode.append(rs) # DTMF gcode_val = str(_gcode.gcode)[2:] if gcode_val == "FF": gcode_val = "Off" elif gcode_val == "0F": gcode_val = "#" elif gcode_val == "0E": gcode_val = "*" elif gcode_val == '00': gcode_val = "" else: gcode_val = gcode_val[1] rs = RadioSetting("gcode", "Group Code", RadioSettingValueList(GROUPCODE, gcode_val)) dtmf.append(rs) icode_list = self._memobj.icode.idcode used_icode = '' for i in icode_list: if i == 0xFF: continue used_icode += str(i)[3] dtmfcharsani = "0123456789ABCD " i_val = RadioSettingValueString(0, 3, used_icode) rs = RadioSetting("icode", "ID Code", i_val) i_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_1 = self._memobj.group1.group1 used_group1 = '' for i in gcode_list_1: if i == 0xFF: continue used_group1 += str(i)[3] group1_val = RadioSettingValueString(0, 7, used_group1) rs = RadioSetting("group1", "1", group1_val) group1_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_2 = self._memobj.group2.group2 used_group2 = '' for i in gcode_list_2: if i == 0xFF: continue used_group2 += str(i)[3] group2_val = RadioSettingValueString(0, 7, used_group2) rs = RadioSetting("group2", "2", group2_val) group2_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_3 = self._memobj.group3.group3 used_group3 = '' for i in gcode_list_3: if i == 0xFF: continue used_group3 += str(i)[3] group3_val = RadioSettingValueString(0, 7, used_group3) rs = RadioSetting("group3", "3", group3_val) group3_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_4 = self._memobj.group4.group4 used_group4 = '' for i in gcode_list_4: if i == 0xFF: continue used_group4 += str(i)[3] group4_val = RadioSettingValueString(0, 7, used_group4) rs = RadioSetting("group4", "4", group4_val) group4_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_5 = self._memobj.group5.group5 used_group5 = '' for i in gcode_list_5: if i == 0xFF: continue used_group5 += str(i)[3] group5_val = RadioSettingValueString(0, 7, used_group5) rs = RadioSetting("group5", "5", group5_val) group5_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_6 = self._memobj.group6.group6 used_group6 = '' for i in gcode_list_6: if i == 0xFF: continue used_group6 += str(i)[3] group6_val = RadioSettingValueString(0, 7, used_group6) rs = RadioSetting("group6", "6", group6_val) group6_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_7 = self._memobj.group7.group7 used_group7 = '' for i in gcode_list_7: if i == 0xFF: continue used_group7 += str(i)[3] group7_val = RadioSettingValueString(0, 7, used_group7) rs = RadioSetting("group7", "7", group7_val) group7_val.set_charset(dtmfcharsani) dtmf.append(rs) gcode_list_8 = self._memobj.group8.group8 used_group8 = '' for i in gcode_list_8: if i == 0xFF: continue used_group8 += str(i)[3] group8_val = RadioSettingValueString(0, 7, used_group8) rs = RadioSetting("group8", "8", group7_val) group8_val.set_charset(dtmfcharsani) dtmf.append(rs) scode_list = self._memobj.startcode.scode used_scode = '' for i in scode_list: if i == 0xFF: continue used_scode += str(i)[3] scode_val = RadioSettingValueString(0, 7, used_scode) rs = RadioSetting("scode", "PTT ID Starting(BOT)", scode_val) scode_val.set_charset(dtmfcharsani) dtmf.append(rs) ecode_list = self._memobj.endcode.ecode used_ecode = '' for i in ecode_list: if i == 0xFF: continue used_ecode += str(i)[3] ecode_val = RadioSettingValueString(0, 7, used_ecode) rs = RadioSetting("ecode", "PTT ID Ending(BOT)", ecode_val) dtmf.append(rs) # H3 if self.MODEL not in H8_LIST: # stuncode ecode_list = self._memobj.skcode.stuncode used_ecode = '' for i in ecode_list: if i == 0xFF: continue used_ecode += str(i)[3] ecode_val = RadioSettingValueString(0, 16, used_ecode) rs = RadioSetting("stuncode", "Stun Code", ecode_val) dtmf.append(rs) # killcode ecode_list = self._memobj.skcode.killcode used_ecode = '' for i in ecode_list: if i == 0xFF: continue used_ecode += str(i)[3] ecode_val = RadioSettingValueString(0, 16, used_ecode) rs = RadioSetting("killcode", "Kill Code", ecode_val) dtmf.append(rs) return group def get_settings(self): try: return self._get_settings() except Exception: raise InvalidValueError("Setting Failed!") def set_settings(self, settings): def fm_validate(value): if 760 > value or value > 1080: msg = ("FM Channel muse be between 76.0-108.0") raise InvalidValueError(msg) _settings = self._memobj.settings _press = self._memobj.press _aoffset = self._memobj.aoffset _boffset = self._memobj.boffset _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob _fmmode = self._memobj.fmmode for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] elif name in PRESS_NAME: obj = _press setting = element.get_name() elif name in VFOA_NAME: obj = _vfoa setting = element.get_name() elif name == "ofseta": obj = _aoffset setting = element.get_name() elif name in VFOB_NAME: obj = _vfob setting = element.get_name() elif name == "ofsetb": obj = _boffset setting = element.get_name() elif "block" in name: obj = _fmmode setting = element.get_name() elif "fmvfo" in name: obj = self._memobj.fmvfo.vfo setting = element.get_name() elif "gcode" in name: obj = self._memobj.groupcode.gcode setting = element.get_name() elif "idcode" in name: obj = self._memobj.icode.idcode setting = element.get_name() elif "scode" in name: obj = self._memobj.startcode.scode setting = element.get_name() elif "ecode" in name: obj = self._memobj.endcode.ecode setting = element.get_name() elif "group1" in name: obj = self._memobj.group1.group1 setting = element.get_name() elif "group2" in name: obj = self._memobj.group2.group2 setting = element.get_name() elif "group3" in name: obj = self._memobj.group3.group3 setting = element.get_name() elif "group4" in name: obj = self._memobj.group4.group4 setting = element.get_name() elif "group5" in name: obj = self._memobj.group5.group5 setting = element.get_name() elif "group6" in name: obj = self._memobj.group6.group6 setting = element.get_name() elif "group7" in name: obj = self._memobj.group7.group7 setting = element.get_name() elif "group8" in name: obj = self._memobj.group8.group8 setting = element.get_name() elif "micgain" in name: obj = self._memobj.mic.micgain setting = element.get_name() elif "killcode" in name: obj = self._memobj.skcode.killcode setting = element.get_name() elif "stuncode" in name: obj = self._memobj.skcode.stuncode setting = element.get_name() else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() # Channel A elif setting == "rxfreqa" and element.value.get_mutable(): val = int(str(element.value).replace( '.', '').ljust(8, '0')) if (val >= 13600000 and val <= 17400000) or \ (val >= 40000000 and val <= 52000000): setattr(obj, setting, val) else: msg = ( "Frequency must be between " "136.00000-174.00000 or 400.00000-520.00000") raise InvalidValueError(msg) elif setting == "ofseta" and element.value.get_mutable(): if '.' in str(element.value): val = str(element.value).replace(' ', '') if len( val[val.index(".") + 1:] ) >= 1 and int(val[val.index(".") + 1:] ) != 0: val = '00' + val.replace('.', '') else: val = '0' + val.replace('.', '') val = val.ljust(8, '0') lenth_val = 0 list_val = [] else: val = '0' + str(element.value).replace(' ', '') val = val.ljust(8, '0') lenth_val = 0 list_val = [] if (int(val) >= 0 and int(val) <= 5999750): if int(val) == 0: _aoffset.ofseta = [0xFF, 0xFF, 0xFF, 0xFF] else: while lenth_val < (len(val)): list_val.insert( 0, val[lenth_val:lenth_val + 2]) lenth_val += 2 for i in range(len(list_val)): list_val[i] = int(list_val[i], 16) _aoffset.ofseta = list_val else: msg = ("Offset must be between 0.00000-59.99750") raise InvalidValueError(msg) # B channel elif setting == "rxfreqb" and element.value.get_mutable(): val = 0 val = int(str(element.value).replace( '.', '').ljust(8, '0')) if (val >= 13600000 and val <= 17400000) or \ (val >= 40000000 and val <= 52000000): setattr(obj, setting, val) else: msg = ( "Frequency must be between " "136.00000-174.00000 or 400.00000-520.00000") raise InvalidValueError(msg) # setattr(obj, setting, val) elif setting == "ofsetb" and element.value.get_mutable(): if '.' in str(element.value): val = str(element.value).replace(' ', '') if len(val[val.index(".") + 1:] ) >= 1 and int(val[val.index(".") + 1:] ) != 0: val = '00' + \ str(element.value).replace('.', '') else: val = '0' + str(element.value).replace('.', '') val = val.ljust(8, '0') lenth_val = 0 list_val = [] else: val = '0' + str(element.value).replace(' ', '') val = val.ljust(8, '0') lenth_val = 0 list_val = [] if (int(val) >= 0 and int(val) <= 5999750): if int(val) == 0: _boffset.ofsetb = [0xFF, 0xFF, 0xFF, 0xFF] else: while lenth_val < (len(val)): list_val.insert( 0, val[lenth_val:lenth_val + 2]) lenth_val += 2 for i in range(len(list_val)): list_val[i] = int(list_val[i], 16) _boffset.ofsetb = list_val else: msg = ("Offset must be between 0.00000-59.99750") raise InvalidValueError(msg) # FM elif "block" in name: val = str(element.value).replace('.', '').zfill(8) num = int(element.get_name().replace('block', '')) + 1 lenth_val = 0 list_val = [] if str(element.value)[0] == ' ': list_val = [0, 0, 0, 0] else: val = val.replace(' ', '').zfill(8) fm_validate(int(val)) while lenth_val < (len(val)): list_val.insert( 0, int(val[lenth_val:lenth_val + 2], 16)) lenth_val += 2 self._memobj.fmmode[num - 1].fmblock = list_val if val != '00000 ': fmblock_xy = self.get_block_xy(num) _fmusedflags = self._get_fmblock_data( fmblock_xy[0]) if fmblock_xy[1] == 1: _fmusedflags.block1 = 1 elif fmblock_xy[1] == 2: _fmusedflags.block2 = 1 elif fmblock_xy[1] == 3: _fmusedflags.block3 = 1 elif fmblock_xy[1] == 4: _fmusedflags.block4 = 1 elif fmblock_xy[1] == 5: _fmusedflags.block5 = 1 elif fmblock_xy[1] == 6: _fmusedflags.block6 = 1 elif fmblock_xy[1] == 7: _fmusedflags.block7 = 1 elif fmblock_xy[1] == 8: _fmusedflags.block8 = 1 else: fmblock_xy = self.get_block_xy(num) _fmusedflags = self._get_fmblock_data( fmblock_xy[0]) if fmblock_xy[1] == 1: _fmusedflags.block1 = 0 elif fmblock_xy[1] == 2: _fmusedflags.block2 = 0 elif fmblock_xy[1] == 3: _fmusedflags.block3 = 0 elif fmblock_xy[1] == 4: _fmusedflags.block4 = 0 elif fmblock_xy[1] == 5: _fmusedflags.block5 = 0 elif fmblock_xy[1] == 6: _fmusedflags.block6 = 0 elif fmblock_xy[1] == 7: _fmusedflags.block7 = 0 elif fmblock_xy[1] == 8: _fmusedflags.block8 = 0 elif setting == 'fmvfo' and element.value.get_mutable(): val = str(element.value).replace('.', '').zfill(8) lenth_val = 0 list_val = [] if " " in val: list_val = [0, 0, 0, 0] else: while lenth_val < (len(val)): list_val.insert( 0, int(val[lenth_val:lenth_val + 2], 16)) lenth_val += 2 self._memobj.fmvfo.vfo = list_val elif setting == 'gcode' and element.value.get_mutable(): val = str(element.value) if val == 'Off': gcode_used = 0xFF elif val == 'A': gcode_used = 0x0A elif val == 'B': gcode_used = 0x0B elif val == 'C': gcode_used = 0x0C elif val == 'D': gcode_used = 0x0D elif val == '#': gcode_used = 0x0F elif val == '*': gcode_used = 0x0E elif val == '': gcode_used = 0x00 self._memobj.groupcode.gcode = gcode_used elif setting == 'icode' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.icode.idcode = list_val elif setting == 'scode' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.startcode.scode = list_val elif setting == 'ecode' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.endcode.ecode = list_val elif setting == 'group1' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group1.group1 = list_val elif setting == 'group2' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group2.group2 = list_val elif setting == 'group3' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group3.group3 = list_val elif setting == 'group4' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group4.group4 = list_val elif setting == 'group5' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group5.group5 = list_val elif setting == 'group6' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group6.group6 = list_val elif setting == 'group7' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group7.group7 = list_val elif setting == 'group8' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.group8.group8 = list_val elif setting == 'micgain': self._memobj.mic.micgain = ( str(element.value)) elif setting == 'stuncode' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.skcode.stuncode = list_val elif setting == 'killcode' and element.value.get_mutable(): val = str(element.value) list_val = [] lenth_val = 0 while lenth_val < (len(val)): if val[lenth_val] != ' ': list_val.append(int(val[lenth_val], 16)) lenth_val += 1 else: list_val.append(0xFF) lenth_val += 1 self._memobj.skcode.killcode = list_val elif element.value.get_mutable(): setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _set_fm_preset(self, settings): for element in settings: try: val = element.value if self._memobj.fm_presets <= 108.0 * 10 - 650: value = int(val.get_value() * 10 - 650) else: value = int(val.get_value() * 10) LOG.debug("Setting fm_presets = %s" % (value)) self._memobj.fm_presets = value except Exception: LOG.debug(element.get_name()) raise @directory.register class TDH8_HAM(TDH8): VENDOR = "TIDRADIO" MODEL = "TD-H8-HAM" ident_mode = b'P31185\xff\xff' _ham = True _vhf_range = (144000000, 149000000) _uhf_range = (420000000, 451000000) @directory.register class TDH8_GMRS(TDH8): VENDOR = "TIDRADIO" MODEL = "TD-H8-GMRS" ident_mode = b'P31184\xff\xff' _gmrs = True _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 521000000) def validate_memory(self, mem): msgs = super().validate_memory(mem) if 31 <= mem.number <= 54 and mem.freq not in GMRS_FREQS: msgs.append(chirp_common.ValidationError( "The frequency in channels 31-54 must be between" "462.55000-462.72500 in 0.025 increments.")) return msgs @directory.register class UV68(TDH8): VENDOR = "TID" MODEL = "TD-UV68" @directory.register class TDH3(TDH8): VENDOR = "TIDRADIO" MODEL = "TD-H3" _memsize = 0x1fef _ranges_main = [(0x0000, 0x1fef)] _idents = [TD_H3] _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 521000000) _aux_block = True _tri_power = True _gmrs = False _ham = False _mem_params = (0x1F2F) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_H3, self._mmap) @directory.register class TDH3_HAM(TDH3): VENDOR = "TIDRADIO" MODEL = "TD-H3-HAM" ident_mode = b'P31185\xff\xff' _ham = True _vhf_range = (144000000, 149000000) _uhf_range = (420000000, 451000000) @directory.register class TDH3_GMRS(TDH3): VENDOR = "TIDRADIO" MODEL = "TD-H3-GMRS" ident_mode = b'P31184\xff\xff' _gmrs = True _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 521000000) def validate_memory(self, mem): msgs = super().validate_memory(mem) if 31 <= mem.number <= 54 and mem.freq not in GMRS_FREQS: msgs.append(chirp_common.ValidationError( "The frequency in channels 31-54 must be between" "462.55000-462.72500 in 0.025 increments.")) return msgs chirp-20240224/chirp/drivers/vx8.py0000644000175000017500000016460414520142245015730 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import re import logging from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, bitwise from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings from chirp.settings import RadioSettingValueInteger, RadioSettingValueString from chirp.settings import RadioSettingValueList, RadioSettingValueBoolean LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x047f; struct { u8 flag; u16 unknown; struct { u8 padded_yaesu[16]; } message; } opening_message; #seekto 0x049a; struct { u8 vfo_a; u8 vfo_b; } squelch; #seekto 0x04bf; struct { u8 beep; } beep_select; #seekto 0x04cc; struct { u8 lcd_dimmer; u8 dtmf_delay; u8 unknown0[3]; u8 unknown1:4, lcd_contrast:4; u8 lamp; u8 unknown2[7]; u8 scan_restart; u8 unknown3; u8 scan_resume; u8 unknown4[6]; u8 tot; u8 unknown5[3]; u8 unknown6:2, scan_lamp:1, unknown7:2, dtmf_speed:1, unknown8:1, dtmf_mode:1; u8 busy_led:1, unknown9:7; u8 unknown10[2]; u8 vol_mode:1, unknown11:7; } scan_settings; #seekto 0x54a; struct { u16 in_use; } bank_used[24]; #seekto 0x064a; struct { u8 unknown0[4]; u8 frequency_band; u8 unknown1:6, manual_or_mr:2; u8 unknown2:7, mr_banks:1; u8 unknown3; u16 mr_index; u16 bank_index; u16 bank_enable; u8 unknown4[5]; u8 unknown5:6, power:2; u8 unknown6:4, tune_step:4; u8 unknown7:6, duplex:2; u8 unknown8:6, tone_mode:2; u8 unknown9:2, tone:6; u8 unknown10; u8 unknown11:6, mode:2; bbcd freq0[4]; bbcd offset_freq[4]; u8 unknown12[2]; char label[16]; u8 unknown13[6]; bbcd band_lower[4]; bbcd band_upper[4]; bbcd rx_freq[4]; u8 unknown14[22]; bbcd freq1[4]; u8 unknown15[11]; u8 unknown16:3, volume:5; u8 unknown17[18]; u8 active_menu_item; u8 checksum; } vfo_info[6]; #seekto 0x094a; struct { u8 memory[16]; } dtmf[10]; #seekto 0x135A; struct { u8 unknown[2]; u8 name[16]; } bank_info[24]; #seekto 0x198a; struct { u16 channel[100]; } bank_members[24]; #seekto 0x2C4A; struct { u8 nosubvfo:1, unknown:3, pskip:1, skip:1, used:1, valid:1; } flag[900]; #seekto 0x328A; struct { u8 unknown1a:2, half_deviation:1, unknown1b:5; u8 mode:2, duplex:2, tune_step:4; bbcd freq[3]; u8 power:2, unknown2:4, tone_mode:2; u8 charsetbits[2]; char label[16]; bbcd offset[3]; u8 unknown5:2, tone:6; u8 unknown6:1, dcs:7; u8 pr_frequency; u8 unknown7; u8 unknown8a:3, unknown8b:1, rx_mode_auto:1, unknown8c:3; } memory[900]; #seekto 0xC0CA; struct { u8 unknown0:6, rx_baud:2; u8 unknown1:4, tx_delay:4; u8 custom_symbol; u8 unknown2; struct { char callsign[6]; u8 ssid; } my_callsign; u8 unknown3:4, selected_position_comment:4; u8 unknown4; u8 set_time_manually:1, tx_interval_beacon:1, ring_beacon:1, ring_msg:1, aprs_mute:1, unknown6:1, tx_smartbeacon:1, af_dual:1; u8 unknown7:1, aprs_units_wind_mph:1, aprs_units_rain_inch:1, aprs_units_temperature_f:1, aprs_units_altitude_ft:1, unknown8:1, aprs_units_distance_m:1, aprs_units_position_mmss:1; u8 unknown9:6, aprs_units_speed:2; u8 unknown11:1, filter_other:1, filter_status:1, filter_item:1, filter_object:1, filter_weather:1, filter_position:1, filter_mic_e:1; u8 unknown12:2, timezone:6; u8 unknown13:4, beacon_interval:4; u8 unknown14; u8 unknown15:7, latitude_sign:1; u8 latitude_degree; u8 latitude_minute; u8 latitude_second; u8 unknown16:7, longitude_sign:1; u8 longitude_degree; u8 longitude_minute; u8 longitude_second; u8 unknown17:4, selected_position:4; u8 unknown18:5, selected_beacon_status_txt:3; u8 unknown19:6, gps_units_altitude_ft:1, gps_units_position_sss:1; u8 unknown20:6, gps_units_speed:2; u8 unknown21[4]; struct { struct { char callsign[6]; u8 ssid; } entry[8]; } digi_path_7; u8 unknown22[2]; } aprs; #seekto 0x%04X; struct { char padded_string[16]; } aprs_msg_macro[%d]; #seekto 0x%04X; struct { u8 unknown23:5, selected_msg_group:3; u8 unknown24; struct { char padded_string[9]; } msg_group[8]; u8 unknown25[4]; u8 active_smartbeaconing; struct { u8 low_speed_mph; u8 high_speed_mph; u8 slow_rate_min; u8 fast_rate_sec; u8 turn_angle; u8 turn_slop; u8 turn_time_sec; } smartbeaconing_profile[3]; u8 unknown26:2, flash_msg:6; u8 unknown27:2, flash_grp:6; u8 unknown28:2, flash_bln:6; u8 selected_digi_path; struct { struct { char callsign[6]; u8 ssid; } entry[2]; } digi_path_3_6[4]; u8 unknown30:6, selected_my_symbol:2; u8 unknown31[3]; u8 unknown32:2, vibrate_msg:6; u8 unknown33:2, vibrate_grp:6; u8 unknown34:2, vibrate_bln:6; } aprs2; #seekto 0x%04X; struct { bbcd date[3]; u8 unknown1; bbcd time[2]; u8 sequence; u8 unknown2; u8 sender_callsign[7]; u8 data_type; u8 yeasu_data_type; u8 unknown3; u8 unknown4:1, callsign_is_ascii:1, unknown5:6; u8 unknown6; u16 pkt_len; u16 in_use; } aprs_beacon_meta[%d]; #seekto 0x%04X; struct { u8 dst_callsign[6]; u8 dst_callsign_ssid; u8 src_callsign[6]; u8 src_callsign_ssid; u8 path_and_body[%d]; } aprs_beacon_pkt[%d]; #seekto 0xf92a; struct { char padded_string[60]; } aprs_beacon_status_txt[5]; #seekto 0xFECA; u8 checksum; """ TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+", "split"] MODES = ["FM", "AM", "WFM", "NFM"] STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0, 200.0] SKIPS = ["", "S", "P"] VX8_DTMF_CHARS = list("0123456789ABCD*#-") CHARSET = ["%i" % int(x) for x in range(0, 10)] + \ [chr(x) for x in range(ord("A"), ord("Z")+1)] + \ [" "] + \ [chr(x) for x in range(ord("a"), ord("z")+1)] + \ list(".,:;*#_-/&()@!?^ ") + list("\x00" * 100) POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00), chirp_common.PowerLevel("L3", watts=2.50), chirp_common.PowerLevel("L2", watts=1.00), chirp_common.PowerLevel("L1", watts=0.05)] class VX8Bank(chirp_common.NamedBank): """A VX-8 bank""" def get_name(self): _bank = self._model._radio._memobj.bank_info[self.index] _bank_used = self._model._radio._memobj.bank_used[self.index] name = "" for i in _bank.name: if i == 0xFF: break name += CHARSET[i & 0x7F] return name.rstrip() def set_name(self, name): _bank = self._model._radio._memobj.bank_info[self.index] _bank.name = [CHARSET.index(x) for x in name.ljust(16)[:16]] class VX8BankModel(chirp_common.BankModel): """A VX-8 bank model""" def __init__(self, radio, name='Banks'): super(VX8BankModel, self).__init__(radio, name) _banks = self._radio._memobj.bank_info self._bank_mappings = [] for index, _bank in enumerate(_banks): bank = VX8Bank(self, "%i" % index, "BANK-%i" % index) bank.index = index self._bank_mappings.append(bank) def get_num_mappings(self): return len(self._bank_mappings) def get_mappings(self): return self._bank_mappings def _channel_numbers_in_bank(self, bank): _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xFFFF: return set() _members = self._radio._memobj.bank_members[bank.index] return set([int(ch) + 1 for ch in _members.channel if ch != 0xFFFF]) def update_vfo(self): chosen_bank = [None, None] chosen_mr = [None, None] flags = self._radio._memobj.flag # Find a suitable bank and MR for VFO A and B. for bank in self.get_mappings(): for channel in self._channel_numbers_in_bank(bank): chosen_bank[0] = bank.index chosen_mr[0] = channel if not flags[channel].nosubvfo: chosen_bank[1] = bank.index chosen_mr[1] = channel break if chosen_bank[1]: break for vfo_index in (0, 1): # 3 VFO info structs are stored as 3 pairs of (master, backup) vfo = self._radio._memobj.vfo_info[vfo_index * 2] vfo_bak = self._radio._memobj.vfo_info[(vfo_index * 2) + 1] if vfo.checksum != vfo_bak.checksum: LOG.warn("VFO settings are inconsistent with backup") else: if ((chosen_bank[vfo_index] is None) and (vfo.bank_index != 0xFFFF)): LOG.info("Disabling banks for VFO %d" % vfo_index) vfo.bank_index = 0xFFFF vfo.mr_index = 0xFFFF vfo.bank_enable = 0xFFFF elif ((chosen_bank[vfo_index] is not None) and (vfo.bank_index == 0xFFFF)): LOG.debug("Enabling banks for VFO %d" % vfo_index) vfo.bank_index = chosen_bank[vfo_index] vfo.mr_index = chosen_mr[vfo_index] vfo.bank_enable = 0x0000 vfo_bak.bank_index = vfo.bank_index vfo_bak.mr_index = vfo.mr_index vfo_bak.bank_enable = vfo.bank_enable def _update_bank_with_channel_numbers(self, bank, channels_in_bank): _members = self._radio._memobj.bank_members[bank.index] if len(channels_in_bank) > len(_members.channel): raise Exception("Too many entries in bank %d" % bank.index) empty = 0 for index, channel_number in enumerate(sorted(channels_in_bank)): _members.channel[index] = channel_number - 1 empty = index + 1 for index in range(empty, len(_members.channel)): _members.channel[index] = 0xFFFF def add_memory_to_mapping(self, memory, bank): channels_in_bank = self._channel_numbers_in_bank(bank) channels_in_bank.add(memory.number) self._update_bank_with_channel_numbers(bank, channels_in_bank) _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0x06 self.update_vfo() def remove_memory_from_mapping(self, memory, bank): channels_in_bank = self._channel_numbers_in_bank(bank) try: channels_in_bank.remove(memory.number) except KeyError: raise Exception("Memory %i is not in bank %s. Cannot remove" % (memory.number, bank)) self._update_bank_with_channel_numbers(bank, channels_in_bank) if not channels_in_bank: _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0xFFFF self.update_vfo() def get_mapping_memories(self, bank): memories = [] for channel in self._channel_numbers_in_bank(bank): memories.append(self._radio.get_memory(channel)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in self._channel_numbers_in_bank(bank): banks.append(bank) return banks def _wipe_memory(mem): mem.set_raw("\x00" * (mem.size() // 8)) @directory.register class VX8Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu VX-8""" BAUD_RATE = 38400 VENDOR = "Yaesu" MODEL = "VX-8R" _model = b"AH029" _memsize = 65227 _block_lengths = [10, 65217] _block_size = 32 _mem_params = (0xC128, # APRS message macros 5, # Number of message macros 0xC178, # APRS2 0xC24A, # APRS beacon metadata address. 40, # Number of beacons stored. 0xC60A, # APRS beacon content address. 194, # Length of beacon data stored. 40) # Number of beacons stored. _has_vibrate = False _has_af_dual = True _SG_RE = re.compile(r"(?P[-+NESW]?)(?P[\d]+)[\s\.,]*" r"(?P[\d]*)[\s\']*(?P[\d]*)") _RX_BAUD = ("off", "1200 baud", "9600 baud") _TX_DELAY = ("100ms", "200ms", "300ms", "400ms", "500ms", "750ms", "1000ms") _WIND_UNITS = ("m/s", "mph") _RAIN_UNITS = ("mm", "inch") _TEMP_UNITS = ("C", "F") _ALT_UNITS = ("m", "ft") _DIST_UNITS = ("km", "mile") _POS_UNITS = ("dd.mmmm'", "dd mm'ss\"") _SPEED_UNITS = ("km/h", "knot", "mph") _TIME_SOURCE = ("manual", "GPS") _TZ = ("-13:00", "-13:30", "-12:00", "-12:30", "-11:00", "-11:30", "-10:00", "-10:30", "-09:00", "-09:30", "-08:00", "-08:30", "-07:00", "-07:30", "-06:00", "-06:30", "-05:00", "-05:30", "-04:00", "-04:30", "-03:00", "-03:30", "-02:00", "-02:30", "-01:00", "-01:30", "-00:00", "-00:30", "+01:00", "+01:30", "+02:00", "+02:30", "+03:00", "+03:30", "+04:00", "+04:30", "+05:00", "+05:30", "+06:00", "+06:30", "+07:00", "+07:30", "+08:00", "+08:30", "+09:00", "+09:30", "+10:00", "+10:30", "+11:00", "+11:30") _BEACON_TYPE = ("Off", "Interval") _BEACON_INT = ("15s", "30s", "1m", "2m", "3m", "5m", "10m", "15m", "30m") _DIGI_PATHS = ("OFF", "WIDE1-1", "WIDE1-1, WIDE2-1", "Digi Path 4", "Digi Path 5", "Digi Path 6", "Digi Path 7", "Digi Path 8") _MSG_GROUP_NAMES = ("Message Group 1", "Message Group 2", "Message Group 3", "Message Group 4", "Message Group 5", "Message Group 6", "Message Group 7", "Message Group 8") _POSITIONS = ("GPS", "Manual Latitude/Longitude", "Manual Latitude/Longitude", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9", "P10") _FLASH = ("OFF", "ON") _BEEP_SELECT = ("Off", "Key+Scan", "Key") _SQUELCH = ["%d" % x for x in range(0, 16)] _VOLUME = ["%d" % x for x in range(0, 33)] _OPENING_MESSAGE = ("Off", "DC", "Message", "Normal") _SCAN_RESUME = ["%.1fs" % (0.5 * x) for x in range(4, 21)] + \ ["Busy", "Hold"] _SCAN_RESTART = ["%.1fs" % (0.1 * x) for x in range(1, 10)] + \ ["%.1fs" % (0.5 * x) for x in range(2, 21)] _LAMP_KEY = ["Key %d sec" % x for x in range(2, 11)] + \ ["Continuous", "OFF"] _LCD_CONTRAST = ["Level %d" % x for x in range(1, 33)] _LCD_DIMMER = ["Level %d" % x for x in range(1, 5)] _TOT_TIME = ["Off"] + ["%.1f min" % (0.5 * x) for x in range(1, 21)] _OFF_ON = ("Off", "On") _VOL_MODE = ("Normal", "Auto Back") _DTMF_MODE = ("Manual", "Auto") _DTMF_SPEED = ("50ms", "100ms") _DTMF_DELAY = ("50ms", "250ms", "450ms", "750ms", "1000ms") _MY_SYMBOL = ("/[ Person", "/b Bike", "/> Car", "User selected") @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to DATA jack.\n" "3. Press and hold in the [FW] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. After clicking OK, press the [BAND] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to DATA jack.\n" "3. Press and hold in the [FW] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. Press the [MODE] key (\"-WAIT-\" will appear on the LCD).\n") return rp def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.valid_modes = list(MODES) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(500000, 999900000)] rf.valid_skips = SKIPS rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 16 rf.memory_bounds = (1, 900) rf.can_odd_split = True rf.has_ctone = False rf.has_bank_names = True rf.has_settings = True return rf def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def _checksums(self): return [yaesu_clone.YaesuChecksum(0x064A, 0x06C8), yaesu_clone.YaesuChecksum(0x06CA, 0x0748), yaesu_clone.YaesuChecksum(0x074A, 0x07C8), yaesu_clone.YaesuChecksum(0x07CA, 0x0848), yaesu_clone.YaesuChecksum(0x0000, 0xFEC9)] @staticmethod def _add_ff_pad(val, length): return val.ljust(length, "\xFF")[:length] @classmethod def _strip_ff_pads(cls, messages): result = [] for msg_text in messages: result.append(str(msg_text).rstrip("\xFF")) return result def get_memory(self, number): flag = self._memobj.flag[number-1] _mem = self._memobj.memory[number-1] mem = chirp_common.Memory() mem.number = number if not flag.used: mem.empty = True if not flag.valid: mem.empty = True return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = int(_mem.offset) * 1000 mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] mem.tmode = TMODES[_mem.tone_mode] mem.duplex = DUPLEX[_mem.duplex] if mem.duplex == "split": mem.offset = chirp_common.fix_rounded_step(mem.offset) if _mem.mode == "FM" and _mem.half_deviation == 1: mem.mode = "NFM" else: mem.mode = MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] mem.tuning_step = STEPS[_mem.tune_step] mem.power = POWER_LEVELS[3 - _mem.power] mem.skip = flag.pskip and "P" or flag.skip and "S" or "" charset = ''.join(CHARSET).ljust(256, '.') mem.name = str(_mem.label).rstrip("\xFF").translate(charset).rstrip() return mem def _debank(self, mem): bm = self.get_bank_model() for bank in bm.get_memory_mappings(mem): bm.remove_memory_from_mapping(mem, bank) def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] flag = self._memobj.flag[mem.number-1] self._debank(mem) if not mem.empty and not flag.valid: _wipe_memory(_mem) if mem.empty and flag.valid and not flag.used: flag.valid = False return flag.used = not mem.empty flag.valid = flag.used if mem.empty: return if mem.freq < 30000000 or \ (mem.freq > 88000000 and mem.freq < 108000000) or \ mem.freq > 580000000: flag.nosubvfo = True # Masked from VFO B else: flag.nosubvfo = False # Available in both VFOs _mem.freq = int(mem.freq / 1000) _mem.offset = int(mem.offset / 1000) _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.tone_mode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) if mem.mode == "NFM": _mem.mode = 0 # Yaesu's NFM, i.e. regular FM _mem.half_deviation = 1 # but half bandwidth else: _mem.mode = MODES.index(mem.mode) _mem.half_deviation = 0 _mem.mode = MODES.index(mem.mode) _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tune_step = STEPS.index(mem.tuning_step) if mem.power: _mem.power = 3 - POWER_LEVELS.index(mem.power) else: _mem.power = 0 label = "".join([chr(CHARSET.index(x)) for x in mem.name.rstrip()]) _mem.label = self._add_ff_pad(label, 16) # We only speak English here in chirpville _mem.charsetbits[0] = 0x00 _mem.charsetbits[1] = 0x00 flag.skip = mem.skip == "S" flag.pskip = mem.skip == "P" def get_bank_model(self): return VX8BankModel(self) @classmethod def _digi_path_to_str(cls, path): path_cmp = [] for entry in path.entry: callsign = str(entry.callsign).rstrip("\xFF") if not callsign: break path_cmp.append("%s-%d" % (callsign, entry.ssid)) return ",".join(path_cmp) @staticmethod def _latlong_sanity(sign, l_d, l_m, l_s, is_lat): if sign not in (0, 1): sign = 0 if is_lat: d_max = 90 else: d_max = 180 if l_d < 0 or l_d > d_max: l_d = 0 l_m = 0 l_s = 0 if l_m < 0 or l_m > 60: l_m = 0 l_s = 0 if l_s < 0 or l_s > 60: l_s = 0 return sign, l_d, l_m, l_s @classmethod def _latlong_to_str(cls, sign, l_d, l_m, l_s, is_lat, to_sexigesimal=True): sign, l_d, l_m, l_s = cls._latlong_sanity(sign, l_d, l_m, l_s, is_lat) mult = sign and -1 or 1 if to_sexigesimal: return "%d,%d'%d\"" % (mult * l_d, l_m, l_s) return "%0.5f" % (mult * l_d + (l_m / 60.0) + (l_s / (60.0 * 60.0))) @classmethod def _str_to_latlong(cls, lat_long, is_lat): sign = 0 result = [0, 0, 0] lat_long = lat_long.strip() if not lat_long: return 1, 0, 0, 0 try: # DD.MMMMM is the simple case, try that first. val = float(lat_long) if val < 0: sign = 1 val = abs(val) result[0] = int(val) result[1] = int(val * 60) % 60 result[2] = int(val * 3600) % 60 except ValueError: # Try DD MM'SS" if DD.MMMMM failed. match = cls._SG_RE.match(lat_long.strip()) if match: if match.group("sign") and (match.group("sign") in "SE-"): sign = 1 else: sign = 0 if match.group("d"): result[0] = int(match.group("d")) if match.group("m"): result[1] = int(match.group("m")) if match.group("s"): result[2] = int(match.group("s")) elif len(lat_long) > 4: raise Exception("Lat/Long should be DD MM'SS\" or DD.MMMMM") return cls._latlong_sanity(sign, result[0], result[1], result[2], is_lat) def _get_aprs_general_settings(self): menu = RadioSettingGroup("aprs_general", "APRS General") aprs = self._memobj.aprs aprs2 = self._memobj.aprs2 val = RadioSettingValueString( 0, 6, str(aprs.my_callsign.callsign).rstrip("\xFF")) rs = RadioSetting("aprs.my_callsign.callsign", "My Callsign", val) rs.set_apply_callback(self.apply_callsign, aprs.my_callsign) menu.append(rs) val = RadioSettingValueList( chirp_common.APRS_SSID, chirp_common.APRS_SSID[aprs.my_callsign.ssid]) rs = RadioSetting("aprs.my_callsign.ssid", "My SSID", val) menu.append(rs) val = RadioSettingValueList(self._MY_SYMBOL, self._MY_SYMBOL[aprs2.selected_my_symbol]) rs = RadioSetting("aprs2.selected_my_symbol", "My Symbol", val) menu.append(rs) symbols = list(chirp_common.APRS_SYMBOLS) selected = aprs.custom_symbol if aprs.custom_symbol >= len(chirp_common.APRS_SYMBOLS): symbols.append("%d" % aprs.custom_symbol) selected = len(symbols) - 1 val = RadioSettingValueList(symbols, symbols[selected]) rs = RadioSetting("aprs.custom_symbol_text", "User Selected Symbol", val) rs.set_apply_callback(self.apply_custom_symbol, aprs) menu.append(rs) val = RadioSettingValueList( chirp_common.APRS_POSITION_COMMENT, chirp_common.APRS_POSITION_COMMENT[aprs.selected_position_comment]) rs = RadioSetting("aprs.selected_position_comment", "Position Comment", val) menu.append(rs) latitude = self._latlong_to_str(aprs.latitude_sign, aprs.latitude_degree, aprs.latitude_minute, aprs.latitude_second, True, aprs.aprs_units_position_mmss) longitude = self._latlong_to_str(aprs.longitude_sign, aprs.longitude_degree, aprs.longitude_minute, aprs.longitude_second, False, aprs.aprs_units_position_mmss) # TODO: Rebuild this when aprs_units_position_mmss changes. # TODO: Rebuild this when latitude/longitude change. # TODO: Add saved positions p1 - p10 to memory map. position_str = list(self._POSITIONS) # position_str[1] = "%s %s" % (latitude, longitude) # position_str[2] = "%s %s" % (latitude, longitude) val = RadioSettingValueList(position_str, position_str[aprs.selected_position]) rs = RadioSetting("aprs.selected_position", "My Position", val) menu.append(rs) val = RadioSettingValueString(0, 10, latitude) rs = RadioSetting("latitude", "Manual Latitude", val) rs.set_apply_callback(self.apply_lat_long, aprs) menu.append(rs) val = RadioSettingValueString(0, 11, longitude) rs = RadioSetting("longitude", "Manual Longitude", val) rs.set_apply_callback(self.apply_lat_long, aprs) menu.append(rs) val = RadioSettingValueList( self._TIME_SOURCE, self._TIME_SOURCE[aprs.set_time_manually]) rs = RadioSetting("aprs.set_time_manually", "Time Source", val) menu.append(rs) val = RadioSettingValueList(self._TZ, self._TZ[aprs.timezone]) rs = RadioSetting("aprs.timezone", "Timezone", val) menu.append(rs) val = RadioSettingValueList( self._SPEED_UNITS, self._SPEED_UNITS[aprs.aprs_units_speed]) rs = RadioSetting("aprs.aprs_units_speed", "APRS Speed Units", val) menu.append(rs) val = RadioSettingValueList( self._SPEED_UNITS, self._SPEED_UNITS[aprs.gps_units_speed]) rs = RadioSetting("aprs.gps_units_speed", "GPS Speed Units", val) menu.append(rs) val = RadioSettingValueList( self._ALT_UNITS, self._ALT_UNITS[aprs.aprs_units_altitude_ft]) rs = RadioSetting("aprs.aprs_units_altitude_ft", "APRS Altitude Units", val) menu.append(rs) val = RadioSettingValueList( self._ALT_UNITS, self._ALT_UNITS[aprs.gps_units_altitude_ft]) rs = RadioSetting("aprs.gps_units_altitude_ft", "GPS Altitude Units", val) menu.append(rs) val = RadioSettingValueList( self._POS_UNITS, self._POS_UNITS[aprs.aprs_units_position_mmss]) rs = RadioSetting("aprs.aprs_units_position_mmss", "APRS Position Format", val) menu.append(rs) val = RadioSettingValueList( self._POS_UNITS, self._POS_UNITS[aprs.gps_units_position_sss]) rs = RadioSetting("aprs.gps_units_position_sss", "GPS Position Format", val) menu.append(rs) val = RadioSettingValueList( self._DIST_UNITS, self._DIST_UNITS[aprs.aprs_units_distance_m]) rs = RadioSetting("aprs.aprs_units_distance_m", "APRS Distance Units", val) menu.append(rs) val = RadioSettingValueList( self._WIND_UNITS, self._WIND_UNITS[aprs.aprs_units_wind_mph]) rs = RadioSetting("aprs.aprs_units_wind_mph", "APRS Wind Speed Units", val) menu.append(rs) val = RadioSettingValueList( self._RAIN_UNITS, self._RAIN_UNITS[aprs.aprs_units_rain_inch]) rs = RadioSetting("aprs.aprs_units_rain_inch", "APRS Rain Units", val) menu.append(rs) val = RadioSettingValueList( self._TEMP_UNITS, self._TEMP_UNITS[aprs.aprs_units_temperature_f]) rs = RadioSetting("aprs.aprs_units_temperature_f", "APRS Temperature Units", val) menu.append(rs) return menu def _get_aprs_rx_settings(self): menu = RadioSettingGroup("aprs_rx", "APRS Receive") aprs = self._memobj.aprs aprs2 = self._memobj.aprs2 val = RadioSettingValueList(self._RX_BAUD, self._RX_BAUD[aprs.rx_baud]) rs = RadioSetting("aprs.rx_baud", "Modem RX", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.aprs_mute) rs = RadioSetting("aprs.aprs_mute", "APRS Mute", val) menu.append(rs) if self._has_af_dual: val = RadioSettingValueBoolean(aprs.af_dual) rs = RadioSetting("aprs.af_dual", "AF Dual", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.ring_msg) rs = RadioSetting("aprs.ring_msg", "Ring on Message RX", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.ring_beacon) rs = RadioSetting("aprs.ring_beacon", "Ring on Beacon RX", val) menu.append(rs) val = RadioSettingValueList(self._FLASH, self._FLASH[aprs2.flash_msg]) rs = RadioSetting("aprs2.flash_msg", "Flash on personal message", val) menu.append(rs) if self._has_vibrate: val = RadioSettingValueList(self._FLASH, self._FLASH[aprs2.vibrate_msg]) rs = RadioSetting("aprs2.vibrate_msg", "Vibrate on personal message", val) menu.append(rs) val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs2.flash_bln]) rs = RadioSetting("aprs2.flash_bln", "Flash on bulletin message", val) menu.append(rs) if self._has_vibrate: val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs2.vibrate_bln]) rs = RadioSetting("aprs2.vibrate_bln", "Vibrate on bulletin message", val) menu.append(rs) val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs2.flash_grp]) rs = RadioSetting("aprs2.flash_grp", "Flash on group message", val) menu.append(rs) if self._has_vibrate: val = RadioSettingValueList(self._FLASH[:10], self._FLASH[aprs2.vibrate_grp]) rs = RadioSetting("aprs2.vibrate_grp", "Vibrate on group message", val) menu.append(rs) filter_val = [m.padded_string for m in aprs2.msg_group] filter_val = self._strip_ff_pads(filter_val) for index, filter_text in enumerate(filter_val): val = RadioSettingValueString(0, 9, filter_text) rs = RadioSetting("aprs2.msg_group_%d" % index, "Message Group %d" % (index + 1), val) menu.append(rs) rs.set_apply_callback(self.apply_ff_padded_string, aprs2.msg_group[index]) # TODO: Use filter_val as the list entries and update it on edit. val = RadioSettingValueList( self._MSG_GROUP_NAMES, self._MSG_GROUP_NAMES[aprs2.selected_msg_group]) rs = RadioSetting("aprs2.selected_msg_group", "Selected Message Group", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_mic_e) rs = RadioSetting("aprs.filter_mic_e", "Receive Mic-E Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_position) rs = RadioSetting("aprs.filter_position", "Receive Position Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_weather) rs = RadioSetting("aprs.filter_weather", "Receive Weather Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_object) rs = RadioSetting("aprs.filter_object", "Receive Object Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_item) rs = RadioSetting("aprs.filter_item", "Receive Item Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_status) rs = RadioSetting("aprs.filter_status", "Receive Status Beacons", val) menu.append(rs) val = RadioSettingValueBoolean(aprs.filter_other) rs = RadioSetting("aprs.filter_other", "Receive Other Beacons", val) menu.append(rs) return menu def _get_aprs_tx_settings(self): menu = RadioSettingGroup("aprs_tx", "APRS Transmit") aprs = self._memobj.aprs aprs2 = self._memobj.aprs2 beacon_type = (aprs.tx_smartbeacon << 1) | aprs.tx_interval_beacon val = RadioSettingValueList( self._BEACON_TYPE, self._BEACON_TYPE[beacon_type]) rs = RadioSetting("aprs.transmit", "TX Beacons", val) rs.set_apply_callback(self.apply_beacon_type, aprs) menu.append(rs) val = RadioSettingValueList( self._TX_DELAY, self._TX_DELAY[aprs.tx_delay]) rs = RadioSetting("aprs.tx_delay", "TX Delay", val) menu.append(rs) val = RadioSettingValueList( self._BEACON_INT, self._BEACON_INT[aprs.beacon_interval]) rs = RadioSetting("aprs.beacon_interval", "Beacon Interval", val) menu.append(rs) desc = [] status = [m.padded_string for m in self._memobj.aprs_beacon_status_txt] status = self._strip_ff_pads(status) for index, msg_text in enumerate(status): val = RadioSettingValueString(0, 60, msg_text) desc.append("Beacon Status Text %d" % (index + 1)) rs = RadioSetting("aprs_beacon_status_txt_%d" % index, desc[-1], val) rs.set_apply_callback(self.apply_ff_padded_string, self._memobj.aprs_beacon_status_txt[index]) menu.append(rs) val = RadioSettingValueList(desc, desc[aprs.selected_beacon_status_txt]) rs = RadioSetting("aprs.selected_beacon_status_txt", "Beacon Status Text", val) menu.append(rs) message_macro = [m.padded_string for m in self._memobj.aprs_msg_macro] message_macro = self._strip_ff_pads(message_macro) for index, msg_text in enumerate(message_macro): val = RadioSettingValueString(0, 16, msg_text) rs = RadioSetting("aprs_msg_macro_%d" % index, "Message Macro %d" % (index + 1), val) rs.set_apply_callback(self.apply_ff_padded_string, self._memobj.aprs_msg_macro[index]) menu.append(rs) path_str = list(self._DIGI_PATHS) path_str[7] = self._digi_path_to_str(aprs.digi_path_7) val = RadioSettingValueString(0, 88, path_str[7]) rs = RadioSetting("aprs.digi_path_7", "Digi Path 8 (8 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_7) menu.append(rs) # Show friendly messages for empty slots rather than blanks. # TODO: Rebuild this when digi_path_[34567] change. # path_str[3] = path_str[3] or self._DIGI_PATHS[3] # path_str[4] = path_str[4] or self._DIGI_PATHS[4] # path_str[5] = path_str[5] or self._DIGI_PATHS[5] # path_str[6] = path_str[6] or self._DIGI_PATHS[6] # path_str[7] = path_str[7] or self._DIGI_PATHS[7] path_str[7] = self._DIGI_PATHS[7] val = RadioSettingValueList(path_str, path_str[aprs2.selected_digi_path]) rs = RadioSetting("aprs2.selected_digi_path", "Selected Digi Path", val) menu.append(rs) return menu def _get_dtmf_settings(self): menu = RadioSettingGroup("dtmf_settings", "DTMF") dtmf = self._memobj.scan_settings val = RadioSettingValueList( self._DTMF_MODE, self._DTMF_MODE[dtmf.dtmf_mode]) rs = RadioSetting("scan_settings.dtmf_mode", "DTMF Mode", val) menu.append(rs) val = RadioSettingValueList( self._DTMF_SPEED, self._DTMF_SPEED[dtmf.dtmf_speed]) rs = RadioSetting("scan_settings.dtmf_speed", "DTMF AutoDial Speed", val) menu.append(rs) val = RadioSettingValueList( self._DTMF_DELAY, self._DTMF_DELAY[dtmf.dtmf_delay]) rs = RadioSetting("scan_settings.dtmf_delay", "DTMF AutoDial Delay", val) menu.append(rs) for i in range(10): name = "dtmf_%02d" % i dtmfsetting = self._memobj.dtmf[i] dtmfstr = "" for c in dtmfsetting.memory: if c == 0xFF: break if c < len(VX8_DTMF_CHARS): dtmfstr += VX8_DTMF_CHARS[c] dtmfentry = RadioSettingValueString(0, 16, dtmfstr) dtmfentry.set_charset(VX8_DTMF_CHARS + list("abcd ")) rs = RadioSetting(name, name.upper(), dtmfentry) rs.set_apply_callback(self.apply_dtmf, i) menu.append(rs) return menu def _get_misc_settings(self): menu = RadioSettingGroup("misc_settings", "Misc") scan_settings = self._memobj.scan_settings val = RadioSettingValueList( self._LCD_DIMMER, self._LCD_DIMMER[scan_settings.lcd_dimmer]) rs = RadioSetting("scan_settings.lcd_dimmer", "LCD Dimmer", val) menu.append(rs) val = RadioSettingValueList( self._LCD_CONTRAST, self._LCD_CONTRAST[scan_settings.lcd_contrast - 1]) rs = RadioSetting("scan_settings.lcd_contrast", "LCD Contrast", val) rs.set_apply_callback(self.apply_lcd_contrast, scan_settings) menu.append(rs) val = RadioSettingValueList( self._LAMP_KEY, self._LAMP_KEY[scan_settings.lamp]) rs = RadioSetting("scan_settings.lamp", "Lamp", val) menu.append(rs) beep_select = self._memobj.beep_select val = RadioSettingValueList( self._BEEP_SELECT, self._BEEP_SELECT[beep_select.beep]) rs = RadioSetting("beep_select.beep", "Beep Select", val) menu.append(rs) opening_message = self._memobj.opening_message val = RadioSettingValueList( self._OPENING_MESSAGE, self._OPENING_MESSAGE[opening_message.flag]) rs = RadioSetting("opening_message.flag", "Opening Msg Mode", val) menu.append(rs) msg = "" for i in opening_message.message.padded_yaesu: if i == 0xFF: break msg += CHARSET[i & 0x7F] val = RadioSettingValueString(0, 16, msg) rs = RadioSetting("opening_message.message.padded_yaesu", "Opening Message", val) rs.set_apply_callback(self.apply_ff_padded_yaesu, opening_message.message) menu.append(rs) return menu def _get_scan_settings(self): menu = RadioSettingGroup("scan_settings", "Scan") scan_settings = self._memobj.scan_settings val = RadioSettingValueList( self._VOL_MODE, self._VOL_MODE[scan_settings.vol_mode]) rs = RadioSetting("scan_settings.vol_mode", "Volume Mode", val) menu.append(rs) vfoa = self._memobj.vfo_info[0] val = RadioSettingValueList( self._VOLUME, self._VOLUME[vfoa.volume]) rs = RadioSetting("vfo_info[0].volume", "VFO A Volume", val) rs.set_apply_callback(self.apply_volume, 0) menu.append(rs) vfob = self._memobj.vfo_info[1] val = RadioSettingValueList( self._VOLUME, self._VOLUME[vfob.volume]) rs = RadioSetting("vfo_info[1].volume", "VFO B Volume", val) rs.set_apply_callback(self.apply_volume, 1) menu.append(rs) squelch = self._memobj.squelch val = RadioSettingValueList( self._SQUELCH, self._SQUELCH[squelch.vfo_a]) rs = RadioSetting("squelch.vfo_a", "VFO A Squelch", val) menu.append(rs) val = RadioSettingValueList( self._SQUELCH, self._SQUELCH[squelch.vfo_b]) rs = RadioSetting("squelch.vfo_b", "VFO B Squelch", val) menu.append(rs) val = RadioSettingValueList( self._SCAN_RESTART, self._SCAN_RESTART[scan_settings.scan_restart]) rs = RadioSetting("scan_settings.scan_restart", "Scan Restart", val) menu.append(rs) val = RadioSettingValueList( self._SCAN_RESUME, self._SCAN_RESUME[scan_settings.scan_resume]) rs = RadioSetting("scan_settings.scan_resume", "Scan Resume", val) menu.append(rs) val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.busy_led]) rs = RadioSetting("scan_settings.busy_led", "Busy LED", val) menu.append(rs) val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.scan_lamp]) rs = RadioSetting("scan_settings.scan_lamp", "Scan Lamp", val) menu.append(rs) val = RadioSettingValueList( self._TOT_TIME, self._TOT_TIME[scan_settings.tot]) rs = RadioSetting("scan_settings.tot", "Transmit Timeout (TOT)", val) menu.append(rs) return menu def _get_settings(self): top = RadioSettings(self._get_aprs_general_settings(), self._get_aprs_rx_settings(), self._get_aprs_tx_settings(), self._get_dtmf_settings(), self._get_misc_settings(), self._get_scan_settings()) return top def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None @staticmethod def apply_custom_symbol(setting, obj): # Ensure new value falls within known bounds, otherwise leave it as # it's a custom value from the radio that's outside our list. if setting.value.get_value() in chirp_common.APRS_SYMBOLS: setattr(obj, "custom_symbol", chirp_common.APRS_SYMBOLS.index(setting.value.get_value())) @classmethod def _apply_callsign(cls, callsign, obj, default_ssid=None): ssid = default_ssid dash_index = callsign.find("-") if dash_index >= 0: ssid = callsign[dash_index + 1:] callsign = callsign[:dash_index] try: ssid = int(ssid) % 16 except ValueError: ssid = default_ssid setattr(obj, "callsign", cls._add_ff_pad(callsign, 6)) if ssid is not None: setattr(obj, "ssid", ssid) def apply_beacon_type(cls, setting, obj): beacon_type = str(setting.value.get_value()) beacon_index = cls._BEACON_TYPE.index(beacon_type) tx_smartbeacon = beacon_index >> 1 tx_interval_beacon = beacon_index & 1 if tx_interval_beacon: setattr(obj, "tx_interval_beacon", 1) setattr(obj, "tx_smartbeacon", 0) elif tx_smartbeacon: setattr(obj, "tx_interval_beacon", 0) setattr(obj, "tx_smartbeacon", 1) else: setattr(obj, "tx_interval_beacon", 0) setattr(obj, "tx_smartbeacon", 0) @classmethod def apply_callsign(cls, setting, obj, default_ssid=None): # Uppercase, strip SSID then FF pad to max string length. callsign = setting.value.get_value().upper() cls._apply_callsign(callsign, obj, default_ssid) def apply_digi_path(self, setting, obj): # Parse and map to aprs.digi_path_4_7[0-3] or aprs.digi_path_8 # and FF terminate. path = str(setting.value.get_value()) callsigns = [c.strip() for c in path.split(",")] for index in range(len(obj.entry)): try: self._apply_callsign(callsigns[index], obj.entry[index], 0) except IndexError: self._apply_callsign("", obj.entry[index], 0) if len(callsigns) > len(obj.entry): raise Exception("This path only supports %d entries" % (index + 1)) @classmethod def apply_ff_padded_string(cls, setting, obj): # FF pad. val = setting.value.get_value() max_len = getattr(obj, "padded_string").size() / 8 val = str(val).rstrip() setattr(obj, "padded_string", cls._add_ff_pad(val, max_len)) @classmethod def apply_lat_long(cls, setting, obj): name = setting.get_name() is_latitude = name.endswith("latitude") lat_long = setting.value.get_value().strip() sign, l_d, l_m, l_s = cls._str_to_latlong(lat_long, is_latitude) LOG.debug("%s: %d %d %d %d" % (name, sign, l_d, l_m, l_s)) setattr(obj, "%s_sign" % name, sign) setattr(obj, "%s_degree" % name, l_d) setattr(obj, "%s_minute" % name, l_m) setattr(obj, "%s_second" % name, l_s) def set_settings(self, settings): _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: if element.has_apply_callback(): LOG.debug("Using apply callback") try: element.run_apply_callback() except NotImplementedError as e: LOG.error("vx8.set_settings: %s", e) continue # Find the object containing setting. obj = _mem bits = element.get_name().split(".") setting = bits[-1] for name in bits[:-1]: if name.endswith("]"): name, index = name.split("[") index = int(index[:-1]) obj = getattr(obj, name)[index] else: obj = getattr(obj, name) try: old_val = getattr(obj, setting) LOG.debug("Setting %s(%r) <= %s" % ( element.get_name(), old_val, element.value)) setattr(obj, setting, element.value) except AttributeError as e: LOG.error("Setting %s is not in the memory map: %s" % (element.get_name(), e)) except Exception: LOG.debug(element.get_name()) raise def apply_ff_padded_yaesu(cls, setting, obj): # FF pad yaesus custom string format. rawval = setting.value.get_value() max_len = getattr(obj, "padded_yaesu").size() / 8 rawval = str(rawval).rstrip() val = [CHARSET.index(x) for x in rawval] for x in range(len(val), max_len): val.append(0xFF) obj.padded_yaesu = val def apply_volume(cls, setting, vfo): val = setting.value.get_value() cls._memobj.vfo_info[(vfo*2)].volume = val cls._memobj.vfo_info[(vfo*2)+1].volume = val def apply_lcd_contrast(cls, setting, obj): rawval = setting.value.get_value() val = cls._LCD_CONTRAST.index(rawval) + 1 obj.lcd_contrast = val def apply_dtmf(cls, setting, i): rawval = setting.value.get_value().upper().rstrip() val = [VX8_DTMF_CHARS.index(x) for x in rawval] for x in range(len(val), 16): val.append(0xFF) cls._memobj.dtmf[i].memory = val @directory.register class VX8DRadio(VX8Radio): """Yaesu VX-8DR""" MODEL = "VX-8DR" _model = b"AH29D" _mem_params = (0xC128, # APRS message macros 7, # Number of message macros 0xC198, # APRS2 0xC24A, # APRS beacon metadata address. 50, # Number of beacons stored. 0xC6FA, # APRS beacon content address. 146, # Length of beacon data stored. 50) # Number of beacons stored. _TX_DELAY = ("100ms", "150ms", "200ms", "250ms", "300ms", "400ms", "500ms", "750ms", "1000ms") _BEACON_TYPE = ("Off", "Interval", "SmartBeaconing") _SMARTBEACON_PROFILE = ("Off", "Type 1", "Type 2", "Type 3") _POSITIONS = ("GPS", "Manual Latitude/Longitude", "Manual Latitude/Longitude", "P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9") _FLASH = ("OFF", "2 seconds", "4 seconds", "6 seconds", "8 seconds", "10 seconds", "20 seconds", "30 seconds", "60 seconds", "CONTINUOUS", "every 2 seconds", "every 3 seconds", "every 4 seconds", "every 5 seconds", "every 6 seconds", "every 7 seconds", "every 8 seconds", "every 9 seconds", "every 10 seconds", "every 20 seconds", "every 30 seconds", "every 40 seconds", "every 50 seconds", "every minute", "every 2 minutes", "every 3 minutes", "every 4 minutes", "every 5 minutes", "every 6 minutes", "every 7 minutes", "every 8 minutes", "every 9 minutes", "every 10 minutes") _LCD_CONTRAST = ["Level %d" % x for x in range(1, 16)] _MY_SYMBOL = ("/[ Person", "/b Bike", "/> Car", "User selected") def _get_aprs_tx_settings(self): menu = RadioSettingGroup("aprs_tx", "APRS Transmit") aprs = self._memobj.aprs aprs2 = self._memobj.aprs2 beacon_type = (aprs.tx_smartbeacon << 1) | aprs.tx_interval_beacon val = RadioSettingValueList( self._BEACON_TYPE, self._BEACON_TYPE[beacon_type]) rs = RadioSetting("aprs.transmit", "TX Beacons", val) rs.set_apply_callback(self.apply_beacon_type, aprs) menu.append(rs) val = RadioSettingValueList( self._TX_DELAY, self._TX_DELAY[aprs.tx_delay]) rs = RadioSetting("aprs.tx_delay", "TX Delay", val) menu.append(rs) val = RadioSettingValueList( self._BEACON_INT, self._BEACON_INT[aprs.beacon_interval]) rs = RadioSetting("aprs.beacon_interval", "Beacon Interval", val) menu.append(rs) desc = [] status = [m.padded_string for m in self._memobj.aprs_beacon_status_txt] status = self._strip_ff_pads(status) for index, msg_text in enumerate(status): val = RadioSettingValueString(0, 60, msg_text) desc.append("Beacon Status Text %d" % (index + 1)) rs = RadioSetting("aprs_beacon_status_txt_%d" % index, desc[-1], val) rs.set_apply_callback(self.apply_ff_padded_string, self._memobj.aprs_beacon_status_txt[index]) menu.append(rs) val = RadioSettingValueList(desc, desc[aprs.selected_beacon_status_txt]) rs = RadioSetting("aprs.selected_beacon_status_txt", "Beacon Status Text", val) menu.append(rs) message_macro = [m.padded_string for m in self._memobj.aprs_msg_macro] message_macro = self._strip_ff_pads(message_macro) for index, msg_text in enumerate(message_macro): val = RadioSettingValueString(0, 16, msg_text) rs = RadioSetting("aprs_msg_macro_%d" % index, "Message Macro %d" % (index + 1), val) rs.set_apply_callback(self.apply_ff_padded_string, self._memobj.aprs_msg_macro[index]) menu.append(rs) path_str = list(self._DIGI_PATHS) path_str[3] = self._digi_path_to_str(aprs2.digi_path_3_6[0]) val = RadioSettingValueString(0, 22, path_str[3]) rs = RadioSetting("aprs2.digi_path_3", "Digi Path 4 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs2.digi_path_3_6[0]) menu.append(rs) path_str[4] = self._digi_path_to_str(aprs2.digi_path_3_6[1]) val = RadioSettingValueString(0, 22, path_str[4]) rs = RadioSetting("aprs2.digi_path_4", "Digi Path 5 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs2.digi_path_3_6[1]) menu.append(rs) path_str[5] = self._digi_path_to_str(aprs2.digi_path_3_6[2]) val = RadioSettingValueString(0, 22, path_str[5]) rs = RadioSetting("aprs2.digi_path_5", "Digi Path 6 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs2.digi_path_3_6[2]) menu.append(rs) path_str[6] = self._digi_path_to_str(aprs2.digi_path_3_6[3]) val = RadioSettingValueString(0, 22, path_str[6]) rs = RadioSetting("aprs2.digi_path_6", "Digi Path 7 (2 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs2.digi_path_3_6[3]) menu.append(rs) path_str[7] = self._digi_path_to_str(aprs.digi_path_7) val = RadioSettingValueString(0, 88, path_str[7]) rs = RadioSetting("aprs.digi_path_7", "Digi Path 8 (8 entries)", val) rs.set_apply_callback(self.apply_digi_path, aprs.digi_path_7) menu.append(rs) # Show friendly messages for empty slots rather than blanks. # TODO: Rebuild this when digi_path_[34567] change. # path_str[3] = path_str[3] or self._DIGI_PATHS[3] # path_str[4] = path_str[4] or self._DIGI_PATHS[4] # path_str[5] = path_str[5] or self._DIGI_PATHS[5] # path_str[6] = path_str[6] or self._DIGI_PATHS[6] # path_str[7] = path_str[7] or self._DIGI_PATHS[7] path_str[3] = self._DIGI_PATHS[3] path_str[4] = self._DIGI_PATHS[4] path_str[5] = self._DIGI_PATHS[5] path_str[6] = self._DIGI_PATHS[6] path_str[7] = self._DIGI_PATHS[7] val = RadioSettingValueList(path_str, path_str[aprs2.selected_digi_path]) rs = RadioSetting("aprs2.selected_digi_path", "Selected Digi Path", val) menu.append(rs) return menu def _get_aprs_smartbeacon(self): menu = RadioSettingGroup("aprs_smartbeacon", "APRS SmartBeacon") aprs2 = self._memobj.aprs2 val = RadioSettingValueList( self._SMARTBEACON_PROFILE, self._SMARTBEACON_PROFILE[aprs2.active_smartbeaconing]) rs = RadioSetting("aprs2.active_smartbeaconing", "SmartBeacon profile", val) menu.append(rs) for profile in range(3): pfx = "type%d" % (profile + 1) path = "aprs2.smartbeaconing_profile[%d]" % profile prof = aprs2.smartbeaconing_profile[profile] low_val = RadioSettingValueInteger(2, 30, prof.low_speed_mph) high_val = RadioSettingValueInteger(3, 70, prof.high_speed_mph) low_val.get_max = lambda: min(30, int(high_val.get_value()) - 1) rs = RadioSetting("%s.low_speed_mph" % path, "%s Low Speed (mph)" % pfx, low_val) menu.append(rs) rs = RadioSetting("%s.high_speed_mph" % path, "%s High Speed (mph)" % pfx, high_val) menu.append(rs) val = RadioSettingValueInteger(1, 100, prof.slow_rate_min) rs = RadioSetting("%s.slow_rate_min" % path, "%s Slow rate (minutes)" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(10, 180, prof.fast_rate_sec) rs = RadioSetting("%s.fast_rate_sec" % path, "%s Fast rate (seconds)" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(5, 90, prof.turn_angle) rs = RadioSetting("%s.turn_angle" % path, "%s Turn angle (degrees)" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(1, 255, prof.turn_slop) rs = RadioSetting("%s.turn_slop" % path, "%s Turn slop" % pfx, val) menu.append(rs) val = RadioSettingValueInteger(5, 180, prof.turn_time_sec) rs = RadioSetting("%s.turn_time_sec" % path, "%s Turn time (seconds)" % pfx, val) menu.append(rs) return menu def _get_settings(self): top = RadioSettings(self._get_aprs_general_settings(), self._get_aprs_rx_settings(), self._get_aprs_tx_settings(), self._get_aprs_smartbeacon(), self._get_dtmf_settings(), self._get_misc_settings(), self._get_scan_settings()) return top @directory.register class VX8GERadio(VX8DRadio): """Yaesu VX-8GE""" MODEL = "VX-8GE" _model = b"AH041" _has_vibrate = True _has_af_dual = False chirp-20240224/chirp/drivers/th_uv8000.py0000644000175000017500000014325514566340166016653 0ustar hibbyhibby# Copyright 2019: Rick DeWitt (RJD), # Version 1.0 for TYT-UV8000D/E # 1.1 Fixes issue #8339, Priority chan OFF (0) # Thanks to Damon Schaefer (K9CQB) and the Loudoun County, VA ARES # club for the donated radio. # And thanks to Ian Harris (VA3IHX) for decoding the memory map. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging import math from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct chns { ul32 rxfreq; ul32 txfreq; u8 rxtone[2]; u8 txtone[2]; u8 wide:1, // 0x0c vox_on:1, chunk01:1, bcl:1, // inv bool epilogue:1, power:1, chunk02:1, chunk03:1; u8 ani:1, // 0x0d inv chunk08:1, ptt:2, chpad04:4; u8 chunk05; // 0x0e u16 id_code; // 0x0f, 10 u8 chunk06; u8 name[7]; ul32 chpad06; // Need 56 byte pad ul16 chpad07; u8 chpad08; }; struct fm_chn { ul16 rxfreq; }; struct frqx { ul32 rxfreq; ul24 ofst; u8 fqunk01:4, // 0x07 funk10:2, duplx:2; u8 rxtone[2]; // 0x08, 9 u8 txtone[2]; // 0x0a, b u8 wide:1, // 0x0c vox_on:1, funk11:1, bcl:1, // inv bool epilogue:1, power:1, fqunk02:2; u8 ani:1, // 0x0d inv bool fqunk03:1, ptt:2, fqunk12:1, fqunk04:3; u8 fqunk07; // 0x0e u16 id_code; // 0x0f, 0x10 u8 name[7]; // dummy u8 fqunk09[8]; // empty bytes after 1st entry }; struct bitmap { u8 map[16]; }; #seekto 0x0010; struct chns chan_mem[128]; struct frqx frq[2]; struct fm_chn fm_stations[25]; struct { u8 fmunk01[14]; ul16 fmcur; } fmfrqs; #seekto 0x1190; struct bitmap chnmap; struct bitmap skpchns; struct { u8 fmset[4]; } fmmap; struct { u8 setunk01[4]; u8 setunk02[3]; u8 chs_name:1, // 0x11bb txsel:1, dbw:1, setunk05:1, ponfmchs:2, ponchs:2; u8 voltx:2, // 0x11bc setunk04:1, keylok:1, setunk07:1, batsav:3; u8 setunk09:1, // 0x11bd rxinhib:1, rgrbeep:1, // inv bool lampon:2, voice:2, beepon:1; u8 setunk11:1, // 0x11be manualset:1, xbandon:1, // inv xbandenable:1, openmsg:2, ledclr:2; u8 tot:4, // 0x11bf sql:4; u8 setunk27:1, // 0x11c0 voxdelay:2, setunk31:1, voxgain:4; u8 fmstep:4, // 0x11c1 freqstep:4; u8 scanspeed:4, // 0x11c2 scanmode:4; u8 scantmo; // 0x11c3 u8 prichan; // 0x11c4 u8 setunk12:4, // 0x11c5 supersave:4; u8 setunk13; u8 fmsclo; // 0x11c7 ??? placeholder u8 radioname[7]; // hex char codes, not true ASCII u8 fmschi; // ??? placeholder u8 setunk14[3]; // 0x11d0 u8 setunk17[2]; // 0x011d3, 4 u8 setunk18:4, dtmfspd:4; u8 dtmfdig1dly:4, // 0x11d6 dtmfdig1time:4; u8 stuntype:1, setunk19:1, dtmfspms:2, grpcode:4; u8 setunk20:1, // 0x11d8 txdecode:1, codeabcd:1, idedit:1, pttidon:2, setunk40:1, dtmfside:1; u8 setunk50:4, autoresettmo:4; u8 codespctim:4, // 0x11da decodetmo:4; u8 pttecnt:4, // 0x11db pttbcnt:4; lbcd dtmfdecode[3]; u8 setunk22; u8 stuncnt; // 0x11e0 u8 stuncode[5]; u8 setunk60; u8 setunk61; u8 pttbot[8]; // 0x11e8-f u8 ptteot[8]; // 0x11f0-7 u8 setunk62; // 0x11f8 u8 setunk63; u8 setunk64; // 0x11fa u8 setunk65; u8 setunk66; u8 manfrqyn; // 0x11fd u8 setunk30:3, frqr3:1, setunk28:1, frqr2:1, setunk29:1, frqr1:1; u8 setunk25; ul32 frqr1lo; // 0x1200 ul32 frqr1hi; ul32 frqr2lo; ul32 frqr2hi; ul32 frqr3lo; // 0x1210 ul32 frqr3hi; u8 setunk26[8]; } setstuf; #seekto 0x1260; struct { u8 modnum[7]; } modcode; #seekto 0x1300; struct { char mod_num[9]; } mod_id; """ MEM_SIZE = 0x1300 BLOCK_SIZE = 0x10 # can read 0x20, but must write 0x10 STIMEOUT = 2 BAUDRATE = 4800 # Channel power: 2 levels POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5.00), chirp_common.PowerLevel("High", watts=10.00)] LIST_RECVMODE = ["QT/DQT", "QT/DQT + Signaling"] LIST_COLOR = ["Off", "Orange", "Blue", "Purple"] LIST_LEDSW = ["Auto", "On"] LIST_TIMEOUT = ["Off"] + ["%s" % x for x in range(30, 390, 30)] LIST_VFOMODE = ["Frequency Mode", "Channel Mode"] # Tones are numeric, Defined in \chirp\chirp_common.py TONES_CTCSS = sorted(chirp_common.TONES) # Converted to strings LIST_CTCSS = ["Off"] + [str(x) for x in TONES_CTCSS] # Now append the DxxxN and DxxxI DTCS codes from chirp_common for x in chirp_common.DTCS_CODES: LIST_CTCSS.append("D{:03d}N".format(x)) for x in chirp_common.DTCS_CODES: LIST_CTCSS.append("D{:03d}R".format(x)) LIST_BW = ["Narrow", "Wide"] LIST_SHIFT = ["off", "+", "-", ""] STEPS = [0.5, 2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 37.5, 50.0, 100.0] LIST_STEPS = [str(x) for x in STEPS] LIST_VOXDLY = ["0.5", "1.0", "2.0", "3.0"] # LISTS must be strings LIST_PTT = ["Both", "EoT", "BoT", "Off"] def _clean_buffer(radio): radio.pipe.timeout = 0.005 junk = radio.pipe.read(256) radio.pipe.timeout = STIMEOUT if junk: LOG.debug("Got %i bytes of junk before starting" % len(junk)) def _rawrecv(radio, amount): """Raw read from the radio device""" data = "" try: data = radio.pipe.read(amount) except Exception: _exit_program_mode(radio) msg = "Generic error reading data from radio; check your cable." raise errors.RadioError(msg) if len(data) != amount: _exit_program_mode(radio) msg = "Error reading from radio: not the amount of data we want." raise errors.RadioError(msg) return data def _rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) except Exception: raise errors.RadioError("Error sending data to radio") def _make_frame(cmd, addr, length, data=""): """Pack the info in the header format""" frame = struct.pack(">shB", cmd, addr, length) # Add the data if set if len(data) != 0: frame += data # Return the data return frame def _recv(radio, addr, length): """Get data from the radio """ data = _rawrecv(radio, length) # DEBUG LOG.info("Response:") LOG.debug(util.hexprint(data)) return data def _do_ident(radio): """Put the radio in PROGRAM mode & identify it""" radio.pipe.baudrate = BAUDRATE radio.pipe.parity = "N" radio.pipe.timeout = STIMEOUT # Flush input buffer _clean_buffer(radio) magic = b"PROGRAMa" _rawsend(radio, magic) ack = _rawrecv(radio, 1) # LOG.warning("PROGa Ack:" + util.hexprint(ack)) if ack != b"\x06": _exit_program_mode(radio) if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond") magic = b"PROGRAMb" _rawsend(radio, magic) ack = _rawrecv(radio, 1) if ack != b"\x06": _exit_program_mode(radio) if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond to B") magic = b"\x02" _rawsend(radio, magic) ack = _rawrecv(radio, 1) # s/b: 0x50 magic = _rawrecv(radio, 7) # s/b TC88... magic = b"MTC88CUMHS3E7BN-" _rawsend(radio, magic) ack = _rawrecv(radio, 1) # s/b 0x80 magic = b"\x06" _rawsend(radio, magic) ack = _rawrecv(radio, 1) return True def _exit_program_mode(radio): endframe = b"E" _rawsend(radio, endframe) def _download(radio): """Get the memory map""" # Put radio in program mode and identify it _do_ident(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data = b"" for addr in range(0, MEM_SIZE, BLOCK_SIZE): frame = _make_frame(b"R", addr, BLOCK_SIZE) # DEBUG LOG.info("Request sent:") LOG.debug("Frame=" + util.hexprint(frame)) # Sending the read request _rawsend(radio, frame) dx = _rawrecv(radio, 4) # Now we read data d = _recv(radio, addr, BLOCK_SIZE) # LOG.warning("Data= " + util.hexprint(d)) # Aggregate the data data += d # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) _exit_program_mode(radio) return data def _upload(radio): """Upload procedure""" # Put radio in program mode and identify it _do_ident(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) # The fun starts here for addr in range(0, MEM_SIZE, BLOCK_SIZE): # Sending the data data = radio.get_mmap()[addr:addr + BLOCK_SIZE] frame = _make_frame(b"W", addr, BLOCK_SIZE, data) # LOG.warning("Frame:%s:" % util.hexprint(frame)) _rawsend(radio, frame) # Receiving the response ack = _rawrecv(radio, 1) if ack != b"\x06": _exit_program_mode(radio) msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) _exit_program_mode(radio) def set_tone(_mem, txrx, ctdt, tval, pol): """Set rxtone[] or txtone[] word values as decimal bytes""" # txrx: Boolean T= set Rx tones, F= set Tx tones # ctdt: Boolean T = CTCSS, F= DTCS # tval = integer tone freq (*10) or DTCS code # pol = string for DTCS polarity "R" or "N" xv = int(str(tval), 16) if txrx: # True = set rxtones _mem.rxtone[0] = xv & 0xFF # Low byte _mem.rxtone[1] = (xv >> 8) # Hi byte if not ctdt: # dtcs, if pol == "R": _mem.rxtone[1] = _mem.rxtone[1] | 0xC0 else: _mem.rxtone[1] = _mem.rxtone[1] | 0x80 else: # txtones _mem.txtone[0] = xv & 0xFF # Low byte _mem.txtone[1] = (xv >> 8) if not ctdt: # dtcs if pol == "R": _mem.txtone[1] = _mem.txtone[1] | 0xC0 else: _mem.txtone[1] = _mem.txtone[1] | 0x80 return 0 def _do_map(chn, sclr, mary): """Set or Clear the chn (1-128) bit in mary[] word array map""" # chn is 1-based channel, sclr:1 = set, 0= = clear, 2= return state # mary[] is u8 array, but the map is by nibbles ndx = int(math.floor((chn - 1) / 8)) bv = (chn - 1) % 8 msk = 1 << bv mapbit = sclr if sclr == 1: # Set the bit mary[ndx] = mary[ndx] | msk elif sclr == 0: # clear mary[ndx] = mary[ndx] & (~ msk) # ~ is complement else: # return current bit state mapbit = 0 if (mary[ndx] & msk) > 0: mapbit = 1 return mapbit @directory.register class THUV8000Radio(chirp_common.CloneModeRadio): """TYT UV8000D Radio""" VENDOR = "TYT" MODEL = "TH-UV8000" NEEDS_COMPAT_SERIAL = False MODES = ["NFM", "FM"] TONES = chirp_common.TONES DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) NAME_LENGTH = 7 DTMF_CHARS = list("0123456789ABCD*#") # NOTE: SE Model supports 220-260 MHz # The following bands are the the range the radio is capable of, # not the legal FCC amateur bands VALID_BANDS = [(87500000, 107900000), (136000000, 174000000), (220000000, 260000000), (400000000, 520000000)] # Valid chars on the LCD VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`!\"#$%&'()*+,-./:;<=>?@[]^_" # Special Channels Declaration # WARNING Indecis are hard wired in get/set_memory code !!! # Channels print in + increasing index order (most negative first) SPECIAL_MEMORIES = { "UpVFO": -2, "LoVFO": -1 } FIRST_FREQ_INDEX = -1 LAST_FREQ_INDEX = -2 SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys())) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = \ ('Remember the # T-R key is the VFO/MEM toggle.\n') rp.pre_download = _( "Follow these instructions to download the radio memory:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio, volume @ 50%\n" "4 - CHIRP Menu - Radio - Download from radio\n") rp.pre_upload = _( "Follow these instructions to upload the radio memory:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio, volume @ 50%\n" "4 - CHIRP Menu - Radio - Upload to radio\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() # .has. attributes are boolean, .valid. are lists rf.has_settings = True rf.has_bank = False rf.has_comment = False rf.has_nostep_tuning = True # Radio accepts any entered freq rf.has_tuning_step = False # Not as chan feature rf.can_odd_split = False rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.has_sub_devices = False rf.valid_name_length = self.NAME_LENGTH rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_duplexes = ["-", "+", "off", ""] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ["Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = [] rf.valid_power_levels = POWER_LEVELS rf.valid_dtcs_codes = self.DTCS_CODES rf.valid_bands = self.VALID_BANDS rf.memory_bounds = (1, 128) rf.valid_skips = ["", "S"] rf.valid_special_chans = sorted(self.SPECIAL_MEMORIES.keys()) return rf def sync_in(self): """Download from radio""" try: data = _download(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.chan_mem[number - 1]) def get_memory(self, number): if isinstance(number, str): return self._get_special(number) elif number < 0: # I can't stop delete operation from losing extd_number but # I know how to get it back return self._get_special(self.SPECIAL_MEMORIES_REV[number]) else: return self._get_normal(number) def set_memory(self, memory): """A value in a UI column for chan 'number' has been modified.""" # update all raw channel memory values (_mem) from UI (mem) if memory.number < 0: return self._set_special(memory) else: return self._set_normal(memory) def _get_normal(self, number): # radio first channel is 1, mem map is base 0 _mem = self._memobj.chan_mem[number - 1] mem = chirp_common.Memory() mem.number = number return self._get_memory(mem, _mem) def _get_memory(self, mem, _mem): """Convert raw channel memory data into UI columns""" mem.extra = RadioSettingGroup("extra", "Extra") if _mem.get_raw()[0] == 0xff: mem.empty = True return mem mem.empty = False # This function process both 'normal' and Freq up/down' entries mem.freq = int(_mem.rxfreq) * 10 mem.power = POWER_LEVELS[_mem.power] mem.mode = self.MODES[_mem.wide] dtcs_pol = ["N", "N"] if _mem.rxtone[0] == 0xFF: rxmode = "" elif _mem.rxtone[1] < 0x26: # CTCSS rxmode = "Tone" tonehi = int(str(_mem.rxtone[1])[2:]) tonelo = int(str(_mem.rxtone[0])[2:]) mem.ctone = int(tonehi * 100 + tonelo) / 10.0 else: # Digital rxmode = "DTCS" tonehi = int(str(_mem.rxtone[1] & 0x3f)) tonelo = int(str(_mem.rxtone[0])[2:]) mem.rx_dtcs = int(tonehi * 100 + tonelo) if (_mem.rxtone[1] & 0x40) != 0: dtcs_pol[1] = "R" if _mem.txtone[0] == 0xFF: txmode = "" elif _mem.txtone[1] < 0x26: # CTCSS txmode = "Tone" tonehi = int(str(_mem.txtone[1])[2:]) tonelo = int(str(_mem.txtone[0])[2:]) mem.rtone = int(tonehi * 100 + tonelo) / 10.0 else: # Digital txmode = "DTCS" tonehi = int(str(_mem.txtone[1] & 0x3f)) tonelo = int(str(_mem.txtone[0])[2:]) mem.dtcs = int(tonehi * 100 + tonelo) if (_mem.txtone[1] & 0x40) != 0: dtcs_pol[0] = "R" mem.tmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) # Now test the mem.number to process special vs normal if mem.number >= 0: # Normal mem.name = "" for i in range(self.NAME_LENGTH): # 0 - 6 mem.name += chr(_mem.name[i] + 32) mem.name = mem.name.rstrip() # remove trailing spaces if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) \ and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 if _do_map(mem.number, 2, self._memobj.skpchns.map) > 0: mem.skip = "S" else: mem.skip = "" else: # specials VFO mem.name = "----" mem.duplex = LIST_SHIFT[_mem.duplx] mem.offset = int(_mem.ofst) * 10 mem.skip = "" # End if specials # Channel Extra settings: Only Boolean & List methods, no call-backs rx = RadioSettingValueBoolean(bool(not _mem.bcl)) # Inverted bool # NOTE: first param of RadioSetting is the object attribute name rset = RadioSetting("bcl", "Busy Channel Lockout", rx) mem.extra.append(rset) rx = RadioSettingValueBoolean(bool(not _mem.vox_on)) rset = RadioSetting("vox_on", "Vox", rx) mem.extra.append(rset) rx = RadioSettingValueBoolean(bool(not _mem.ani)) rset = RadioSetting("ani", "Auto Number ID (ANI)", rx) mem.extra.append(rset) # ID code can't be done in extra - no Integer method or call-back rx = RadioSettingValueList(LIST_PTT, LIST_PTT[_mem.ptt]) rset = RadioSetting("ptt", "Xmit PTT ID", rx) mem.extra.append(rset) rx = RadioSettingValueBoolean(bool(_mem.epilogue)) rset = RadioSetting("epilogue", "Epilogue/Tail", rx) mem.extra.append(rset) return mem def _get_special(self, number): mem = chirp_common.Memory() mem.number = self.SPECIAL_MEMORIES[number] mem.extd_number = number # Unused attributes are ignored in Set_memory if (mem.number == -1) or (mem.number == -2): # Print Upper[1] first, and Lower[0] next rx = 0 if mem.number == -2: rx = 1 _mem = self._memobj.frq[rx] # immutable = ["number", "extd_number", "name"] mem = self._get_memory(mem, _mem) else: raise Exception("Sorry, you can't edit that special" " memory channel %i." % mem.number) # mem.immutable = immutable return mem def _set_memory(self, mem, _mem): """Convert UI column data (mem) into MEM_FORMAT memory (_mem).""" # At this point mem points to either normal or Freq chans # These first attributes are common to all types if mem.empty: if mem.number > 0: _mem.rxfreq = 0xffffffff # Set 'empty' and 'skip' bits _do_map(mem.number, 1, self._memobj.chnmap.map) _do_map(mem.number, 1, self._memobj.skpchns.map) elif mem.number == -2: # upper VFO Freq _mem.rxfreq = 14652000 # VHF National Calling freq elif mem.number == -1: # lower VFO _mem.rxfreq = 44600000 # UHF National Calling freq return _mem.rxfreq = mem.freq / 10 if str(mem.power) == "Low": _mem.power = 0 else: _mem.power = 1 _mem.wide = self.MODES.index(mem.mode) rxmode = "" txmode = "" if mem.tmode == "Tone": txmode = "Tone" elif mem.tmode == "TSQL": rxmode = "Tone" txmode = "TSQL" elif mem.tmode == "DTCS": rxmode = "DTCSSQL" txmode = "DTCS" elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) sx = mem.dtcs_polarity[1] if rxmode == "": _mem.rxtone[0] = 0xFF _mem.rxtone[1] = 0xFF elif rxmode == "Tone": val = int(mem.ctone * 10) i = set_tone(_mem, True, True, val, sx) elif rxmode == "DTCSSQL": i = set_tone(_mem, True, False, mem.dtcs, sx) elif rxmode == "DTCS": i = set_tone(_mem, True, False, mem.rx_dtcs, sx) sx = mem.dtcs_polarity[0] if txmode == "": _mem.txtone[0] = 0xFF _mem.txtone[1] = 0xFF elif txmode == "Tone": val = int(mem.rtone * 10) i = set_tone(_mem, False, True, val, sx) elif txmode == "TSQL": val = int(mem.ctone * 10) i = set_tone(_mem, False, True, val, sx) elif txmode == "DTCS": i = set_tone(_mem, False, False, mem.dtcs, sx) if mem.number > 0: # Normal chans for i in range(self.NAME_LENGTH): pq = ord(mem.name.ljust(self.NAME_LENGTH)[i]) - 32 if pq < 0: pq = 0 _mem.name[i] = pq if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 # Set the channel map bit FALSE = Enabled _do_map(mem.number, 0, self._memobj.chnmap.map) # Skip if mem.skip == "S": _do_map(mem.number, 1, self._memobj.skpchns.map) else: _do_map(mem.number, 0, self._memobj.skpchns.map) else: # Freq (VFO) chans _mem.duplx = 0 _mem.ofst = 0 if mem.duplex == "+": _mem.duplx = 1 _mem.ofst = mem.offset / 10 elif mem.duplex == "-": _mem.duplx = 2 _mem.ofst = mem.offset / 10 for i in range(self.NAME_LENGTH): _mem.name[i] = 0xff # All mem.extra << Once the channel is defined for setting in mem.extra: # Override list strings with signed value if setting.get_name() == "ptt": sx = str(setting.value) for i in range(0, 4): if sx == LIST_PTT[i]: val = i setattr(_mem, "ptt", val) elif setting.get_name() == "epilogue": # not inverted bool setattr(_mem, setting.get_name(), setting.value) else: # inverted booleans setattr(_mem, setting.get_name(), not setting.value) def _set_special(self, mem): cur_mem = self._get_special(self.SPECIAL_MEMORIES_REV[mem.number]) if mem.number == -2: # upper frq[1] _mem = self._memobj.frq[1] elif mem.number == -1: # lower frq[0] _mem = self._memobj.frq[0] else: raise Exception("Sorry, you can't edit that special memory.") self._set_memory(mem, _mem) # Now update the _mem def _set_normal(self, mem): _mem = self._memobj.chan_mem[mem.number - 1] self._set_memory(mem, _mem) def get_settings(self): """Translate the MEM_FORMAT structs into setstuf in the UI""" # Define mem struct write-back shortcuts _sets = self._memobj.setstuf _fmx = self._memobj.fmfrqs basic = RadioSettingGroup("basic", "Basic Settings") adv = RadioSettingGroup("adv", "Other Settings") fmb = RadioSettingGroup("fmb", "FM Broadcast") scn = RadioSettingGroup("scn", "Scan Settings") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") frng = RadioSettingGroup("frng", "Frequency Ranges") group = RadioSettings(basic, adv, scn, fmb, dtmf, frng) def my_val_list(setting, obj, atrb): """Callback:from ValueList with non-sequential, actual values.""" # This call back also used in get_settings value = int(str(setting.value)) # Get the integer value setattr(obj, atrb, value) return def my_adjraw(setting, obj, atrb, fix): """Callback from Integer add or subtract fix from value.""" vx = int(str(setting.value)) value = vx + int(fix) if value < 0: value = 0 setattr(obj, atrb, value) return def my_strnam(setting, obj, atrb, mln): """Callback from String to build u8 array with -32 offset.""" # mln is max string length ary = [] knt = mln for j in range(mln - 1, -1, -1): # Strip trailing spaces or nulls pq = str(setting.value)[j] if pq == "" or pq == " ": knt = knt - 1 else: break for j in range(mln): # 0 to mln-1 pq = str(setting.value).ljust(mln)[j] if j < knt: ary.append(ord(pq) - 32) else: ary.append(0) setattr(obj, atrb, ary) return def unpack_str(cary, cknt, mxw): """Convert u8 nibble array to a string: NOT a callback.""" # cknt is char count, 2/word; mxw is max WORDS stx = "" mty = True for i in range(mxw): # unpack entire array nib = (cary[i] & 0xf0) >> 4 # LE, Hi nib first if nib != 0xf: mty = False stx += format(nib, '0X') nib = cary[i] & 0xf if nib != 0xf: mty = False stx += format(nib, '0X') stx = stx[:cknt] if mty: # all ff, empty string sty = "" else: # Convert E to #, F to * sty = "" for i in range(cknt): if stx[i] == "E": sty += "#" elif stx[i] == "F": sty += "*" else: sty += stx[i] return sty def pack_chars(setting, obj, atrstr, atrcnt, mxl): """Callback to build 0-9,A-D,*# nibble array from string""" # cknt is generated char count, 2 chars per word # String will be f padded to mxl # Chars are stored as hex values # store cknt-1 in atrcnt, 0xf if empty cknt = 0 ary = [] stx = str(setting.value).upper() stx = stx.strip() # trim spaces # Remove illegal characters first sty = "" for j in range(0, len(stx)): if stx[j] in self.DTMF_CHARS: sty += stx[j] for j in range(mxl): if j < len(sty): if sty[j] == "#": chrv = 0xE elif sty[j] == "*": chrv = 0xF else: chrv = int(sty[j], 16) cknt += 1 # char count else: # pad to mxl, cknt does not increment chrv = 0xF if (j % 2) == 0: # odd count (0-based), high nibble hi_nib = chrv else: # even count, lower nibble lo_nib = chrv nibs = lo_nib | (hi_nib << 4) ary.append(nibs) # append word setattr(obj, atrstr, ary) if setting.get_name() != "setstuf.stuncode": # cknt is actual if cknt > 0: cknt = cknt - 1 else: cknt = 0xf setattr(obj, atrcnt, cknt) return def myset_freq(setting, obj, atrb, mult): """ Callback to set frequency by applying multiplier""" value = int(float(str(setting.value)) * mult) setattr(obj, atrb, value) return def my_invbool(setting, obj, atrb): """Callback to invert the boolean """ bval = not setting.value setattr(obj, atrb, bval) return def my_batsav(setting, obj, atrb): """Callback to set batsav attribute """ stx = str(setting.value) # Off, 1:1... if stx == "Off": value = 0x1 # bit value 4 clear, ratio 1 = 1:2 elif stx == "1:1": value = 0x4 # On, ratio 0 = 1:1 elif stx == "1:2": value = 0x5 # On, ratio 1 = 1:2 elif stx == "1:3": value = 0x6 # On, ratio 2 = 1:3 else: value = 0x7 # On, ratio 3 = 1:4 # LOG.warning("Batsav stx:%s:, value= %x" % (stx, value)) setattr(obj, atrb, value) return def my_manfrq(setting, obj, atrb): """Callback to set 2-byte manfrqyn yes/no """ # LOG.warning("Manfrq value = %d" % setting.value) if (str(setting.value)) == "No": value = 0xff else: value = 0xaa setattr(obj, atrb, value) return def myset_mask(setting, obj, atrb, nx): if bool(setting.value): # Enabled = 0 vx = 0 else: vx = 1 _do_map(nx + 1, vx, self._memobj.fmmap.fmset) return def myset_fmfrq(setting, obj, atrb, nx): """ Callback to set xx.x FM freq in memory as xx.x * 40""" # in-valid even kHz freqs are allowed; to satisfy run_tests vx = float(str(setting.value)) vx = int(vx * 40) setattr(obj[nx], atrb, vx) return rx = RadioSettingValueInteger(1, 9, _sets.voxgain + 1) rset = RadioSetting("setstuf.voxgain", "Vox Level", rx) rset.set_apply_callback(my_adjraw, _sets, "voxgain", -1) basic.append(rset) rx = RadioSettingValueList(LIST_VOXDLY, LIST_VOXDLY[_sets.voxdelay]) rset = RadioSetting("setstuf.voxdelay", "Vox Delay (secs)", rx) basic.append(rset) rx = RadioSettingValueInteger(0, 9, _sets.sql) rset = RadioSetting("setstuf.sql", "Squelch", rx) basic.append(rset) rx = RadioSettingValueList(LIST_STEPS, LIST_STEPS[_sets.freqstep]) rset = RadioSetting("setstuf.freqstep", "VFO Tune Step (kHz)", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(_sets.dbw)) # true logic rset = RadioSetting("setstuf.dbw", "Dual Band Watch (D.WAIT)", rx) basic.append(rset) options = ["Off", "On", "Auto"] rx = RadioSettingValueList(options, options[_sets.lampon]) rset = RadioSetting("setstuf.lampon", "Backlight (LED)", rx) basic.append(rset) options = ["Orange", "Purple", "Blue"] rx = RadioSettingValueList(options, options[_sets.ledclr]) rset = RadioSetting("setstuf.ledclr", "Backlight Color (LIGHT)", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(_sets.beepon)) rset = RadioSetting("setstuf.beepon", "Keypad Beep", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(_sets.xbandenable)) rset = RadioSetting("setstuf.xbandenable", "Cross Band Allowed", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(not _sets.xbandon)) rset = RadioSetting("setstuf.xbandon", "Cross Band On", rx) rset.set_apply_callback(my_invbool, _sets, "xbandon") basic.append(rset) rx = RadioSettingValueList(LIST_TIMEOUT, LIST_TIMEOUT[_sets.tot]) rset = RadioSetting("setstuf.tot", "TX Timeout (Secs)", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(not _sets.rgrbeep)) # Invert rset = RadioSetting("setstuf.rgrbeep", "Beep at Eot (Roger)", rx) rset.set_apply_callback(my_invbool, _sets, "rgrbeep") basic.append(rset) rx = RadioSettingValueBoolean(bool(not _sets.keylok)) rset = RadioSetting("setstuf.keylok", "Keypad AutoLock", rx) rset.set_apply_callback(my_invbool, _sets, "keylok") basic.append(rset) options = ["None", "Message", "DC Volts"] rx = RadioSettingValueList(options, options[_sets.openmsg]) rset = RadioSetting("setstuf.openmsg", "Power-On Display", rx) basic.append(rset) options = ["Channel Name", "Frequency"] rx = RadioSettingValueList(options, options[_sets.chs_name]) rset = RadioSetting("setstuf.chs_name", "Display Name/Frq", rx) basic.append(rset) sx = "" for i in range(7): if _sets.radioname[i] != 0: sx += chr(_sets.radioname[i] + 32) rx = RadioSettingValueString(0, 7, sx) rset = RadioSetting("setstuf.radioname", "Power-On Message", rx) rset.set_apply_callback(my_strnam, _sets, "radioname", 7) basic.append(rset) # Advanced (Strange) Settings options = ["Busy: Last Tx Band", "Edit: Current Band"] rx = RadioSettingValueList(options, options[_sets.txsel]) rset = RadioSetting("setstuf.txsel", "Transmit Priority", rx) rset.set_doc("'Busy' transmits on last band used, not current one.") adv.append(rset) options = ["Off", "English", "Unk", "Chinese"] val = _sets.voice rx = RadioSettingValueList(options, options[val]) rset = RadioSetting("setstuf.voice", "Voice", rx) adv.append(rset) options = ["Off", "1:1", "1:2", "1:3", "1:4"] val = (_sets.batsav & 0x3) + 1 # ratio if (_sets.batsav & 0x4) == 0: # Off val = 0 rx = RadioSettingValueList(options, options[val]) rset = RadioSetting("setstuf.batsav", "Battery Saver", rx) rset.set_apply_callback(my_batsav, _sets, "batsav") adv.append(rset) # Find out what & where SuperSave is options = ["Off", "1", "2", "3", "4", "5", "6", "7", "8", "9"] rx = RadioSettingValueList(options, options[_sets.supersave]) rset = RadioSetting("setstuf.supersave", "Super Save (Secs)", rx) rset.set_doc("Unknown radio attribute??") adv.append(rset) sx = unpack_str(_sets.pttbot, _sets.pttbcnt + 1, 8) rx = RadioSettingValueString(0, 16, sx) rset = RadioSetting("setstuf.pttbot", "PTT BoT Code", rx) rset.set_apply_callback(pack_chars, _sets, "pttbot", "pttbcnt", 16) adv.append(rset) sx = unpack_str(_sets.ptteot, _sets.pttecnt + 1, 8) rx = RadioSettingValueString(0, 16, sx) rset = RadioSetting("setstuf.ptteot", "PTT EoT Code", rx) rset.set_apply_callback(pack_chars, _sets, "ptteot", "pttecnt", 16) adv.append(rset) options = ["None", "Low", "High", "Both"] rx = RadioSettingValueList(options, options[_sets.voltx]) rset = RadioSetting("setstuf.voltx", "Transmit Inhibit Voltage", rx) rset.set_doc("Block Transmit if battery volts are too high or low,") adv.append(rset) val = 0 # No = 0xff if _sets.manfrqyn == 0xaa: val = 1 options = ["No", "Yes"] rx = RadioSettingValueList(options, options[val]) rset = RadioSetting("setstuf.manfrqyn", "Manual Frequency", rx) rset.set_apply_callback(my_manfrq, _sets, "manfrqyn") adv.append(rset) rx = RadioSettingValueBoolean(bool(_sets.manualset)) rset = RadioSetting("setstuf.manualset", "Manual Setting", rx) adv.append(rset) # Scan Settings options = ["CO: During Rx", "TO: Timed", "SE: Halt"] rx = RadioSettingValueList(options, options[_sets.scanmode]) rset = RadioSetting("setstuf.scanmode", "Scan Mode (Scan Pauses When)", rx) scn.append(rset) options = ["100", "150", "200", "250", "300", "350", "400", "450"] rx = RadioSettingValueList(options, options[_sets.scanspeed]) rset = RadioSetting("setstuf.scanspeed", "Scan Speed (ms)", rx) scn.append(rset) val = _sets.scantmo + 3 rx = RadioSettingValueInteger(3, 30, val) rset = RadioSetting("setstuf.scantmo", "TO Mode Timeout (secs)", rx) rset.set_apply_callback(my_adjraw, _sets, "scantmo", -3) scn.append(rset) val = _sets.prichan rx = RadioSettingValueInteger(0, 128, val) rset = RadioSetting("setstuf.prichan", "Priority Channel (0:Off)", rx) scn.append(rset) # FM Broadcast Settings val = _fmx.fmcur val = val / 40.0 if val < 87.5 or val > 107.9: val = 88.0 rx = RadioSettingValueFloat(87.5, 107.9, val, 0.1, 1) rset = RadioSetting("fmfrqs.fmcur", "Manual FM Freq (MHz)", rx) rset.set_apply_callback(myset_freq, _fmx, "fmcur", 40) fmb.append(rset) options = ["5", "50", "100", "200(USA)"] # 5 is not used rx = RadioSettingValueList(options, options[_sets.fmstep]) rset = RadioSetting("setstuf.fmstep", "FM Freq Step (kHz)", rx) fmb.append(rset) # FM Scan Range fmsclo and fmschi are unknown memory locations, # Not supported at this time rx = RadioSettingValueBoolean(bool(_sets.rxinhib)) rset = RadioSetting("setstuf.rxinhib", "Rcvr Will Interrupt FM (DW)", rx) fmb.append(rset) _fmfrq = self._memobj.fm_stations _fmap = self._memobj.fmmap for j in range(0, 25): val = _fmfrq[j].rxfreq if val == 0xFFFF: val = 88.0 fmset = False else: val = (float(int(val)) / 40) # get fmmap bit value: 0 = enabled ndx = int(math.floor((j) / 8)) bv = j % 8 msk = 1 << bv vx = _fmap.fmset[ndx] fmset = not bool(vx & msk) rx = RadioSettingValueBoolean(fmset) rset = RadioSetting("fmmap.fmset/%d" % j, "FM Preset %02d" % (j + 1), rx) rset.set_apply_callback(myset_mask, _fmap, "fmset", j) fmb.append(rset) rx = RadioSettingValueFloat(87.5, 107.9, val, 0.1, 1) rset = RadioSetting("fm_stations/%d.rxfreq" % j, " Preset %02d Freq" % (j + 1), rx) # This callback uses the array index rset.set_apply_callback(myset_fmfrq, _fmfrq, "rxfreq", j) fmb.append(rset) # DTMF Settings options = [str(x) for x in range(4, 16)] rx = RadioSettingValueList(options, options[_sets.dtmfspd]) rset = RadioSetting("setstuf.dtmfspd", "Tx Speed (digits/sec)", rx) dtmf.append(rset) options = [str(x) for x in range(0, 1100, 100)] rx = RadioSettingValueList(options, options[_sets.dtmfdig1time]) rset = RadioSetting("setstuf.dtmfdig1time", "Tx 1st Digit Time (ms)", rx) dtmf.append(rset) options = [str(x) for x in range(100, 1100, 100)] rx = RadioSettingValueList(options, options[_sets.dtmfdig1dly]) rset = RadioSetting("setstuf.dtmfdig1dly", "Tx 1st Digit Delay (ms)", rx) dtmf.append(rset) options = ["0", "100", "500", "1000"] rx = RadioSettingValueList(options, options[_sets.dtmfspms]) rset = RadioSetting("setstuf.dtmfspms", "Tx Star & Pound Time (ms)", rx) dtmf.append(rset) options = ["None"] + [str(x) for x in range(600, 2100, 100)] rx = RadioSettingValueList(options, options[_sets.codespctim]) rset = RadioSetting("setstuf.codespctim", "Tx Code Space Time (ms)", rx) dtmf.append(rset) rx = RadioSettingValueBoolean(bool(_sets.codeabcd)) rset = RadioSetting("setstuf.codeabcd", "Tx Codes A,B,C,D", rx) dtmf.append(rset) rx = RadioSettingValueBoolean(bool(_sets.dtmfside)) rset = RadioSetting("setstuf.dtmfside", "DTMF Side Tone", rx) dtmf.append(rset) options = ["Off", "A", "B", "C", "D"] rx = RadioSettingValueList(options, options[_sets.grpcode]) rset = RadioSetting("setstuf.grpcode", "Rx Group Code", rx) dtmf.append(rset) options = ["Off"] + [str(x) for x in range(1, 16)] rx = RadioSettingValueList(options, options[_sets.autoresettmo]) rset = RadioSetting("setstuf.autoresettmo", "Rx Auto Reset Timeout (secs)", rx) dtmf.append(rset) rx = RadioSettingValueBoolean(bool(_sets.txdecode)) rset = RadioSetting("setstuf.txdecode", "Tx Decode", rx) dtmf.append(rset) rx = RadioSettingValueBoolean(bool(_sets.idedit)) rset = RadioSetting("setstuf.idedit", "Allow ANI Code Edit", rx) dtmf.append(rset) options = [str(x) for x in range(500, 1600, 100)] rx = RadioSettingValueList(options, options[_sets.decodetmo]) rset = RadioSetting("setstuf.decodetmo", "Rx Decode Timeout (ms)", rx) dtmf.append(rset) options = ["Tx & Rx Inhibit", "Tx Inhibit"] rx = RadioSettingValueList(options, options[_sets.stuntype]) rset = RadioSetting("setstuf.stuntype", "Stun Type", rx) dtmf.append(rset) sx = unpack_str(_sets.stuncode, _sets.stuncnt, 5) rx = RadioSettingValueString(0, 10, sx) rset = RadioSetting("setstuf.stuncode", "Stun Code", rx) rset.set_apply_callback(pack_chars, _sets, "stuncode", "stuncnt", 10) dtmf.append(rset) # Frequency ranges rx = RadioSettingValueBoolean(bool(_sets.frqr1)) rset = RadioSetting("setstuf.frqr1", "Freq Range 1 (UHF)", rx) rset.set_doc("Enable the UHF frequency bank.") frng.append(rset) rx = RadioSettingValueBoolean(bool(_sets.frqr2)) rset = RadioSetting("setstuf.frqr2", "Freq Range 2 (VHF)", rx) rset.set_doc("Enable the VHF frequency bank.") frng.append(rset) mod_se = True # UV8000SE has 3rd freq bank if mod_se: rx = RadioSettingValueBoolean(bool(_sets.frqr3)) rset = RadioSetting("setstuf.frqr3", "Freq Range 3 (220 MHz)", rx) rset.set_doc("Enable the 220 MHz frequency bank.") frng.append(rset) frqm = 100000 val = _sets.frqr1lo / frqm rx = RadioSettingValueFloat(400.0, 520.0, val, 0.005, 3) rset = RadioSetting("setstuf.frqr1lo", "UHF Range Low Limit (MHz)", rx) rset.set_apply_callback(myset_freq, _sets, "frqr1lo", frqm) rset.set_doc("Low limit of the UHF frequency bank.") frng.append(rset) val = _sets.frqr1hi / frqm rx = RadioSettingValueFloat(400.0, 520.0, val, 0.005, 3) rset = RadioSetting("setstuf.frqr1hi", "UHF Range High Limit (MHz)", rx) rset.set_apply_callback(myset_freq, _sets, "frqr1hi", frqm) rset.set_doc("High limit of the UHF frequency bank.") frng.append(rset) val = _sets.frqr2lo / frqm rx = RadioSettingValueFloat(136.0, 174.0, val, 0.005, 3) rset = RadioSetting("setstuf.frqr2lo", "VHF Range Low Limit (MHz)", rx) rset.set_apply_callback(myset_freq, _sets, "frqr2lo", frqm) rset.set_doc("Low limit of the VHF frequency bank.") frng.append(rset) val = _sets.frqr2hi / frqm rx = RadioSettingValueFloat(136.0, 174.0, val, 0.005, 3) rset = RadioSetting("setstuf.frqr2hi", "VHF Range High Limit (MHz)", rx) rset.set_apply_callback(myset_freq, _sets, "frqr2hi", frqm) rset.set_doc("High limit of the VHF frequency bank.") frng.append(rset) if mod_se: val = _sets.frqr3lo / frqm if val < 220.0: val = 220.0 rx = RadioSettingValueFloat(220.0, 260.0, val, 0.005, 3) rset = RadioSetting("setstuf.frqr3lo", "1.25m Range Low Limit (MHz)", rx) rset.set_apply_callback(myset_freq, _sets, "frqr3lo", frqm) frng.append(rset) val = _sets.frqr3hi / frqm if val < 220.0: val = 260.0 rx = RadioSettingValueFloat(220.0, 260.0, val, 0.005, 3) rset = RadioSetting("setstuf.frqr3hi", "1.25m Range High Limit (MHz)", rx) rset.set_apply_callback(myset_freq, _sets, "frqr3hi", 1000) frng.append(rset) return group # END get_settings() def set_settings(self, settings): _settings = self._memobj.setstuf _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/mursv1.py0000644000175000017500000007100114551723752016440 0ustar hibbyhibby# Copyright 2018: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import baofeng_common from chirp import chirp_common, directory from chirp import bitwise from chirp import bandplan_na from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) # #### MAGICS ######################################################### # BTECH MURS-V1 magic string MSTRING_MURSV1 = b"\x50\x5F\x20\x15\x12\x15\x4D" # #### ID strings ##################################################### # BTECH MURS-V1 MURSV1_fp1 = b"USM2402" DTMF_CHARS = "0123456789 *#ABCD" LIST_AB = ["A", "B"] LIST_ALMOD = ["Off", "Site", "Tone", "Code"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_COLOR = ["Off", "Blue", "Orange", "Purple"] LIST_DTMFSPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_DTMFST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] LIST_MODE = ["Channel", "Name", "Frequency"] LIST_OFF1TO9 = ["Off"] + list("123456789") LIST_OFF1TO10 = LIST_OFF1TO9 + ["10"] LIST_OFFAB = ["Off"] + LIST_AB LIST_RESUME = ["TO", "CO", "SE"] LIST_PONMSG = ["Full", "Message"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_SCODE = ["%s" % x for x in range(1, 16)] LIST_RPSTE = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_RTONE = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SHIFTD = ["Off", "+", "-"] LIST_STEDELAY = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] LIST_TIMEOUT = ["%s sec" % x for x in range(15, 615, 15)] LIST_TXPOWER = ["High", "Low"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_WORKMODE = ["Frequency", "Channel"] MURS_FREQS = bandplan_na.ALL_MURS_FREQS * 3 def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0x1EF0:0x1EF7] if rid in cls._fileid: return True return False @directory.register class MURSV1(baofeng_common.BaofengCommonHT): """BTech MURS-V1""" VENDOR = "BTECH" MODEL = "MURS-V1" NEEDS_COMPAT_SERIAL = False _fileid = [MURSV1_fp1, ] _magic = [MSTRING_MURSV1, ] _magic_response_length = 8 _fw_ver_start = 0x1EF0 _recv_block_size = 0x40 _mem_size = 0x2000 _ack_block = True _ranges = [(0x0000, 0x0DF0), (0x0E00, 0x1800), (0x1EE0, 0x1EF0), (0x1F60, 0x1F70), (0x1F80, 0x1F90), (0x1FC0, 0x1FD0)] _send_block_size = 0x10 MODES = ["NFM", "FM"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" LENGTH_NAME = 7 SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=.50)] VALID_BANDS = [(151820000, 154600250)] PTTID_LIST = LIST_PTTID SCODE_LIST = LIST_SCODE def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = False rf.has_name = True rf.has_offset = False rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_name_length = self.LENGTH_NAME rf.valid_duplexes = [] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = self.SKIP_VALUES rf.valid_dtcs_codes = self.DTCS_CODES rf.memory_bounds = (1, 15) rf.valid_power_levels = self.POWER_LEVELS rf.valid_bands = self.VALID_BANDS return rf MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1; u8 unknown2:7, lowpower:1; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[15]; #seekto 0x0B00; struct { u8 code[5]; u8 unused[11]; } pttid[15]; #seekto 0x0C80; struct { u8 unknown222[5]; u8 unknown333[5]; u8 alarm[5]; u8 unknown1; u8 unknown555[5]; u8 unknown666[5]; u8 unknown777[5]; u8 unknown2; u8 unknown60606[5]; u8 unknown70707[5]; u8 code[5]; u8 unused1:6, aniid:2; u8 unknown[2]; u8 dtmfon; u8 dtmfoff; } ani; #seekto 0x0E20; struct { u8 unused01:4, squelch:4; u8 unused02; u8 unused03; u8 unused04:5, save:3; u8 unused05:4, vox:4; u8 unused06; u8 unused07:4, abr:4; u8 unused08:7, tdr:1; u8 unused09:7, beep:1; u8 unused10:2, timeout:6; u8 unused11[4]; u8 unused12:6, voice:2; u8 unused13; u8 unused14:6, dtmfst:2; u8 unused15; u8 unused16:6, screv:2; u8 unused17:6, pttid:2; u8 unused18:2, pttlt:6; u8 unused19:6, mdfa:2; u8 unused20:6, mdfb:2; u8 unused21; u8 unused22:7, sync:1; u8 unused23[4]; u8 unused24:6, wtled:2; u8 unused25:6, rxled:2; u8 unused26:6, txled:2; u8 unused27:6, almod:2; u8 unused28:7, dbptt:1; u8 unused29:6, tdrab:2; u8 unused30:7, ste:1; u8 unused31:4, rpste:4; u8 unused32:4, rptrl:4; u8 unused33:7, ponmsg:1; u8 unused34:7, roger:1; u8 unused35:6, rtone:2; u8 unused36; u8 unused37:6, rogerrx:2; u8 unused38; u8 displayab:1, unknown1:2, fmradio:1, alarm:1, unknown2:1, reset:1, menu:1; u8 unused39; u8 workmode; u8 keylock; u8 cht; } settings; #seekto 0x0E76; struct { u8 unused1:1, mrcha:7; u8 unused2:1, mrchb:7; } wmchannel; #seekto 0x0F4E; u16 fm_presets; #seekto 0x1010; struct { char name[7]; u8 unknown1[9]; } names[15]; #seekto 0x1ED0; struct { char line1[7]; char line2[7]; } sixpoweron_msg; #seekto 0x1EE0; struct { char line1[7]; char line2[7]; } poweron_msg; #seekto 0x1EF0; struct { char line1[7]; char line2[7]; } firmware_msg; struct squelch { u8 sql0; u8 sql1; u8 sql2; u8 sql3; u8 sql4; u8 sql5; u8 sql6; u8 sql7; u8 sql8; u8 sql9; }; #seekto 0x1F60; struct { struct squelch vhf; } squelch; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('The BTech MURS-V1 driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def _get_mem(self, number): return self._memobj.memory[number - 1] def _get_nam(self, number): return self._memobj.names[number - 1] def get_memory(self, number): _mem = self._get_mem(number) _nam = self._get_nam(number) mem = chirp_common.Memory() mem.number = number if _mem.get_raw()[:1] == b"\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 for char in _nam.name: if str(char) == "\xFF": char = " " # The OEM software may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() dtcs_pol = ["N", "N"] if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 elif _mem.txtone <= 0x0258: txmode = "DTCS" if _mem.txtone > 0x69: index = _mem.txtone - 0x6A dtcs_pol[0] = "R" else: index = _mem.txtone - 1 mem.dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 elif _mem.rxtone <= 0x0258: rxmode = "DTCS" if _mem.rxtone >= 0x6A: index = _mem.rxtone - 0x6A dtcs_pol[1] = "R" else: index = _mem.rxtone - 1 mem.rx_dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) if not _mem.scan: mem.skip = "S" levels = self.POWER_LEVELS try: mem.power = levels[_mem.lowpower] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.power, levels)) mem.power = levels[0] mem.mode = _mem.wide and "FM" or "NFM" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(self.PTTID_LIST, self.PTTID_LIST[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("scode", "S-CODE", RadioSettingValueList(self.SCODE_LIST, self.SCODE_LIST[_mem.scode])) mem.extra.append(rs) immutable = [] if mem.freq in MURS_FREQS: if mem.number >= 1 and mem.number <= 15: MURS_FREQ = MURS_FREQS[mem.number - 1] mem.freq = MURS_FREQ mem.duplex == '' mem.offset = 0 immutable = ["empty", "freq", "duplex", "offset"] if mem.freq in bandplan_na.MURS_NFM: mem.mode = "NFM" immutable += ["mode"] mem.immutable = immutable return mem def _set_mem(self, number): return self._memobj.memory[number - 1] def _set_nam(self, number): return self._memobj.names[number - 1] def set_memory(self, mem): _mem = self._set_mem(mem.number) _nam = self._set_nam(mem.number) if mem.empty: _mem.set_raw("\xff" * 16) _nam.set_raw("\xff" * 16) return _mem.set_raw("\x00" * 16) _mem.rxfreq = mem.freq / 10 _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": rxmode = txmode = "DTCS" _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 _mem.rxtone = self.DTCS_CODES.index(mem.dtcs) + 1 elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) elif txmode == "DTCS": _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCS": _mem.rxtone = self.DTCS_CODES.index(mem.rx_dtcs) + 1 else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 if txmode == "DTCS" and mem.dtcs_polarity[0] == "R": _mem.txtone += 0x69 if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R": _mem.rxtone += 0x69 _mem.scan = mem.skip != "S" _mem.wide = mem.mode == "FM" if mem.power: _mem.lowpower = self.POWER_LEVELS.index(mem.power) else: _mem.lowpower = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) else: # there are no extra settings, load defaults _mem.bcl = 0 _mem.pttid = 0 _mem.scode = 0 def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") fm_preset = RadioSettingGroup("fm_preset", "FM Preset") dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") service = RadioSettingGroup("service", "Service Settings") top = RadioSettings(basic, advanced, other, work, fm_preset, dtmfe, service) # Basic settings if _mem.settings.squelch > 0x09: val = 0x00 else: val = _mem.settings.squelch rs = RadioSetting("settings.squelch", "Squelch", RadioSettingValueList( LIST_OFF1TO9, LIST_OFF1TO9[val])) basic.append(rs) if _mem.settings.save > 0x04: val = 0x00 else: val = _mem.settings.save rs = RadioSetting("settings.save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) if _mem.settings.vox > 0x0A: val = 0x00 else: val = _mem.settings.vox rs = RadioSetting("settings.vox", "Vox", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) if _mem.settings.abr > 0x0A: val = 0x00 else: val = _mem.settings.abr rs = RadioSetting("settings.abr", "Backlight Timeout", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) rs = RadioSetting("settings.tdr", "Dual Watch", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean(_mem.settings.beep)) basic.append(rs) if _mem.settings.timeout > 0x27: val = 0x03 else: val = _mem.settings.timeout rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( LIST_TIMEOUT, LIST_TIMEOUT[val])) basic.append(rs) if _mem.settings.voice > 0x02: val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) if _mem.settings.screv > 0x02: val = 0x01 else: val = _mem.settings.screv rs = RadioSetting("settings.screv", "Scan Resume", RadioSettingValueList( LIST_RESUME, LIST_RESUME[val])) basic.append(rs) rs = RadioSetting("settings.pttid", "When to send PTT ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[ _mem.settings.pttid])) basic.append(rs) if _mem.settings.pttlt > 0x32: val = 0x05 else: val = _mem.settings.pttlt rs = RadioSetting("pttlt", "PTT ID Delay", RadioSettingValueInteger(0, 50, val)) basic.append(rs) rs = RadioSetting("settings.mdfa", "Display Mode (A)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfa])) basic.append(rs) rs = RadioSetting("settings.mdfb", "Display Mode (B)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfb])) basic.append(rs) rs = RadioSetting("settings.sync", "Sync A & B", RadioSettingValueBoolean(_mem.settings.sync)) basic.append(rs) rs = RadioSetting("settings.wtled", "Standby LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.wtled])) basic.append(rs) rs = RadioSetting("settings.rxled", "RX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.rxled])) basic.append(rs) rs = RadioSetting("settings.txled", "TX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.txled])) basic.append(rs) val = _mem.settings.almod rs = RadioSetting("settings.almod", "Alarm Mode", RadioSettingValueList( LIST_ALMOD, LIST_ALMOD[val])) basic.append(rs) rs = RadioSetting("settings.dbptt", "Double PTT", RadioSettingValueBoolean(_mem.settings.dbptt)) basic.append(rs) rs = RadioSetting("settings.ste", "Squelch Tail Eliminate (HT to HT)", RadioSettingValueBoolean(_mem.settings.ste)) basic.append(rs) rs = RadioSetting("settings.ponmsg", "Power-On Message", RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[ _mem.settings.ponmsg])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger Beep", RadioSettingValueBoolean(_mem.settings.roger)) basic.append(rs) rs = RadioSetting("settings.rtone", "Tone Burst Frequency", RadioSettingValueList(LIST_RTONE, LIST_RTONE[ _mem.settings.rtone])) basic.append(rs) rs = RadioSetting("settings.rogerrx", "Roger Beep (RX)", RadioSettingValueList( LIST_OFFAB, LIST_OFFAB[ _mem.settings.rogerrx])) basic.append(rs) # Advanced settings rs = RadioSetting("settings.reset", "RESET Menu", RadioSettingValueBoolean(_mem.settings.reset)) advanced.append(rs) rs = RadioSetting("settings.menu", "All Menus", RadioSettingValueBoolean(_mem.settings.menu)) advanced.append(rs) rs = RadioSetting("settings.fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_mem.settings.fmradio)) advanced.append(rs) rs = RadioSetting("settings.alarm", "Alarm Sound", RadioSettingValueBoolean(_mem.settings.alarm)) advanced.append(rs) # Other settings def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = _mem.firmware_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val) other.append(rs) _msg = _mem.sixpoweron_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2", val) other.append(rs) _msg = _mem.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 7, _filter(_msg.line2))) other.append(rs) # Work mode settings rs = RadioSetting("settings.displayab", "Display", RadioSettingValueList( LIST_AB, LIST_AB[_mem.settings.displayab])) work.append(rs) rs = RadioSetting("settings.keylock", "Keypad Lock", RadioSettingValueBoolean(_mem.settings.keylock)) work.append(rs) rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(1, 15, _mem.wmchannel.mrcha)) work.append(rs) rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(1, 15, _mem.wmchannel.mrchb)) work.append(rs) # broadcast FM settings _fm_presets = self._memobj.fm_presets if _fm_presets <= 108.0 * 10 - 650: preset = _fm_presets / 10.0 + 65 elif _fm_presets >= 65.0 * 10 and _fm_presets <= 108.0 * 10: preset = _fm_presets / 10.0 else: preset = 76.0 rs = RadioSetting("fm_presets", "FM Preset(MHz)", RadioSettingValueFloat(65, 108.0, preset, 0.1, 1)) fm_preset.append(rs) # DTMF settings def apply_code(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) pttid = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) pttid.set_apply_callback(apply_code, self._memobj.pttid[i], 5) dtmfe.append(pttid) if _mem.ani.dtmfon > 0xC3: val = 0x03 else: val = _mem.ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if _mem.ani.dtmfoff > 0xC3: val = 0x03 else: val = _mem.ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) _codeobj = self._memobj.ani.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.code", "ANI Code", val) rs.set_apply_callback(apply_code, self._memobj.ani, 5) dtmfe.append(rs) rs = RadioSetting("ani.aniid", "When to send ANI ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[_mem.ani.aniid])) dtmfe.append(rs) def apply_alarmcode(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.alarm = code _codeobj = self._memobj.ani.alarm _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.alarm", "Alarm Code", val) rs.set_apply_callback(apply_alarmcode, self._memobj.ani, 5) dtmfe.append(rs) # Service settings for index in range(0, 10): key = "squelch.vhf.sql%i" % (index) _obj = self._memobj.squelch.vhf val = RadioSettingValueInteger(0, 123, getattr(_obj, "sql%i" % (index))) if index == 0: val.set_mutable(False) name = "Squelch %i" % (index) rs = RadioSetting(key, name, val) service.append(rs) return top @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == 0x2008: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/th_uv88.py0000644000175000017500000012513214562116574016515 0ustar hibbyhibby# Version 1.0 for TYT-UV88 # Initial radio protocol decode, channels and memory layout # by James Berry , Summer 2020 # Additional configuration and help, Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. import struct import logging import math from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) CHAN_NUM = 200 MEM_FORMAT = """ struct chns { ul32 rxfreq; ul32 txfreq; ul16 scramble:4, rxtone:12; //decode:12 ul16 decodeDSCI:1, encodeDSCI:1, unk1:1, unk2:1, txtone:12; //encode:12 u8 power:2, wide:2, b_lock:2, unk3:2; u8 unk4:3, signal:2, displayName:1, unk5:2; u8 unk6:2, pttid:2, unk7:1, step:3; // not required u8 name[6]; }; struct vfo { ul32 rxfreq; ul32 txfreq; // displayed as an offset ul16 scramble:4, rxtone:12; //decode:12 ul16 decodeDSCI:1, encodeDSCI:1, unk1:1, unk2:1, txtone:12; //encode:12 u8 power:2, wide:2, b_lock:2, unk3:2; u8 unk4:3, signal:2, displayName:1, unk5:2; u8 unk6:2, pttid:2, step:4; u8 name[6]; }; struct chname { u8 extra_name[10]; }; // #seekto 0x0000; struct chns chan_mem[200]; // CHAN_NUM #seekto 0x1140; struct { u8 autoKeylock:1, // 0x1140 [18] *OFF, On unk1:1, // vfomrmodeb:1, // *VFO B, MR B vfomrmode:1, // *VFO, MR unk2:4; // u8 mrAch; // 0x1141 MR A Channel # u8 mrBch; // 0x1142 MR B Channel # u8 unk3:5, // ab:1, // * A, B unk4:2; // } workmodesettings; """ MEM_FORMAT_PT2 = """ // #seekto 0x1180; struct { u8 bitmap[26]; // one bit for each channel marked in use } chan_avail; #seekto 0x11A0; struct { u8 bitmap[26]; // one bit for each channel skipped } chan_skip; #seekto 0x191E; struct { u8 unk1:4, // region:4; // 0x191E Radio Region (read only) // 0 = Unlocked TX: 136-174 MHz / 400-480 MHz // 2-3 = Unknown // 3 = EU TX: 144-146 MHz / 430-440 MHz // 4 = US TX: 144-148 MHz / 420-450 MHz // 5-15 = Unknown } settings2; #seekto 0x1940; struct { char name1[16]; // Intro Screen Line 1 (16 alpha text characters) char name2[16]; // Intro Screen Line 2 (16 alpha text characters) } openradioname; struct fm_chn { ul32 rxfreq; }; // #seekto 0x1960; struct chname chan_name[200]; // CHAN_NUM #seekto 0x2180; struct fm_chn fm_stations[24]; // #seekto 0x021E0; struct { u8 fmset[4]; } fmmap; // #seekto 0x21E4; struct { ul32 fmcur; } fmfrqs; """ THUV88_SETTINGS = """ #seekto 0x1160; struct { char introScreen1[12]; // 0x1160 *Intro Screen Line 1(truncated to 12 // alpha text characters) u8 offFreqVoltage : 3, // 0x116C unknown referred to in code but not on // screen unk1:1, // sqlLevel : 4; // [05] *OFF, 1-9 u8 beep : 1, // 0x116D [09] *OFF, On callKind : 2, // code says 1750,2100,1000,1450 as options // not on screen introScreen: 2, // [20] *OFF, Voltage, Char String unk2:2, // txChSelect : 1; // [02] *Last CH, Main CH u8 autoPowOff : 3, // 0x116E not on screen? OFF, 30Min, 1HR, 2HR unk3:1, // tot : 4; // [11] *OFF, 30 Second, 60 Second, 90 Second, // ... , 270 Second u8 unk4:1, // 0x116F roger:1, // [14] *OFF, On dailDef:1, // Unknown - 'Volume, Frequency' language:1, // ?Chinese, English (English only FW BQ1.38+) unk5:1, // endToneElim:1, // *OFF, Frequency unk6:1, // unk7:1; // u8 scanResumeTime : 2, // 0x1170 2S, 5S, 10S, 15S (not on screen) disMode : 2, // [33] *Frequency, Channel, Name scanType: 2, // [17] *To, Co, Se ledMode: 2; // [07] *Off, On, Auto u8 unk8; // 0x1171 u8 unk9; // 0x1172 Has flags to do with logging - factory // enabled (bits 16,64,128) u8 unk10; // 0x1173 u8 swAudio : 1, // 0x1174 [19] *OFF, On radioMoni : 1, // [34] *OFF, On keylock : 1, // [18] *OFF, On dualWait : 1, // [06] *OFF, On unk11:1, // light : 3; // [08] *1, 2, 3, 4, 5, 6, 7 u8 voxSw : 1, // 0x1175 [13] *OFF, On voxDelay: 4, // *0.5S, 1.0S, 1.5S, 2.0S, 2.5S, 3.0S, 3.5S, // 4.0S, 4.5S, 5.0S voxLevel : 3; // [03] *1, 2, 3, 4, 5, 6, 7 u8 unk12:4, // 0x1176 saveMode : 2, // [16] *OFF, 1:1, 1:2, 1:4 keyMode : 2; // [32] *ALL, PTT, KEY, Key & Side Key u8 unk13; // 0x1177 u8 unk14; // 0x1178 u8 unk15; // 0x1179 u8 name2[6]; // 0x117A unused } basicsettings; """ RA89_SETTINGS = """ #seekto 0x1160; struct { u8 sideKey2:4, // 0x1160 side key 2 sideKey1:4; // side key 1 u8 sideKey2_long:4, // 0x1161 side key 2 Long sideKey1_long:4; // side key 1 Long u8 unknownBytes[10]; // 0x1162 - 0x116B u8 offFreqVoltage : 3, // 0x116C unknown referred to in code but not on // screen unk1:1, // sqlLevel : 4; // [05] *OFF, 1-9 u8 beep : 1, // 0x116D [09] *OFF, On callKind : 2, // code says 1750,2100,1000,1450 as options // not on screen introScreen: 2, // [20] *OFF, Voltage, Char String unk2:2, // txChSelect : 1; // [02] *Last CH, Main CH u8 autoPowOff : 3, // 0x116E not on screen? OFF, 30Min, 1HR, 2HR unk3:1, // tot : 4; // [11] *OFF, 30 Second, 60 Second, 90 Second, // ... , 270 Second u8 unk4:1, // 0x116F roger:1, // [14] *OFF, On dailDef:1, // Unknown - 'Volume, Frequency' language:1, // English only endToneElim:2, // *Frequency, 120, 180, 240 (RA89) unk5:1, // unk6:1; // u8 scanType: 2, // 0x1170 [17] *Off, On, 5s, 10s, 15s, 20s, 25s, 30s disMode : 2, // [33] *Frequency, Channel, Name ledMode: 4; // [07] *Off, On, 5s, 10s, 15s, 20s, 25s, 30s u8 unk7; // 0x1171 u8 unk8; // 0x1172 Has flags to do with logging - factory // enabled (bits 16,64,128) u8 unk9; // 0x1173 u8 swAudio : 1, // 0x1174 [19] *OFF, On radioMoni : 1, // [34] *OFF, On keylock : 1, // [18] *OFF, On dualWait : 1, // [06] *OFF, On unk10:1, // light : 3; // [08] *1, 2, 3, 4, 5, 6, 7 u8 voxSw : 1, // 0x1175 [13] *OFF, On voxDelay: 4, // *0.5S, 1.0S, 1.5S, 2.0S, 2.5S, 3.0S, 3.5S, // 4.0S, 4.5S, 5.0S voxLevel : 3; // [03] *1, 2, 3, 4, 5, 6, 7 u8 unk11:4, // 0x1176 saveMode : 2, // [16] *OFF, 1:1, 1:2, 1:4 keyMode : 2; // [32] *ALL, PTT, KEY, Key & Side Key u8 unk12; // 0x1177 u8 unk13; // 0x1178 u8 unk14; // 0x1179 u8 name2[6]; // 0x117A unused } basicsettings; """ MEM_SIZE = 0x22A0 BLOCK_SIZE = 0x20 STIMEOUT = 2 BAUDRATE = 57600 # Channel power: 3 levels POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Mid", watts=2.50), chirp_common.PowerLevel("Low", watts=0.50)] SCRAMBLE_LIST = ["OFF", "1", "2", "3", "4", "5", "6", "7", "8"] B_LOCK_LIST = ["OFF", "Sub", "Carrier"] OPTSIG_LIST = ["OFF", "DTMF", "2TONE", "5TONE"] PTTID_LIST = ["Off", "BOT", "EOT", "Both"] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] LIST_STEPS = [str(x) for x in STEPS] def _clean_buffer(radio): radio.pipe.timeout = 0.005 junk = radio.pipe.read(256) radio.pipe.timeout = STIMEOUT if junk: LOG.debug("Got %i bytes of junk before starting" % len(junk)) def _rawrecv(radio, amount): """Raw read from the radio device""" data = "" try: data = radio.pipe.read(amount) except Exception: _exit_program_mode(radio) msg = "Generic error reading data from radio; check your cable." raise errors.RadioError(msg) if len(data) != amount: _exit_program_mode(radio) msg = "Error reading from radio: not the amount of data we want." raise errors.RadioError(msg) return data def _rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) except Exception: raise errors.RadioError("Error sending data to radio") def _make_read_frame(addr, length): frame = b"\xFE\xFE\xEE\xEF\xEB" """Pack the info in the header format""" frame += struct.pack(">ih", addr, length) frame += b"\xFD" # Return the data return frame def _make_write_frame(addr, length, data=""): frame = b"\xFE\xFE\xEE\xEF\xE4" """Pack the info in the header format""" output = struct.pack(">ih", addr, length) # Add the data if set if len(data) != 0: output += data frame += output frame += _calculate_checksum(output) frame += b"\xFD" # Return the data return frame def _calculate_checksum(data): num = 0 for x in range(0, len(data)): num = (num + data[x]) % 256 if num == 0: return bytes([0]) return bytes([256 - num]) def _recv(radio, addr, length): """Get data from the radio """ data = _rawrecv(radio, length) # DEBUG LOG.info("Response:") LOG.debug(util.hexprint(data)) return data def _do_ident(radio): """Put the radio in PROGRAM mode & identify it""" radio.pipe.baudrate = BAUDRATE radio.pipe.parity = "N" radio.pipe.timeout = STIMEOUT # Ident radio magic = radio._magic0 _rawsend(radio, magic) ack = _rawrecv(radio, 36) if not ack.startswith(radio._fingerprint) or not ack.endswith(b"\xFD"): _exit_program_mode(radio) if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond as expected (A)") return True def _exit_program_mode(radio): # This may be the last part of a read magic = radio._magic5 _rawsend(radio, magic) _clean_buffer(radio) def _download(radio): """Get the memory map""" # Put radio in program mode and identify it _do_ident(radio) # Enter read mode magic = radio._magic2 _rawsend(radio, magic) ack = _rawrecv(radio, 7) if ack != b"\xFE\xFE\xEF\xEE\xE6\x00\xFD": _exit_program_mode(radio) if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond to enter read mode") # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data = b"" for addr in range(0, MEM_SIZE, BLOCK_SIZE): frame = _make_read_frame(addr, BLOCK_SIZE) # DEBUG LOG.debug("Frame=" + util.hexprint(frame)) # Sending the read request _rawsend(radio, frame) # Now we read data d = _recv(radio, addr, BLOCK_SIZE + 13) LOG.debug("Response Data= " + util.hexprint(d)) if not d.startswith(b"\xFE\xFE\xEF\xEE\xE4"): LOG.warning("Incorrect start") if not d.endswith(b"\xFD"): LOG.warning("Incorrect end") # could validate the block data # Aggregate the data data += d[11:-2] # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) _exit_program_mode(radio) return data def _upload(radio): """Upload procedure""" # Put radio in program mode and identify it _do_ident(radio) magic = radio._magic3 _rawsend(radio, magic) ack = _rawrecv(radio, 7) if ack != b"\xFE\xFE\xEF\xEE\xE6\x00\xFD": _exit_program_mode(radio) if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond to enter write mode") # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) # The fun starts here for addr in range(0, MEM_SIZE, BLOCK_SIZE): # Official programmer skips writing these memory locations if addr >= 0x1680 and addr < 0x1940: continue # Sending the data data = radio.get_mmap()[addr:addr + BLOCK_SIZE] frame = _make_write_frame(addr, BLOCK_SIZE, data) LOG.warning("Frame:%s:" % util.hexprint(frame)) _rawsend(radio, frame) ack = _rawrecv(radio, 7) LOG.debug("Response Data= " + util.hexprint(ack)) if not ack.startswith(b"\xFE\xFE\xEF\xEE\xE6\x00\xFD"): LOG.warning("Unexpected response") _exit_program_mode(radio) msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) _exit_program_mode(radio) def _do_map(chn, sclr, mary): """Set or Clear the chn (1-128) bit in mary[] word array map""" # chn is 1-based channel, sclr:1 = set, 0= = clear, 2= return state # mary[] is u8 array, but the map is by nibbles ndx = int(math.floor((chn - 1) / 8)) bv = (chn - 1) % 8 msk = 1 << bv mapbit = sclr if sclr == 1: # Set the bit mary[ndx] = mary[ndx] | msk elif sclr == 0: # clear mary[ndx] = mary[ndx] & (~ msk) # ~ is complement else: # return current bit state mapbit = 0 if (mary[ndx] & msk) > 0: mapbit = 1 return mapbit @directory.register class THUV88Radio(chirp_common.CloneModeRadio): """TYT UV88 Radio""" VENDOR = "TYT" MODEL = "TH-UV88" NEEDS_COMPAT_SERIAL = False MODES = ['WFM', 'FM', 'NFM'] # 62.5 is a non standard tone listed in the official programming software # 169.9 is a non standard tone listed in the official programming software # probably by mistake instead of 167.9 TONES = (62.5,) + chirp_common.TONES + (169.9,) DTCS_CODES = chirp_common.DTCS_CODES NAME_LENGTH = 10 DTMF_CHARS = list("0123456789ABCD*#") # 136-174, 400-480 VALID_BANDS = [(136000000, 174000000), (400000000, 480000000)] # Valid chars on the LCD VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`!\"#$%&'()*+,-./:;<=>?@[]^_" _magic0 = b"\xFE\xFE\xEE\xEF\xE0" + b"UV88" + b"\xFD" _magic2 = b"\xFE\xFE\xEE\xEF\xE2" + b"UV88" + b"\xFD" _magic3 = b"\xFE\xFE\xEE\xEF\xE3" + b"UV88" + b"\xFD" _magic5 = b"\xFE\xFE\xEE\xEF\xE5" + b"UV88" + b"\xFD" _fingerprint = b"\xFE\xFE\xEF\xEE\xE1" + b"UV88" @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = \ (cls.VENDOR + ' ' + cls.MODEL + '\n') rp.pre_download = _( "This is an early stage beta driver\n") rp.pre_upload = _( "This is an early stage beta driver - upload at your own risk\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_comment = False rf.has_tuning_step = False # Not as chan feature rf.valid_tuning_steps = STEPS rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.has_sub_devices = False rf.valid_name_length = self.NAME_LENGTH rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ["Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = [] rf.valid_power_levels = POWER_LEVELS rf.valid_tones = self.TONES rf.valid_dtcs_codes = self.DTCS_CODES rf.valid_bands = self.VALID_BANDS rf.memory_bounds = (1, CHAN_NUM) rf.valid_skips = ["", "S"] return rf def sync_in(self): """Download from radio""" try: data = _download(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def process_mmap(self): """Process the mem map into the mem object""" mem_format = MEM_FORMAT + THUV88_SETTINGS + MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def set_memory(self, memory): """A value in a UI column for chan 'number' has been modified.""" # update all raw channel memory values (_mem) from UI (mem) _mem = self._memobj.chan_mem[memory.number - 1] _name = self._memobj.chan_name[memory.number - 1] if memory.empty: _do_map(memory.number, 0, self._memobj.chan_avail.bitmap) return _do_map(memory.number, 1, self._memobj.chan_avail.bitmap) if memory.skip == "": _do_map(memory.number, 1, self._memobj.chan_skip.bitmap) else: _do_map(memory.number, 0, self._memobj.chan_skip.bitmap) return self._set_memory(memory, _mem, _name) def get_memory(self, number): # radio first channel is 1, mem map is base 0 _mem = self._memobj.chan_mem[number - 1] _name = self._memobj.chan_name[number - 1] mem = chirp_common.Memory() mem.number = number # Determine if channel is empty if _do_map(number, 2, self._memobj.chan_avail.bitmap) == 0: mem.empty = True return mem if _do_map(mem.number, 2, self._memobj.chan_skip.bitmap) > 0: mem.skip = "" else: mem.skip = "S" return self._get_memory(mem, _mem, _name) def _get_memory(self, mem, _mem, _name): """Convert raw channel memory data into UI columns""" mem.extra = RadioSettingGroup("extra", "Extra") mem.empty = False # This function process both 'normal' and Freq up/down' entries mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 25000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) \ and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.name = "" for i in range(6): # 0 - 6 mem.name += chr(_mem.name[i]) for i in range(10): mem.name += chr(_name.extra_name[i]) mem.name = mem.name.rstrip() # remove trailing spaces # ########## TONE ########## if _mem.txtone > 2600: # All off txmode = "" elif _mem.txtone > 511: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 else: # DTSC txmode = "DTCS" mem.dtcs = int(format(int(_mem.txtone), 'o')) if _mem.rxtone > 2600: rxmode = "" elif _mem.rxtone > 511: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 else: rxmode = "DTCS" mem.rx_dtcs = int(format(int(_mem.rxtone), 'o')) mem.dtcs_polarity = ("N", "R")[_mem.encodeDSCI] + ( "N", "R")[_mem.decodeDSCI] mem.tmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # ########## TONE ########## mem.mode = self.MODES[_mem.wide] mem.power = POWER_LEVELS[int(_mem.power)] rs = RadioSettingValueList(B_LOCK_LIST, B_LOCK_LIST[min(_mem.b_lock, 0x02)]) b_lock = RadioSetting("b_lock", "B_Lock", rs) mem.extra.append(b_lock) step = RadioSetting("step", "Step", RadioSettingValueList(LIST_STEPS, LIST_STEPS[_mem.step])) mem.extra.append(step) scramble_value = _mem.scramble if self.MODEL == "RA89": if scramble_value >= 2: scramble_value = 0 rs = RadioSetting("scramble", "Scramble", RadioSettingValueBoolean(_mem.scramble)) mem.extra.append(rs) else: if scramble_value >= 8: # Looks like OFF is 0x0f ** CONFIRM scramble_value = 0 scramble = RadioSetting("scramble", "Scramble", RadioSettingValueList(SCRAMBLE_LIST, SCRAMBLE_LIST[ scramble_value])) mem.extra.append(scramble) optsig = RadioSetting("signal", "Optional signaling", RadioSettingValueList( OPTSIG_LIST, OPTSIG_LIST[_mem.signal])) mem.extra.append(optsig) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_mem.pttid])) mem.extra.append(rs) return mem def _set_memory(self, mem, _mem, _name): # """Convert UI column data (mem) into MEM_FORMAT memory (_mem).""" _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = _mem.rxfreq out_name = mem.name.ljust(16) for i in range(6): # 0 - 6 _mem.name[i] = ord(out_name[i]) for i in range(10): _name.extra_name[i] = ord(out_name[i+6]) if mem.name != "": _mem.displayName = 1 # Name only displayed if this is set on else: _mem.displayName = 0 rxmode = "" txmode = "" if mem.tmode == "Tone": txmode = "Tone" elif mem.tmode == "TSQL": rxmode = "Tone" txmode = "TSQL" elif mem.tmode == "DTCS": rxmode = "DTCSSQL" txmode = "DTCS" elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if mem.dtcs_polarity[1] == "N": _mem.decodeDSCI = 0 else: _mem.decodeDSCI = 1 if rxmode == "": _mem.rxtone = 0xFFF elif rxmode == "Tone": _mem.rxtone = int(float(mem.ctone) * 10) elif rxmode == "DTCSSQL": _mem.rxtone = int(str(mem.dtcs), 8) elif rxmode == "DTCS": _mem.rxtone = int(str(mem.rx_dtcs), 8) if mem.dtcs_polarity[0] == "N": _mem.encodeDSCI = 0 else: _mem.encodeDSCI = 1 if txmode == "": _mem.txtone = 0xFFF elif txmode == "Tone": _mem.txtone = int(float(mem.rtone) * 10) elif txmode == "TSQL": _mem.txtone = int(float(mem.ctone) * 10) elif txmode == "DTCS": _mem.txtone = int(str(mem.dtcs), 8) _mem.wide = self.MODES.index(mem.mode) _mem.power = 0 if mem.power is None else POWER_LEVELS.index(mem.power) for element in mem.extra: setattr(_mem, element.get_name(), element.value) return def get_settings(self): """Translate the MEM_FORMAT structs into setstuf in the UI""" _settings = self._memobj.basicsettings _settings2 = self._memobj.settings2 _workmode = self._memobj.workmodesettings _openradioname = self._memobj.openradioname basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) # Menu 02 - TX Channel Select options = ["Last Channel", "Main Channel"] rx = RadioSettingValueList(options, options[_settings.txChSelect]) rset = RadioSetting("basicsettings.txChSelect", "Priority Transmit", rx) basic.append(rset) # Menu 03 - VOX Level rx = RadioSettingValueInteger(1, 7, _settings.voxLevel + 1) rset = RadioSetting("basicsettings.voxLevel", "Vox Level", rx) basic.append(rset) # Menu 05 - Squelch Level options = ["OFF"] + ["%s" % x for x in range(1, 10)] rx = RadioSettingValueList(options, options[_settings.sqlLevel]) rset = RadioSetting("basicsettings.sqlLevel", "Squelch Level", rx) basic.append(rset) # Menu 06 - Dual Wait rx = RadioSettingValueBoolean(_settings.dualWait) rset = RadioSetting("basicsettings.dualWait", "Dual Wait/Standby", rx) basic.append(rset) # Menu 07 - LED Mode if self.MODEL == "RA89": options = ["Off", "On", "5s", "10s", "15s", "20s", "25s", "30s"] else: options = ["Off", "On", "Auto"] rx = RadioSettingValueList(options, options[_settings.ledMode]) rset = RadioSetting("basicsettings.ledMode", "LED Display Mode", rx) basic.append(rset) # Menu 08 - Light options = ["%s" % x for x in range(1, 8)] rx = RadioSettingValueList(options, options[_settings.light]) rset = RadioSetting("basicsettings.light", "Background Light Color", rx) basic.append(rset) # Menu 09 - Beep rx = RadioSettingValueBoolean(_settings.beep) rset = RadioSetting("basicsettings.beep", "Keypad Beep", rx) basic.append(rset) # Menu 11 - TOT options = ["Off"] + ["%s seconds" % x for x in range(30, 300, 30)] rx = RadioSettingValueList(options, options[_settings.tot]) rset = RadioSetting("basicsettings.tot", "Transmission Time-out Timer", rx) basic.append(rset) # Menu 13 - VOX Switch rx = RadioSettingValueBoolean(_settings.voxSw) rset = RadioSetting("basicsettings.voxSw", "Vox Switch", rx) basic.append(rset) # Menu 14 - Roger rx = RadioSettingValueBoolean(_settings.roger) rset = RadioSetting("basicsettings.roger", "Roger Beep", rx) basic.append(rset) # Menu 16 - Save Mode options = ["Off", "1:1", "1:2", "1:4"] rx = RadioSettingValueList(options, options[_settings.saveMode]) rset = RadioSetting("basicsettings.saveMode", "Battery Save Mode", rx) basic.append(rset) # Menu 17 - Scan Type if self.MODEL == "QRZ-1": options = ["Time", "Carrier", "Stop"] else: options = ["TO", "CO", "SE"] rx = RadioSettingValueList(options, options[_settings.scanType]) rset = RadioSetting("basicsettings.scanType", "Scan Type", rx) basic.append(rset) # Menu 18 - Key Lock rx = RadioSettingValueBoolean(_settings.keylock) rset = RadioSetting("basicsettings.keylock", "Auto Key Lock", rx) basic.append(rset) if self.MODEL != "QRZ-1": # Menu 19 - SW Audio rx = RadioSettingValueBoolean(_settings.swAudio) rset = RadioSetting("basicsettings.swAudio", "Voice Prompts", rx) basic.append(rset) # Menu 20 - Intro Screen if self.MODEL == "RA89": options = ["Off", "Voltage", "Character String", "Startup Logo"] else: options = ["Off", "Voltage", "Character String"] rx = RadioSettingValueList(options, options[_settings.introScreen]) rset = RadioSetting("basicsettings.introScreen", "Intro Screen", rx) basic.append(rset) # Menu 32 - Key Mode options = ["ALL", "PTT", "KEY", "Key & Side Key"] rx = RadioSettingValueList(options, options[_settings.keyMode]) rset = RadioSetting("basicsettings.keyMode", "Key Lock Mode", rx) basic.append(rset) # Menu 33 - Display Mode options = ['Frequency', 'Channel #', 'Name'] rx = RadioSettingValueList(options, options[_settings.disMode]) rset = RadioSetting("basicsettings.disMode", "Display Mode", rx) basic.append(rset) # Menu 34 - FM Dual Wait rx = RadioSettingValueBoolean(_settings.radioMoni) rset = RadioSetting("basicsettings.radioMoni", "Radio Monitor", rx) basic.append(rset) advanced = RadioSettingGroup("advanced", "Advanced Settings") group.append(advanced) # software only if self.MODEL == "RA89": options = ['Frequency', '120', '180', '240'] else: options = ['Off', 'Frequency'] rx = RadioSettingValueList(options, options[_settings.endToneElim]) rset = RadioSetting("basicsettings.endToneElim", "End Tone Elim", rx) advanced.append(rset) def _name_apply(setting, obj1, atrb1, obj2, atrb2): # Store a trunctaded version avec the first line # in basicsettings.intrScreen1. The original # do this for an unkown reason setattr(obj1, atrb1, str(setting.value)[:12]) setattr(obj2, atrb2, setting.value) return def _name_validate(value): # The 16th char is not displayed correctly. # Force it to space return value[:15].ljust(16) def _char_to_name(name): rname = "" for i in range(16): # 0 - 15 char = chr(int(name[i])) if char == "\x00": char = " " # Other software may have 0x00 mid-name rname += char return rname.rstrip() # remove trailing spaces # software only rx = RadioSettingValueString(0, 16, _char_to_name(_openradioname.name1)) rx.set_validate_callback(_name_validate) rset = RadioSetting("openradioname.name1", "Intro Line 1", rx) # On model others than RA89 store a trunctated name1 into basicsettings if self.MODEL != "RA89": rset.set_apply_callback(_name_apply, _settings, "introScreen1", _openradioname, "name1") advanced.append(rset) # software only rx = RadioSettingValueString(0, 16, _char_to_name(_openradioname.name2)) rx.set_validate_callback(_name_validate) rset = RadioSetting("openradioname.name2", "Intro Line 2", rx) advanced.append(rset) # software only options = ['0.5S', '1.0S', '1.5S', '2.0S', '2.5S', '3.0S', '3.5S', '4.0S', '4.5S', '5.0S'] rx = RadioSettingValueList(options, options[_settings.voxDelay]) rset = RadioSetting("basicsettings.voxDelay", "VOX Delay", rx) advanced.append(rset) options = ['Unlocked', 'Unknown 1', 'Unknown 2', 'EU', 'US'] # extend option list with unknown description for values 5 - 15. for ix in range(len(options), _settings2.region + 1): item_to_add = 'Unknown {region_code}'.format(region_code=ix) options.append(item_to_add) # log unknown region codes greater than 4 if _settings2.region > 4: LOG.debug("Unknown region code: {value}". format(value=_settings2.region)) rx = RadioSettingValueList(options, options[_settings2.region]) rx.set_mutable(False) rset = RadioSetting("settings2.region", "Region", rx) advanced.append(rset) if self.MODEL == "RA89": options = ["None", "VOX", "Dual Wait", "Scan", "Moni", "1750 Tone", "Flashlight", "Power Level", "Alarm", "Noise Cancelaton", "Temp Monitor", "FM Radio", "Talk Around", "Frequency Reverse"] rx = RadioSettingValueList(options, options[_settings.sideKey1]) rset = RadioSetting("basicsettings.sideKey1", "Side Key 1", rx) advanced.append(rset) rx = RadioSettingValueList(options, options[_settings.sideKey1_long]) rset = RadioSetting("basicsettings.sideKey1_long", "Side Key 1 Long", rx) advanced.append(rset) rx = RadioSettingValueList(options, options[_settings.sideKey2]) rset = RadioSetting("basicsettings.sideKey2", "Side Key 2", rx) advanced.append(rset) rx = RadioSettingValueList(options, options[_settings.sideKey2_long]) rset = RadioSetting("basicsettings.sideKey2_long", "Side Key 2 Long", rx) advanced.append(rset) workmode = RadioSettingGroup("workmode", "Work Mode Settings") group.append(workmode) # Toggle with [#] key options = ["Frequency", "Channel"] rx = RadioSettingValueList(options, options[_workmode.vfomrmode]) rset = RadioSetting("workmodesettings.vfomrmode", "VFO/MR Mode", rx) workmode.append(rset) # Toggle with [#] key options = ["Frequency", "Channel"] rx = RadioSettingValueList(options, options[_workmode.vfomrmodeb]) rset = RadioSetting("workmodesettings.vfomrmodeb", "VFO/MR Mode B", rx) workmode.append(rset) # Toggle with [A/B] key options = ["B", "A"] rx = RadioSettingValueList(options, options[_workmode.ab]) rset = RadioSetting("workmodesettings.ab", "A/B Select", rx) workmode.append(rset) rx = RadioSettingValueInteger(1, CHAN_NUM, _workmode.mrAch + 1) rset = RadioSetting("workmodesettings.mrAch", "MR A Channel #", rx) workmode.append(rset) rx = RadioSettingValueInteger(1, CHAN_NUM, _workmode.mrBch + 1) rset = RadioSetting("workmodesettings.mrBch", "MR B Channel #", rx) workmode.append(rset) fmb = RadioSettingGroup("fmradioc", "FM Radio Settings") group.append(fmb) def myset_mask(setting, obj, atrb, nx): if bool(setting.value): # Enabled = 1 vx = 1 else: vx = 0 _do_map(nx + 1, vx, self._memobj.fmmap.fmset) return def myset_fmfrq(setting, obj, atrb, nx): """ Callback to set xx.x FM freq in memory as xx.x * 100000""" # in-valid even kHz freqs are allowed; to satisfy run_tests vx = float(str(setting.value)) vx = int(vx * 100000) setattr(obj[nx], atrb, vx) return def myset_freq(setting, obj, atrb, mult): """ Callback to set frequency by applying multiplier""" value = int(float(str(setting.value)) * mult) setattr(obj, atrb, value) return _fmx = self._memobj.fmfrqs # FM Broadcast Manual Settings val = _fmx.fmcur val = val / 100000.0 if val < 64.0 or val > 108.0: val = 100.7 rx = RadioSettingValueFloat(64.0, 108.0, val, 0.1, 1) rset = RadioSetting("fmfrqs.fmcur", "Manual FM Freq (MHz)", rx) rset.set_apply_callback(myset_freq, _fmx, "fmcur", 100000) fmb.append(rset) _fmfrq = self._memobj.fm_stations _fmap = self._memobj.fmmap # FM Broadcast Presets Settings for j in range(0, 24): val = _fmfrq[j].rxfreq if val < 6400000 or val > 10800000: val = 88.0 fmset = False else: val = (float(int(val)) / 100000) # get fmmap bit value: 1 = enabled ndx = int(math.floor((j) / 8)) bv = j % 8 msk = 1 << bv vx = _fmap.fmset[ndx] fmset = bool(vx & msk) rx = RadioSettingValueBoolean(fmset) rset = RadioSetting("fmmap.fmset/%d" % j, "FM Preset %02d" % (j + 1), rx) rset.set_apply_callback(myset_mask, _fmap, "fmset", j) fmb.append(rset) rx = RadioSettingValueFloat(64.0, 108.0, val, 0.1, 1) rset = RadioSetting("fm_stations/%d.rxfreq" % j, " Preset %02d Freq" % (j + 1), rx) # This callback uses the array index rset.set_apply_callback(myset_fmfrq, _fmfrq, "rxfreq", j) fmb.append(rset) return group # END get_settings() def set_settings(self, settings): _settings = self._memobj.basicsettings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "mrAch" or setting == "mrBch": setattr(obj, setting, int(element.value) - 1) elif setting == "voxLevel": setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @directory.register class RT85(THUV88Radio): VENDOR = "Retevis" MODEL = "RT85" @directory.register class RA89(THUV88Radio): VENDOR = "Retevis" MODEL = "RA89" _magic0 = b"\xFE\xFE\xEE\xEF\xE0" + b"UV99" + b"\xFD" _magic2 = b"\xFE\xFE\xEE\xEF\xE2" + b"UV99" + b"\xFD" _magic3 = b"\xFE\xFE\xEE\xEF\xE3" + b"UV99" + b"\xFD" _magic5 = b"\xFE\xFE\xEE\xEF\xE5" + b"UV99" + b"\xFD" _fingerprint = b"\xFE\xFE\xEF\xEE\xE1" + b"UV99" def process_mmap(self): """Process the mem map into the mem object""" mem_format = MEM_FORMAT + RA89_SETTINGS + MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format, self._mmap) @directory.register class QRZ1(THUV88Radio): VENDOR = "Explorer" MODEL = "QRZ-1" _magic0 = b"\xFE\xFE\xEE\xEF\xE0" + b"UV78" + b"\xFD" _magic2 = b"\xFE\xFE\xEE\xEF\xE2" + b"UV78" + b"\xFD" _magic3 = b"\xFE\xFE\xEE\xEF\xE3" + b"UV78" + b"\xFD" _magic5 = b"\xFE\xFE\xEE\xEF\xE5" + b"UV78" + b"\xFD" _fingerprint = b"\xFE\xFE\xEF\xEE\xE1" + b"UV78" chirp-20240224/chirp/drivers/ft2900.py0000644000175000017500000012364214522657251016136 0ustar hibbyhibby# Copyright 2011 Dan Smith # # FT-2900-specific modifications by Richard Cochran, # Initial work on settings by Chris Fosnight, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging from chirp import util, memmap, chirp_common, bitwise, directory, errors from chirp.drivers.yaesu_clone import YaesuCloneModeRadio from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueString, RadioSettings LOG = logging.getLogger(__name__) def _send(s, data): s.write(data) echo = s.read(len(data)) if data != echo: raise Exception("Failed to read echo") LOG.debug("got echo\n%s\n" % util.hexprint(echo)) ACK = b"\x06" INITIAL_CHECKSUM = 0 def _download(radio): blankChunk = b"" for _i in range(0, 32): blankChunk += b"\xff" LOG.debug("in _download\n") data = b"" for _i in range(0, 20): data = radio.pipe.read(20) LOG.debug("Header:\n%s" % util.hexprint(data)) LOG.debug("len(header) = %s\n" % len(data)) if data == radio.IDBLOCK: break if data != radio.IDBLOCK: raise Exception("Failed to read header") _send(radio.pipe, ACK) # initialize data, the big var that holds all memory data = b"" _blockNum = 0 while len(data) < radio._block_sizes[1]: _blockNum += 1 time.sleep(0.03) chunk = radio.pipe.read(32) LOG.debug("Block %i " % (_blockNum)) if chunk == blankChunk: LOG.debug("blank chunk\n") else: LOG.debug("Got: %i:\n%s" % (len(chunk), util.hexprint(chunk))) if len(chunk) != 32: LOG.debug("len chunk is %i\n" % (len(chunk))) raise Exception("Failed to get full data block") else: data += chunk if radio.status_fn: status = chirp_common.Status() status.max = radio._block_sizes[1] status.cur = len(data) status.msg = "Cloning from radio" radio.status_fn(status) LOG.debug("Total: %i" % len(data)) # radio should send us one final termination byte, containing # checksum chunk = radio.pipe.read(32) if len(chunk) != 1: LOG.debug("len(chunk) is %i\n" % len(chunk)) raise Exception("radio sent extra unknown data") LOG.debug("Got: %i:\n%s" % (len(chunk), util.hexprint(chunk))) # compute checksum cs = INITIAL_CHECKSUM for byte in radio.IDBLOCK: cs += byte for byte in data: cs += byte LOG.debug("calculated checksum is %x\n" % (cs & 0xff)) LOG.debug("Radio sent checksum is %x\n" % chunk[0]) if (cs & 0xff) != chunk[0]: raise Exception("Failed checksum on read.") # for debugging purposes, dump the channels, in hex. for _i in range(0, 200): _startData = 1892 + 20 * _i chunk = data[_startData:_startData + 20] LOG.debug("channel %i:\n%s" % (_i, util.hexprint(chunk))) return memmap.MemoryMapBytes(data) def _upload(radio): for _i in range(0, 10): data = radio.pipe.read(256) if not data: break LOG.debug("What is this garbage?\n%s" % util.hexprint(data)) raise Exception("Radio sent unrecognized data") _send(radio.pipe, radio.IDBLOCK) time.sleep(.2) ack = radio.pipe.read(300) LOG.debug("Ack was (%i):\n%s" % (len(ack), util.hexprint(ack))) if ack != ACK: raise Exception("Radio did not ack ID. Check cable, verify" " radio is not locked.\n" " (press & Hold red \"*L\" button to unlock" " radio if needed)") block = 0 cs = INITIAL_CHECKSUM for byte in radio.IDBLOCK: cs += byte while block < (radio.get_memsize() // 32): data = radio.get_mmap()[block * 32:(block + 1) * 32] LOG.debug("Writing block %i:\n%s" % (block, util.hexprint(data))) _send(radio.pipe, data) time.sleep(0.03) for byte in data: cs += byte if radio.status_fn: status = chirp_common.Status() status.max = radio._block_sizes[1] status.cur = block * 32 status.msg = "Cloning to radio" radio.status_fn(status) block += 1 _send(radio.pipe, bytes([cs & 0xFF])) MEM_FORMAT = """ #seekto 0x0080; struct { u8 apo; u8 arts_beep; u8 bell; u8 dimmer; u8 cw_id_string[16]; u8 cw_trng; u8 x95; u8 x96; u8 x97; u8 int_cd; u8 int_set; u8 x9A; u8 x9B; u8 lock; u8 x9D; u8 mic_gain; u8 open_msg; u8 openMsg_Text[6]; u8 rf_sql; u8 unk:6, pag_abk:1, unk:1; u8 pag_cdr_1; u8 pag_cdr_2; u8 pag_cdt_1; u8 pag_cdt_2; u8 prog_p1; u8 xAD; u8 prog_p2; u8 xAF; u8 prog_p3; u8 xB1; u8 prog_p4; u8 xB3; u8 resume; u8 tot; u8 unk:1, cw_id:1, unk:1, ts_speed:1, ars:1, unk:2, dtmf_mode:1; u8 unk:1, ts_mut:1, wires_auto:1, busy_lockout:1, edge_beep:1, unk:3; u8 unk:2, s_search:1, unk:2, cw_trng_units:1, unk:2; u8 dtmf_speed:1, unk:2, arts_interval:1, unk:1, inverted_dcs:1, unk:1, mw_mode:1; u8 unk:2, wires_mode:1, wx_alert:1, unk:1, wx_vol_max:1, revert:1, unk:1; u8 vfo_scan; u8 scan_mode; u8 dtmf_delay; u8 beep; u8 xBF; } settings; #seekto 0x00d0; u8 passwd[4]; u8 mbs; #seekto 0x00c0; struct { u16 in_use; } bank_used[8]; #seekto 0x00ef; u8 currentTone; #seekto 0x00f0; u8 curChannelMem[20]; #seekto 0x1e0; struct { u8 dtmf_string[16]; } dtmf_strings[10]; #seekto 0x0127; u8 curChannelNum; #seekto 0x012a; u8 banksoff1; #seekto 0x15f; u8 checksum1; #seekto 0x16f; u8 curentTone2; #seekto 0x1aa; u16 banksoff2; #seekto 0x1df; u8 checksum2; #seekto 0x0360; struct{ u8 name[6]; } bank_names[8]; #seekto 0x03c4; struct{ u16 channels[50]; } banks[8]; #seekto 0x06e4; struct { u8 even_pskip:1, even_skip:1, even_valid:1, even_masked:1, odd_pskip:1, odd_skip:1, odd_valid:1, odd_masked:1; } flags[225]; #seekto 0x0764; struct { u8 unknown0:2, isnarrow:1, unknown1:5; u8 unknown2:2, duplex:2, unknown3:1, step:3; bbcd freq[3]; u8 power:2, unknown4:3, tmode:3; u8 name[6]; bbcd offset[3]; u8 ctonesplitflag:1, ctone:7; u8 rx_dtcssplitflag:1, rx_dtcs:7; u8 unknown5; u8 rtonesplitflag:1, rtone:7; u8 dtcssplitflag:1, dtcs:7; } memory[200]; """ MODES = ["FM", "NFM"] TMODES = ["", "Tone", "TSQL", "DTCS", "TSQL-R", "Cross"] CROSS_MODES = ["DTCS->", "Tone->DTCS", "DTCS->Tone", "Tone->Tone", "DTCS->DTCS"] DUPLEX = ["", "-", "+", "split"] POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=75), chirp_common.PowerLevel("Low3", watts=30), chirp_common.PowerLevel("Low2", watts=10), chirp_common.PowerLevel("Low1", watts=5), ] CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-/?C[] _" STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] def _decode_tone(radiotone): try: chirptone = chirp_common.TONES[radiotone] except IndexError: chirptone = 100 LOG.debug("found invalid radio tone: %i\n" % radiotone) return chirptone def _decode_dtcs(radiodtcs): try: chirpdtcs = chirp_common.DTCS_CODES[radiodtcs] except IndexError: chirpdtcs = 23 LOG.debug("found invalid radio dtcs code: %i\n" % radiodtcs) return chirpdtcs def _decode_name(mem): name = "" for i in mem: if (i & 0x7F) == 0x7F: break try: name += CHARSET[i & 0x7F] except IndexError: LOG.debug("Unknown char index: %x " % (i)) name = name.strip() return name def _encode_name(mem): if (mem.strip() == ""): return [0xff] * 6 name = [None] * 6 for i in range(0, 6): try: name[i] = CHARSET.index(mem[i]) except IndexError: name[i] = CHARSET.index(" ") name[0] = name[0] | 0x80 return name def _wipe_memory(mem): mem.set_raw(b"\xff" * (mem.size() // 8)) class FT2900Bank(chirp_common.NamedBank): def get_name(self): _bank = self._model._radio._memobj.bank_names[self.index] name = "" for i in _bank.name: if i == 0xff: break name += CHARSET[i & 0x7f] return name.rstrip() def set_name(self, name): name = name.upper().ljust(6)[:6] _bank = self._model._radio._memobj.bank_names[self.index] _bank.name = [CHARSET.index(x) for x in name.ljust(6)[:6]] class FT2900BankModel(chirp_common.BankModel): def get_num_mappings(self): return 8 def get_mappings(self): banks = self._radio._memobj.banks bank_mappings = [] for index, _bank in enumerate(banks): bank = FT2900Bank(self, "%i" % index, "b%i" % (index + 1)) bank.index = index bank_mappings.append(bank) return bank_mappings def _get_channel_numbers_in_bank(self, bank): _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xffff: return set() _members = self._radio._memobj.banks[bank.index] return set([int(ch) for ch in _members.channels if ch != 0xffff]) def _update_bank_with_channel_numbers(self, bank, channels_in_bank): _members = self._radio._memobj.banks[bank.index] if len(channels_in_bank) > len(_members.channels): raise Exception("More than %i entries in bank %d" % (len(_members.channels), bank.index)) empty = 0 for index, channel_number in enumerate(sorted(channels_in_bank)): _members.channels[index] = channel_number empty = index + 1 for index in range(empty, len(_members.channels)): _members.channels[index] = 0xffff _bank_used = self._radio._memobj.bank_used[bank.index] if empty == 0: _bank_used.in_use = 0xffff else: _bank_used.in_use = empty - 1 def add_memory_to_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) channels_in_bank.add(memory.number) self._update_bank_with_channel_numbers(bank, channels_in_bank) # tells radio that banks are active self._radio._memobj.banksoff1 = bank.index self._radio._memobj.banksoff2 = bank.index def remove_memory_from_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) try: channels_in_bank.remove(memory.number) except KeyError: raise Exception("Memory %i is not in bank %s. Cannot remove" % (memory.number, bank)) self._update_bank_with_channel_numbers(bank, channels_in_bank) def get_mapping_memories(self, bank): memories = [] for channel in self._get_channel_numbers_in_bank(bank): memories.append(self._radio.get_memory(channel)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in self._get_channel_numbers_in_bank(bank): banks.append(bank) return banks @directory.register class FT2900Radio(YaesuCloneModeRadio): """Yaesu FT-2900""" VENDOR = "Yaesu" MODEL = "FT-2900R/1900R" IDBLOCK = b"\x56\x43\x32\x33\x00\x02\x46\x01\x01\x01" BAUD_RATE = 19200 _memsize = 8000 _block_sizes = [8, 8000] def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.can_odd_split = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_dtcs_polarity = False rf.has_bank = True rf.has_bank_names = True rf.has_settings = True rf.valid_tuning_steps = STEPS rf.valid_modes = MODES rf.valid_tmodes = TMODES rf.valid_cross_modes = CROSS_MODES rf.valid_bands = [(136000000, 174000000)] rf.valid_power_levels = POWER_LEVELS rf.valid_duplexes = DUPLEX rf.valid_skips = ["", "S", "P"] rf.valid_name_length = 6 rf.valid_characters = CHARSET return rf def sync_in(self): start = time.time() try: self._mmap = _download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Downloaded in %.2f sec" % (time.time() - start)) self.process_mmap() def sync_out(self): self.pipe.timeout = 1 start = time.time() try: _upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Uploaded in %.2f sec" % (time.time() - start)) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): _mem = self._memobj.memory[number] _flag = self._memobj.flags[(number) / 2] nibble = ((number) % 2) and "even" or "odd" used = _flag["%s_masked" % nibble] valid = _flag["%s_valid" % nibble] pskip = _flag["%s_pskip" % nibble] skip = _flag["%s_skip" % nibble] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xFF" or not valid or not used: mem.empty = True return mem mem.tuning_step = STEPS[_mem.step] mem.freq = int(_mem.freq) * 1000 # compensate for 12.5 kHz tuning steps, add 500 Hz if needed if (mem.tuning_step == 12.5): lastdigit = int(_mem.freq) % 10 if (lastdigit == 2 or lastdigit == 7): mem.freq += 500 mem.offset = chirp_common.fix_rounded_step(int(_mem.offset) * 1000) mem.duplex = DUPLEX[_mem.duplex] if _mem.tmode < TMODES.index("Cross"): mem.tmode = TMODES[_mem.tmode] mem.cross_mode = CROSS_MODES[0] else: mem.tmode = "Cross" mem.cross_mode = CROSS_MODES[_mem.tmode - TMODES.index("Cross")] mem.rtone = _decode_tone(_mem.rtone) mem.ctone = _decode_tone(_mem.ctone) # check for unequal ctone/rtone in TSQL mode. map it as a # cross tone mode if mem.rtone != mem.ctone and (mem.tmode == "TSQL" or mem.tmode == "Tone"): mem.tmode = "Cross" mem.cross_mode = "Tone->Tone" mem.dtcs = _decode_dtcs(_mem.dtcs) mem.rx_dtcs = _decode_dtcs(_mem.rx_dtcs) # check for unequal dtcs/rx_dtcs in DTCS mode. map it as a # cross tone mode if mem.dtcs != mem.rx_dtcs and mem.tmode == "DTCS": mem.tmode = "Cross" mem.cross_mode = "DTCS->DTCS" if (int(_mem.name[0]) & 0x80) != 0: mem.name = _decode_name(_mem.name) mem.mode = _mem.isnarrow and "NFM" or "FM" mem.skip = pskip and "P" or skip and "S" or "" mem.power = POWER_LEVELS[3 - _mem.power] return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _flag = self._memobj.flags[(mem.number) / 2] nibble = ((mem.number) % 2) and "even" or "odd" valid = _flag["%s_valid" % nibble] used = _flag["%s_masked" % nibble] if not valid: _wipe_memory(_mem) if mem.empty and valid and not used: _flag["%s_valid" % nibble] = False return _flag["%s_masked" % nibble] = not mem.empty if mem.empty: return _flag["%s_valid" % nibble] = True _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 1000 _mem.duplex = DUPLEX.index(mem.duplex) # clear all the split tone flags -- we'll set them as needed below _mem.ctonesplitflag = 0 _mem.rx_dtcssplitflag = 0 _mem.rtonesplitflag = 0 _mem.dtcssplitflag = 0 if mem.tmode != "Cross": _mem.tmode = TMODES.index(mem.tmode) # for the non-cross modes, use ONE tone for both send # and receive but figure out where to get it from. if mem.tmode == "TSQL" or mem.tmode == "TSQL-R": _mem.rtone = chirp_common.TONES.index(mem.ctone) _mem.ctone = chirp_common.TONES.index(mem.ctone) else: _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.rtone) # and one tone for dtcs, but this is always the sending one _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.rx_dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) else: _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.rx_dtcs = chirp_common.DTCS_CODES.index(mem.rx_dtcs) if mem.cross_mode == "Tone->Tone": # tone->tone cross mode is treated as # TSQL, but with separate tones for # send and receive _mem.tmode = TMODES.index("TSQL") _mem.rtonesplitflag = 1 elif mem.cross_mode == "DTCS->DTCS": # DTCS->DTCS cross mode is treated as # DTCS, but with separate codes for # send and receive _mem.tmode = TMODES.index("DTCS") _mem.dtcssplitflag = 1 else: _mem.tmode = TMODES.index("Cross") + \ CROSS_MODES.index(mem.cross_mode) _mem.isnarrow = MODES.index(mem.mode) _mem.step = STEPS.index(mem.tuning_step) _flag["%s_pskip" % nibble] = mem.skip == "P" _flag["%s_skip" % nibble] = mem.skip == "S" if mem.power: _mem.power = 3 - POWER_LEVELS.index(mem.power) else: _mem.power = 3 _mem.name = _encode_name(mem.name) # set all unknown areas of the memory map to 0 _mem.unknown0 = 0 _mem.unknown1 = 0 _mem.unknown2 = 0 _mem.unknown3 = 0 _mem.unknown4 = 0 _mem.unknown5 = 0 LOG.debug("encoded mem\n%s\n" % (util.hexprint( _mem.get_raw(asbytes=False)[0:20]))) def get_settings(self): _settings = self._memobj.settings _dtmf_strings = self._memobj.dtmf_strings _passwd = self._memobj.passwd repeater = RadioSettingGroup("repeater", "Repeater Settings") ctcss = RadioSettingGroup("ctcss", "CTCSS/DCS/EPCS Settings") arts = RadioSettingGroup("arts", "ARTS Settings") mbls = RadioSettingGroup("banks", "Memory Settings") scan = RadioSettingGroup("scan", "Scan Settings") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") wires = RadioSettingGroup("wires", "WiRES(tm) Settings") switch = RadioSettingGroup("switch", "Switch/Knob Settings") disp = RadioSettingGroup("disp", "Display Settings") misc = RadioSettingGroup("misc", "Miscellaneous Settings") setmode = RadioSettings(repeater, ctcss, arts, mbls, scan, dtmf, wires, switch, disp, misc) # numbers and names of settings refer to the way they're # presented in the set menu, as well as the list starting on # page 74 of the manual # 1 APO opts = ["Off", "30 Min", "1 Hour", "3 Hour", "5 Hour", "8 Hour"] misc.append( RadioSetting( "apo", "Automatic Power Off", RadioSettingValueList(opts, opts[_settings.apo]))) # 2 AR.BEP opts = ["Off", "In Range", "Always"] arts.append( RadioSetting( "arts_beep", "ARTS Beep", RadioSettingValueList(opts, opts[_settings.arts_beep]))) # 3 AR.INT opts = ["15 Sec", "25 Sec"] arts.append( RadioSetting( "arts_interval", "ARTS Polling Interval", RadioSettingValueList(opts, opts[_settings.arts_interval]))) # 4 ARS opts = ["Off", "On"] repeater.append( RadioSetting( "ars", "Automatic Repeater Shift", RadioSettingValueList(opts, opts[_settings.ars]))) # 5 BCLO opts = ["Off", "On"] misc.append(RadioSetting( "busy_lockout", "Busy Channel Lock-Out", RadioSettingValueList(opts, opts[_settings.busy_lockout]))) # 6 BEEP opts = ["Off", "Key+Scan", "Key"] switch.append(RadioSetting( "beep", "Enable the Beeper", RadioSettingValueList(opts, opts[_settings.beep]))) # 7 BELL opts = ["Off", "1", "3", "5", "8", "Continuous"] ctcss.append(RadioSetting("bell", "Bell Repetitions", RadioSettingValueList(opts, opts[ _settings.bell]))) # 8 BNK.LNK for i in range(0, 8): opts = ["Off", "On"] mbs = (self._memobj.mbs >> i) & 1 rs = RadioSetting("mbs%i" % i, "Bank %s Scan" % (i + 1), RadioSettingValueList(opts, opts[mbs])) def apply_mbs(s, index): if int(s.value): self._memobj.mbs |= (1 << index) else: self._memobj.mbs &= ~(1 << index) rs.set_apply_callback(apply_mbs, i) mbls.append(rs) # 9 BNK.NM - A per-bank attribute, nothing to do here. # 10 CLK.SFT - A per-channel attribute, nothing to do here. # 11 CW.ID opts = ["Off", "On"] arts.append(RadioSetting("cw_id", "CW ID Enable", RadioSettingValueList(opts, opts[ _settings.cw_id]))) cw_id_text = "" for i in _settings.cw_id_string: try: cw_id_text += CHARSET[i & 0x7F] except IndexError: if i != 0xff: LOG.debug("unknown char index in cw id: %x " % (i)) val = RadioSettingValueString(0, 16, cw_id_text, True) val.set_charset(CHARSET + "abcdefghijklmnopqrstuvwxyz") rs = RadioSetting("cw_id_string", "CW Identifier Text", val) def apply_cw_id(s): str = s.value.get_value().upper().rstrip() mval = "" mval = [chr(CHARSET.index(x)) for x in str] for x in range(len(mval), 16): mval.append(chr(0xff)) for x in range(0, 16): _settings.cw_id_string[x] = ord(mval[x]) rs.set_apply_callback(apply_cw_id) arts.append(rs) # 12 CWTRNG opts = ["Off", "4WPM", "5WPM", "6WPM", "7WPM", "8WPM", "9WPM", "10WPM", "11WPM", "12WPM", "13WPM", "15WPM", "17WPM", "20WPM", "24WPM", "30WPM", "40WPM"] misc.append(RadioSetting("cw_trng", "CW Training", RadioSettingValueList(opts, opts[ _settings.cw_trng]))) # todo: make the setting of the units here affect the display # of the speed. Not critical, but would be slick. opts = ["CPM", "WPM"] misc.append(RadioSetting("cw_trng_units", "CW Training Units", RadioSettingValueList(opts, opts[_settings. cw_trng_units]))) # 13 DC VLT - a read-only status, so nothing to do here # 14 DCS CD - A per-channel attribute, nothing to do here # 15 DCS.RV opts = ["Disabled", "Enabled"] ctcss.append(RadioSetting( "inverted_dcs", "\"Inverted\" DCS Code Decoding", RadioSettingValueList(opts, opts[_settings.inverted_dcs]))) # 16 DIMMER opts = ["Off"] + ["Level %d" % (x) for x in range(1, 11)] disp.append(RadioSetting("dimmer", "Dimmer", RadioSettingValueList(opts, opts[_settings .dimmer]))) # 17 DT.A/M opts = ["Manual", "Auto"] dtmf.append(RadioSetting("dtmf_mode", "DTMF Autodialer", RadioSettingValueList(opts, opts[_settings .dtmf_mode]))) # 18 DT.DLY opts = ["50 ms", "250 ms", "450 ms", "750 ms", "1000 ms"] dtmf.append(RadioSetting("dtmf_delay", "DTMF Autodialer Delay Time", RadioSettingValueList(opts, opts[_settings .dtmf_delay]))) # 19 DT.SET for memslot in range(0, 10): dtmf_memory = "" for i in _dtmf_strings[memslot].dtmf_string: if i != 0xFF: try: dtmf_memory += CHARSET[i] except IndexError: LOG.debug("unknown char index in dtmf: %x " % (i)) val = RadioSettingValueString(0, 16, dtmf_memory, True) val.set_charset(CHARSET + "abcdef") rs = RadioSetting("dtmf_string_%d" % memslot, "DTMF Memory %d" % memslot, val) def apply_dtmf(s, i): LOG.debug("applying dtmf for %x\n" % i) str = s.value.get_value().upper().rstrip() LOG.debug("str is %s\n" % str) mval = "" mval = [chr(CHARSET.index(x)) for x in str] for x in range(len(mval), 16): mval.append(chr(0xff)) for x in range(0, 16): _dtmf_strings[i].dtmf_string[x] = ord(mval[x]) rs.set_apply_callback(apply_dtmf, memslot) dtmf.append(rs) # 20 DT.SPD opts = ["50 ms", "100 ms"] dtmf.append(RadioSetting("dtmf_speed", "DTMF Autodialer Sending Speed", RadioSettingValueList(opts, opts[_settings. dtmf_speed]))) # 21 EDG.BEP opts = ["Off", "On"] mbls.append(RadioSetting("edge_beep", "Band Edge Beeper", RadioSettingValueList(opts, opts[_settings. edge_beep]))) # 22 INT.CD opts = ["DTMF %X" % (x) for x in range(0, 16)] wires.append(RadioSetting("int_cd", "Access Number for WiRES(TM)", RadioSettingValueList(opts, opts[ _settings.int_cd]))) # 23 ING MD opts = ["Sister Radio Group", "Friends Radio Group"] wires.append(RadioSetting("wires_mode", "Internet Link Connection Mode", RadioSettingValueList(opts, opts[_settings. wires_mode]))) # 24 INT.A/M opts = ["Manual", "Auto"] wires.append(RadioSetting("wires_auto", "Internet Link Autodialer", RadioSettingValueList(opts, opts[_settings .wires_auto]))) # 25 INT.SET opts = ["F%d" % (x) for x in range(0, 10)] wires.append(RadioSetting("int_set", "Memory Register for " "non-WiRES Internet", RadioSettingValueList(opts, opts[_settings .int_set]))) # 26 LOCK opts = ["Key", "Dial", "Key + Dial", "PTT", "Key + PTT", "Dial + PTT", "All"] switch.append(RadioSetting("lock", "Control Locking", RadioSettingValueList(opts, opts[_settings .lock]))) # 27 MCGAIN opts = ["Level %d" % (x) for x in range(1, 10)] misc.append(RadioSetting("mic_gain", "Microphone Gain", RadioSettingValueList(opts, opts[_settings .mic_gain]))) # 28 MEM.SCN opts = ["Tag 1", "Tag 2", "All Channels"] rs = RadioSetting("scan_mode", "Memory Scan Mode", RadioSettingValueList(opts, opts[_settings .scan_mode - 1])) # this setting is unusual in that it starts at 1 instead of 0. # that is, index 1 corresponds to "Tag 1", and index 0 is invalid. # so we create a custom callback to handle this. def apply_scan_mode(s): myopts = ["Tag 1", "Tag 2", "All Channels"] _settings.scan_mode = myopts.index(s.value.get_value()) + 1 rs.set_apply_callback(apply_scan_mode) mbls.append(rs) # 29 MW MD opts = ["Lower", "Next"] mbls.append(RadioSetting("mw_mode", "Memory Write Mode", RadioSettingValueList(opts, opts[_settings .mw_mode]))) # 30 NM SET - This is per channel, so nothing to do here # 31 OPN.MSG opts = ["Off", "DC Supply Voltage", "Text Message"] disp.append(RadioSetting("open_msg", "Opening Message Type", RadioSettingValueList(opts, opts[_settings. open_msg]))) openmsg = "" for i in _settings.openMsg_Text: try: openmsg += CHARSET[i & 0x7F] except IndexError: if i != 0xff: LOG.debug("unknown char index in openmsg: %x " % (i)) val = RadioSettingValueString(0, 6, openmsg, True) val.set_charset(CHARSET + "abcdefghijklmnopqrstuvwxyz") rs = RadioSetting("openMsg_Text", "Opening Message Text", val) def apply_openmsg(s): str = s.value.get_value().upper().rstrip() mval = "" mval = [chr(CHARSET.index(x)) for x in str] for x in range(len(mval), 6): mval.append(chr(0xff)) for x in range(0, 6): _settings.openMsg_Text[x] = ord(mval[x]) rs.set_apply_callback(apply_openmsg) disp.append(rs) # 32 PAGER - a per-channel attribute # 33 PAG.ABK opts = ["Off", "On"] ctcss.append(RadioSetting("pag_abk", "Paging Answer Back", RadioSettingValueList(opts, opts[_settings .pag_abk]))) # 34 PAG.CDR opts = ["%2.2d" % (x) for x in range(1, 50)] ctcss.append(RadioSetting("pag_cdr_1", "Receive Page Code 1", RadioSettingValueList(opts, opts[_settings .pag_cdr_1]))) ctcss.append(RadioSetting("pag_cdr_2", "Receive Page Code 2", RadioSettingValueList(opts, opts[_settings .pag_cdr_2]))) # 35 PAG.CDT opts = ["%2.2d" % (x) for x in range(1, 50)] ctcss.append(RadioSetting("pag_cdt_1", "Transmit Page Code 1", RadioSettingValueList(opts, opts[_settings .pag_cdt_1]))) ctcss.append(RadioSetting("pag_cdt_2", "Transmit Page Code 2", RadioSettingValueList(opts, opts[_settings .pag_cdt_2]))) # Common Button Options button_opts = ["Squelch Off", "Weather", "Smart Search", "Tone Scan", "Scan", "T Call", "ARTS"] # 36 PRG P1 opts = button_opts + ["DC Volts"] switch.append(RadioSetting( "prog_p1", "P1 Button", RadioSettingValueList(opts, opts[_settings.prog_p1]))) # 37 PRG P2 opts = button_opts + ["Dimmer"] switch.append(RadioSetting( "prog_p2", "P2 Button", RadioSettingValueList(opts, opts[_settings.prog_p2]))) # 38 PRG P3 opts = button_opts + ["Mic Gain"] switch.append(RadioSetting( "prog_p3", "P3 Button", RadioSettingValueList(opts, opts[_settings.prog_p3]))) # 39 PRG P4 opts = button_opts + ["Skip"] switch.append(RadioSetting( "prog_p4", "P4 Button", RadioSettingValueList(opts, opts[_settings.prog_p4]))) # 40 PSWD password = "" for i in _passwd: if i != 0xFF: try: password += CHARSET[i] except IndexError: LOG.debug("unknown char index in password: %x " % (i)) val = RadioSettingValueString(0, 4, password, True) val.set_charset(CHARSET[0:15] + "abcdef ") rs = RadioSetting("passwd", "Password", val) def apply_password(s): str = s.value.get_value().upper().rstrip() mval = "" mval = [chr(CHARSET.index(x)) for x in str] for x in range(len(mval), 4): mval.append(chr(0xff)) for x in range(0, 4): _passwd[x] = ord(mval[x]) rs.set_apply_callback(apply_password) misc.append(rs) # 41 RESUME opts = ["3 Sec", "5 Sec", "10 Sec", "Busy", "Hold"] scan.append(RadioSetting("resume", "Scan Resume Mode", RadioSettingValueList(opts, opts[ _settings.resume]))) # 42 RF.SQL opts = ["Off"] + ["S-%d" % (x) for x in range(1, 10)] misc.append(RadioSetting("rf_sql", "RF Squelch Threshold", RadioSettingValueList(opts, opts[ _settings.rf_sql]))) # 43 RPT - per channel attribute, nothing to do here # 44 RVRT opts = ["Off", "On"] misc.append(RadioSetting("revert", "Priority Revert", RadioSettingValueList(opts, opts[ _settings.revert]))) # 45 S.SRCH opts = ["Single", "Continuous"] misc.append(RadioSetting("s_search", "Smart Search Sweep Mode", RadioSettingValueList(opts, opts[ _settings.s_search]))) # 46 SHIFT - per channel setting, nothing to do here # 47 SKIP = per channel setting, nothing to do here # 48 SPLIT - per channel attribute, nothing to do here # 49 SQL.TYP - per channel attribute, nothing to do here # 50 STEP - per channel attribute, nothing to do here # 51 TEMP - read-only status, nothing to do here # 52 TN FRQ - per channel attribute, nothing to do here # 53 TOT opts = ["Off", "1 Min", "3 Min", "5 Min", "10 Min"] misc.append(RadioSetting("tot", "Timeout Timer", RadioSettingValueList(opts, opts[_settings.tot]))) # 54 TS MUT opts = ["Off", "On"] ctcss.append(RadioSetting("ts_mut", "Tone Search Mute", RadioSettingValueList(opts, opts[_settings .ts_mut]))) # 55 TS SPEED opts = ["Fast", "Slow"] ctcss.append(RadioSetting("ts_speed", "Tone Search Scanner Speed", RadioSettingValueList(opts, opts[_settings .ts_speed]))) # 56 VFO.SCN opts = ["+/- 1 MHz", "+/- 2 MHz", "+/-5 MHz", "All"] scan.append(RadioSetting("vfo_scan", "VFO Scanner Width", RadioSettingValueList(opts, opts[_settings .vfo_scan]))) # 57 WX.ALT opts = ["Off", "On"] misc.append(RadioSetting("wx_alert", "Weather Alert Scan", RadioSettingValueList(opts, opts[ _settings.wx_alert]))) # 58 WX.VOL opts = ["Normal", "Maximum"] misc.append(RadioSetting("wx_vol_max", "Weather Alert Volume", RadioSettingValueList(opts, opts[ _settings.wx_vol_max]))) # 59 W/N DV - this is a per-channel attribute, nothing to do here return setmode def set_settings(self, uisettings): _settings = self._memobj.settings for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: name = element.get_name() value = element.value if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: obj = getattr(_settings, name) setattr(_settings, name, value) LOG.debug("Setting %s: %s" % (name, value)) except Exception: LOG.debug(element.get_name()) raise def get_bank_model(self): return FT2900BankModel(self) @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn Radio off.\n" "2. Connect data cable.\n" "3. While holding \"A/N LOW\" button, turn radio on.\n" "4. After clicking OK, press \"SET MHz\" to send image.\n") rp.pre_upload = _( "1. Turn Radio off.\n" "2. Connect data cable.\n" "3. While holding \"A/N LOW\" button, turn radio on.\n" "4. Press \"MW D/MR\" to receive image.\n" "5. Make sure display says \"-WAIT-\" (see note below if not)\n" "6. Click OK to dismiss this dialog and start transfer.\n" "Note: if you don't see \"-WAIT-\" at step 5, try cycling\n" " power and pressing and holding red \"*L\" button to" " unlock\n" " radio, then start back at step 1.\n") return rp # the FT2900E is the European version of the radio, almost identical # to the R (USA) version, except for the model number and ID Block. We # create and register a class for it, with only the needed overrides # NOTE: Disabled until detection is fixed # @directory.register class FT2900ERadio(FT2900Radio): """Yaesu FT-2900E""" MODEL = "FT-2900E/1900E" VARIANT = "E" IDBLOCK = b"\x56\x43\x32\x33\x00\x02\x41\x02\x01\x01" # This class is for the TX Modified FT-1900/FT-2900 (MARS/CAP Mod). # Enabling out of band TX changes the header received by CHIRP @directory.register class FT2900ModRadio(FT2900Radio): """Yaesu FT-2900Mod""" MODEL = "FT-2900R/1900R(TXMod)" VARIANT = "Opened Xmit" IDBLOCK = b"\x56\x43\x32\x33\x00\x02\xc7\x01\x01\x01" @classmethod def match_model(cls, filedata, filename): return False chirp-20240224/chirp/drivers/ft450d.py0000644000175000017500000020563114562116574016221 0ustar hibbyhibby# Copyright 2018 by Rick DeWitt (aa0rd@yahoo.com) V2.0 # PY3 Compliant release. # Thanks to Filippi Marco for Yaesu processes # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """FT450D Yaesu Radio Driver""" from chirp.drivers import yaesu_clone from chirp import chirp_common, util, memmap, errors, directory, bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings import time import struct import logging import itertools LOG = logging.getLogger(__name__) CMD_ACK = b'\x06' # can't update chirp_common data modes for this radio, so for weird # data modes we will use main mode of DIG and then have these sub-modes DATA_MODES = ["USER-L", "USER-U", "RTTY", "N/A"] T_STEPS = sorted(list(chirp_common.TUNING_STEPS)) T_STEPS.remove(30.0) T_STEPS.remove(100.0) T_STEPS.remove(125.0) T_STEPS.remove(200.0) def filters_for_mode(mode): if mode in ("USB", "LSB"): return "sb_width", ["1.8 kHz", "2.4 kHz", "3.0 kHz"] elif mode in ("CW", "CWR"): return "cw_width", ["300 Hz", "500 kHz", "2.4 kHz"] elif mode == "DIG": return "sb_width", ["300 Hz", "2.4 kHz", "3.0 kHz"] elif mode == "AM": return "am_width", ["3.0 kHz", "6.0 kHz", "9.0 kHz"] elif mode in ("NFM", "FM"): return "fm_width", ["2.5 kHz", "5.0 kHz"] else: raise ValueError("Internal error: unknown mode %s" % mode) def filter_to_hz(item): mag, units = item.split(' ') return float(mag) * (1000 if units == 'kHz' else 1) def all_filters(): options = list(itertools.chain.from_iterable( filterlist for k, filterlist in [ filters_for_mode('CW'), filters_for_mode('USB'), filters_for_mode('DIG'), filters_for_mode('FM'), filters_for_mode('AM')])) return sorted(set(options), key=filter_to_hz) def closest_filter(options, value): value = filter_to_hz(value) dists = [abs(value - filter_to_hz(o)) for o in options] closest = options[dists.index(min(dists))] LOG.debug('Chose %s as closest filter to %s from %s', closest, value, ','.join(options)) return closest @directory.register class FT450DRadio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT-450D""" FT450 = False BAUD_RATE = 38400 COM_BITS = 8 # number of data bits COM_PRTY = 'N' # parity checking COM_STOP = 1 # stop bits MODEL = "FT-450D" NEEDS_COMPAT_SERIAL = False DUPLEX = ["", "-", "+"] MODES = ["LSB", "USB", "CW", "AM", "FM", "DIG", "NFM", "CWR"] TMODES = ["", "Tone", "TSQL"] STEPSFM = [5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0] STEPSAM = [2.5, 5.0, 9.0, 10.0, 12.5, 25.0] STEPSSSB = [1.0, 2.5, 5.0] VALID_BANDS = [(100000, 33000000), (33000000, 56000000)] FUNC_LIST = ['MONI', 'N/A', 'PBAK', 'PLAY1', 'PLAY2', 'PLAY3', 'QSPLIT', 'SPOT', 'SQLOFF', 'SWR', 'TXW', 'VCC', 'VOICE2', 'VM1MONI', 'VM1REC', 'VM1TX', 'VM2MONI', 'VM2REC', 'VM2TX', 'DOWN', 'FAST', 'UP', 'DSP', 'IPO/ATT', 'NB', 'AGC', 'MODEDN', 'MODEUP', 'DSP/SEL', 'KEYER', 'CLAR', 'BANDDN', 'BANDUP', 'A=B', 'A/B', 'LOCK', 'TUNE', 'VOICE', 'MW', 'V/M', 'HOME', 'RCL', 'VOX', 'STO', 'STEP', 'SPLIT', 'PMS', 'SCAN', 'MENU', 'DIMMER', 'MTR'] CHARSET = list(chirp_common.CHARSET_ASCII) CHARSET.remove("\\") MEM_SIZE = 15017 # block 9 (135 Bytes long) is to be repeated 101 times _block_lengths = [4, 84, 135, 162, 135, 162, 151, 130, 135, 127, 189, 103] MEM_FORMAT = """ struct mem_struct { // 27 bytes per channel u8 tag_on_off:2, // @ Byte 0 1=Off, 2=On unk0:2, mode:4; u8 duplex:2, // @ byte 1 att:1, ipo:1, unka1:1, tunerbad:1, // ?? Possible tuner failed unk1b:1, // @@@??? uprband:1; u8 cnturpk:1, // @ Byte 2 Peak (clr), Null (set) cnturmd:3, // Contour filter mode cnturgn:1, // Contour filter gain Low/high mode2:3; // When mode is data(5) u8 ssb_step:2, // @ Byte 3 am_step:3, fm_step:3; u8 tunerok:1, // @ Byte 4 ?? Poss tuned ok cnturon:1, unk4b:1, dnr_on:1, notch:1, unk4c:1, tmode:2; // Tone/Cross/etc as Off/Enc/Enc+Dec u8 unk5a:4, // @ byte 5 dnr_val:4; u8 cw_width:2, // # byte 6, Notch width indexes fm_width:2, am_width:2, sb_width:2; i8 notch_pos; // @ Byte 7 Signed: - 0 + u8 tone; // @ Byte 8 u8 unk9; // @ Byte 9 Always set to 0 u8 unkA; // @ Byte A u8 unkB; // @ Byte B u32 freq; // @ C-F u32 offset; // @ 10-13 u8 name[7]; // @ 14-1A }; struct model{ u8 modname[4]; }; #seekto 0x04; struct { u8 set04; // ?Checksum / Clone counter? u8 set05; // Current VFO? u8 set06; u8 fast:1, lock:1, // Inverted: 1 = Off nb:1, agc:5; u8 set08a:3, keyer:1, set08b:2, mtr_mode:2; u8 set09; u8 set0A; u8 set0B:2, clk_sft:1, cont:5; // 1:1 u8 beepvol_sgn:1, // @x0C: set : Link @0x41, clear: fix @ 0x40 set0Ca:3, clar_btn:1, // 0 = Dial, 1= SEL cwstone_sgn:1, // Set: Lnk @ x42, clear: Fixed at 0x43 beepton:2; // Index 0-3 u8 set0Da:1, cw_key:1, set0Db:3, dialstp_mode:1, dialstp:2; u8 set0E:1, keyhold:1, lockmod:1, set0ea:1, amfmdial:1, // 0= Enabled. 1 = Disabled cwpitch:3; // 0-based index u8 sql_rfg:1, set0F:2, cwweigt:5; // Index 1:2.5=0 -> 1:4.5=20 u8 cw_dly; // @x10 ms = val * 10 u8 set11; u8 cwspeed; // val 4-60 is wpm, *5 is cpm u8 vox_gain; // val 1:1 u8 set14:2, emergen:1, vox_dly:5; // ms = val * 100 u8 set15a:1, stby_beep:1, set15b:1, mem_grp:1, apo:4; u8 tot; // Byte x16, 1:1 u8 micscan:1, set17:5, micgain:2; u8 cwpaddl:1, // @x18 0=Key, 1=Mic set18:7; u8 set19; u8 set1A; u8 set1B; u8 set1C; u8 dig_vox; // 1:1 u8 set1E; i16 d_disp; // @ x1F,x20 signed 16bit u8 pnl_cs; // 0-based index u8 pm_up; u8 pm_fst; u8 pm_dwn; u8 set25; u8 set26; u8 set27; u8 set28; u8 beacon_time; // 1:1 u8 set2A; u8 cat_rts:1, // @x2b: Enable=0, Disable=1 peakhold:1, set2B:4, cat_tot:2; // Index 0-3 u8 set2CA:2, rtyrpol:1, rtytpol:1, rty_sft:2, rty_ton:1, set2CC:1; u8 dig_vox; // 1:1 u8 ext_mnu:1, m_tune:1, set2E:2, scn_res:4; u8 cw_auto:1, // Off=0, On=1 cwtrain:2, // Index set2F:1, cw_qsk:2, // Index cw_bfo:2; // Index u8 mic_eq; // @x30 1:1 u8 set31:5, catrate:3; // Index 0-4 u8 set32; u8 dimmer:4, set33:4; u8 set34; u8 set35; u8 set36; u8 set37; u8 set38a:1, rfpower:7; // 1:1 u8 set39a:2, tuner:3, // Index 0-4 seldial:3; // Index 0-5 u8 set3A; u8 set3B; u8 set3C; i8 qspl_f; // Signed u8 set3E; u8 set3F; u8 beepvol_fix; // 1:1 i8 beepvol_lnk; // SIGNED 2's compl byte u8 cwstone_fix; i8 cwstone_lnk; // signed byte u8 set44:2, mym_data:1, // My Mode: Data, set = OFF mym_fm:1, mym_am:1, mym_cw:1, mym_usb:1, mym_lsb:1; u8 myb_24:1, // My Band: 24 MHz set = OFF myb_21:1, myb_18:1, myb_14:1, myb_10:1, myb_7:1, myb_3_5:1, myb_1_8:1; u8 set46:6, myb_28:1, myb_50:1; u8 set47; u8 set48; u8 set49; u8 set4A; u8 set4B; u8 set4C; u8 set4D; u8 set4E; u8 set4F; u8 set50; u8 set51; u8 set52; u8 set53; u8 set54; u8 set55; u8 set56a:3, split:1, set56b:4; u8 set57; } settings; #seekto 0x58; struct mem_struct vfoa[11]; // The current cfgs for each vfo 'band' struct mem_struct vfob[11]; struct mem_struct home[2]; // The 2 Home cfgs (HF and 6m) struct mem_struct qmb; // The Quick Memory Bank STO/RCL struct mem_struct mtqmb; // Last QMB-MemTune cfg (not displayed) struct mem_struct mtune; // Last MemTune cfg (not displayed) #seekto 0x343; // chan status u8 visible[63]; // 1 bit per channel u8 pmsvisible; // @ 0x382 #seekto 0x383; u8 filled[63]; u8 pmsfilled; // @ 0x3c2 #seekto 0x3C3; struct mem_struct memory[500]; struct mem_struct pms[4]; // Programmed Scan limits @ x387F #seekto 0x3906; struct { char t1[40]; // CW Beacon Text char t2[40]; char t3[40]; } beacontext; // to 0x397E #seekto 0x3985; struct mem_struct m60[5]; // to 0x3A0B #seekto 0x03a45; struct mem_struct current; """ _CALLSIGN_CHARSET = [chr(x) for x in list(range(ord("0"), ord("9") + 1)) + list(range(ord("A"), ord("Z") + 1)) + [ord(" ")]] _CALLSIGN_CHARSET_REV = dict(zip(_CALLSIGN_CHARSET, range(0, len(_CALLSIGN_CHARSET)))) # WARNING Indecis are hard wired in get/set_memory code !!! # Channels print in + increasing index order (PMS first) SPECIAL_MEMORIES = { "VFOa-1.8M": -27, "VFOa-3.5M": -26, "VFOa-7M": -25, "VFOa-10M": -24, "VFOa-14M": -23, "VFOa-18M": -22, "VFOa-21M": -21, "VFOa-24M": -20, "VFOa-28M": -19, "VFOa-50M": -18, "VFOa-HF": -17, "VFOb-1.8M": -16, "VFOb-3.5M": -15, "VFOb-7M": -14, "VFOb-10M": -13, "VFOb-14M": -12, "VFOb-18M": -11, "VFOb-21M": - 10, "VFOb-24M": -9, "VFOb-28M": -8, "VFOb-50M": -7, "VFOb-HF": -6, "HOME-HF": -5, "HOME-50M": -4, "QMB": -3, "QMB-MTune": -2, "Mem-Tune": -1, } FIRST_VFOB_INDEX = -6 LAST_VFOB_INDEX = -16 FIRST_VFOA_INDEX = -17 LAST_VFOA_INDEX = -27 SPECIAL_PMS = { "PMS1-L": -36, "PMS1-U": -35, "PMS2-L": -34, "PMS2-U": -33, } LAST_PMS_INDEX = -36 SPECIAL_MEMORIES.update(SPECIAL_PMS) SPECIAL_60M = { "60m-Ch1": -32, "60m-Ch2": -31, "60m-Ch3": -30, "60m-Ch4": -29, "60m-Ch5": -28, } LAST_60M_INDEX = -32 SPECIAL_MEMORIES.update(SPECIAL_60M) SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys())) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = _( "The FT-450D radio driver loads the 'Special Channels' tab\n" "with the PMS scanning range memories (group 11), 60meter\n" "channels (group 12), the QMB (STO/RCL) memory, the HF and\n" "50m HOME memories and all the A and B VFO memories.\n" "There are VFO memories for the last frequency dialed in\n" "each band. The last mem-tune config is also stored.\n" "These Special Channels allow limited field editing.\n" "This driver also populates the 'Other' tab in the channel\n" "memory Properties window. This tab contains values for\n" "those channel memory settings that don't fall under the\n" "standard Chirp display columns. With FT450 support, the gui now\n" "uses the mode 'DIG' to represent data modes and a new column\n" "'DATA MODE' to select USER-U, USER-L and RTTY \n") rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to ACC jack.\n" "3. Press and hold in the [MODE <] and [MODE >] keys" " while\n" " turning the radio on (\"CLONE MODE\" will appear on the\n" " display).\n" "4. After clicking OK here, press the [C.S.] key to\n" " send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to ACC jack.\n" "3. Press and hold in the [MODE <] and [MODE >] keys" " while\n" " turning the radio on (\"CLONE MODE\" will appear on the\n" " display).\n" "4. Click OK here.\n" " (\"Receiving\" will appear on the LCD).\n") return rp def _read(self, block, blocknum): # be very patient at first block if blocknum == 0: attempts = 60 else: attempts = 5 for _i in range(0, attempts): data = self.pipe.read(block + 2) # Blocknum, data,checksum if data: break time.sleep(0.5) if len(data) == block + 2 and data[0] == blocknum: checksum = yaesu_clone.YaesuChecksum(1, block) if checksum.get_existing(data) != \ checksum.get_calculated(data): raise Exception("Checksum Failed [%02X<>%02X] block %02X" % (checksum.get_existing(data), checksum.get_calculated(data), blocknum)) # Remove the block number and checksum data = data[1:block + 1] elif self.FT450: # unique FT450 (and 450AT?) vs D, only 2 bytes in first block if blocknum == 0 and len(data) == 4: checksum = yaesu_clone.YaesuChecksum(1, block - 2) if checksum.get_existing(data) != \ checksum.get_calculated(data): raise Exception("Checksum Failed [%02X<>%02X] block %02X" % (checksum.get_existing(data), checksum.get_calculated(data), blocknum)) # Remove the block number and checksum data = data[1:block - 2 + 1] # pad the data to the correct 450d size data += b" " else: # FT450, but bad block raise Exception("Unable to read block %i expected %i got %i" % (blocknum, block + 2, len(data))) else: # Use this info to decode a new Yaesu model # Not an old FT450 or 450AT raise Exception("Unable to read block %i expected %i got %i" % (blocknum, block + 2, len(data))) return data def _clone_in(self): # Be very patient with the radio self.pipe.timeout = 2 self.pipe.baudrate = self.BAUD_RATE self.pipe.bytesize = self.COM_BITS self.pipe.parity = self.COM_PRTY self.pipe.stopbits = self.COM_STOP self.pipe.rtscts = False start = time.time() data = b"" blocks = 0 status = chirp_common.Status() status.msg = _("Cloning from radio") nblocks = len(self._block_lengths) + 100 # Block 8 repeats status.max = nblocks for block in self._block_lengths: if blocks == 8: # repeated read of block 8 same size (chan memory area) repeat = 101 else: repeat = 1 for _i in range(0, repeat): data += self._read(block, blocks) self.pipe.write(CMD_ACK) blocks += 1 status.cur = blocks self.status_fn(status) data += self.MODEL.encode() return memmap.MemoryMapBytes(data) def _clone_out(self): self.pipe.baudrate = self.BAUD_RATE self.pipe.bytesize = self.COM_BITS self.pipe.parity = self.COM_PRTY self.pipe.stopbits = self.COM_STOP self.pipe.rtscts = False delay = 0.5 start = time.time() blocks = 0 pos = 0 status = chirp_common.Status() status.msg = _("Cloning to radio") status.max = len(self._block_lengths) + 100 for block in self._block_lengths: if blocks == 8: repeat = 101 else: repeat = 1 for _i in range(0, repeat): time.sleep(0.01) # If this is a 450 model, we need to send just the first two model bytes # in block 0 and just checksum that part if self.FT450 and blocks == 0: checksum = yaesu_clone.YaesuChecksum(pos, pos + block - 2 - 1) else: checksum = yaesu_clone.YaesuChecksum(pos, pos + block - 1) LOG.debug("Sending block %s" % hex(blocks)) self.pipe.write(struct.pack('B', blocks)) if self.FT450 and blocks == 0: blkdat = self.get_mmap()[pos:pos + block - 2] else: blkdat = self.get_mmap()[pos:pos + block] LOG.debug("Sending %d bytes:\n%s" % (len(blkdat), util.hexprint(blkdat))) self.pipe.write(blkdat) xs = checksum.get_calculated(self.get_mmap()) LOG.debug("Sending checksum %s" % hex(xs)) self.pipe.write(struct.pack('B', xs)) buf = self.pipe.read(1) if not buf or buf[:1] != CMD_ACK: time.sleep(delay) buf = self.pipe.read(1) if not buf or buf[:1] != CMD_ACK: raise Exception(_("Radio did not ack block %i") % blocks) pos += block blocks += 1 status.cur = blocks self.status_fn(status) def sync_in(self): try: self._mmap = self._clone_in() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: self._clone_out() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_dtcs = False rf.valid_modes = [x for x in self.MODES if x in chirp_common.MODES] rf.valid_tmodes = list(self.TMODES) rf.valid_duplexes = list(self.DUPLEX) rf.valid_tuning_steps = list(T_STEPS) rf.valid_bands = self.VALID_BANDS rf.valid_power_levels = [] rf.valid_characters = "".join(self.CHARSET) rf.valid_name_length = 7 rf.valid_skips = [] rf.valid_special_chans = sorted(self.SPECIAL_MEMORIES.keys()) rf.memory_bounds = (1, 500) rf.has_ctone = True rf.has_settings = True rf.has_cross = True return rf def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tmode(self, mem, _mem): mem.tmode = self.TMODES[_mem.tmode] mem.rtone = chirp_common.TONES[_mem.tone] mem.ctone = mem.rtone def _set_duplex(self, mem, _mem): _mem.duplex = self.DUPLEX.index(mem.duplex) def get_memory(self, number): if isinstance(number, str): return self._get_special(number) elif number < 0: # I can't stop delete operation from losing extd_number but # I know how to get it back return self._get_special(self.SPECIAL_MEMORIES_REV[number]) else: return self._get_normal(number) def set_memory(self, memory): # If this is called due to a delete request on the gui, # then the memory passed might be passed as a str, # since the special memories have string tags on the GUI and not # numbers. Convert these back to the int for the specials if isinstance(memory.number, str): memory.number = self.SPECIAL_MEMORIES[memory.number] return self._set_special(memory) if memory.number < 0: return self._set_special(memory) else: return self._set_normal(memory) def _get_special(self, number): mem = chirp_common.Memory() mem.number = self.SPECIAL_MEMORIES[number] mem.extd_number = number if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX - 1, -1): _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number] immutable = ["number", "extd_number", "name", "power"] elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX - 1, -1): _mem = self._memobj.vfob[-self.LAST_VFOB_INDEX + mem.number] immutable = ["number", "extd_number", "name", "power"] elif mem.number in range(-4, -6, -1): # 2 Home Chans _mem = self._memobj.home[5 + mem.number] immutable = ["number", "extd_number", "name", "power"] elif mem.number == -3: _mem = self._memobj.qmb immutable = ["number", "extd_number", "name", "power"] elif mem.number == -2: _mem = self._memobj.mtqmb immutable = ["number", "extd_number", "name", "power"] elif mem.number == -1: _mem = self._memobj.mtune immutable = ["number", "extd_number", "name", "power"] elif mem.number in self.SPECIAL_PMS.values(): # ft450 does NOT use the pmsvisible or pmsfilled fields, # it uses the next 4 bits after the 500 normal memories # in the main visible and filled settings area. if self.FT450: pmsnum = 501 + (-self.LAST_PMS_INDEX) + mem.number used = (self._memobj.visible[(pmsnum - 1) // 8] >> \ (pmsnum - 1) % 8) & 0x01 valid = (self._memobj.filled[(pmsnum - 1) // 8] >> \ (pmsnum - 1) % 8) & 0x01 else: bitindex = (-self.LAST_PMS_INDEX) + mem.number used = (self._memobj.pmsvisible >> bitindex) & 0x01 valid = (self._memobj.pmsfilled >> bitindex) & 0x01 # You can clear the PMS memories on the FT450 # using the CLAR button and then they do not display. if not used: mem.empty = True if not valid: mem.empty = True return mem mx = (-self.LAST_PMS_INDEX) + mem.number _mem = self._memobj.pms[mx] mx = mx + 1 immutable = ["number", "rtone", "ctone", "extd_number", "tmode", "cross_mode", "power", "duplex", "offset"] elif mem.number in self.SPECIAL_60M.values(): mx = (-self.LAST_60M_INDEX) + mem.number _mem = self._memobj.m60[mx] mx = mx + 1 immutable = ["number", "rtone", "ctone", "extd_number", "tmode", "cross_mode", "frequency", "power", "duplex", "offset"] else: raise Exception("Sorry, you can't edit that special" " memory channel %i." % mem.number) mem = self._get_memory(mem, _mem) mem.immutable = immutable return mem def _set_special(self, mem): if mem.empty and mem.number not in self.SPECIAL_PMS.values(): # can't delete special memories! But can delete PMS mems raise errors.RadioError("Sorry, special memory can't be deleted") cur_mem = self._get_special(self.SPECIAL_MEMORIES_REV[mem.number]) if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX - 1, -1): _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number] elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX - 1, -1): _mem = self._memobj.vfob[-self.LAST_VFOB_INDEX + mem.number] elif mem.number in range(-4, -6, -1): _mem = self._memobj.home[5 + mem.number] elif mem.number == -3: _mem = self._memobj.qmb elif mem.number == -2: _mem = self._memobj.mtqmb elif mem.number == -1: _mem = self._memobj.mtune elif mem.number in self.SPECIAL_PMS.values(): # ft450 does NOT use the pmsvisible or pmsfilled fields, # it uses the next 4 bits after the 500 normal memories # in the main visible and filled settings area. if self.FT450: pmsnum = 501 + (-self.LAST_PMS_INDEX) + mem.number wasused = (self._memobj.visible[(pmsnum - 1) // 8] >> (pmsnum - 1) % 8) & 0x01 wasvalid = (self._memobj.filled[(pmsnum - 1) // 8] >> (pmsnum - 1) % 8) & 0x01 if mem.empty: if wasvalid and not wasused: self._memobj.filled[(pmsnum - 1) // 8] &= \ ~(1 << (pmsnum - 1) % 8) self._memobj.visible[(pmsnum - 1) // 8] &= \ ~(1 << (pmsnum - 1) % 8) return self._memobj.visible[(pmsnum - 1) // 8] |= 1 << (pmsnum - 1) \ % 8 self._memobj.filled[(pmsnum - 1) // 8] |= 1 << (pmsnum - 1) \ % 8 _mem = self._memobj.pms[-self.LAST_PMS_INDEX + mem.number] else: #self.FT450 bitindex = (-self.LAST_PMS_INDEX) + mem.number wasused = (self._memobj.pmsvisible >> bitindex) & 0x01 wasvalid = (self._memobj.pmsfilled >> bitindex) & 0x01 if mem.empty: if wasvalid and not wasused: # pylint get confused by &= operator self._memobj.pmsfilled = self._memobj.pmsfilled & \ ~ (1 << bitindex) # pylint get confused by &= operator self._memobj.pmsvisible = self._memobj.pmsvisible & \ ~ (1 << bitindex) return # pylint get confused by |= operator self._memobj.pmsvisible = self._memobj.pmsvisible | 1 << bitindex self._memobj.pmsfilled = self._memobj.pmsfilled | 1 << bitindex _mem = self._memobj.pms[-self.LAST_PMS_INDEX + mem.number] else: raise errors.RadioError("Sorry, you can't edit" " that special memory.") for key in cur_mem.immutable: if key != "extd_number": if cur_mem.__dict__[key] != mem.__dict__[key]: raise errors.RadioError("Editing field `%s' " % key + "is not supported on this channel") self._set_memory(mem, _mem) def _get_normal(self, number): _mem = self._memobj.memory[number - 1] used = (self._memobj.visible[(number - 1) // 8] >> (number - 1) % 8) \ & 0x01 valid = (self._memobj.filled[(number - 1) // 8] >> (number - 1) % 8) \ & 0x01 mem = chirp_common.Memory() mem.number = number if not used: mem.empty = True if not valid or _mem.freq == 0xffffffff: return mem if mem.number == 1: mem.immutable = ['empty'] return self._get_memory(mem, _mem) def _set_normal(self, mem): _mem = self._memobj.memory[mem.number - 1] wasused = (self._memobj.visible[(mem.number - 1) // 8] >> (mem.number - 1) % 8) & 0x01 wasvalid = (self._memobj.filled[(mem.number - 1) // 8] >> (mem.number - 1) % 8) & 0x01 if mem.empty: if mem.number == 1: raise Exception("Sorry, can't delete first memory") if wasvalid and not wasused: self._memobj.filled[(mem.number - 1) // 8] &= \ ~(1 << (mem.number - 1) % 8) _mem.set_raw("\xFF" * (_mem.size() // 8)) # clean up self._memobj.visible[(mem.number - 1) // 8] &= \ ~(1 << (mem.number - 1) % 8) return if not wasvalid: _mem.set_raw("\x00" * (_mem.size() // 8)) # clean up self._memobj.visible[(mem.number - 1) // 8] |= 1 << (mem.number - 1) \ % 8 self._memobj.filled[(mem.number - 1) // 8] |= 1 << (mem.number - 1) \ % 8 self._set_memory(mem, _mem) def _get_memory(self, mem, _mem): mem.freq = int(_mem.freq) mem.offset = int(_mem.offset) mem.duplex = self.DUPLEX[_mem.duplex] # Mode gets tricky with dual (USB+DATA) options # WDC on FT450, the high bit of the nybble really # means something else, but I don't know # what it is. IE Sometimes LSB comes in as 1, sometime 8... vx = _mem.mode vx_data = 3 # Assume N/A unless reset below if vx == 0: # LSB pass elif vx == 1: # USB pass elif vx == 2: # USB CW (CW) pass elif vx == 3: # AM pass elif vx == 4: # FM/NFM if _mem.mode2 == 1: vx = 6 else: vx = 4 pass elif vx == 5: # USER\L # This looks different from FT450D if self.FT450: vx = 5 # set to new "DIG" vx_data = 1 else: # on 450D only 5 used for dig modes, no 13 if _mem.mode2 == 0: # RTTY vx = 5 # Set to new "DIG" vx_data = 2 # RTTY elif _mem.mode2 == 1: # USER-L vx = 5 # set to new "DIG" vx_data = 0 elif _mem.mode2 == 2: # USER-U variant vx = 5 # Set to new "DIG" vx_data = 1 # USER-U with Split? elif vx == 8: # LSB vx = 0 elif vx == 9: # USB vx = 1 elif vx == 10: # LSB CW (CWR) vx = 7 # CWR elif vx == 13: if _mem.mode2 == 0: # RTTY vx = 5 # Set to new "DIG" vx_data = 2 # RTTY elif _mem.mode2 == 1: # USER-L vx = 5 # set to new "DIG" vx_data = 0 elif _mem.mode2 == 2: # USER-U variant vx = 5 # Set to new "DIG" vx_data = 1 # USER-U with Split? else: LOG.error("unknown combo of mem.mode 13 and mem mode 2: %s %s", vx,_mem.mode2) else: LOG.error("unknown _mem.mode value : %s", vx) try: mem.mode = self.MODES[vx] except ValueError: LOG.error('The FT-450 driver is broken for unsupported modes') if mem.mode == "FM" or mem.mode == "NFM": mem.tuning_step = self.STEPSFM[_mem.fm_step] elif mem.mode == "AM": mem.tuning_step = self.STEPSAM[_mem.am_step] elif mem.mode[:2] == "CW": mem.tuning_step = self.STEPSSSB[_mem.ssb_step] else: try: mem.tuning_step = self.STEPSSSB[_mem.ssb_step] except IndexError: pass self._get_tmode(mem, _mem) if _mem.tag_on_off == 2: for i in _mem.name: if i == 0xFF: break if chr(i) in self.CHARSET: mem.name += chr(i) else: # radio has some graphical chars that are not supported # we replace those with a * LOG.info("Replacing char %x with *" % i) mem.name += "*" mem.name = mem.name.rstrip() else: mem.name = "" mem.extra = RadioSettingGroup("extra", "Extra") # add a new field to handle the new sub-modes if dig options = DATA_MODES rs = RadioSetting("data_modes", "DATA MODE", RadioSettingValueList(options, options[vx_data])) rs.set_doc("Extended Data Modes") mem.extra.append(rs) rs = RadioSetting("ipo", "IPO", RadioSettingValueBoolean(bool(_mem.ipo))) rs.set_doc("Bypass preamp") mem.extra.append(rs) rs = RadioSetting("att", "ATT", RadioSettingValueBoolean(bool(_mem.att))) rs.set_doc("10dB front end attenuator") mem.extra.append(rs) rs = RadioSetting("cnturon", "Contour Filter", RadioSettingValueBoolean(_mem.cnturon)) rs.set_doc("Contour filter on/off") mem.extra.append(rs) options = ["Peak", "Null"] rs = RadioSetting("cnturpk", "Contour Filter Mode", RadioSettingValueList(options, options[_mem.cnturpk])) mem.extra.append(rs) options = ["Low", "High"] rs = RadioSetting("cnturgn", "Contour Filter Gain", RadioSettingValueList(options, options[_mem.cnturgn])) rs.set_doc("Filter gain/attenuation") mem.extra.append(rs) options = ["-2", "-1", "Center", "+1", "+2"] rs = RadioSetting("cnturmd", "Contour Filter Notch", RadioSettingValueList(options, options[_mem.cnturmd])) rs.set_doc("Filter notch offset") mem.extra.append(rs) rs = RadioSetting("notch", "Notch Filter", RadioSettingValueBoolean(_mem.notch)) rs.set_doc("IF bandpass filter") mem.extra.append(rs) vx = 1 options = ["<-", "Center", "+>"] if _mem.notch_pos < 0: vx = 0 if _mem.notch_pos > 0: vx = 2 rs = RadioSetting("notch_pos", "Notch Position", RadioSettingValueList(options, options[vx])) rs.set_doc("IF bandpass filter shift") mem.extra.append(rs) stx, options = filters_for_mode(mem.mode) vx = getattr(_mem, stx) rs = RadioSetting("bpfilter", "IF Bandpass Filter Width", RadioSettingValueList(all_filters(), options[vx])) rs.set_doc("DSP IF bandpass Notch width (Hz)") mem.extra.append(rs) rs = RadioSetting("dnr_on", "DSP Noise Reduction", RadioSettingValueBoolean(bool(_mem.dnr_on))) rs.set_doc("Digital noise processing") mem.extra.append(rs) options = ["Off", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"] rs = RadioSetting("dnr_val", "DSP Noise Reduction Alg", RadioSettingValueList(options, options[_mem.dnr_val])) rs.set_doc("Digital noise reduction algorithm number (1-11)") mem.extra.append(rs) return mem # end get_memory def _set_memory(self, mem, _mem): if len(mem.name) > 0: _mem.tag_on_off = 2 else: _mem.tag_on_off = 1 self._set_duplex(mem, _mem) _mem.mode2 = 0 tmpmemmode = str(mem.mode) if mem.mode == "DIG": _mem.mode = 5 # We'll set _mode2 from extra data_modes elif tmpmemmode == "CWR": _mem.mode = 10 # 450 looks different if self.FT450: _mem.mode2 = 2 else: _mem.mode2 = 0 elif tmpmemmode == "CW": _mem.mode = 2 # 450 looks different if self.FT450: _mem.mode2 = 2 else: _mem.mode2 = 0 elif tmpmemmode == "NFM": _mem.mode = 4 _mem.mode2 = 1 elif tmpmemmode == "FM": _mem.mode = 4 _mem.mode2 = 2 elif tmpmemmode == "LSB": _mem.mode = 0 # 450 looks different if self.FT450: _mem.mode2 = 2 else: _mem.mode2 = 0 elif tmpmemmode == "USB": _mem.mode = 1 if self.FT450: _mem.mode2 = 2 else: _mem.mode2 = 0 elif tmpmemmode == "AM": _mem.mode = 3 if self.FT450: _mem.mode2 = 2 else: _mem.mode2 = 0 else: # SHOULD NOT OCCUR _mem.mode = self.MODES.index(mem.mode) _mem.mode2 = 0 try: _mem.ssb_step = self.STEPSSSB.index(mem.tuning_step) except ValueError: pass try: _mem.am_step = self.STEPSAM.index(mem.tuning_step) except ValueError: pass try: _mem.fm_step = self.STEPSFM.index(mem.tuning_step) except ValueError: pass _mem.freq = mem.freq _mem.uprband = 0 if mem.freq >= 33000000: _mem.uprband = 1 _mem.offset = mem.offset _mem.tmode = self.TMODES.index(mem.tmode) _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.tunerok = 0 # Dont know what these two do... _mem.tunerbad = 0 for i in range(0, 7): _mem.name[i] = ord(mem.name.ljust(7)[i]) for setting in mem.extra: if setting.get_name() == "notch_pos": vx = 0 # Override list string with signed value stx = str(setting.value) if stx == "<-": vx = -13 if stx == "+>": vx = 12 setattr(_mem, "notch_pos", vx) elif setting.get_name() == "dnr_val": stx = str(setting.value) # Convert string to int vx = 0 if stx != "Off": vx = int(stx) else: setattr(_mem, "dnr_on", 0) setattr(_mem, setting.get_name(), vx) elif setting.get_name() == "data_modes": if tmpmemmode == "DIG": stx = str(setting.value) if stx == "USER-L": if self.FT450: _mem.mode = 13 _mem.mode2 = 1 else: _mem.mode = 5 _mem.mode2 = 1 elif stx == "USER-U": _mem.mode = 5 _mem.mode2 = 2 elif stx == "RTTY": if self.FT450: _mem.mode = 13 _mem.mode2 = 0 else: _mem.mode = 5 _mem.mode2 = 0 elif stx == "N/A": _mem.mode = 5 _mem.mode2 = 2 else: LOG.error("In _set_memory invalid digital data type %s", stx) elif setting.get_name() == "bpfilter": element, options = filters_for_mode(mem.mode) if str(setting.value) in options: setattr(_mem, element, options.index(str(setting.value))) else: default = closest_filter(options, str(setting.value)) LOG.warning('Memory specified filter width of %s for ' 'mode %s which is not in allowed list of ' '%s. Defaulting to %s', str(setting.value), mem.mode, ','.join(options), default) setattr(_mem, element, options.index(default)) else: setattr(_mem, setting.get_name(), setting.value) @classmethod def match_model(cls, filedata, filename): """Match the opened/downloaded image to the correct version""" if len(filedata) == cls.MEM_SIZE + 7: # +7 bytes of model name rid = filedata[cls.MEM_SIZE:cls.MEM_SIZE + 7] if rid.startswith(cls.MODEL.encode()): return True else: return False def _invert_me(self, setting, obj, atrb): """Callback: from inverted logic 1-bit booleans""" invb = not setting.value setattr(obj, atrb, invb) return def _chars2str(self, cary, knt): """Convert raw memory char array to a string: NOT a callback.""" stx = "" for char in cary[0:knt]: stx += chr(int(char)) return stx def _my_str2ary(self, setting, obj, atrba, knt): """Callback: convert string to fixed-length char array..""" ary = "" for j in range(0, knt, 1): chx = ord(str(setting.value)[j]) if chx < 32 or chx > 125: # strip non-printing ary += " " else: ary += str(setting.value)[j] setattr(obj, atrba, ary) return def get_settings(self): _settings = self._memobj.settings _beacon = self._memobj.beacontext gen = RadioSettingGroup("gen", "General") cw = RadioSettingGroup("cw", "CW") pnlcfg = RadioSettingGroup("pnlcfg", "Panel buttons") pnlset = RadioSettingGroup("pnlset", "Panel settings") voxdat = RadioSettingGroup("voxdat", "VOX and Data") mic = RadioSettingGroup("mic", "Microphone") mybands = RadioSettingGroup("mybands", "My Bands") mymodes = RadioSettingGroup("mymodes", "My Modes") top = RadioSettings(gen, cw, pnlcfg, pnlset, voxdat, mic, mymodes, mybands) self._do_general_settings(gen) self._do_cw_settings(cw) self._do_panel_buttons(pnlcfg) self._do_panel_settings(pnlset) self._do_vox_settings(voxdat) self._do_mic_settings(mic) self._do_mymodes_settings(mymodes) self._do_mybands_settings(mybands) return top def _do_general_settings(self, tab): _settings = self._memobj.settings rs = RadioSetting("ext_mnu", "Extended menu", RadioSettingValueBoolean(_settings.ext_mnu)) rs.set_doc("Enables access to extended settings in the radio") tab.append(rs) # Issue #8183 bugfix rs = RadioSetting("apo", "APO time (Hrs)", RadioSettingValueInteger(0, 12, _settings.apo)) tab.append(rs) options = ["%i" % i for i in range(0, 21)] options[0] = "Off" rs = RadioSetting("tot", "TX 'TOT' time-out (mins)", RadioSettingValueList(options, options[_settings.tot])) tab.append(rs) bx = not _settings.cat_rts # Convert from Enable=0 rs = RadioSetting("cat_rts", "CAT RTS flow control", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "cat_rts") tab.append(rs) options = ["0", "100ms", "1000ms", "3000ms"] rs = RadioSetting("cat_tot", "CAT Timeout", RadioSettingValueList(options, options[_settings.cat_tot])) tab.append(rs) options = ["4800", "9600", "19200", "38400", "Data"] rs = RadioSetting("catrate", "CAT rate", RadioSettingValueList(options, options[_settings.catrate])) tab.append(rs) rs = RadioSetting("mem_grp", "Mem groups", RadioSettingValueBoolean(_settings.mem_grp)) tab.append(rs) rs = RadioSetting("scn_res", "Resume scan (secs)", RadioSettingValueInteger(0, 10, _settings.scn_res)) tab.append(rs) rs = RadioSetting("clk_sft", "CPU clock shift", RadioSettingValueBoolean(_settings.clk_sft)) tab.append(rs) rs = RadioSetting("split", "TX/RX Frequency Split", RadioSettingValueBoolean(_settings.split)) tab.append(rs) rs = RadioSetting("qspl_f", "Quick-Split freq offset (kHz)", RadioSettingValueInteger(-20, 20, _settings.qspl_f)) tab.append(rs) rs = RadioSetting("emergen", "Alaska Emergency Mem 5167.5 kHz", RadioSettingValueBoolean(_settings.emergen)) tab.append(rs) rs = RadioSetting("stby_beep", "PTT release 'Standby' beep", RadioSettingValueBoolean(_settings.stby_beep)) tab.append(rs) options = ["ATAS", "EXT ATU", "INT ATU", "INTRATU", "F-TRANS"] rs = RadioSetting("tuner", "Antenna Tuner", RadioSettingValueList(options, options[_settings.tuner])) tab.append(rs) rs = RadioSetting("rfpower", "RF power (watts)", RadioSettingValueInteger(5, 100, _settings.rfpower)) tab.append(rs) # End of _do_general_settings def _do_cw_settings(self, cw): # - - - CW - - - _settings = self._memobj.settings _beacon = self._memobj.beacontext rs = RadioSetting("cw_dly", "CW break-in delay (ms * 10)", RadioSettingValueInteger(0, 300, _settings.cw_dly)) cw.append(rs) options = ["%i Hz" % i for i in range(400, 801, 100)] rs = RadioSetting("cwpitch", "CW pitch", RadioSettingValueList(options, options[_settings.cwpitch])) cw.append(rs) rs = RadioSetting("cwspeed", "CW speed (wpm)", RadioSettingValueInteger(4, 60, _settings.cwspeed)) rs.set_doc("Cpm is Wpm * 5") cw.append(rs) options = ["1:%1.1f" % (i / 10) for i in range(25, 46, 1)] rs = RadioSetting("cwweigt", "CW weight", RadioSettingValueList(options, options[_settings.cwweigt])) cw.append(rs) options = ["15ms", "20ms", "25ms", "30ms"] rs = RadioSetting("cw_qsk", "CW delay before TX in QSK mode", RadioSettingValueList(options, options[_settings.cw_qsk])) cw.append(rs) rs = RadioSetting("cwstone_sgn", "CW sidetone volume Linked", RadioSettingValueBoolean(_settings.cwstone_sgn)) rs.set_doc("If set; volume is relative to AF Gain knob.") cw.append(rs) rs = RadioSetting("cwstone_lnk", "CW sidetone linked volume", RadioSettingValueInteger(-50, 50, _settings.cwstone_lnk)) cw.append(rs) rs = RadioSetting("cwstone_fix", "CW sidetone fixed volume", RadioSettingValueInteger(0, 100, _settings.cwstone_fix)) cw.append(rs) options = ["Numeric", "Alpha", "Mixed"] rs = RadioSetting("cwtrain", "CW Training mode", RadioSettingValueList(options, options[_settings.cwtrain])) cw.append(rs) rs = RadioSetting("cw_auto", "CW key jack- auto CW mode", RadioSettingValueBoolean(_settings.cw_auto)) rs.set_doc("Enable for CW mode auto-set when keyer pluuged in.") cw.append(rs) options = ["Normal", "Reverse"] rs = RadioSetting("cw_key", "CW paddle wiring", RadioSettingValueList(options, options[_settings.cw_key])) cw.append(rs) rs = RadioSetting("beacon_time", "CW beacon Tx interval (secs)", RadioSettingValueInteger(0, 255, _settings.beacon_time)) cw.append(rs) tmp = self._chars2str(_beacon.t1, 40) rs = RadioSetting("t1", "CW Beacon Line 1", RadioSettingValueString(0, 40, tmp)) rs.set_apply_callback(self._my_str2ary, _beacon, "t1", 40) cw.append(rs) tmp = self._chars2str(_beacon.t2, 40) rs = RadioSetting("t2", "CW Beacon Line 2", RadioSettingValueString(0, 40, tmp)) rs.set_apply_callback(self._my_str2ary, _beacon, "t2", 40) cw.append(rs) tmp = self._chars2str(_beacon.t3, 40) rs = RadioSetting("t3", "CW Beacon Line 3", RadioSettingValueString(0, 40, tmp)) rs.set_apply_callback(self._my_str2ary, _beacon, "t3", 40) cw.append(rs) # END _do_cw_settings def _do_panel_settings(self, pnlset): # - - - Panel settings _settings = self._memobj.settings bx = not _settings.amfmdial # Convert from Enable=0 rs = RadioSetting("amfmdial", "AM&FM Dial", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "amfmdial") pnlset.append(rs) options = ["440 Hz", "880 Hz", "1760 Hz"] rs = RadioSetting("beepton", "Beep frequency", RadioSettingValueList(options, options[_settings.beepton])) pnlset.append(rs) rs = RadioSetting("beepvol_sgn", "Beep volume Linked", RadioSettingValueBoolean(_settings.beepvol_sgn)) rs.set_doc("If set; volume is relative to AF Gain knob.") pnlset.append(rs) rs = RadioSetting("beepvol_lnk", "Linked beep volume", RadioSettingValueInteger(-50, 50, _settings.beepvol_lnk)) rs.set_doc("Relative to AF-Gain setting.") pnlset.append(rs) rs = RadioSetting("beepvol_fix", "Fixed beep volume", RadioSettingValueInteger(0, 100, _settings.beepvol_fix)) rs.set_doc("When Linked setting is unchecked.") pnlset.append(rs) rs = RadioSetting("cont", "LCD Contrast", RadioSettingValueInteger(1, 24, _settings.cont)) rs.set_doc("This setting does not appear to do anything...") pnlset.append(rs) rs = RadioSetting("dimmer", "LCD Dimmer", RadioSettingValueInteger(1, 8, _settings.dimmer)) pnlset.append(rs) options = ["RF-Gain", "Squelch"] rs = RadioSetting("sql_rfg", "Squelch/RF-Gain", RadioSettingValueList(options, options[_settings.sql_rfg])) pnlset.append(rs) options = ["Frequencies", "Panel", "All"] rs = RadioSetting("lockmod", "Lock Mode", RadioSettingValueList(options, options[_settings.lockmod])) pnlset.append(rs) options = ["Dial", "SEL"] rs = RadioSetting("clar_btn", "CLAR button control", RadioSettingValueList(options, options[_settings.clar_btn])) pnlset.append(rs) if _settings.dialstp_mode == 0: # AM/FM options = ["SSB/CW:1Hz", "SSB/CW:10Hz", "SSB/CW:20Hz"] else: options = ["AM/FM:100Hz", "AM/FM:200Hz"] rs = RadioSetting("dialstp", "Dial tuning step", RadioSettingValueList(options, options[_settings.dialstp])) pnlset.append(rs) options = ["0.5secs", "1.0secs", "1.5secs", "2.0secs"] rs = RadioSetting("keyhold", "Buttons hold-to-activate time", RadioSettingValueList(options, options[_settings.keyhold])) pnlset.append(rs) rs = RadioSetting("m_tune", "Memory tune", RadioSettingValueBoolean(_settings.m_tune)) pnlset.append(rs) rs = RadioSetting("peakhold", "S-Meter display hold (1sec)", RadioSettingValueBoolean(_settings.peakhold)) pnlset.append(rs) options = ["CW Sidetone", "CW Speed", "100 kHz step", "1 MHz Step", "Mic Gain", "RF Power"] rs = RadioSetting("seldial", "SEL dial 2nd function (push)", RadioSettingValueList(options, options[_settings.seldial])) pnlset.append(rs) # End _do_panel_settings def _do_panel_buttons(self, pnlcfg): # - - - Current Panel Config _settings = self._memobj.settings rs = RadioSetting("pnl_cs", "C.S. Function", RadioSettingValueList(self.FUNC_LIST, self.FUNC_LIST[_settings.pnl_cs])) pnlcfg.append(rs) rs = RadioSetting("nb", "Noise blanker", RadioSettingValueBoolean(_settings.nb)) pnlcfg.append(rs) # The old FT450 uses different codes for the AGC setting, and only uses the # last 3 bits of the AGC definition. The two upper bits appear to always be x"11" # We will mask this in the routine that processes the agc value if self.FT450: options = ["Auto", "Fast", "Slow", "UNK3", "UNK4", "UNK5", "OFF", "UNK7"] # mask off the two upper bits of the agc settings value FT450agc = _settings.agc & int('0x7',16) rs = RadioSetting("agc", "AGC", RadioSettingValueList(options, options[FT450agc])) else: options = ["Auto", "Fast", "Slow", "Auto/Fast", "Auto/Slow", "?5?"] rs = RadioSetting("agc", "AGC", RadioSettingValueList(options, options[_settings.agc])) pnlcfg.append(rs) rs = RadioSetting("keyer", "Keyer", RadioSettingValueBoolean(_settings.keyer)) pnlcfg.append(rs) rs = RadioSetting("fast", "Fast step", RadioSettingValueBoolean(_settings.fast)) pnlcfg.append(rs) rs = RadioSetting("lock", "Lock (per Lock Mode)", RadioSettingValueBoolean(_settings.lock)) pnlcfg.append(rs) options = ["PO", "ALC", "SWR"] rs = RadioSetting("mtr_mode", "S-Meter mode", RadioSettingValueList(options, options[_settings.mtr_mode])) pnlcfg.append(rs) # End _do_panel_Buttons def _do_vox_settings(self, voxdat): # - - VOX and DATA Settings _settings = self._memobj.settings rs = RadioSetting("vox_dly", "VOX delay (x 100 ms)", RadioSettingValueInteger(1, 30, _settings.vox_dly)) voxdat.append(rs) rs = RadioSetting("vox_gain", "VOX Gain", RadioSettingValueInteger(0, 100, _settings.vox_gain)) voxdat.append(rs) rs = RadioSetting("dig_vox", "Digital VOX Gain", RadioSettingValueInteger(0, 100, _settings.dig_vox)) voxdat.append(rs) rs = RadioSetting("d_disp", "User-L/U freq offset (Hz)", RadioSettingValueInteger(-3000, 30000, _settings.d_disp, 10)) voxdat.append(rs) options = ["170 Hz", "200 Hz", "425 Hz", "850 Hz"] rs = RadioSetting("rty_sft", "RTTY FSK Freq Shift", RadioSettingValueList(options, options[_settings.rty_sft])) voxdat.append(rs) options = ["1275 Hz", "2125 Hz"] rs = RadioSetting("rty_ton", "RTTY FSK Mark tone", RadioSettingValueList(options, options[_settings.rty_ton])) voxdat.append(rs) options = ["Normal", "Reverse"] rs = RadioSetting("rtyrpol", "RTTY Mark/Space RX polarity", RadioSettingValueList(options, options[_settings.rtyrpol])) voxdat.append(rs) rs = RadioSetting("rtytpol", "RTTY Mark/Space TX polarity", RadioSettingValueList(options, options[_settings.rtytpol])) voxdat.append(rs) # End _do_vox_settings def _do_mic_settings(self, mic): # - - MIC Settings _settings = self._memobj.settings rs = RadioSetting("mic_eq", "Mic Equalizer", RadioSettingValueInteger(0, 9, _settings.mic_eq)) mic.append(rs) options = ["Low", "Normal", "High"] rs = RadioSetting("micgain", "Mic Gain", RadioSettingValueList(options, options[_settings.micgain])) mic.append(rs) rs = RadioSetting("micscan", "Mic scan enabled", RadioSettingValueBoolean(_settings.micscan)) rs.set_doc("Enables channel scanning via mic up/down buttons.") mic.append(rs) rs = RadioSetting("pm_dwn", "Mic Down button function", RadioSettingValueList(self.FUNC_LIST, self.FUNC_LIST[_settings.pm_dwn])) mic.append(rs) rs = RadioSetting("pm_fst", "Mic Fast button function", RadioSettingValueList(self.FUNC_LIST, self.FUNC_LIST[_settings.pm_fst])) mic.append(rs) rs = RadioSetting("pm_up", "Mic Up button function", RadioSettingValueList(self.FUNC_LIST, self.FUNC_LIST[_settings.pm_up])) mic.append(rs) # End _do_mic_settings def _do_mymodes_settings(self, mymodes): # - - MYMODES _settings = self._memobj.settings # Inverted Logic requires callback bx = not _settings.mym_lsb rs = RadioSetting("mym_lsb", "LSB", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "mym_lsb") mymodes.append(rs) bx = not _settings.mym_usb rs = RadioSetting("mym_usb", "USB", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "mym_usb") mymodes.append(rs) bx = not _settings.mym_cw rs = RadioSetting("mym_cw", "CW", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "mym_cw") mymodes.append(rs) bx = not _settings.mym_am rs = RadioSetting("mym_am", "AM", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "mym_am") mymodes.append(rs) bx = not _settings.mym_fm rs = RadioSetting("mym_fm", "FM", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "mym_fm") mymodes.append(rs) bx = not _settings.mym_data rs = RadioSetting("mym_data", "DATA", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "mym_data") mymodes.append(rs) # End _do_mymodes_settings def _do_mybands_settings(self, mybands): # - - MYBANDS Settings _settings = self._memobj.settings # Inverted Logic requires callback bx = not _settings.myb_1_8 rs = RadioSetting("myb_1_8", "1.8 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_1_8") mybands.append(rs) bx = not _settings.myb_3_5 rs = RadioSetting("myb_3_5", "3.5 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_3_5") mybands.append(rs) bx = not _settings.myb_7 rs = RadioSetting("myb_7", "7 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_7") mybands.append(rs) bx = not _settings.myb_10 rs = RadioSetting("myb_10", "10 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_10") mybands.append(rs) bx = not _settings.myb_14 rs = RadioSetting("myb_14", "14 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_14") mybands.append(rs) bx = not _settings.myb_18 rs = RadioSetting("myb_18", "18 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_18") mybands.append(rs) bx = not _settings.myb_21 rs = RadioSetting("myb_21", "21 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_21") mybands.append(rs) bx = not _settings.myb_24 rs = RadioSetting("myb_24", "24 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_24") mybands.append(rs) bx = not _settings.myb_28 rs = RadioSetting("myb_28", "28 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_28") mybands.append(rs) bx = not _settings.myb_50 rs = RadioSetting("myb_50", "50 MHz", RadioSettingValueBoolean(bx)) rs.set_apply_callback(self._invert_me, _settings, "myb_50") mybands.append(rs) # End _do_mybands_settings def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[: -1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def validate_memory(self, mem): msgs = super().validate_memory(mem) if 'bpfilter' in mem.extra: _, options = filters_for_mode(mem.mode) bpfilter = str(mem.extra['bpfilter'].value) if bpfilter not in options: msgs.append(chirp_common.ValidationWarning( ('Filter width %s is not allowed for mode %s - ' 'the closest suitable option %s will be used') % ( bpfilter, mem.mode, closest_filter(options, bpfilter)))) return msgs @directory.register class FT450Radio(FT450DRadio): """Yaesu FT-450""" FT450 = True MODEL = "FT-450" @classmethod def match_model(cls, filedata, filename): return False chirp-20240224/chirp/drivers/generic_csv.py0000644000175000017500000004222414562640504017472 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import csv import logging from chirp import chirp_common, errors, directory LOG = logging.getLogger(__name__) DEFAULT_POWER_LEVEL = chirp_common.AutoNamedPowerLevel(50) class OmittedHeaderError(Exception): """Internal exception to signal that a column has been omitted""" pass def get_datum_by_header(headers, data, header): """Return the column corresponding to @headers[@header] from @data""" if header not in headers: raise OmittedHeaderError("Header %s not provided" % header) try: return data[headers.index(header)] except IndexError: raise OmittedHeaderError("Header %s not provided on this line" % header) def write_memory(writer, mem): """Write @mem using @writer if not empty""" if mem.empty: return writer.writerow(mem.to_csv()) def parse_cross_mode(value): if value not in chirp_common.CROSS_MODES: raise ValueError('Invalid cross mode %r' % value) return value @directory.register class CSVRadio(chirp_common.FileBackedRadio): """A driver for Generic CSV files""" VENDOR = "Generic" MODEL = "CSV" FILE_EXTENSION = "csv" FORMATS = [directory.register_format('CSV', '*.csv')] ATTR_MAP = { "Location": (int, "number"), "Name": (str, "name"), "Frequency": (chirp_common.parse_freq, "freq"), "Duplex": (str, "duplex"), "Offset": (chirp_common.parse_freq, "offset"), "Tone": (str, "tmode"), "rToneFreq": (float, "rtone"), "cToneFreq": (float, "ctone"), "DtcsCode": (int, "dtcs"), "DtcsPolarity": (str, "dtcs_polarity"), "RxDtcsCode": (int, "rx_dtcs"), "CrossMode": (parse_cross_mode, "cross_mode"), "Mode": (str, "mode"), "TStep": (float, "tuning_step"), "Skip": (str, "skip"), "Power": (chirp_common.parse_power, "power"), "Comment": (str, "comment"), } def _blank(self, setDefault=False): self.errors = [] self.memories = [chirp_common.Memory(i, True) for i in range(0, 1000)] if (setDefault): self.memories[0].empty = False self.memories[0].freq = 146010000 # Default to 50W self.memories[0].power = DEFAULT_POWER_LEVEL def __init__(self, pipe): chirp_common.FileBackedRadio.__init__(self, None) self.memories = [] self.file_has_rTone = None # Set in load(), used in _clean_tmode() self.file_has_cTone = None # Persistence for comment lines # List of tuples of (previous_memory, comment) self._comments = [] self._filename = pipe if self._filename and os.path.exists(self._filename): self.load() else: self._blank(True) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.requires_call_lists = False rf.has_implicit_calls = False rf.memory_bounds = (0, len(self.memories)-1) rf.has_infinite_number = True rf.has_nostep_tuning = True rf.has_comment = True rf.has_rx_dtcs = True rf.has_variable_power = True rf.can_odd_split = True rf.valid_modes = list(chirp_common.MODES) rf.valid_tmodes = list(chirp_common.TONE_MODES) rf.valid_cross_modes = list(chirp_common.CROSS_MODES) rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tuning_steps = list(chirp_common.TUNING_STEPS) rf.valid_bands = [(1, 10000000000)] rf.valid_skips = ["", "S"] rf.valid_characters = chirp_common.CHARSET_1252 rf.valid_name_length = 999 rf.valid_power_levels = [chirp_common.AutoNamedPowerLevel(0.1), DEFAULT_POWER_LEVEL, chirp_common.AutoNamedPowerLevel(1500)] return rf def _clean(self, headers, line, mem): """Runs post-processing functions on new mem objects. This is useful for parsing other CSV dialects when multiple columns convert to a single Chirp column.""" for attr in dir(mem): fname = "_clean_%s" % attr if hasattr(self, fname): mem = getattr(self, fname)(headers, line, mem) return mem def _clean_tmode(self, headers, line, mem): """ If there is exactly one of [rToneFreq, cToneFreq] columns in the csv file, use it for both rtone & ctone. Makes TSQL use friendlier.""" if self.file_has_rTone and not self.file_has_cTone: mem.ctone = mem.rtone elif self.file_has_cTone and not self.file_has_rTone: mem.rtone = mem.ctone return mem def _parse_csv_data_line(self, headers, line): mem = chirp_common.Memory() try: if get_datum_by_header(headers, line, "Mode") == "DV": mem = chirp_common.DVMemory() except OmittedHeaderError: pass for header in headers: try: typ, attr = self.ATTR_MAP[header] except KeyError: continue try: val = get_datum_by_header(headers, line, header) if not val and typ == int: val = None else: val = typ(val) if hasattr(mem, attr): setattr(mem, attr, val) except OmittedHeaderError: pass except Exception as e: raise Exception("[%s] %s" % (attr, e)) if not mem.power: # Default power level to something if not set mem.power = DEFAULT_POWER_LEVEL return self._clean(headers, line, mem) def load(self, filename=None): if filename is None and self._filename is None: raise errors.RadioError("Need a location to load from") if filename: self._filename = filename self._blank() with open(self._filename, newline='', encoding='utf-8-sig') as f: return self._load(f) def _load(self, f): reader = csv.reader(f, delimiter=chirp_common.SEPCHAR, quotechar='"') self._comments = [] good = 0 lineno = 0 last_number = -1 for line in reader: # Skip (but stash) comment lines that start with # if line and line[0].startswith('#'): self._comments.append((last_number, ' '.join(line))) continue lineno += 1 if lineno == 1: header = line self.file_has_rTone = "rToneFreq" in header self.file_has_cTone = "cToneFreq" in header continue if len(header) > len(line): LOG.error("Line %i has %i columns, expected %i", lineno, len(line), len(header)) self.errors.append("Column number mismatch on line %i" % lineno) continue try: mem = self._parse_csv_data_line(header, line) if mem.number is None: raise Exception("Invalid Location field" % lineno) except Exception as e: LOG.error("Line %i: %s", lineno, e) self.errors.append("Line %i: %s" % (lineno, e)) continue last_number = mem.number self._grow(mem.number) self.memories[mem.number] = mem good += 1 if not good: LOG.error(self.errors) raise errors.InvalidDataError("No channels found") def save(self, filename=None): if filename is None and self._filename is None: raise errors.RadioError("Need a location to save to") if filename: self._filename = filename with open(self._filename, "w", newline='', encoding='utf-8') as f: comments = list(self._comments) writer = csv.writer(f, delimiter=chirp_common.SEPCHAR) for index, comment in comments[:]: if index >= 0: break writer.writerow([comment]) comments.pop(0) writer.writerow(chirp_common.Memory.CSV_FORMAT) for mem in self.memories: for index, comment in comments[:]: if index >= mem.number: break writer.writerow([comment]) comments.pop(0) write_memory(writer, mem) # MMAP compatibility def save_mmap(self, filename): return self.save(filename) def load_mmap(self, filename): return self.load(filename) def get_memories(self, lo=0, hi=999): return [x for x in self.memories if x.number >= lo and x.number <= hi] def get_memory(self, number): try: return self.memories[number].dupe() except: raise errors.InvalidMemoryLocation("No such memory %s" % number) def _grow(self, target): delta = target - len(self.memories) if delta < 0: return delta += 1 for i in range(len(self.memories), len(self.memories) + delta + 1): mem = chirp_common.Memory() mem.empty = True mem.number = i self.memories.append(mem) def set_memory(self, newmem): newmem = newmem.dupe() if newmem.power is None: newmem.power = DEFAULT_POWER_LEVEL else: # Accept any power level because we are CSV, but convert it to # the class that will str() into our desired format. newmem.power = chirp_common.AutoNamedPowerLevel( chirp_common.dBm_to_watts(float(newmem.power))) self._grow(newmem.number) self.memories[newmem.number] = newmem self.memories[newmem.number].name = newmem.name.rstrip() def erase_memory(self, number): mem = chirp_common.Memory() mem.number = number mem.empty = True self.memories[number] = mem def get_raw_memory(self, number): return ",".join(chirp_common.Memory.CSV_FORMAT) + \ os.linesep + \ ",".join(self.memories[number].to_csv()) @classmethod def match_model(cls, filedata, filename): """Match files ending in .CSV""" try: filedata = filedata.decode() except UnicodeDecodeError: # CSV files are text return False return filename.lower().endswith("." + cls.FILE_EXTENSION) and \ (find_csv_header(filedata) or filedata == "") def find_csv_header(filedata): while filedata.startswith('#'): filedata = filedata[filedata.find('\n') + 1:] return filedata.startswith('Location,') @directory.register class CommanderCSVRadio(CSVRadio): """A driver for reading CSV files generated by KG-UV Commander software""" VENDOR = "Commander" MODEL = "KG-UV" FILE_EXTENSION = "csv" MODE_MAP = { "NARR": "NFM", "WIDE": "FM", } SCAN_MAP = { "ON": "", "OFF": "S" } ATTR_MAP = { "#": (int, "number"), "Name": (str, "name"), "RX Freq": (chirp_common.parse_freq, "freq"), "Scan": (lambda v: CommanderCSVRadio.SCAN_MAP.get(v), "skip"), "TX Dev": (lambda v: CommanderCSVRadio.MODE_MAP.get(v), "mode"), "Group/Notes": (str, "comment"), } def _clean_number(self, headers, line, mem): if mem.number == 0: for memory in self.memories: if memory.empty: mem.number = memory.number break return mem def _clean_duplex(self, headers, line, mem): try: txfreq = chirp_common.parse_freq( get_datum_by_header(headers, line, "TX Freq")) except ValueError: mem.duplex = "off" return mem if mem.freq == txfreq: mem.duplex = "" elif txfreq: mem.duplex = "split" mem.offset = txfreq return mem def _clean_tmode(self, headers, line, mem): rtone = get_datum_by_header(headers, line, "Encode") ctone = get_datum_by_header(headers, line, "Decode") if rtone == "OFF": rtone = None else: rtone = float(rtone) if ctone == "OFF": ctone = None else: ctone = float(ctone) if rtone: mem.tmode = "Tone" if ctone: mem.tmode = "TSQL" mem.rtone = rtone or 88.5 mem.ctone = ctone or mem.rtone return mem @classmethod def match_model(cls, filedata, filename): """Match files ending in .csv and using Commander column names.""" return filename.lower().endswith("." + cls.FILE_EXTENSION) and \ filedata.startswith(b"Name,RX Freq,TX Freq,Decode,Encode,TX Pwr," b"Scan,TX Dev,Busy Lck,Group/Notes") or \ filedata.startswith(b'"#","Name","RX Freq","TX Freq","Decode",' b'"Encode","TX Pwr","Scan","TX Dev",' b'"Busy Lck","Group/Notes"') @directory.register class RTCSVRadio(CSVRadio): """A driver for reading CSV files generated by RT Systems software""" VENDOR = "RT Systems" MODEL = "CSV" FILE_EXTENSION = "csv" DUPLEX_MAP = { "Minus": "-", "Plus": "+", "Simplex": "", "Split": "split", } SKIP_MAP = { "Off": "", "On": "S", "P Scan": "P", "Skip": "S", } TMODE_MAP = { "None": "", "T Sql": "TSQL", } BOOL_MAP = { "Off": False, "On": True, } ATTR_MAP = { "Channel Number": (int, "number"), "Receive Frequency": (chirp_common.parse_freq, "freq"), "Offset Frequency": (chirp_common.parse_freq, "offset"), "Offset Direction": (lambda v: RTCSVRadio.DUPLEX_MAP.get(v, v), "duplex"), "Operating Mode": (str, "mode"), "Name": (str, "name"), "Tone Mode": (lambda v: RTCSVRadio.TMODE_MAP.get(v, v), "tmode"), "CTCSS": (lambda v: float(v.split(" ")[0]), "rtone"), "DCS": (int, "dtcs"), "Skip": (lambda v: RTCSVRadio.SKIP_MAP.get(v, v), "skip"), "Step": (lambda v: float(v.split(" ")[0]), "tuning_step"), "Mask": (lambda v: RTCSVRadio.BOOL_MAP.get(v, v), "empty",), "Comment": (str, "comment"), } def _clean_duplex(self, headers, line, mem): if mem.duplex == "split": try: val = get_datum_by_header(headers, line, "Transmit Frequency") val = chirp_common.parse_freq(val) mem.offset = val except OmittedHeaderError: pass return mem def _clean_mode(self, headers, line, mem): if mem.mode == "FM": try: val = get_datum_by_header(headers, line, "Half Dev") if self.BOOL_MAP[val]: mem.mode = "FMN" except OmittedHeaderError: pass return mem def _clean_ctone(self, headers, line, mem): # RT Systems only stores a single tone value mem.ctone = mem.rtone return mem @classmethod def match_model(cls, filedata, filename): """Match files ending in .csv and using RT Systems column names.""" # RT Systems provides a different set of columns for each radio. # We attempt to match only the first few columns, hoping they are # consistent across radio models. try: filedata = filedata.decode() except UnicodeDecodeError: # CSV files are text return False return filename.lower().endswith("." + cls.FILE_EXTENSION) and \ filedata.startswith("Channel Number,Receive Frequency," "Transmit Frequency,Offset Frequency," "Offset Direction,Operating Mode," "Name,Tone Mode,CTCSS,DCS") chirp-20240224/chirp/drivers/ic2820.py0000644000175000017500000002254214447245346016122 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, util, directory, bitwise MEM_FORMAT = """ struct { u32 freq; u32 offset; char urcall[8]; char r1call[8]; char r2call[8]; u8 unknown1; u8 unknown2:1, duplex:2, tmode:3, unknown3:2; u16 ctone:6, rtone:6, tune_step:4; u16 dtcs:7, mode:3, unknown4:6; u8 unknown5:1, digital_code:7; u8 unknown6:2, dtcs_polarity:2, unknown7:4; char name[8]; } memory[522]; #seekto 0x61E0; u8 used_flags[66]; #seekto 0x6222; u8 skip_flags[65]; u8 pskip_flags[65]; #seekto 0x62A4; struct { u8 bank; u8 index; } bank_info[500]; #seekto 0x66C0; struct { char name[8]; } bank_names[26]; #seekto 0x6970; struct { char call[8]; u8 unknown[4]; } mycall[6]; #seekto 0x69B8; struct { char call[8]; } urcall[60]; struct { char call[8]; } rptcall[60]; """ TMODES = ["", "Tone", "??0", "TSQL", "??1", "??2", "DTCS"] DUPLEX = ["", "-", "+", "+"] # Not sure about index 3 MODES = ["FM", "NFM", "AM", "??", "DV"] DTCSP = ["NN", "NR", "RN", "RR"] MEM_LOC_SIZE = 48 class IC2820Bank(icf.IcomNamedBank): """An IC2820 bank""" def get_name(self): _banks = self._model._radio._memobj.bank_names return str(_banks[self.index].name).rstrip() def set_name(self, name): _banks = self._model._radio._memobj.bank_names _banks[self.index].name = str(name).ljust(8)[:8] def _get_special(): special = {"C0": 500 + 20, "C1": 500 + 21} for i in range(0, 10): ida = "%iA" % i idb = "%iB" % i special[ida] = 500 + i * 2 special[idb] = 500 + i * 2 + 1 return special def _resolve_memory_number(number): if isinstance(number, str): return _get_special()[number] else: return number def _wipe_memory(mem, char): mem.set_raw(char * (mem.size() // 8)) @directory.register class IC2820Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): """Icom IC-2820""" VENDOR = "Icom" MODEL = "IC-2820H" _model = "\x29\x70\x00\x01" _memsize = 44224 _endframe = "Icom Inc\x2e68" _ranges = [(0x0000, 0x6960, 32), (0x6960, 0x6980, 16), (0x6980, 0x7160, 32), (0x7160, 0x7180, 16), (0x7180, 0xACC0, 32), ] _num_banks = 26 _bank_class = IC2820Bank _can_hispeed = True MYCALL_LIMIT = (1, 7) URCALL_LIMIT = (1, 61) RPTCALL_LIMIT = (1, 61) _memories = {} def _get_bank(self, loc): _bank = self._memobj.bank_info[loc] if _bank.bank == 0xFF: return None else: return _bank.bank def _set_bank(self, loc, bank): _bank = self._memobj.bank_info[loc] if bank is None: _bank.bank = 0xFF else: _bank.bank = bank def _get_bank_index(self, loc): _bank = self._memobj.bank_info[loc] return _bank.index def _set_bank_index(self, loc, index): _bank = self._memobj.bank_info[loc] _bank.index = index def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank_index = True rf.has_bank_names = True rf.requires_call_lists = False rf.memory_bounds = (0, 499) rf.valid_modes = [x for x in MODES if '?' not in x] rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(set(DUPLEX)) rf.valid_tuning_steps = list(chirp_common.TUNING_STEPS) rf.valid_bands = [(118000000, 999990000)] rf.valid_skips = ["", "S", "P"] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 8 rf.valid_special_chans = sorted(_get_special().keys()) return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_memory(self, number): number = _resolve_memory_number(number) bitpos = (1 << (number % 8)) bytepos = number / 8 _mem = self._memobj.memory[number] _used = self._memobj.used_flags[bytepos] is_used = ((_used & bitpos) == 0) if is_used and MODES[_mem.mode] == "DV": mem = chirp_common.DVMemory() mem.dv_urcall = str(_mem.urcall).rstrip() mem.dv_rpt1call = str(_mem.r1call).rstrip() mem.dv_rpt2call = str(_mem.r2call).rstrip() else: mem = chirp_common.Memory() mem.number = number if number < 500: _skip = self._memobj.skip_flags[bytepos] _pskip = self._memobj.pskip_flags[bytepos] if _skip & bitpos: mem.skip = "S" elif _pskip & bitpos: mem.skip = "P" else: mem.extd_number = util.get_dict_rev(_get_special(), number) mem.immutable = ["number", "skip", "extd_number"] if not is_used: mem.empty = True return mem mem.freq = int(_mem.freq) mem.offset = int(_mem.offset) mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.mode = MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCSP[_mem.dtcs_polarity] if _mem.tune_step > 8: mem.tuning_step = 5.0 # Sometimes TS is garbage? else: mem.tuning_step = chirp_common.TUNING_STEPS[_mem.tune_step] mem.name = str(_mem.name).rstrip() return mem def set_memory(self, mem): bitpos = (1 << (mem.number % 8)) bytepos = mem.number / 8 _mem = self._memobj.memory[mem.number] _used = self._memobj.used_flags[bytepos] was_empty = _used & bitpos if mem.number < 500: skip = self._memobj.skip_flags[bytepos] pskip = self._memobj.pskip_flags[bytepos] if mem.skip == "S": skip |= bitpos else: skip &= ~bitpos if mem.skip == "P": pskip |= bitpos else: pskip &= ~bitpos if mem.empty: _used |= bitpos _wipe_memory(_mem, "\xFF") if mem.number < 500: self._set_bank(mem.number, None) return _used &= ~bitpos if was_empty: _wipe_memory(_mem, "\x00") _mem.freq = mem.freq _mem.offset = mem.offset _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) _mem.mode = MODES.index(mem.mode) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = DTCSP.index(mem.dtcs_polarity) _mem.tune_step = chirp_common.TUNING_STEPS.index(mem.tuning_step) _mem.name = mem.name.ljust(8) if isinstance(mem, chirp_common.DVMemory): _mem.urcall = mem.dv_urcall.ljust(8) _mem.r1call = mem.dv_rpt1call.ljust(8) _mem.r2call = mem.dv_rpt2call.ljust(8) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_urcall_list(self): _calls = self._memobj.urcall calls = [] for i in range(*self.URCALL_LIMIT): calls.append(str(_calls[i-1].call)) return calls def get_repeater_call_list(self): _calls = self._memobj.rptcall calls = [] for i in range(*self.RPTCALL_LIMIT): calls.append(str(_calls[i-1].call)) return calls def get_mycall_list(self): _calls = self._memobj.mycall calls = [] for i in range(*self.MYCALL_LIMIT): calls.append(str(_calls[i-1].call)) return calls def set_urcall_list(self, calls): _calls = self._memobj.urcall for i in range(*self.URCALL_LIMIT): try: call = calls[i-1] except IndexError: call = " " * 8 _calls[i-1].call = call.ljust(8)[:8] def set_repeater_call_list(self, calls): _calls = self._memobj.rptcall for i in range(*self.RPTCALL_LIMIT): try: call = calls[i-1] except IndexError: call = " " * 8 _calls[i-1].call = call.ljust(8)[:8] def set_mycall_list(self, calls): _calls = self._memobj.mycall for i in range(*self.MYCALL_LIMIT): try: call = calls[i-1] except IndexError: call = " " * 8 _calls[i-1].call = call.ljust(8)[:8] chirp-20240224/chirp/drivers/ict70.py0000644000175000017500000001417614411666130016132 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, directory, bitwise MEM_FORMAT = """ struct { u24 freq; ul16 offset; char name[6]; u8 unknown2:2, rtone:6; u8 unknown3:2, ctone:6; u8 unknown4:1, dtcs:7; u8 tuning_step:4, narrow:1, unknown5:1, duplex:2; u8 unknown6:1, power:2, dtcs_polarity:2, tmode:3; } memory[300]; #seekto 0x12E0; u8 used[38]; #seekto 0x1306; u8 skips[38]; #seekto 0x132C; u8 pskips[38]; #seekto 0x1360; struct { u8 bank; u8 index; } banks[300]; #seekto 0x16D0; struct { char name[6]; } bank_names[26]; """ TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS"] DUPLEX = ["", "-", "+"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] TUNING_STEPS = [5.0, 5.0, 5.0, 5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 125.0, 200.0] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5), chirp_common.PowerLevel("Low", watts=0.5), chirp_common.PowerLevel("Mid", watts=1.0), ] class ICT70Bank(icf.IcomBank): """ICT70 bank""" def get_name(self): _bank = self._model._radio._memobj.bank_names[self.index] return str(_bank.name).rstrip() def set_name(self, name): _bank = self._model._radio._memobj.bank_names[self.index] _bank.name = name.ljust(6)[:6] @directory.register class ICT70Radio(icf.IcomCloneModeRadio): """Icom IC-T70""" VENDOR = "Icom" MODEL = "IC-T70" _model = "\x32\x53\x00\x01" _memsize = 0x19E0 _endframe = "Icom Inc\x2eCF" _ranges = [(0x0000, 0x19E0, 32)] _num_banks = 26 _bank_class = ICT70Bank def _get_bank(self, loc): _bank = self._memobj.banks[loc] if _bank.bank != 0xFF: return _bank.bank else: return None def _set_bank(self, loc, bank): _bank = self._memobj.banks[loc] if bank is None: _bank.bank = 0xFF else: _bank.bank = bank def _get_bank_index(self, loc): _bank = self._memobj.banks[loc] return _bank.index def _set_bank_index(self, loc, index): _bank = self._memobj.banks[loc] _bank.index = index def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 299) rf.valid_tmodes = TMODES rf.valid_duplexes = DUPLEX rf.valid_power_levels = POWER_LEVELS rf.valid_modes = ["FM", "NFM"] rf.valid_bands = [(136000000, 174000000), (400000000, 479000000)] rf.valid_skips = ["", "S", "P"] rf.valid_tuning_steps = TUNING_STEPS rf.valid_name_length = 6 rf.has_ctone = True rf.has_bank = True rf.has_bank_index = True rf.has_bank_names = True return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): bit = 1 << (number % 8) byte = int(number / 8) _mem = self._memobj.memory[number] _usd = self._memobj.used[byte] _skp = self._memobj.skips[byte] _psk = self._memobj.pskips[byte] mem = chirp_common.Memory() mem.number = number if _usd & bit: mem.empty = True return mem if _mem.freq & 0x800000: mem.freq = (_mem.freq & ~0x800000) * 6250 else: mem.freq = _mem.freq * 5000 mem.offset = _mem.offset * 5000 mem.name = str(_mem.name).rstrip() mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.tuning_step = TUNING_STEPS[_mem.tuning_step] mem.mode = _mem.narrow and "NFM" or "FM" mem.duplex = DUPLEX[_mem.duplex] mem.power = POWER_LEVELS[_mem.power] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.tmode = TMODES[_mem.tmode] mem.skip = (_psk & bit and "P") or (_skp & bit and "S") or "" return mem def set_memory(self, mem): bit = 1 << (mem.number % 8) byte = int(mem.number / 8) _mem = self._memobj.memory[mem.number] _usd = self._memobj.used[byte] _skp = self._memobj.skips[byte] _psk = self._memobj.pskips[byte] _mem.set_raw("\x00" * (_mem.size() // 8)) if mem.empty: _usd |= bit return _usd &= ~bit if chirp_common.is_12_5(mem.freq): _mem.freq = (mem.freq // 6250) | 0x800000 else: _mem.freq = mem.freq // 5000 _mem.offset = mem.offset // 5000 _mem.name = mem.name.ljust(6)[:6] _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tuning_step = TUNING_STEPS.index(mem.tuning_step) _mem.narrow = mem.mode == "NFM" _mem.duplex = DUPLEX.index(mem.duplex) _mem.dtcs_polarity = DTCS_POLARITY.index(mem.dtcs_polarity) _mem.tmode = TMODES.index(mem.tmode) if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 if mem.skip == "S": _skp |= bit _psk &= ~bit elif mem.skip == "P": _skp &= ~bit _psk |= bit else: _skp &= ~bit _psk &= ~bit chirp-20240224/chirp/drivers/tdxone_tdq8a.py0000644000175000017500000007640214522657251017615 0ustar hibbyhibby# Copyright 2016: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown1:2, dtmf:1, // DTMF unknown2:1, bcl:1, // Busy Channel Lockout unknown3:3; u8 unknown4:1, scan:1, // Scan Add highpower:1, // TX Power Level wide:1, // BandWidth unknown5:4; u8 unknown6[2]; } memory[128]; #seekto 0x0E17; struct { u8 displayab:1, // Selected Display unknown1:6, unknown2:1; } settings1; #seekto 0x0E22; struct { u8 squelcha; // menu 02a Squelch Level 0xe22 u8 unknown1; u8 tdrab; // TDR A/B 0xe24 u8 roger; // menu 20 Roger Beep 0xe25 u8 timeout; // menu 16 TOT 0xe26 u8 vox; // menu 05 VOX 0xe27 u8 unknown2; u8 mdfb; // menu 27b Memory Display Format B 0xe37 u8 dw; // menu 37 DW 0xe2a u8 tdr; // menu 29 Dual Watch 0xe2b u8 voice; // menu 03 Voice Prompts 0xe2c u8 beep; // menu 01 Key Beep 0xe2d u8 ani; // menu 30 ANI 0xe2e u8 unknown3[4]; u8 pttdly; // menu 31 PTT-ID Delay 0xe33 u8 unknown4; u8 dtmfst; // menu 33 DTMF Side Tone 0xe35 u8 toa; // menu 15 TOT Pre-Alert 0xe36 u8 mdfa; // menu 27a Memory Display Format A 0xe37 u8 screv; // menu 09 Scan Resume Method 0xe38 u8 pttid; // menu 32 PTT-ID Enable 0xe39 u8 ponmsg; // menu 36 Power-on Message 0xe3a u8 pf1; // menu 28 Programmable Function Key 0xe3b u8 unknown5; u8 wtled; // menu 17 Standby LED Color 0xe3d u8 rxled; // menu 18 RX LED Color 0xe3e u8 txled; // menu 19 TX LED Color 0xe3f u8 unknown6; u8 autolk; // menu 06 Auto Key Lock 0xe41 u8 squelchb; // menu 02b Squelch Level 0xe42 u8 control; // Control Code 0xe43 u8 unknown7; u8 ach; // Selected A channel Number 0xe45 u8 unknown8[4]; u8 password[6]; // Control Password 0xe4a-0xe4f u8 unknown9[7]; u8 code[3]; // PTT ID Code 0xe57-0xe59 u8 vfomr; // Frequency/Channel Modevel 0xe5a u8 keylk; // Key Lock 0xe5b u8 unknown10[2]; u8 prioritych; // Priority Channel 0xe5e u8 bch; // Selected B channel Number 0xe5f } settings; struct vfo { u8 unknown0[8]; u8 freq[8]; u8 offset[6]; ul16 rxtone; ul16 txtone; u8 unused0:7, band:1; u8 unknown3; u8 unknown4:2, sftd:2, scode:4; u8 unknown5; u8 unknown6:1, step:3, unknown7:4; u8 txpower:1, widenarr:1, unknown8:6; }; #seekto 0x0F10; struct { struct vfo a; struct vfo b; } vfo; #seekto 0x1010; struct { u8 name[6]; u8 unknown[10]; } names[128]; """ # #### MAGICS ######################################################### # TDXone TD-Q8A magic string MSTRING_TDQ8A = "\x02PYNCRAM" LIST_DTMF = ["QT", "QT+DTMF"] LIST_VOICE = ["Off", "Chinese", "English"] LIST_OFF1TO9 = ["Off"] + list("123456789") LIST_OFF1TO10 = LIST_OFF1TO9 + ["10"] LIST_RESUME = ["Time Operated(TO)", "Carrier Operated(CO)", "Search(SE)"] LIST_COLOR = ["Off", "Blue", "Orange", "Purple"] LIST_MODE = ["Channel", "Frequency", "Name"] LIST_PF1 = ["Off", "Scan", "Lamp", "FM Radio", "Alarm"] LIST_OFF1TO30 = ["OFF"] + ["%s" % x for x in range(1, 31)] LIST_DTMFST = ["Off", "DTMF Sidetone", "ANI Sidetone", "DTMF+ANI Sidetone"] LIST_PONMSG = ["Full", "Welcome", "Battery Voltage"] LIST_TIMEOUT = ["Off"] + ["%s sec" % x for x in range(15, 615, 15)] LIST_PTTID = ["BOT", "EOT", "Both"] LIST_ROGER = ["Off"] + LIST_PTTID LIST_PRIORITY = ["Off"] + ["%s" % x for x in range(1, 129)] LIST_WORKMODE = ["Frequency", "Channel"] LIST_AB = ["A", "B"] LIST_ALMOD = ["Site", "Tone", "Code"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_DELAYPROCTIME = ["%s ms" % x for x in range(100, 4100, 100)] LIST_DTMFSPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_OFFAB = ["Off"] + LIST_AB LIST_RESETTIME = ["%s ms" % x for x in range(100, 16100, 100)] LIST_SCODE = ["%s" % x for x in range(1, 16)] LIST_RPSTE = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SHIFTD = ["Off", "+", "-"] LIST_STEDELAY = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] LIST_TXPOWER = ["High", "Low"] LIST_DTMF_SPECIAL_DIGITS = ["*", "#", "A", "B", "C", "D"] LIST_DTMF_SPECIAL_VALUES = [0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00] CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ?+-*" STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5), chirp_common.PowerLevel("Low", watts=1)] VALID_BANDS = [(136000000, 174000000), (400000000, 520000000)] def _rawrecv(radio, amount): """Raw read from the radio device""" data = "" try: data = radio.pipe.read(amount) except: msg = "Generic error reading data from radio; check your cable." raise errors.RadioError(msg) if len(data) != amount: msg = "Error reading data from radio: not the amount of data we want." raise errors.RadioError(msg) return data def _rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) except: raise errors.RadioError("Error sending data to radio") def _make_frame(cmd, addr, length, data=""): """Pack the info in the header format""" frame = struct.pack(">BHB", ord(cmd), addr, length) # add the data if set if len(data) != 0: frame += data # return the data return frame def _recv(radio, addr, length): """Get data from the radio """ # read 4 bytes of header hdr = _rawrecv(radio, 4) # read data data = _rawrecv(radio, length) # DEBUG LOG.info("Response:") LOG.debug(util.hexprint(hdr + data)) c, a, l = struct.unpack(">BHB", hdr) if a != addr or l != length or c != ord("W"): LOG.error("Invalid answer for block 0x%04x:" % addr) LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (c, a, l)) raise errors.RadioError("Unknown response from the radio") return data def _do_ident(radio, magic): """Put the radio in PROGRAM mode""" # set the serial discipline radio.pipe.baudrate = 9600 # send request to enter program mode _rawsend(radio, magic) ack = _rawrecv(radio, 1) if ack != "\x06": if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond") _rawsend(radio, "\x02") # Ok, get the response ident = _rawrecv(radio, radio._magic_response_length) # check if response is OK if not ident.startswith("P3107"): # bad response msg = "Unexpected response, got this:" msg += util.hexprint(ident) LOG.debug(msg) raise errors.RadioError("Unexpected response from radio.") # DEBUG LOG.info("Valid response, got this:") LOG.debug(util.hexprint(ident)) _rawsend(radio, "\x06") ack = _rawrecv(radio, 1) if ack != "\x06": if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio refused clone") return ident def _ident_radio(radio): for magic in radio._magic: error = None try: data = _do_ident(radio, magic) return data except errors.RadioError as e: print(e) error = e time.sleep(2) if error: raise error raise errors.RadioError("Radio did not respond") def _download(radio): """Get the memory map""" # put radio in program mode ident = _ident_radio(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._mem_size / radio._recv_block_size status.msg = "Cloning from radio..." radio.status_fn(status) data = "" for addr in range(0, radio._mem_size, radio._recv_block_size): frame = _make_frame("R", addr, radio._recv_block_size) # DEBUG LOG.info("Request sent:") LOG.debug(util.hexprint(frame)) # sending the read request _rawsend(radio, frame) # now we read d = _recv(radio, addr, radio._recv_block_size) time.sleep(0.05) _rawsend(radio, "\x06") ack = _rawrecv(radio, 1) if ack != "\x06": raise errors.RadioError( "Radio refused to send block 0x%04x" % addr) # aggregate the data data += d # UI Update status.cur = addr / radio._recv_block_size status.msg = "Cloning from radio..." radio.status_fn(status) data += radio.MODEL.ljust(8) return data def _upload(radio): """Upload procedure""" # put radio in program mode _ident_radio(radio) addr = 0x0f80 frame = _make_frame("R", addr, radio._recv_block_size) # DEBUG LOG.info("Request sent:") LOG.debug(util.hexprint(frame)) # sending the read request _rawsend(radio, frame) # now we read d = _recv(radio, addr, radio._recv_block_size) time.sleep(0.05) _rawsend(radio, "\x06") ack = _rawrecv(radio, 1) if ack != "\x06": raise errors.RadioError( "Radio refused to send block 0x%04x" % addr) _ranges = radio._ranges # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._mem_size / radio._send_block_size status.msg = "Cloning to radio..." radio.status_fn(status) # the fun start here for start, end in _ranges: for addr in range(start, end, radio._send_block_size): # sending the data data = radio.get_mmap()[addr:addr + radio._send_block_size] frame = _make_frame("W", addr, radio._send_block_size, data) _rawsend(radio, frame) # receiving the response ack = _rawrecv(radio, 1) if ack != "\x06": msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) # UI Update status.cur = addr / radio._send_block_size status.msg = "Cloning to radio..." radio.status_fn(status) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" if len(data) == 0x2008: rid = data[0x2000:0x2008] return rid.startswith(cls._model) else: return False def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True @directory.register class TDXoneTDQ8A(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """TDXone TD-Q8A Radio""" VENDOR = "TDXone" MODEL = "TD-Q8A" _model = b'TD-Q8A' _magic = [MSTRING_TDQ8A, MSTRING_TDQ8A, ] _magic_response_length = 8 _fw_ver_start = 0x1EF0 _recv_block_size = 0x40 _mem_size = 0x2000 _ranges = [(0x0010, 0x0810), (0x0E20, 0x0E60), (0x0F10, 0x0F30), (0x1010, 0x1810), (0x1F10, 0x1F30)] _send_block_size = 0x10 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('The TDXone TD-Q8A driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def get_features(self): """Get the radio's features""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = False rf.has_rx_dtcs = False rf.has_dtcs_polarity = False rf.has_ctone = True rf.has_cross = True rf.valid_modes = ["FM", "NFM"] rf.valid_characters = CHARSET rf.valid_name_length = 6 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "->Tone"] rf.valid_skips = ["", "S"] rf.memory_bounds = (1, 128) rf.valid_power_levels = POWER_LEVELS rf.valid_tuning_steps = STEPS rf.valid_bands = VALID_BANDS return rf def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): """Download from radio""" try: data = _download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMap(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def _is_txinh(self, _mem): raw_tx = "" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw(asbytes=False) return raw_tx == "\xFF\xFF\xFF\xFF" def _get_mem(self, number): return self._memobj.memory[number - 1] def _get_nam(self, number): return self._memobj.names[number - 1] def get_memory(self, number): _mem = self._get_mem(number) _nam = self._get_nam(number) mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if self._is_txinh(_mem): # TX freq not set mem.duplex = "off" mem.offset = 0 else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 if _nam.name: for char in _nam.name: try: mem.name += CHARSET[char] except IndexError: break mem.name = mem.name.rstrip() if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) if not _mem.scan: mem.skip = "S" mem.power = POWER_LEVELS[1 - _mem.highpower] mem.mode = _mem.wide and "FM" or "NFM" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("dtmf", "DTMF", RadioSettingValueList(LIST_DTMF, LIST_DTMF[_mem.dtmf])) mem.extra.append(rs) rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) return mem def _set_mem(self, number): return self._memobj.memory[number - 1] def _set_nam(self, number): return self._memobj.names[number - 1] def set_memory(self, mem): _mem = self._get_mem(mem.number) _nam = self._get_nam(mem.number) if mem.empty: _mem.set_raw("\xff" * 12 + "\xbf" + "\xff" * 3) _nam.set_raw("\xff" * 16) return _mem.set_raw("\xff" * 12 + "\x9f" + "\xff" * 3) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 if _nam.name: for i in range(0, 6): try: _nam.name[i] = CHARSET.index(mem.name[i]) except IndexError: _nam.name[i] = 0xFF rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 _mem.scan = mem.skip != "S" _mem.wide = mem.mode == "FM" _mem.highpower = mem.power == POWER_LEVELS[0] for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") top = RadioSettings(basic, advanced, ) # Basic settings rs = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean( _mem.settings.beep)) basic.append(rs) if _mem.settings.squelcha > 0x09: val = 0x00 else: val = _mem.settings.squelcha rs = RadioSetting("squelcha", "Squelch Level A", RadioSettingValueInteger( 0, 9, _mem.settings.squelcha)) basic.append(rs) if _mem.settings.squelchb > 0x09: val = 0x00 else: val = _mem.settings.squelchb rs = RadioSetting("squelchb", "Squelch Level B", RadioSettingValueInteger( 0, 9, _mem.settings.squelchb)) basic.append(rs) if _mem.settings.voice > 0x02: val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) if _mem.settings.vox > 0x0A: val = 0x00 else: val = _mem.settings.vox rs = RadioSetting("settings.vox", "VOX", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) rs = RadioSetting("settings.autolk", "Automatic Key Lock", RadioSettingValueBoolean(_mem.settings.autolk)) basic.append(rs) if _mem.settings.screv > 0x02: val = 0x01 else: val = _mem.settings.screv rs = RadioSetting("settings.screv", "Scan Resume", RadioSettingValueList( LIST_RESUME, LIST_RESUME[val])) basic.append(rs) if _mem.settings.toa > 0x0A: val = 0x00 else: val = _mem.settings.toa rs = RadioSetting("settings.toa", "Time-out Pre-Alert", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) if _mem.settings.timeout > 0x28: val = 0x03 else: val = _mem.settings.timeout rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( LIST_TIMEOUT, LIST_TIMEOUT[val])) basic.append(rs) rs = RadioSetting("settings.wtled", "Standby LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.wtled])) basic.append(rs) rs = RadioSetting("settings.rxled", "RX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.rxled])) basic.append(rs) rs = RadioSetting("settings.txled", "TX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.txled])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger Beep", RadioSettingValueList(LIST_ROGER, LIST_ROGER[ _mem.settings.roger])) basic.append(rs) rs = RadioSetting("settings.mdfa", "Display Mode (A)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfa])) basic.append(rs) rs = RadioSetting("settings.mdfb", "Display Mode (B)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfb])) basic.append(rs) rs = RadioSetting("settings.pf1", "PF1 Key Assignment", RadioSettingValueList(LIST_PF1, LIST_PF1[ _mem.settings.pf1])) basic.append(rs) rs = RadioSetting("settings.tdr", "Dual Watch(TDR)", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(rs) rs = RadioSetting("settings.ani", "ANI", RadioSettingValueBoolean(_mem.settings.ani)) basic.append(rs) if _mem.settings.pttdly > 0x0A: val = 0x00 else: val = _mem.settings.pttdly rs = RadioSetting("settings.pttdly", "PTT ID Delay", RadioSettingValueList( LIST_OFF1TO30, LIST_OFF1TO30[val])) basic.append(rs) rs = RadioSetting("settings.pttid", "When to send PTT ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[ _mem.settings.pttid])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) rs = RadioSetting("settings.ponmsg", "Power-On Message", RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[ _mem.settings.ponmsg])) basic.append(rs) rs = RadioSetting("settings.dw", "DW", RadioSettingValueBoolean(_mem.settings.dw)) basic.append(rs) # Advanced settings rs = RadioSetting("settings.prioritych", "Priority Channel", RadioSettingValueList(LIST_PRIORITY, LIST_PRIORITY[ _mem.settings.prioritych])) advanced.append(rs) rs = RadioSetting("settings.vfomr", "Work Mode", RadioSettingValueList(LIST_WORKMODE, LIST_WORKMODE[ _mem.settings.vfomr])) advanced.append(rs) dtmfchars = "0123456789" _codeobj = _mem.settings.code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 3, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("settings.code", "PTT-ID Code", val) def apply_code(setting, obj): code = [] for j in range(0, 3): try: code.append(dtmfchars.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, _mem.settings) advanced.append(rs) _codeobj = _mem.settings.password _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("settings.password", "Control Password", val) def apply_code(setting, obj): code = [] for j in range(0, 6): try: code.append(dtmfchars.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.password = code rs.set_apply_callback(apply_code, _mem.settings) advanced.append(rs) if _mem.settings.tdrab > 0x01: val = 0x00 else: val = _mem.settings.tdrab rs = RadioSetting("settings.tdrab", "Dual Watch TX Priority", RadioSettingValueList( LIST_AB, LIST_AB[val])) advanced.append(rs) rs = RadioSetting("settings.keylk", "Key Lock", RadioSettingValueBoolean(_mem.settings.keylk)) advanced.append(rs) rs = RadioSetting("settings.control", "Control Code", RadioSettingValueBoolean(_mem.settings.control)) advanced.append(rs) return top def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _set_fm_preset(self, settings): for element in settings: try: val = element.value if self._memobj.fm_presets <= 108.0 * 10 - 650: value = int(val.get_value() * 10 - 650) else: value = int(val.get_value() * 10) LOG.debug("Setting fm_presets = %s" % (value)) self._memobj.fm_presets = value except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == 0x2008: match_size = True # testing the model fingerprint match_model = model_match(cls, filedata) # if match_size and match_model: if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/tmv71.py0000644000175000017500000000471014411666130016153 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, errors, util from chirp.drivers import tmv71_ll import logging LOG = logging.getLogger(__name__) class TMV71ARadio(chirp_common.CloneModeRadio): BAUD_RATE = 9600 VENDOR = "Kenwood" MODEL = "TM-V71A" mem_upper_limit = 1022 _memsize = 32512 _model = "" # FIXME: REMOVE def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 999) return rf def _detect_baud(self): for baud in [9600, 19200, 38400, 57600]: self.pipe.baudrate = baud self.pipe.write("\r\r") self.pipe.read(32) try: id = tmv71_ll.get_id(self.pipe) LOG.info("Radio %s at %i baud" % (id, baud)) return True except errors.RadioError: pass raise errors.RadioError("No response from radio") def get_raw_memory(self, number): return util.hexprint(tmv71_ll.get_raw_mem(self._mmap, number)) def get_special_locations(self): return sorted(tmv71_ll.V71_SPECIAL.keys()) def get_memory(self, number): if isinstance(number, str): try: number = tmv71_ll.V71_SPECIAL[number] except KeyError: raise errors.InvalidMemoryLocation("Unknown channel %s" % number) return tmv71_ll.get_memory(self._mmap, number) def set_memory(self, mem): return tmv71_ll.set_memory(self._mmap, mem) def erase_memory(self, number): tmv71_ll.set_used(self._mmap, number, 0) def sync_in(self): self._detect_baud() self._mmap = tmv71_ll.download(self) def sync_out(self): self._detect_baud() tmv71_ll.upload(self) chirp-20240224/chirp/drivers/gmrsv2.py0000644000175000017500000010732414565075506016435 0ustar hibbyhibby# Copyright 2022: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory from chirp import bitwise from chirp import bandplan_na from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings, \ InvalidValueError LOG = logging.getLogger(__name__) # #### MAGICS ######################################################### # BTECH GMRS-V2 magic string MSTRING_GMRSV2 = b"\x50\x5F\x20\x21\x12\x15\x4D" # BTECH MURS-V2 magic string MSTRING_MURSV2 = b"\x50\x5F\x20\x21\x12\x15\x4D" # #### ID strings ##################################################### # BTECH GMRS-V2 GMRSV2_fp1 = b"US32419" # original # BTECH MURS-V2 MURSV2_fp1 = b"USM2403" # original DTMF_CHARS = "0123456789 *#ABCD" STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] LIST_AB = ["A", "B"] LIST_ALMOD = ["Off", "Site", "Tone", "Code"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_COLOR = ["Off", "Blue", "Orange", "Purple"] LIST_DTMFSPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_DTMFST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] LIST_MODE = ["Channel", "Name", "Frequency"] LIST_OFF1TO9 = ["Off"] + list("123456789") LIST_OFF1TO10 = LIST_OFF1TO9 + ["10"] LIST_OFFAB = ["Off"] + LIST_AB LIST_RESUME = ["TO", "CO", "SE"] LIST_PONMSG = ["Full", "Message"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_SCODE = ["%s" % x for x in range(1, 16)] LIST_RPSTE = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_RTONE = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SHIFTD = ["Off", "+", "-"] LIST_STEDELAY = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] LIST_STEP = [str(x) for x in STEPS] LIST_TIMEOUT = ["%s sec" % x for x in range(15, 615, 15)] LIST_TXPOWER = ["High", "Low"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_WORKMODE = ["Frequency", "Channel"] class GMRSV2base(bfc.BaofengCommonHT): """BTech GMRS-V2base""" VENDOR = "" MODEL = "" NEEDS_COMPAT_SERIAL = False _fw_ver_start = 0x1EF0 _recv_block_size = 0x40 _mem_size = 0x2000 _ack_block = True _ranges = [(0x0000, 0x1EF0), (0x1F60, 0x1F70), (0x1F80, 0x1F90), (0x1FC0, 0x1FD0)] _send_block_size = 0x10 MODES = ["NFM", "FM"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" LENGTH_NAME = 7 SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(130000000, 180000000), (400000000, 521000000)] PTTID_LIST = LIST_PTTID SCODE_LIST = LIST_SCODE def get_features(self): """Get the radio's features""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = False rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_name_length = self.LENGTH_NAME rf.valid_duplexes = ["", "+", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = self.SKIP_VALUES rf.valid_dtcs_codes = self.DTCS_CODES rf.memory_bounds = (0, 199) rf.valid_power_levels = self.POWER_LEVELS rf.valid_bands = self.VALID_BANDS rf.valid_tuning_steps = STEPS return rf MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1; u8 unknown2:7, lowpower:1; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[200]; #seekto 0x0D00; struct { u8 code[5]; u8 unused[11]; } pttid[15]; // #seekto 0x0DF0; struct { u8 dtmfon; u8 dtmfoff; u8 unknown1:4, unknown2:2, aniid:2; u8 alarm[5]; u8 code[5]; } ani; #seekto 0x0E20; struct { u8 unused01:4, squelch:4; u8 unused02; u8 unused03; u8 unused04:5, save:3; u8 unused05:4, vox:4; u8 unused06; u8 unused07:4, abr:4; u8 unused08:7, tdr:1; u8 unused09:7, beep:1; u8 unused10:2, timeout:6; u8 unused11[4]; u8 unused12:6, voice:2; u8 unused13; u8 unused14:6, dtmfst:2; u8 unused15; u8 unused16:6, screv:2; u8 unused17; u8 unused18:2, pttlt:6; u8 unused19:6, mdfa:2; u8 unused20:6, mdfb:2; u8 unused21; u8 unused22:7, sync:1; u8 unused23[4]; u8 unused24:6, wtled:2; u8 unused25:6, rxled:2; u8 unused26:6, txled:2; u8 unused27:6, almod:2; u8 unused28:7, dbptt:1; u8 unused29:6, tdrab:2; u8 unused30:7, ste:1; u8 unused31:4, rpste:4; u8 unused32:4, rptrl:4; u8 unused33:7, ponmsg:1; u8 unused34:7, roger:1; u8 unused35:6, rtone:2; u8 unused36; u8 unused37:6, rogerrx:2; u8 unused38; u8 displayab:1, unknown1:7; u8 unused39[2]; u8 keylock; u8 cht; u8 unused40[5]; u8 unknown3:3, fmradio:1, alarm:1, unknown2:1, reset:1, menu:1; u8 unused41; u8 unknown4:7, workmode:1; } settings; #seekto 0x0E76; struct { u8 unused1:1, mrcha:7; u8 unused2:1, mrchb:7; } wmchannel; struct vfo { u8 unknown0[8]; u8 freq[8]; u8 unknown1; u8 offset[4]; u8 unknown2; ul16 rxtone; ul16 txtone; u8 unused1:7, band:1; u8 unknown3; u8 unused2:2, sftd:2, unused5:4; u8 unknown4; u8 unused3:1, step:3, unused4:4; u8 txpower:1, widenarr:1, unknown5:4, txpower3:2; }; #seekto 0x0F00; struct { struct vfo a; struct vfo b; } vfo; #seekto 0x0F4E; u16 fm_presets; #seekto 0x1000; struct { char name[7]; u8 unknown1[9]; } names[200]; #seekto 0x1ED0; struct { char line1[7]; char line2[7]; } sixpoweron_msg; #seekto 0x1EE0; struct { char line1[7]; char line2[7]; } poweron_msg; #seekto 0x1EF0; struct { char line1[7]; char line2[7]; } firmware_msg; struct squelch { u8 sql0; u8 sql1; u8 sql2; u8 sql3; u8 sql4; u8 sql5; u8 sql6; u8 sql7; u8 sql8; u8 sql9; }; #seekto 0x1F60; struct { struct squelch vhf; u8 unknown1[6]; u8 unknown2[16]; struct squelch uhf; } squelch; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('The BTech ' + cls.MODEL + ' driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number if _mem.get_raw()[:1] == b"\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if self._is_txinh(_mem): # TX freq not set mem.duplex = "off" mem.offset = 0 else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if offset > 0: mem.duplex = "+" mem.offset = 5000000 else: mem.duplex = "" mem.offset = 0 for char in _nam.name: if str(char) == "\xFF": char = " " # The OEM software may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() dtcs_pol = ["N", "N"] if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 elif _mem.txtone <= 0x0258: txmode = "DTCS" if _mem.txtone > 0x69: index = _mem.txtone - 0x6A dtcs_pol[0] = "R" else: index = _mem.txtone - 1 mem.dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 elif _mem.rxtone <= 0x0258: rxmode = "DTCS" if _mem.rxtone >= 0x6A: index = _mem.rxtone - 0x6A dtcs_pol[1] = "R" else: index = _mem.rxtone - 1 mem.rx_dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) if not _mem.scan: mem.skip = "S" levels = self.POWER_LEVELS try: mem.power = levels[_mem.lowpower] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.power, levels)) mem.power = levels[0] mem.mode = _mem.wide and "FM" or "NFM" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(self.PTTID_LIST, self.PTTID_LIST[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("scode", "S-CODE", RadioSettingValueList(self.SCODE_LIST, self.SCODE_LIST[_mem.scode])) mem.extra.append(rs) immutable = [] if self.MODEL == "GMRS-V2": if mem.freq in bandplan_na.ALL_GMRS_FREQS: if mem.freq in bandplan_na.GMRS_LOW: # Non-repeater GMRS channels (limit duplex) mem.duplex = '' mem.offset = 0 immutable = ["duplex", "offset"] elif mem.freq in bandplan_na.GMRS_HHONLY: # Non-repeater GMRS hand-held only channels # (limit duplex, power) mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable = ["duplex", "offset", "mode", "power"] elif mem.freq in bandplan_na.GMRS_HIRPT: # GMRS repeater channels, always either simplex or +5 MHz if mem.duplex == '': mem.offset = 0 if mem.duplex == '+': mem.offset = 5000000 else: # Not a GMRS channel, so restrict duplex since it will be # forced to off. if mem.freq not in bandplan_na.ALL_GMRS_FREQS: mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] if self.MODEL == "MURS-V2": if mem.freq in bandplan_na.ALL_MURS_FREQS: if mem.freq in bandplan_na.MURS_NFM: # Narrow only MURS channels (limit mode) mem.duplex == '' mem.offset = 0 mem.mode = "NFM" immutable = ["duplex", "offset", "mode"] if mem.freq in bandplan_na.MURS_FM: # Narrow or wide MURS channels mem.duplex == '' mem.offset = 0 immutable = ["duplex", "offset"] else: # Not a MURS channel, so restrict duplex since it will be # forced to off. if mem.freq not in bandplan_na.ALL_MURS_FREQS: mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] mem.immutable = immutable return mem def check_set_memory_immutable_policy(self, existing, new): existing.immutable = [] super().check_set_memory_immutable_policy(existing, new) def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _nam = self._memobj.names[mem.number] if mem.empty: _mem.set_raw("\xff" * 16) _nam.set_raw("\xff" * 16) return _mem.set_raw("\x00" * 16) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "+": offset = 5000000 _mem.txfreq = (mem.freq + offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": rxmode = txmode = "DTCS" _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 _mem.rxtone = self.DTCS_CODES.index(mem.dtcs) + 1 elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) elif txmode == "DTCS": _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCS": _mem.rxtone = self.DTCS_CODES.index(mem.rx_dtcs) + 1 else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 if txmode == "DTCS" and mem.dtcs_polarity[0] == "R": _mem.txtone += 0x69 if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R": _mem.rxtone += 0x69 _mem.scan = mem.skip != "S" _mem.wide = mem.mode == "FM" if mem.power: _mem.lowpower = self.POWER_LEVELS.index(mem.power) else: _mem.lowpower = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) else: # there are no extra settings, load defaults _mem.bcl = 0 _mem.pttid = 0 _mem.scode = 0 def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") fm_preset = RadioSettingGroup("fm_preset", "FM Preset") dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") service = RadioSettingGroup("service", "Service Settings") top = RadioSettings(basic, advanced, other, work, fm_preset, dtmfe, service) # Basic settings if _mem.settings.squelch > 0x09: val = 0x00 else: val = _mem.settings.squelch rs = RadioSetting("settings.squelch", "Squelch", RadioSettingValueList( LIST_OFF1TO9, LIST_OFF1TO9[val])) basic.append(rs) if _mem.settings.save > 0x04: val = 0x00 else: val = _mem.settings.save rs = RadioSetting("settings.save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) if _mem.settings.vox > 0x0A: val = 0x00 else: val = _mem.settings.vox rs = RadioSetting("settings.vox", "Vox", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) if _mem.settings.abr > 0x0A: val = 0x00 else: val = _mem.settings.abr rs = RadioSetting("settings.abr", "Backlight Timeout", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) rs = RadioSetting("settings.tdr", "Dual Watch", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean(_mem.settings.beep)) basic.append(rs) if _mem.settings.timeout > 0x27: val = 0x03 else: val = _mem.settings.timeout rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( LIST_TIMEOUT, LIST_TIMEOUT[val])) basic.append(rs) if _mem.settings.voice > 0x02: val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) if _mem.settings.screv > 0x02: val = 0x01 else: val = _mem.settings.screv rs = RadioSetting("settings.screv", "Scan Resume", RadioSettingValueList( LIST_RESUME, LIST_RESUME[val])) basic.append(rs) if _mem.settings.pttlt > 0x32: val = 0x05 else: val = _mem.settings.pttlt rs = RadioSetting("pttlt", "PTT ID Delay", RadioSettingValueInteger(0, 50, val)) basic.append(rs) rs = RadioSetting("settings.mdfa", "Display Mode (A)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfa])) basic.append(rs) rs = RadioSetting("settings.mdfb", "Display Mode (B)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfb])) basic.append(rs) rs = RadioSetting("settings.sync", "Sync A & B", RadioSettingValueBoolean(_mem.settings.sync)) basic.append(rs) rs = RadioSetting("settings.wtled", "Standby LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.wtled])) basic.append(rs) rs = RadioSetting("settings.rxled", "RX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.rxled])) basic.append(rs) rs = RadioSetting("settings.txled", "TX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.txled])) basic.append(rs) val = _mem.settings.almod rs = RadioSetting("settings.almod", "Alarm Mode", RadioSettingValueList( LIST_ALMOD, LIST_ALMOD[val])) basic.append(rs) rs = RadioSetting("settings.dbptt", "Double PTT", RadioSettingValueBoolean(_mem.settings.dbptt)) basic.append(rs) if _mem.settings.tdrab > 0x02: val = 0x00 else: val = _mem.settings.tdrab rs = RadioSetting("settings.tdrab", "Dual Watch TX Priority", RadioSettingValueList( LIST_OFFAB, LIST_OFFAB[val])) basic.append(rs) rs = RadioSetting("settings.ste", "Squelch Tail Eliminate (HT to HT)", RadioSettingValueBoolean(_mem.settings.ste)) basic.append(rs) if _mem.settings.rpste > 0x0A: val = 0x00 else: val = _mem.settings.rpste rs = RadioSetting("settings.rpste", "Squelch Tail Eliminate (repeater)", RadioSettingValueList( LIST_RPSTE, LIST_RPSTE[val])) basic.append(rs) if _mem.settings.rptrl > 0x0A: val = 0x00 else: val = _mem.settings.rptrl rs = RadioSetting("settings.rptrl", "STE Repeater Delay", RadioSettingValueList( LIST_STEDELAY, LIST_STEDELAY[val])) basic.append(rs) rs = RadioSetting("settings.ponmsg", "Power-On Message", RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[ _mem.settings.ponmsg])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger Beep", RadioSettingValueBoolean(_mem.settings.roger)) basic.append(rs) rs = RadioSetting("settings.rtone", "Tone Burst Frequency", RadioSettingValueList(LIST_RTONE, LIST_RTONE[ _mem.settings.rtone])) basic.append(rs) rs = RadioSetting("settings.rogerrx", "Roger Beep (RX)", RadioSettingValueList( LIST_OFFAB, LIST_OFFAB[ _mem.settings.rogerrx])) basic.append(rs) # Advanced settings rs = RadioSetting("settings.reset", "RESET Menu", RadioSettingValueBoolean(_mem.settings.reset)) advanced.append(rs) rs = RadioSetting("settings.menu", "All Menus", RadioSettingValueBoolean(_mem.settings.menu)) advanced.append(rs) rs = RadioSetting("settings.fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_mem.settings.fmradio)) advanced.append(rs) rs = RadioSetting("settings.alarm", "Alarm Sound", RadioSettingValueBoolean(_mem.settings.alarm)) advanced.append(rs) # Other settings def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = _mem.firmware_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val) other.append(rs) _msg = _mem.sixpoweron_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2", val) other.append(rs) _msg = _mem.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 7, _filter(_msg.line2))) other.append(rs) # Work mode settings rs = RadioSetting("settings.displayab", "Display", RadioSettingValueList( LIST_AB, LIST_AB[_mem.settings.displayab])) work.append(rs) rs = RadioSetting("settings.workmode", "VFO/MR Mode", RadioSettingValueList( LIST_WORKMODE, LIST_WORKMODE[_mem.settings.workmode])) work.append(rs) rs = RadioSetting("settings.keylock", "Keypad Lock", RadioSettingValueBoolean(_mem.settings.keylock)) work.append(rs) rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrcha)) work.append(rs) rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrchb)) work.append(rs) def my_validate(value): value = chirp_common.parse_freq(value) msg = ("Can't be less than %i.0000") if value > 99000000 and value < 130 * 1000000: raise InvalidValueError(msg % (130)) msg = ("Can't be between %i.9975-%i.0000") if (179 + 1) * 1000000 <= value and value < 400 * 1000000: raise InvalidValueError(msg % (179, 400)) msg = ("Can't be greater than %i.9975") if value > 99000000 and value > (520 + 1) * 1000000: raise InvalidValueError(msg % (520)) return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.a.freq)) val1a.set_validate_callback(my_validate) rs = RadioSetting("vfo.a.freq", "VFO A Frequency", val1a) rs.set_apply_callback(apply_freq, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.b.freq)) val1b.set_validate_callback(my_validate) rs = RadioSetting("vfo.b.freq", "VFO B Frequency", val1b) rs.set_apply_callback(apply_freq, _mem.vfo.b) work.append(rs) rs = RadioSetting("vfo.a.step", "VFO A Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.a.step])) work.append(rs) rs = RadioSetting("vfo.b.step", "VFO B Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.b.step])) work.append(rs) # broadcast FM settings _fm_presets = self._memobj.fm_presets if _fm_presets <= 108.0 * 10 - 650: preset = _fm_presets / 10.0 + 65 elif _fm_presets >= 65.0 * 10 and _fm_presets <= 108.0 * 10: preset = _fm_presets / 10.0 else: preset = 76.0 rs = RadioSetting("fm_presets", "FM Preset(MHz)", RadioSettingValueFloat(65, 108.0, preset, 0.1, 1)) fm_preset.append(rs) # DTMF settings def apply_code(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) pttid = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) pttid.set_apply_callback(apply_code, self._memobj.pttid[i], 5) dtmfe.append(pttid) if _mem.ani.dtmfon > 0xC3: val = 0x03 else: val = _mem.ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if _mem.ani.dtmfoff > 0xC3: val = 0x03 else: val = _mem.ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) _codeobj = self._memobj.ani.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.code", "ANI Code", val) rs.set_apply_callback(apply_code, self._memobj.ani, 5) dtmfe.append(rs) rs = RadioSetting("ani.aniid", "When to send ANI ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[_mem.ani.aniid])) dtmfe.append(rs) def apply_alarmcode(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.alarm = code _codeobj = self._memobj.ani.alarm _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.alarm", "Alarm Code", val) rs.set_apply_callback(apply_alarmcode, self._memobj.ani, 5) dtmfe.append(rs) # Service settings for band in ["vhf", "uhf"]: for index in range(0, 10): key = "squelch.%s.sql%i" % (band, index) if band == "vhf": _obj = self._memobj.squelch.vhf elif band == "uhf": _obj = self._memobj.squelch.uhf val = RadioSettingValueInteger(0, 123, getattr(_obj, "sql%i" % ( index))) if index == 0: val.set_mutable(False) name = "%s Squelch %i" % (band.upper(), index) rs = RadioSetting(key, name, val) service.append(rs) return top @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class GMRSV2(GMRSV2base): """BTech GMRS-V2""" VENDOR = "BTECH" MODEL = "GMRS-V2" NEEDS_COMPAT_SERIAL = False _fileid = [GMRSV2_fp1, ] _magic = [MSTRING_GMRSV2, ] _magic_response_length = 8 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if mem.freq not in bandplan_na.ALL_GMRS_FREQS: if mem.duplex != "off": msgs.append(chirp_common.ValidationWarning(_msg_duplex)) if mem.freq in bandplan_na.GMRS_HIRPT: if mem.duplex and mem.offset != 5000000: msgs.append(chirp_common.ValidationWarning(_msg_offset)) return msgs @directory.register class MURSV2(GMRSV2base): """BTech MURS-V2""" VENDOR = "BTECH" MODEL = "MURS-V2" _fileid = [MURSV2_fp1, ] _magic = [MSTRING_MURSV2, ] _magic_response_length = 8 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if mem.freq not in bandplan_na.ALL_MURS_FREQS: if mem.duplex != "off": msgs.append(chirp_common.ValidationWarning(_msg_duplex)) return msgs chirp-20240224/chirp/drivers/ict7h.py0000644000175000017500000000715114411666130016215 0ustar hibbyhibby# Copyright 2012 Eric Allen # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, directory, bitwise mem_format = """ struct { bbcd freq[2]; u8 lastfreq:4, fraction:4; bbcd offset[2]; u8 unknown; u8 rtone; u8 ctone; } memory[60]; #seekto 0x0270; struct { u8 empty:1, tmode:2, duplex:2, unknown3:1, skip:1, unknown4:1; } flags[60]; """ TMODES = ["", "", "Tone", "TSQL", "TSQL"] # last one is pocket beep DUPLEX = ["", "", "-", "+"] MODES = ["FM"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0] @directory.register class ICT7HRadio(icf.IcomCloneModeRadio): VENDOR = "Icom" MODEL = "IC-T7H" _model = "\x18\x10\x00\x01" _memsize = 0x03B0 _endframe = "Icom Inc\x2e" _ranges = [(0x0000, _memsize, 16)] def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 60) rf.valid_modes = list(MODES) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(118000000, 174000000), (400000000, 470000000)] rf.valid_skips = ["", "S"] rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_name = False rf.has_tuning_step = False return rf def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): _mem = self._memobj.memory[number - 1] _flag = self._memobj.flags[number - 1] mem = chirp_common.Memory() mem.number = number mem.empty = _flag.empty == 1 and True or False mem.freq = int(_mem.freq) * 100000 mem.freq += _mem.lastfreq * 10000 mem.freq += int(_mem.fraction / 2.0 * 1000) mem.offset = int(_mem.offset) * 10000 mem.rtone = chirp_common.TONES[_mem.rtone - 1] mem.ctone = chirp_common.TONES[_mem.ctone - 1] mem.tmode = TMODES[_flag.tmode] mem.duplex = DUPLEX[_flag.duplex] mem.mode = "FM" if _flag.skip: mem.skip = "S" return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _flag = self._memobj.flags[mem.number - 1] _mem.freq = int(mem.freq / 100000) topfreq = int(mem.freq / 100000) * 100000 lastfreq = int((mem.freq - topfreq) / 10000) _mem.lastfreq = lastfreq midfreq = (mem.freq - topfreq - lastfreq * 10000) _mem.fraction = midfreq // 500 _mem.offset = mem.offset / 10000 _mem.rtone = chirp_common.TONES.index(mem.rtone) + 1 _mem.ctone = chirp_common.TONES.index(mem.ctone) + 1 _flag.tmode = TMODES.index(mem.tmode) _flag.duplex = DUPLEX.index(mem.duplex) _flag.skip = mem.skip == "S" and 1 or 0 _flag.empty = mem.empty and 1 or 0 chirp-20240224/chirp/drivers/tk8102.py0000644000175000017500000003753514522657251016150 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import logging import struct from chirp import chirp_common, directory, memmap, errors, util from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting from chirp.settings import RadioSettingValueBoolean, RadioSettingValueList from chirp.settings import RadioSettingValueString, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0030; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; ul16 rx_tone; ul16 tx_tone; u8 signaling:2, unknown1:3, bcl:1, wide:1, beatshift:1; u8 pttid:2, highpower:1, scan:1, unknown2:4; u8 unknown3[2]; } memory[8]; #seekto 0x0250; struct { u8 unknown0; u8 unknown1; u8 unknown2; u8 unknown3; // 0x04 Emergency, 0x05 keylock, 0x06 Monitor 0x09 temp delete, 0x0A none u8 speakerkey; u8 circlekey; } settings; #seekto 0x0270; struct { u8 scanresume; // 0=selected 1=selected+talkback u8 dropoutdelay; // 0.5s*value, 0.5-5.0 u8 txdwell; // same as above u8 offhookscan; // 0=off 1=on } settings2; #seekto 0x0310; struct { char line1[32]; char line2[32]; } messages; """ # These are 4+index KEYS = [ 'Emergency', 'Key Lock', 'Monitor', 'Scan On/Off', 'Talk Around', 'Temporary Delete', 'None', ] SCAN_RESUME = ['Selected', 'Selected+Talkback'] SCAN_TIME = ['%.1f' % (v * 0.5) for v in range(11)] POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("High", watts=50)] MODES = ["NFM", "FM"] PTTID = ["", "BOT", "EOT", "Both"] SIGNAL = ["", "DTMF"] def make_frame(cmd, addr, length, data=b""): return struct.pack(">BHB", ord(cmd), addr, length) + bytes(data) def send(radio, frame): # LOG.debug("%04i P>R: %s" % (len(frame), util.hexprint(frame))) radio.pipe.write(frame) def recv(radio, readdata=True): hdr = radio.pipe.read(4) cmd, addr, length = struct.unpack(">BHB", hdr) if readdata: data = radio.pipe.read(length) # LOG.debug(" PTone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_skips = ["", "S"] rf.valid_bands = [self._range] rf.memory_bounds = (1, self._upper) return rf def sync_in(self): try: self._mmap = do_download(self) except errors.RadioError: self.pipe.write(b"\x45") raise except Exception as e: raise errors.RadioError("Failed to download from radio: %s" % e) self.process_mmap() def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_out(self): try: do_upload(self) except errors.RadioError: self.pipe.write(b"\x45") raise except Exception as e: raise errors.RadioError("Failed to upload to radio: %s" % e) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2800: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" elif _mem.tx_tone != 0xFFFF: mem.rtone = _mem.tx_tone / 10.0 txmode = "Tone" else: txmode = "" if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2800: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rx_tone != 0xFFFF: mem.ctone = _mem.rx_tone / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) if mem.tmode == "DTCS": mem.dtcs_polarity = "%s%s" % (tpol, rpol) def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[:4] == "\xFF\xFF\xFF\xFF": mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 offset = (int(_mem.tx_freq) * 10) - mem.freq if offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 self._get_tone(_mem, mem) mem.power = POWER_LEVELS[_mem.highpower] mem.mode = MODES[_mem.wide] mem.skip = not _mem.scan and "S" or "" mem.extra = RadioSettingGroup("all", "All Settings") bcl = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueBoolean(bool(_mem.bcl))) mem.extra.append(bcl) beat = RadioSetting("beatshift", "Beat Shift", RadioSettingValueBoolean(bool(_mem.beatshift))) mem.extra.append(beat) pttid = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTTID, PTTID[_mem.pttid])) mem.extra.append(pttid) signal = RadioSetting("signaling", "Signaling", RadioSettingValueList(SIGNAL, SIGNAL[ _mem.signaling & 0x01])) mem.extra.append(signal) return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0xA000 return val rx_mode = tx_mode = None rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None tx_tone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = int(mem.rtone * 10) if rx_mode == "DTCS": rx_tone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = int(mem.ctone * 10) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.tx_tone, rx_mode, _mem.rx_tone)) def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw("\xFF" * 16) return _mem.unknown3[0] = 0x07 _mem.unknown3[1] = 0x22 _mem.rx_freq = mem.freq / 10 if mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 else: _mem.tx_freq = mem.freq / 10 self._set_tone(mem, _mem) _mem.highpower = mem.power == POWER_LEVELS[1] _mem.wide = mem.mode == "FM" _mem.scan = mem.skip != "S" for setting in mem.extra: if setting.get_name == "signaling": if setting.value == "DTMF": _mem.signaling = 0x03 else: _mem.signaling = 0x00 else: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _mem = self._memobj basic = RadioSettingGroup("basic", "Basic") scan = RadioSettingGroup("scan", "Scan") top = RadioSettings(basic, scan) def _f(val): string = "" for char in str(val): if char == "\xFF": break string += char return string line1 = RadioSetting("messages.line1", "Message Line 1", RadioSettingValueString(0, 32, _f(_mem.messages.line1), autopad=False)) basic.append(line1) line2 = RadioSetting("messages.line2", "Message Line 2", RadioSettingValueString(0, 32, _f(_mem.messages.line2), autopad=False)) basic.append(line2) skey = RadioSetting( "settings.speakerkey", "Speaker Key", RadioSettingValueList( KEYS, current_index=int(_mem.settings.speakerkey) - 4)) basic.append(skey) ckey = RadioSetting( "settings.circlekey", "Circle Key", RadioSettingValueList( KEYS, current_index=int(_mem.settings.circlekey) - 4)) basic.append(ckey) scanresume = RadioSetting( "settings2.scanresume", "Scan Resume", RadioSettingValueList(SCAN_RESUME, current_index=_mem.settings2.scanresume)) scan.append(scanresume) offhookscan = RadioSetting( "settings2.offhookscan", "Off-Hook Scan", RadioSettingValueBoolean(bool(_mem.settings2.offhookscan))) scan.append(offhookscan) dropout = RadioSetting( "settings2.dropoutdelay", "Drop-out Delay Time", RadioSettingValueList( SCAN_TIME, current_index=int(_mem.settings2.dropoutdelay))) scan.append(dropout) txdwell = RadioSetting( "settings2.txdwell", "TX Dwell Time", RadioSettingValueList( SCAN_TIME, current_index=int(_mem.settings2.txdwell))) scan.append(txdwell) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if "line" in setting: value = str(element.value).ljust(32, "\xFF") elif 'key' in setting: value = int(element.value) + 4 else: value = element.value setattr(obj, setting, value) @classmethod def match_model(cls, filedata, filename): model = filedata[0x03D1:0x03D5] return model == cls.MODEL.encode().split(b"-")[1] @directory.register class KenwoodTK7102Radio(KenwoodTKx102Radio): MODEL = "TK-7102" _range = (136000000, 174000000) _upper = 4 @directory.register class KenwoodTK8102Radio(KenwoodTKx102Radio): MODEL = "TK-8102" _range = (400000000, 500000000) _upper = 4 @directory.register class KenwoodTK7108Radio(KenwoodTKx102Radio): MODEL = "TK-7108" _range = (136000000, 174000000) _upper = 8 @directory.register class KenwoodTK8108Radio(KenwoodTKx102Radio): MODEL = "TK-8108" _range = (400000000, 500000000) _upper = 8 chirp-20240224/chirp/drivers/tmv71_ll.py0000644000175000017500000002142114430171343016636 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import time import logging from chirp import memmap, chirp_common, errors LOG = logging.getLogger(__name__) POS_MODE = 5 POS_DUP = 6 POS_TMODE = 6 POS_RTONE = 7 POS_CTONE = 8 POS_DTCS = 9 POS_OFFSET = 10 MEM_LOC_BASE = 0x1700 MEM_LOC_SIZE = 16 MEM_TAG_BASE = 0x5800 MEM_FLG_BASE = 0x0E00 V71_SPECIAL = {} for i in range(0, 10): V71_SPECIAL["L%i" % i] = 1000 + (i * 2) V71_SPECIAL["U%i" % i] = 1000 + (i * 2) + 1 for i in range(0, 10): V71_SPECIAL["WX%i" % (i + 1)] = 1020 + i V71_SPECIAL["C VHF"] = 1030 V71_SPECIAL["C UHF"] = 1031 V71_SPECIAL_REV = {} for k, v in V71_SPECIAL.items(): V71_SPECIAL_REV[v] = k def command(s, cmd, timeout=0.5): start = time.time() data = "" LOG.debug("PC->V71: %s" % cmd) s.write(cmd + "\r") while not data.endswith("\r") and (time.time() - start) < timeout: data += s.read(1) LOG.debug("V71->PC: %s" % data.strip()) return data.strip() def get_id(s): r = command(s, "ID") if r.startswith("ID "): return r.split(" ")[1] else: raise errors.RadioError("No response to ID command") EXCH_R = "R\x00\x00\x00" EXCH_W = "W\x00\x00\x00" def read_block(s, block, count=256): s.write(struct.pack(" (max(V71_SPECIAL.values()) + 1): raise errors.InvalidMemoryLocation("Number must be between 0 and 999") mem = chirp_common.Memory() mem.number = number if number > 999: mem.extd_number = V71_SPECIAL_REV[number] if not get_used(map, number): mem.empty = True return mem mmap = get_raw_mem(map, number) mem.freq = get_freq(mmap) mem.name = get_name(map, number) mem.tmode = get_tmode(mmap) mem.rtone = get_tone(mmap, POS_RTONE) mem.ctone = get_tone(mmap, POS_CTONE) mem.dtcs = get_dtcs(mmap) mem.duplex = get_duplex(mmap) mem.offset = get_offset(mmap) mem.mode = get_mode(mmap) if number < 999: mem.skip = get_skip(map, number) if number > 999: mem.immutable = ["number", "bank", "extd_number", "name"] if number > 1020 and number < 1030: mem.immutable += ["freq"] # FIXME: ALL return mem def initialize(mmap): mmap[0] = \ "\x80\xc8\xb3\x08\x00\x01\x00\x08" + \ "\x08\x00\xc0\x27\x09\x00\x00\xff" def set_memory(map, mem): if mem.number < 0 or mem.number > (max(V71_SPECIAL.values()) + 1): raise errors.InvalidMemoryLocation("Number must be between 0 and 999") mmap = memmap.MemoryMap(get_raw_mem(map, mem.number)) if not get_used(map, mem.number): initialize(mmap) set_freq(mmap, mem.freq) if mem.number < 999: set_name(map, mem.number, mem.name) set_tmode(mmap, mem.tmode) set_tone(mmap, mem.rtone, POS_RTONE) set_tone(mmap, mem.ctone, POS_CTONE) set_dtcs(mmap, mem.dtcs) set_duplex(mmap, mem.duplex) set_offset(mmap, mem.offset) set_mode(mmap, mem.mode) base = get_mem_offset(mem.number) map[base] = mmap.get_packed() set_used(map, mem.number, mem.freq) if mem.number < 999: set_skip(map, mem.number, mem.skip) return map if __name__ == "__main__": import sys import serial s = serial.Serial(port=sys.argv[1], baudrate=9600, dsrdtr=True, timeout=0.25) # s.write("\r\r") # print get_id(s) data = download(s) open(sys.argv[2], "wb").write(data) chirp-20240224/chirp/drivers/retevis_rb15.py0000644000175000017500000006167414566340166017534 0ustar hibbyhibby# Copyright 2022 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct memory { u32 rxfreq; // 00-03 u16 decQT; // 04-05 u32 txfreq; // 06-09 u16 encQT; // 0a-0b u8 lowpower:1, // Power Level // 0c unknown1:1, isnarrow:1, // Bandwidth bcl:2, // Busy Channel Lockout scan:1, // Scan Add encode:1, // Encode isunused:1; // Is Unused u8 unknown3[3]; // 0d-0f }; #seekto 0x0170; struct memory channels[99]; #seekto 0x0162; struct { u8 unknown_1:1, // 0x0162 voice:2, // Voice Prompt beep:1, // Beep Switch unknown_2:1, vox:1, // VOX autolock:1, // Auto Lock vibrate:1; // Vibrate Switch u8 squelch:4, // 0x0163 SQ Level unknown_3:1, volume:3; // Volume Level u8 voxl:4, // 0x0164 VOX Level voxd:4; // VOX Delay u8 unknown_5:1, // 0x0165 save:3, // Power Save calltone:4; // Call Tone u8 unknown_6:4, // 0x0166 roger:2, // Roger Tone backlight:2; // Backlight Set u16 tot; // 0x0167-0x0168 Time-out Timer u8 unknown_7[3]; // 0x0169-0x016B u8 skeyul; // 0x016C Side Key Up Long u8 skeyus; // 0x016D Side Key Up Short u8 skeydl; // 0x016E Side Key Down Long u8 skeyds; // 0x016F Side Key Down Short } settings; """ CMD_ACK = b"\x06" RB15_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) LIST_BACKLIGHT = ["Off", "On", "Auto"] LIST_BCL = ["None", "Carrier", "QT/DQT Match"] LIST_ROGER = ["Off", "Start", "End", "Start and End"] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4", "1:5"] _STEP_LIST = [2.5, 5., 6.25, 10., 12.5, 20., 25., 50.] LIST_VOICE = ["Off", "Chinese", "English"] LIST_VOXD = ["0.0", "0.5", "1.0", "1.5", "2.0", "2.5", "3.0", "3.5", "4.0", "4.5", "5.0S"] SKEY_CHOICES = ["None", "Scan", "Monitor", "VOX On/Off", "Local Alarm", "Remote Alarm", "Backlight On/Off", "Call Tone"] SKEY_VALUES = [0x00, 0x01, 0x03, 0x04, 0x09, 0x0A, 0x13, 0x14] TOT_CHOICES = ["Off", "15", "30", "45", "60", "75", "90", "105", "120", "135", "150", "165", "180", "195", "210", "225", "240", "255", "270", "285", "300", "315", "330", "345", "360", "375", "390", "405", "420", "435", "450", "465", "480", "495", "510", "525", "540", "555", "570", "585", "600" ] TOT_VALUES = [0x00, 0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78, 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF0, 0xFF, 0x10E, 0x11D, 0x12C, 0x13B, 0x14A, 0x159, 0x168, 0x177, 0x186, 0x195, 0x1A4, 0x1B3, 0x1C2, 0x1D1, 0x1E0, 0x1EF, 0x1FE, 0x20D, 0x21C, 0x22B, 0x23A, 0x249, 0x258 ] def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def tone2short(t): """Convert a string tone or DCS to an encoded u16 """ tone = str(t) if tone == "----": u16tone = 0x0000 elif tone[0] == 'D': # This is a DCS code c = tone[1: -1] code = int(c, 8) if tone[-1] == 'I': code |= 0x4000 u16tone = code | 0x8000 else: # This is an analog CTCSS u16tone = int(tone[0:-2]+tone[-1]) & 0xffff # strip the '.' return u16tone def short2tone(tone): """ Map a binary CTCSS/DCS to a string name for the tone """ if tone == 0xC000 or tone == 0xffff: ret = "----" else: code = tone & 0x3fff if tone & 0x4000: # This is a DCS ret = "D%0.3oN" % code elif tone & 0x8000: # This is an inverse code ret = "D%0.3oI" % code else: # Just plain old analog CTCSS ret = "%4.1f" % (code / 10.0) return ret def _rb15_enter_programming_mode(radio): serial = radio.pipe # lengthen the timeout here as these radios are resetting due to timeout radio.pipe.timeout = 0.75 exito = False for i in range(0, 5): serial.write(radio.magic) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except: LOG.debug("Attempt #%s, failed, trying again" % i) pass # return timeout to default value radio.pipe.timeout = 0.25 # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) def _rb15_exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"21" + b"\x05\xEE" + b"V") except: raise errors.RadioError("Radio refused to exit programming mode") def _rb15_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">BH", ord(b'R'), block_addr) ccs = bytes([_checksum(cmd)]) expectedresponse = b"R" + cmd[1:] cmd = cmd + ccs LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(3 + block_size + 1) cs = bytes([_checksum(response[:-1])]) if response[:3] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) chunk = response[3:] if chunk[-1:] != cs: raise Exception("Block failed checksum!") block_data = chunk[:-1] except: raise errors.RadioError("Failed to read block at %04x" % block_addr) return block_data def _rb15_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">BH", ord(b'W'), block_addr) data = radio.get_mmap()[block_addr:block_addr + block_size] cs = bytes([_checksum(cmd + data)]) data += cs LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _rb15_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0x0000, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _rb15_read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _rb15_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _rb15_enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) _rb15_write_block(radio, addr, radio.BLOCK_SIZE) _rb15_exit_programming_mode(radio) def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True class RB15RadioBase(chirp_common.CloneModeRadio): """RETEVIS RB15 BASE""" VENDOR = "Retevis" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x10 magic = b"21" + b"\x05\x10" + b"x" VALID_BANDS = [(400000000, 480000000)] _ranges = [ (0x0150, 0x07A0), ] _memsize = 0x07A0 _frs = _pmr = False def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_dtcs_codes = RB15_DTCS rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = _STEP_LIST rf.valid_bands = self.VALID_BANDS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): """Decode both the encode and decode CTSS/DCS codes from the memory channel and stuff them into the UI memory channel row. """ txtone = short2tone(_mem.encQT) rxtone = short2tone(_mem.decQT) pt = "N" pr = "N" if txtone == "----": txmode = "" elif txtone[0] == "D": mem.dtcs = int(txtone[1:4]) if txtone[4] == "I": pt = "R" txmode = "DTCS" else: mem.rtone = float(txtone) txmode = "Tone" if rxtone == "----": rxmode = "" elif rxtone[0] == "D": mem.rx_dtcs = int(rxtone[1:4]) if rxtone[4] == "I": pr = "R" rxmode = "DTCS" else: mem.ctone = float(rxtone) rxmode = "Tone" if txmode == "Tone" and len(rxmode) == 0: mem.tmode = "Tone" elif (txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone): mem.tmode = "TSQL" elif (txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs): mem.tmode = "DTCS" elif (len(rxmode) + len(txmode)) > 0: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = pt + pr LOG.debug("_get_tone: Got TX %s (%i) RX %s (%i)" % (txmode, _mem.encQT, rxmode, _mem.decQT)) def _set_tone(self, mem, _mem): """Update the memory channel block CTCC/DCS tones from the UI fields """ def _set_dcs(code, pol): val = int("%i" % code, 8) | 0x4000 if pol == "R": val = int("%i" % code, 8) | 0x8000 return val rx_mode = tx_mode = None rxtone = txtone = 0xC000 if mem.tmode == "Tone": tx_mode = "Tone" txtone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) _mem.decQT = rxtone _mem.encQT = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.encQT, rx_mode, _mem.decQT)) def get_memory(self, number): mem = chirp_common.Memory() _mem = self._memobj.channels[number - 1] mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if _mem.get_raw() == (b"\xFF" * 16): LOG.debug("Initializing empty memory") _mem.set_raw(b"\x00" * 16) # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 mem.mode = _mem.isnarrow and "NFM" or "FM" self._get_tone(_mem, mem) mem.power = self.POWER_LEVELS[_mem.lowpower] if not _mem.scan: mem.skip = "S" mem.extra = RadioSettingGroup("Extra", "extra") if _mem.bcl > 0x02: val = 0 else: val = _mem.bcl rs = RadioSetting("bcl", "BCL", RadioSettingValueList( LIST_BCL, LIST_BCL[val])) mem.extra.append(rs) rs = RadioSetting("encode", "Encode", RadioSettingValueBoolean(_mem.encode)) mem.extra.append(rs) return mem def set_memory(self, mem): LOG.debug("Setting %i(%s)" % (mem.number, mem.extd_number)) _mem = self._memobj.channels[mem.number - 1] # if empty memory if mem.empty: _mem.set_raw("\xFF" * 16) return _mem.isunused = False _mem.unknown1 = False _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq.fill_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.scan = mem.skip != "S" _mem.isnarrow = mem.mode == "NFM" self._set_tone(mem, _mem) _mem.lowpower = mem.power == self.POWER_LEVELS[1] for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") sidekey = RadioSettingGroup("sidekey", "Side Key Settings") voxset = RadioSettingGroup("vox", "VOX Settings") top = RadioSettings(basic, sidekey, voxset) voice = RadioSetting("voice", "Language", RadioSettingValueList( LIST_VOICE, LIST_VOICE[_settings.voice])) basic.append(voice) beep = RadioSetting("beep", "Key Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(beep) volume = RadioSetting("volume", "Volume Level", RadioSettingValueInteger( 0, 7, _settings.volume)) basic.append(volume) save = RadioSetting("save", "Battery Save", RadioSettingValueList( LIST_SAVE, LIST_SAVE[_settings.save])) basic.append(save) backlight = RadioSetting("backlight", "Backlight", RadioSettingValueList( LIST_BACKLIGHT, LIST_BACKLIGHT[_settings.backlight])) basic.append(backlight) vibrate = RadioSetting("vibrate", "Vibrate", RadioSettingValueBoolean(_settings.vibrate)) basic.append(vibrate) autolock = RadioSetting("autolock", "Auto Lock", RadioSettingValueBoolean(_settings.autolock)) basic.append(autolock) calltone = RadioSetting("calltone", "Call Tone", RadioSettingValueInteger( 1, 10, _settings.calltone)) basic.append(calltone) roger = RadioSetting("roger", "Roger Tone", RadioSettingValueList( LIST_ROGER, LIST_ROGER[_settings.roger])) basic.append(roger) squelch = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger( 0, 10, _settings.squelch)) basic.append(squelch) def apply_tot_listvalue(setting, obj): LOG.debug("Setting value: " + str( setting.value) + " from list") val = str(setting.value) index = TOT_CHOICES.index(val) val = TOT_VALUES[index] obj.set_value(val) if _settings.tot in TOT_VALUES: idx = TOT_VALUES.index(_settings.tot) else: idx = TOT_VALUES.index(0x78) rs = RadioSettingValueList(TOT_CHOICES, TOT_CHOICES[idx]) rset = RadioSetting("tot", "Time-out Timer", rs) rset.set_apply_callback(apply_tot_listvalue, _settings.tot) basic.append(rset) # Side Key Settings def apply_skey_listvalue(setting, obj): LOG.debug("Setting value: " + str( setting.value) + " from list") val = str(setting.value) index = SKEY_CHOICES.index(val) val = SKEY_VALUES[index] obj.set_value(val) # Side Key (Upper) - Short Press if _settings.skeyus in SKEY_VALUES: idx = SKEY_VALUES.index(_settings.skeyus) else: idx = SKEY_VALUES.index(0x01) rs = RadioSettingValueList(SKEY_CHOICES, SKEY_CHOICES[idx]) rset = RadioSetting("skeyus", "Side Key(upper) - Short Press", rs) rset.set_apply_callback(apply_skey_listvalue, _settings.skeyus) sidekey.append(rset) # Side Key (Upper) - Long Press if _settings.skeyul in SKEY_VALUES: idx = SKEY_VALUES.index(_settings.skeyul) else: idx = SKEY_VALUES.index(0x04) rs = RadioSettingValueList(SKEY_CHOICES, SKEY_CHOICES[idx]) rset = RadioSetting("skeyul", "Side Key(upper) - Long Press", rs) rset.set_apply_callback(apply_skey_listvalue, _settings.skeyul) sidekey.append(rset) # Side Key (Lower) - Short Press if _settings.skeyds in SKEY_VALUES: idx = SKEY_VALUES.index(_settings.skeyds) else: idx = SKEY_VALUES.index(0x03) rs = RadioSettingValueList(SKEY_CHOICES, SKEY_CHOICES[idx]) rset = RadioSetting("skeyds", "Side Key(lower) - Short Press", rs) rset.set_apply_callback(apply_skey_listvalue, _settings.skeyds) sidekey.append(rset) # Side Key (Lower) - Long Press if _settings.skeyul in SKEY_VALUES: idx = SKEY_VALUES.index(_settings.skeydl) else: idx = SKEY_VALUES.index(0x14) rs = RadioSettingValueList(SKEY_CHOICES, SKEY_CHOICES[idx]) rset = RadioSetting("skeydl", "Side Key(lower) - Long Press", rs) rset.set_apply_callback(apply_skey_listvalue, _settings.skeydl) sidekey.append(rset) # VOX Settings vox = RadioSetting("vox", "VOX", RadioSettingValueBoolean(_settings.vox)) voxset.append(vox) voxl = RadioSetting("voxl", "VOX Level", RadioSettingValueInteger( 0, 10, _settings.voxl)) voxset.append(voxl) voxd = RadioSetting("voxd", "VOX Delay (seconde)", RadioSettingValueList( LIST_VOXD, LIST_VOXD[_settings.voxd])) voxset.append(voxd) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class RB15Radio(RB15RadioBase): """RETEVIS RB15""" VENDOR = "Retevis" MODEL = "RB15" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _ranges = [ (0x0150, 0x07A0), ] _memsize = 0x07A0 _upper = 99 _frs = False # sold as FRS radio but supports full band TX/RX @directory.register class RB615RadioBase(RB15RadioBase): """RETEVIS RB615""" VENDOR = "Retevis" MODEL = "RB615" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _ranges = [ (0x0150, 0x07A0), ] _memsize = 0x07A0 _upper = 99 _pmr = False # sold as PMR radio but supports full band TX/RX chirp-20240224/chirp/drivers/kguv920pa.py0000644000175000017500000014507514520142245016734 0ustar hibbyhibby# Copyright 2022 Matthew Handley # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun KG-UV920P-A radio management module based""" import time import logging from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettingValueMap, RadioSettingValueFloat, RadioSettings import struct LOG = logging.getLogger(__name__) CMD_ID = 0x80 CMD_END = 0x81 CMD_RD = 0x82 CMD_WR = 0x83 CHARSET_NUMERIC = "0123456789" CHARSET = "0123456789" + \ ":;<=>?@" + \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + \ "[\\]^_`" + \ "abcdefghijklmnopqrstuvwxyz" + \ "{|}~\x4E" + \ " !\"#$%&'()*+,-./" MUTE_MODE_MAP = [('QT', 0b01), ('QT*DTMF', 0b10), ('QT+DTMF', 0b11)] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 30.0, 50.0, 100.0] STEP_LIST = [str(x) for x in STEPS] M_POWER_MAP = [('10', 1), ('20', 2)] ROGER_LIST = ["Off", "BOT", "EOT", "Both"] VOICE_LIST = ["Off", "Chinese", "English"] SC_REV_MAP = [('Timeout (TO)', 1), ('Carrier (CO)', 2), ('Stop (SE)', 3)] TOT_MAP = [('%d' % i, int('%02d' % i, 16)) for i in range(1, 61)] TOA_MAP = [('Off', 0)] + \ [('%d' % i, int('%02d' % i, 16)) for i in range(1, 11)] RING_MAP = [('Off', 0)] + \ [('%d' % i, int('%02d' % i, 16)) for i in range(1, 11)] DTMF_ST_LIST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] PTT_ID_LIST = ["BOT", "EOT", "Both"] PTT_ID_MAP = [('BOT', 1), ('EOT', 2), ('Both', 3)] BACKLIGHT_LIST = ["Off", "White", "Blue", "Green"] SPEAKER_MAP = [('1', 1), ('2', 2), ('1+2', 3)] RPT_MODE_LIST = ["Off", "X-DIRPT", "X-TWRPT", "CRPT-RX", "CRPT-TX"] APO_TIME_LIST = ["Off", "30", "60", "90", "120", "150"] ALERT_MAP = [('1750', 1), ('2100', 2), ('1000', 3), ('1450', 4)] FAN_MODE_LIST = ["TX", "Hi-Temp/TX", "Always"] SCAN_GROUP_LIST = ["All", "1", "2", "3", "4"] WORKMODE_MAP = [('VFO', 1), ('Ch. No.', 2), ('Ch. No.+Freq.', 3), ('Ch. No.+Name', 4)] AB_LIST = ["A", "B"] POWER_MAP = [('L', 0), ('M', 1), ('H', 3)] BANDWIDTH_MAP = [('NFM', 0b11), ('FM', 0b00)] SCRAMBLER_LIST = ["Off", "1", "2", "3", "4", "5", "6", "7", "8"] ANS_LIST = ["Off", "Normal", "Strong"] DTMF_TIMES = [str(x) for x in range(80, 501, 20)] DTMF_INTERVALS = [str(x) for x in range(60, 501, 20)] ROGER_TIMES = [str(x) for x in range(20, 1001, 20)] PTT_ID_DELAY_MAP = [(str(x), x/100) for x in range(100, 1001, 100)] ROGER_INTERVALS = ROGER_TIMES TONE_MAP = [('Off', 0x0000)] + \ [('%.1f' % tone, int(tone * 10)) for tone in chirp_common.TONES] + \ [('DN%d' % tone, int(0x8000 + tone * 10)) for tone in chirp_common.DTCS_CODES] + \ [('DR%d' % tone, int(0xC000 + tone * 10)) for tone in chirp_common.DTCS_CODES] DUPLEX_LIST = ["Off", "+", "-"] # structure elements whose name starts with x are currently unidentified _MEM_FORMAT = """ #seekto 0x0040; struct { u8 left[8]; u8 right[8]; } ponmsg; // Limit changes here don't persist, so may be incorrect. Currently unused // in driver. #seekto 0x0070; struct { u16 uhf_rx_start; // 0x0070 u16 uhf_rx_stop; // 0x0072 u16 vhf_rx_start; // 0x0074 u16 vhf_rx_stop; // 0x0076 u16 uhf_tx_start; // 0x0078 u16 uhf_tx_stop; // 0x007A u16 vhf_tx_start; // 0x007C u16 vhf_tx_stop; // 0x007E } limits; #seekto 0x0068; struct { u8 unknown1[8]; // 0x0068 u8 x0070[368]; u8 x01E0[8]; u8 x01E8[8]; u8 model[8]; // 0x01F0 u8 date[8]; u8 oem1[8]; u8 oem2[8]; u8 unknown2[8]; u8 unknown3[8]; } oem_info; #seekto 0x0250; struct { u32 rxfreq; u32 txoffset; u16 txtone; u16 rxtone; u8 unknown1_7downto5:3, mute_mode:2, unknown1_3downto0:3; u8 named:1, scan_add:1, power:2, unknown2_32:2, isnarrow:2; u8 unknown3_7downto2:6, duplex:2; u8 unknown4:3, compander:1, scrambler:4; } vfoa; #seekto 0x0260; struct { u32 rxfreq; u32 txoffset; u16 txtone; u16 rxtone; u8 unknown1_7downto5:3, mute_mode:2, unknown1_3downto0:3; u8 named:1, scan_add:1, power:2, unknown2_3downto2:2, isnarrow:2; u8 unknown3_7downto2:6, duplex:2; u8 unknown4:3, compander:1, scrambler:4; } vfob; #seekto 0x0270; struct { u8 rc_power; // 0x0270 u8 voice; // 0x0271 u8 tot; // 0x0272 u8 toa; // 0x0273 u8 roger; // 0x0274 u8 sc_rev; // 0x0275 u8 dtmf_st; // 0x0276 u8 ptt_id; // 0x0277 u8 ring; // 0x0278 u8 ani_sw; // 0x0279 u8 x027A; u8 alert; // 0x027B u8 bcl_a; // 0x027C u8 pri_ch_sw; // 0x027D u8 scan_group; // 0x027E u8 ptt_id_delay; // 0x027F u8 x0280; u8 x0281; u8 beep; // 0x0282 u8 x0283; u8 x0284; u8 tx_led; // 0x0285 u8 wt_led; // 0x0286 u8 rx_led; // 0x0287 u8 active_display; // 0x0288 u8 workmode_a; // 0x0289 u8 workmode_b; // 0x028A u8 squelch_a; // 0x028B u8 squelch_b; // 0x028C u8 step_a; // 0x028D u8 step_b; // 0x028E u8 single_display; // 0x028F u8 x0290; u16 work_cha; // 0x0291 u8 x0293; u16 work_chb; // 0x0294 u8 dtmf_time; // 0x0296 u8 x0297; u8 dtmf_interval; // 0x0298 u8 x0299; u16 pri_ch; // 0x029A u8 x029C; u8 x029D; u8 speaker; // 0x029E u8 x029F; u8 rpt_spk; // 0x02A0 u8 rpt_ptt; // 0x02A1 u8 autolock; // 0x02A2 u8 apo_time; // 0x02A3 u8 low_v; // 0x02A4 u8 fan_mode; // 0x02A5 u8 x02A6; u8 rc_sw; // 0x02A7 u8 x02A8; u8 roger_time; // 0x02A9 u8 roger_int; // 0x02AA u8 bcl_b; // 0x02AB u8 m_power_set; // 0x02AC u8 x02AD; u8 ans; // 0x02AE u8 x02AF; u8 ani[3]; // 0x02B0 u8 x02B3; u8 ani_mcc[3]; // 0x02B4 u8 x02B7; u8 ani_scc[3]; // 0x02B8 u8 x02BB; u8 ani_ctrl[3]; // 0x02BC u8 x02BF; u8 roger_begin[4]; // 0x02C0 u8 roger_end[4]; // 0x02C4 u8 x02C8[8]; u16 grp1_lower; // 0x02D0 u16 grp1_upper; u16 grp2_lower; // 0x02D4 u16 grp2_upper; u16 grp3_lower; // 0x02D8 u16 grp3_upper; u16 grp4_lower; // 0x02DC u16 grp4_upper; u8 x02E0[16]; u8 x02F0[16]; u8 x0300[16]; u8 x0310[7]; u8 rpt_tone; // 0x0317 u8 x0318[8]; u8 x0320[16]; u8 x0330[16]; u8 x0340[16]; u8 x0350[16]; u8 x0360[16]; u8 x0370[16]; u8 x0380[16]; u8 x0390[16]; u8 x03A0[16]; u8 x03B0[16]; u8 rpt_mode; // 0x03C0 u8 x03C1; u8 x03C2; u8 x03C3; u8 x03C4; u8 x03C5; u8 scan_det; // 0x0x3C6 } settings; #seekto 0x0400; struct { u16 freq; } fm_preset[20]; #seekto 0x0800; struct { u32 rxfreq; u32 txfreq; u16 txtone; u16 rxtone; u8 unknown1_7downto5:3, mute_mode:2, unknown1_3downto0:3; u8 named:1, scan_add:1, power:2, unknown2_32:2, isnarrow:2; u8 unknown3_7downto2:6, shift_dir:2; u8 unknown4:3, compander:1, scrambler:4; } memory[999]; #seekto 0x4700; struct { u8 name[8]; } names[999]; """ def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 16 def _str_decode(in_str): out_str = '' for c in in_str: if c < len(CHARSET): out_str += CHARSET[c] return out_str.rstrip() def _str_encode(in_str): out_str = [] for c in in_str: try: out_str.append(CHARSET.index(c)) except ValueError: pass while len(out_str) < 8: out_str.append(CHARSET.index(' ')) return bytes(out_str) def _freq_decode(in_freq, bytes=4): out_freq = 0 for i in range(bytes*2): out_freq += (in_freq & 0xF) * (10 ** i) in_freq = in_freq >> 4 if bytes == 4: return out_freq * 10 elif bytes == 2: return out_freq * 100000 def _freq_encode(in_freq, bytes=4): if bytes == 4: return int('%08d' % (in_freq / 10), 16) elif bytes == 2: return int('%04d' % (in_freq / 100000), 16) def _ani_decode(in_ani): return ''.join(['%02x' % b for b in in_ani]).strip('c') def _ani_encode(in_ani): ani_str = '' while len(in_ani) < 6: in_ani += 'c' for i in range(3): ani_str += chr(int(in_ani[i*2:i*2+2], 16)) return ani_str def _chnum_decode(in_ch): return int(('%04x' % in_ch)[0:3]) def _chnum_encode(in_ch): return int('%03d0' % in_ch, 16) def _roger_decode(in_roger): return ''.join(['%02x' % b for b in in_roger]).strip('ef') def _roger_encode(in_roger): roger_str = '' in_roger = 'e' + in_roger while len(in_roger) < 8: in_roger += 'f' for i in range(4): roger_str += chr(int(in_roger[i*2:i*2+2], 16)) return roger_str def _get_tone(_mem, mem): def _get_dcs(val): code = (val & 0x3FF) pol = (val & 0x4000) and "R" or "N" return code, pol tpol = False if _mem.txtone != 0xFFFF and (_mem.txtone & 0x8000) == 0x8000: tcode, tpol = _get_dcs(_mem.txtone) mem.dtcs = tcode txmode = "DTCS" elif _mem.txtone != 0xFFFF and _mem.txtone != 0x0: mem.rtone = (_mem.txtone & 0xFff) / 10.0 txmode = "Tone" else: txmode = "" rpol = False if _mem.rxtone != 0xFFFF and (_mem.rxtone & 0x8000) == 0x8000: rcode, rpol = _get_dcs(_mem.rxtone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rxtone != 0xFFFF and _mem.rxtone != 0x0: mem.ctone = (_mem.rxtone & 0xFff) / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.txtone, rxmode, _mem.rxtone)) def _set_tone(mem, _mem): def _set_dcs(code, pol): val = (code & 0x3FF) + 0x8000 if pol == "R": val += 0x4000 return val rx_mode = tx_mode = None rxtone = txtone = 0 if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None txtone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) _mem.rxtone = rxtone _mem.txtone = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.txtone, rx_mode, _mem.rxtone)) # Support for the Wouxun KG-UV920P-A radio # Serial coms are at 19200 baud # The data is passed in variable length records # Record structure: # Offset Usage # 0 start of record (\x7e) # 1 Command (\x80 Identify \x81 End/Reboot \x82 Read \x83 Write) # 2 direction (\xff PC-> Radio, \x00 Radio -> PC) # 3 length of payload (excluding header/checksum) (n) # 4 payload (n bytes) # 4+n+1 checksum - byte sum (% 16) of bytes 1 -> 4+n # # Memory Read Records: # the payload is 3 bytes, first 2 are offset (big endian), # 3rd is number of bytes to read # Memory Write Records: # 2 bytes location + data. @directory.register class KGUV920PARadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-UV920P-A""" VENDOR = "Wouxun" MODEL = "KG-UV920P-A" _model = "KG-UV920Rr" # what the radio responds to CMD_ID with _file_ident = b"KGUV920PA" BAUD_RATE = 19200 POWER_LEVELS = [chirp_common.PowerLevel("L", watts=5), chirp_common.PowerLevel("M", watts=20), chirp_common.PowerLevel("H", watts=50)] NEEDS_COMPAT_SERIAL = False def _write_record(self, cmd, payload=None): _length = 0 if payload: _length = len(payload) _packet = struct.pack('BBBB', 0x7E, cmd, 0xFF, _length) if payload: # add the chars to the packet _packet += payload # calculate and add the checksum to the packet _packet += bytes([_checksum(_packet[1:])]) LOG.debug("Sent:\n%s" % util.hexprint(_packet)) self.pipe.write(_packet) def _read_record(self): # read 4 chars for the header _header = self.pipe.read(4) if len(_header) != 4: raise errors.RadioError('Radio did not respond') _length = _header[3] _packet = self.pipe.read(_length) _cs = _checksum(_header[1:]) _cs += _checksum(_packet) _cs %= 16 try: _rcs = self.pipe.read(1)[0] except (TypeError, IndexError): raise errors.RadioError('Radio did not respond') if _rcs != _cs: LOG.error("_cs =%x", _cs) LOG.error("_rcs=%x", _rcs) return (_rcs != _cs, _packet) @classmethod def match_model(cls, filedata, filename): return cls._file_ident in filedata[0x400:0x408] def _identify(self): """ Offset 0:10 Model 'KG-UV920Rr' 11: Not used (limits) """ self._write_record(CMD_ID) time.sleep(0.6) _chksum_err, _resp = self._read_record() LOG.debug("Got:\n%s" % util.hexprint(_resp)) if _chksum_err: raise Exception("Checksum error") if len(_resp) == 0: raise Exception("Radio not responding") reported_model = _str_decode(_resp[0:10]) if reported_model != self._model: raise Exception("Unable to identify radio (Got %s, Expected)" % reported_model, self._model) def _finish(self): self._write_record(CMD_END) def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._download() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): self._upload() # TODO: This is a dumb, brute force method of downloading the memory. # it would be smarter to only load the active areas and none of # the padding/unused areas. def _download(self): """Talk to a Wouxun KG-UV920P-A and do a download""" try: self._identify() return self._do_download(0, 0x6640, 0x40) except errors.RadioError: raise except Exception as e: LOG.exception('Unknown error during download process') raise errors.RadioError("Failed to communicate with radio: %s" % e) def _do_download(self, start, end, blocksize): # allocate & fill memory image = b"" for i in range(start, end, blocksize): req = struct.pack('>HB', i, blocksize) self._write_record(CMD_RD, req) cs_error, resp = self._read_record() if cs_error: LOG.debug(util.hexprint(resp)) raise Exception("Checksum error on read") LOG.debug("Got:\n%s" % util.hexprint(resp)) image += resp[2:] if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning from radio" self.status_fn(status) self._finish() return memmap.MemoryMapBytes(image) def _upload(self): """Talk to a Wouxun KG-UV920P-A and do a upload""" try: self._identify() self._do_upload(0x0000, 0x6640, 0x40) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) return def _do_upload(self, start, end, blocksize): ptr = start for i in range(start, end, blocksize): req = struct.pack('>H', i) chunk = self.get_mmap()[ptr:ptr + blocksize] self._write_record(CMD_WR, req + chunk) LOG.debug(util.hexprint(req + chunk)) cserr, ack = self._read_record() LOG.debug(util.hexprint(ack)) j = struct.unpack('>H', ack[0:2])[0] if cserr or j != ptr: print(cserr) print(j) print(ptr) raise Exception("Radio did not ack block %i" % ptr) ptr += blocksize if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning to radio" self.status_fn(status) self._finish() def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_tuning_steps = STEPS rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_bands = [(136000000, 175000000), # supports 2m (420000000, 520000000)] # supports 70cm rf.valid_characters = CHARSET rf.memory_bounds = (1, 999) # 999 memories return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is a beta version. " "There are no known issues with it, but you should " "proceed with caution.") return rp def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def get_memory(self, number): mem = chirp_common.Memory() mem.number = number _mem = self._memobj.memory[mem.number-1] if _mem.rxfreq & 0xFF000000 == 0xFF000000: mem.empty = True return mem else: mem.empty = False _rxfreq = _freq_decode(_mem.rxfreq) _txfreq = _freq_decode(_mem.txfreq) mem.freq = _rxfreq if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_rxfreq) == int(_txfreq): mem.duplex = "" mem.offset = 0 elif abs(_rxfreq - _txfreq) > 70000000: mem.duplex = "split" mem.offset = _txfreq else: mem.duplex = _rxfreq > _txfreq and "-" or "+" mem.offset = abs(_rxfreq - _txfreq) if _mem.named: mem.name = _str_decode(self._memobj.names[number-1].name) else: mem.name = '' _get_tone(_mem, mem) mem.skip = "" if bool(_mem.scan_add) else "S" if _mem.power == 3: mem.power = self.POWER_LEVELS[2] else: mem.power = self.POWER_LEVELS[_mem.power] mem.mode = _mem.isnarrow and "NFM" or "FM" mem.extra = RadioSettingGroup("Extra", "extra") _scram = _mem.scrambler if _mem.scrambler > 8: _scram = 0 rs = RadioSetting("scrambler", "Scrambler", RadioSettingValueList(SCRAMBLER_LIST, SCRAMBLER_LIST[_scram])) mem.extra.append(rs) rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(_mem.compander)) mem.extra.append(rs) rs = RadioSetting("mute_mode", "Mute", RadioSettingValueMap(MUTE_MODE_MAP, _mem.mute_mode)) mem.extra.append(rs) return mem def set_memory(self, mem): number = mem.number _mem = self._memobj.memory[number-1] _nam = self._memobj.names[number-1] if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) _nam.set_raw(_str_encode("")) _mem.rxfreq = 0xFFFFFFFF return _mem.rxfreq = _freq_encode(mem.freq) if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = _freq_encode(mem.offset) elif mem.duplex == "+": _mem.txfreq = _freq_encode(mem.freq + mem.offset) elif mem.duplex == "-": _mem.txfreq = _freq_encode(mem.freq - mem.offset) else: _mem.txfreq = _freq_encode(mem.freq) _mem.scan_add = int(mem.skip != "S") _mem.isnarrow = 0b11 * int(mem.mode == "NFM") # set the tone _set_tone(mem, _mem) # set the power if mem.power: idx = self.POWER_LEVELS.index(mem.power) if idx == 2: _mem.power = 3 else: _mem.power = idx else: _mem.power = True if len(mem.name) > 0: _mem.named = True name_encoded = _str_encode(mem.name) for i in range(0, 8): _nam.name[i] = name_encoded[i] else: _mem.named = False for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def _get_settings(self): _settings = self._memobj.settings _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob _fm_preset = self._memobj.fm_preset cfg_grp = RadioSettingGroup("cfg_grp", "Configuration") ui_grp = RadioSettingGroup("ui_grp", "User Interface") vfoa_grp = RadioSettingGroup("vfoa_grp", "VFO A") vfob_grp = RadioSettingGroup("vfob_grp", "VFO B") scn_grp = RadioSettingGroup("scn_grp", "Scan") rpt_grp = RadioSettingGroup("rmt_grp", "Repeater") rmt_grp = RadioSettingGroup("rmt_grp", "Remote Control") fmp_grp = RadioSettingGroup("fmp_grp", "FM Radio Presets") oem_grp = RadioSettingGroup("oem_grp", "OEM Info") group = RadioSettings(cfg_grp, ui_grp, vfoa_grp, vfob_grp, scn_grp, rpt_grp, rmt_grp, fmp_grp, oem_grp) # # Configuration Settings # rs = RadioSetting("m_power_set", "Medium Power Level (W)", RadioSettingValueMap(M_POWER_MAP, _settings.m_power_set)) cfg_grp.append(rs) rs = RadioSetting("roger", "Roger Beep", RadioSettingValueList(ROGER_LIST, ROGER_LIST[_settings.roger])) cfg_grp.append(rs) rs = RadioSetting("roger_time", "Roger Tx Duration (ms)", RadioSettingValueList( ROGER_TIMES, ROGER_TIMES[_settings.roger_time])) cfg_grp.append(rs) rs = RadioSetting("roger_int", "Roger Interval (ms)", RadioSettingValueList( ROGER_INTERVALS, ROGER_INTERVALS[_settings.roger_int])) cfg_grp.append(rs) val = RadioSettingValueString(1, 6, _roger_decode(_settings.roger_begin), False, CHARSET_NUMERIC) rs = RadioSetting("roger_begin", "Roger Begin", val) cfg_grp.append(rs) val = RadioSettingValueString(1, 6, _roger_decode(_settings.roger_end), False, CHARSET_NUMERIC) rs = RadioSetting("roger_end", "Roger End", val) cfg_grp.append(rs) rs = RadioSetting("tot", "Time-Out Timer (TOT) (Min)", RadioSettingValueMap(TOT_MAP, _settings.tot)) cfg_grp.append(rs) rs = RadioSetting("toa", "Time-Out Alarm (TOA) (Sec)", RadioSettingValueMap(TOA_MAP, _settings.toa)) cfg_grp.append(rs) rs = RadioSetting("ani_sw", "Caller ID Tx", RadioSettingValueBoolean(_settings.ani_sw)) cfg_grp.append(rs) rs = RadioSetting("ptt_id", "Caller ID Tx Mode", RadioSettingValueMap(PTT_ID_MAP, _settings.ptt_id)) cfg_grp.append(rs) rs = RadioSetting("ptt_id_delay", "Caller ID Tx Delay (ms)", RadioSettingValueMap(PTT_ID_DELAY_MAP, _settings.ptt_id_delay)) cfg_grp.append(rs) rs = RadioSetting("ring", "Ring Time (Sec)", RadioSettingValueMap(RING_MAP, _settings.ring)) cfg_grp.append(rs) rs = RadioSetting("dtmf_st", "DTMF Sidetone", RadioSettingValueList( DTMF_ST_LIST, DTMF_ST_LIST[_settings.dtmf_st])) cfg_grp.append(rs) rs = RadioSetting("pri_ch_sw", "Priority Channel Switch", RadioSettingValueBoolean(_settings.pri_ch_sw)) cfg_grp.append(rs) rs = RadioSetting("pri_ch", "Priority Channel", RadioSettingValueInteger( 1, 999, _chnum_decode(_settings.pri_ch))) cfg_grp.append(rs) rs = RadioSetting("apo_time", "Auto Power-Off (Min)", RadioSettingValueList( APO_TIME_LIST, APO_TIME_LIST[_settings.apo_time])) cfg_grp.append(rs) rs = RadioSetting("alert", "Alert Pulse (Hz)", RadioSettingValueMap(ALERT_MAP, _settings.alert)) cfg_grp.append(rs) rs = RadioSetting("fan_mode", "Fan Mode", RadioSettingValueList( FAN_MODE_LIST, FAN_MODE_LIST[_settings.fan_mode])) cfg_grp.append(rs) rs = RadioSetting("low_v", "Low Voltage Shutoff", RadioSettingValueBoolean(_settings.low_v)) cfg_grp.append(rs) rs = RadioSetting("ans", "Noise Reduction", RadioSettingValueList(ANS_LIST, ANS_LIST[_settings.ans])) cfg_grp.append(rs) rs = RadioSetting("dtmf_time", "DTMF Tx Duration (ms)", RadioSettingValueList( DTMF_TIMES, DTMF_TIMES[_settings.dtmf_time])) cfg_grp.append(rs) rs = RadioSetting("dtmf_interval", "DTMF Interval (ms)", RadioSettingValueList( DTMF_INTERVALS, DTMF_INTERVALS[_settings.dtmf_interval])) cfg_grp.append(rs) # # UI Settings # rs = RadioSetting("ponmsg.left", "Power On Message Left & \n Single Band Message", RadioSettingValueString( 0, 8, _str_decode(self._memobj.ponmsg.left))) ui_grp.append(rs) rs = RadioSetting("ponmsg.right", "Power On Message Right", RadioSettingValueString( 0, 8, _str_decode(self._memobj.ponmsg.right))) ui_grp.append(rs) rs = RadioSetting("autolock", "Autolock", RadioSettingValueBoolean(_settings.autolock)) ui_grp.append(rs) rs = RadioSetting("speaker", "Speaker Select", RadioSettingValueMap(SPEAKER_MAP, _settings.speaker)) ui_grp.append(rs) rs = RadioSetting("voice", "Voice Guide", RadioSettingValueList(VOICE_LIST, VOICE_LIST[_settings.voice])) ui_grp.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep)) ui_grp.append(rs) rs = RadioSetting("active_display", "Active Display", RadioSettingValueList( AB_LIST, AB_LIST[_settings.active_display])) ui_grp.append(rs) rs = RadioSetting("single_display", "Single Display", RadioSettingValueBoolean(_settings.single_display)) ui_grp.append(rs) rs = RadioSetting("tx_led", "TX Backlight", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.tx_led])) ui_grp.append(rs) rs = RadioSetting("wt_led", "Standby Backlight", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.wt_led])) ui_grp.append(rs) rs = RadioSetting("rx_led", "Rx Backlight", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.rx_led])) ui_grp.append(rs) # # VFO A Settings # rs = RadioSetting("workmode_a", "Workmode", RadioSettingValueMap( WORKMODE_MAP, _settings.workmode_a)) vfoa_grp.append(rs) rs = RadioSetting("work_cha", "Channel", RadioSettingValueInteger( 1, 999, _chnum_decode(_settings.work_cha))) vfoa_grp.append(rs) rs = RadioSetting("vfoa.rxfreq", "Rx Frequency", RadioSettingValueInteger( 137000000, 470000000, _freq_decode(_vfoa.rxfreq), 2500)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.txoffset", "Tx Offset", RadioSettingValueInteger( 0, 470000000, _freq_decode(_vfoa.txoffset), 2500)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.rxtone", "Rx Tone", RadioSettingValueMap(TONE_MAP, _vfoa.rxtone)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.txtone", "Tx Tone", RadioSettingValueMap(TONE_MAP, _vfoa.txtone)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.power", "Power", RadioSettingValueMap(POWER_MAP, _vfoa.power)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.duplex", "Duplex", RadioSettingValueList(DUPLEX_LIST, DUPLEX_LIST[_vfoa.duplex])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.isnarrow", "Mode", RadioSettingValueMap(BANDWIDTH_MAP, _vfoa.isnarrow)) vfoa_grp.append(rs) _vfoa_scram = _vfoa.scrambler if _vfoa_scram > 8: _vfoa_scram = 0 rs = RadioSetting("vfoa.scrambler", "Scrambler", RadioSettingValueList(SCRAMBLER_LIST, SCRAMBLER_LIST[_vfoa_scram])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.compander", "Compander", RadioSettingValueBoolean(_vfoa.compander)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.mute_mode", "Mute", RadioSettingValueMap(MUTE_MODE_MAP, _vfoa.mute_mode)) vfoa_grp.append(rs) rs = RadioSetting("step_a", "Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_settings.step_a])) vfoa_grp.append(rs) rs = RadioSetting("squelch_a", "Squelch", RadioSettingValueInteger( 0, 9, _settings.squelch_a)) vfoa_grp.append(rs) rs = RadioSetting("bcl_a", "Busy Channel Lock-out", RadioSettingValueBoolean(_settings.bcl_a)) vfoa_grp.append(rs) # # VFO B Settings # rs = RadioSetting("workmode_b", "Workmode", RadioSettingValueMap( WORKMODE_MAP, _settings.workmode_b)) vfob_grp.append(rs) rs = RadioSetting("work_chb", "Channel", RadioSettingValueInteger( 1, 999, _chnum_decode(_settings.work_chb))) vfob_grp.append(rs) rs = RadioSetting("vfob.rxfreq", "Rx Frequency", RadioSettingValueInteger( 137000000, 470000000, _freq_decode(_vfob.rxfreq), 2500)) vfob_grp.append(rs) rs = RadioSetting("vfob.txoffset", "Tx Offset", RadioSettingValueInteger( 0, 470000000, _freq_decode(_vfob.txoffset), 2500)) vfob_grp.append(rs) rs = RadioSetting("vfob.rxtone", "Rx Tone", RadioSettingValueMap(TONE_MAP, _vfob.rxtone)) vfob_grp.append(rs) rs = RadioSetting("vfob.txtone", "Tx Tone", RadioSettingValueMap(TONE_MAP, _vfob.txtone)) vfob_grp.append(rs) rs = RadioSetting("vfob.power", "Power", RadioSettingValueMap(POWER_MAP, _vfob.power)) vfob_grp.append(rs) rs = RadioSetting("vfob.duplex", "Duplex", RadioSettingValueList(DUPLEX_LIST, DUPLEX_LIST[_vfob.duplex])) vfob_grp.append(rs) rs = RadioSetting("vfob.isnarrow", "Mode", RadioSettingValueMap(BANDWIDTH_MAP, _vfob.isnarrow)) vfob_grp.append(rs) _vfob_scram = _vfob.scrambler if _vfob_scram > 8: _vfob_scram = 0 rs = RadioSetting("vfob.scrambler", "Scrambler", RadioSettingValueList(SCRAMBLER_LIST, SCRAMBLER_LIST[_vfob_scram])) vfob_grp.append(rs) rs = RadioSetting("vfob.compander", "Compander", RadioSettingValueBoolean(_vfob.compander)) vfob_grp.append(rs) rs = RadioSetting("vfob.mute_mode", "Mute", RadioSettingValueMap(MUTE_MODE_MAP, _vfob.mute_mode)) vfob_grp.append(rs) rs = RadioSetting("step_b", "Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_settings.step_b])) vfob_grp.append(rs) rs = RadioSetting("squelch_b", "Squelch", RadioSettingValueInteger( 0, 9, _settings.squelch_b)) vfob_grp.append(rs) rs = RadioSetting("bcl_b", "Busy Channel Lock-out", RadioSettingValueBoolean(_settings.bcl_b)) vfob_grp.append(rs) # # Scan Settings # rs = RadioSetting("sc_rev", "Scan Resume Mode", RadioSettingValueMap(SC_REV_MAP, _settings.sc_rev)) scn_grp.append(rs) rs = RadioSetting("scan_group", "Scan Group", RadioSettingValueList(SCAN_GROUP_LIST, SCAN_GROUP_LIST[ _settings.scan_group])) scn_grp.append(rs) rs = RadioSetting("grp1_lower", "Group 1 Lower", RadioSettingValueInteger(1, 999, _settings.grp1_lower)) scn_grp.append(rs) rs = RadioSetting("grp1_upper", "Group 1 Upper", RadioSettingValueInteger(1, 999, _settings.grp1_upper)) scn_grp.append(rs) rs = RadioSetting("grp2_lower", "Group 2 Lower", RadioSettingValueInteger(1, 999, _settings.grp2_lower)) scn_grp.append(rs) rs = RadioSetting("grp2_upper", "Group 2 Upper", RadioSettingValueInteger(1, 999, _settings.grp2_upper)) scn_grp.append(rs) rs = RadioSetting("grp3_lower", "Group 3 Lower", RadioSettingValueInteger(1, 999, _settings.grp3_lower)) scn_grp.append(rs) rs = RadioSetting("grp3_upper", "Group 3 Upper", RadioSettingValueInteger(1, 999, _settings.grp3_upper)) scn_grp.append(rs) rs = RadioSetting("grp4_lower", "Group 4 Lower", RadioSettingValueInteger(1, 999, _settings.grp4_lower)) scn_grp.append(rs) rs = RadioSetting("grp4_upper", "Group 4 Upper", RadioSettingValueInteger(1, 999, _settings.grp4_upper)) scn_grp.append(rs) rs = RadioSetting("scan_det", "Scan DET", RadioSettingValueBoolean(_settings.scan_det)) scn_grp.append(rs) # # Repeater Settings # rs = RadioSetting("rpt_spk", "Speaker", RadioSettingValueBoolean(_settings.rpt_spk)) rpt_grp.append(rs) rs = RadioSetting("rpt_ptt", "PTT", RadioSettingValueBoolean(_settings.rpt_ptt)) rpt_grp.append(rs) rs = RadioSetting("rpt_mode", "Mode", RadioSettingValueList(RPT_MODE_LIST, RPT_MODE_LIST[ _settings.rpt_mode])) rpt_grp.append(rs) rs = RadioSetting("rpt_tone", "Tone", RadioSettingValueBoolean(_settings.rpt_tone)) rpt_grp.append(rs) # # Remote Settings # rs = RadioSetting("rc_sw", "Remote Control", RadioSettingValueBoolean(_settings.rc_sw)) rmt_grp.append(rs) rs = RadioSetting("rc_power", "Remote Control Power", RadioSettingValueBoolean(_settings.rc_power)) rmt_grp.append(rs) val = RadioSettingValueString(3, 6, _ani_decode(_settings.ani), False, CHARSET_NUMERIC) rs = RadioSetting("ani", "Caller ID (ANI)", val) rmt_grp.append(rs) val = RadioSettingValueString(3, 6, _ani_decode(_settings.ani_mcc), False, CHARSET_NUMERIC) rs = RadioSetting("ani_mcc", "MCC-Edit", val) rmt_grp.append(rs) val = RadioSettingValueString(3, 6, _ani_decode(_settings.ani_scc), False, CHARSET_NUMERIC) rs = RadioSetting("ani_scc", "SCC-Edit", val) rmt_grp.append(rs) val = RadioSettingValueString(3, 6, _ani_decode(_settings.ani_ctrl), False, CHARSET_NUMERIC) rs = RadioSetting("ani_ctrl", "Control", val) rmt_grp.append(rs) # # FM Radio Presets Settings # for i in range(1, 21): val = _fm_preset[i-1].freq / 100.0 rs = RadioSetting(str(i), str(i), RadioSettingValueFloat(65.00, 108.00, val, precision=2)) fmp_grp.append(rs) # # OEM info # _str = _str_decode(self._memobj.oem_info.model) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("model", "Model", val) oem_grp.append(rs) _str = _str_decode(self._memobj.oem_info.date) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("date", "OEM Date", val) oem_grp.append(rs) _str = _str_decode(self._memobj.oem_info.oem1) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem1", "OEM String 1", val) oem_grp.append(rs) _str = _str_decode(self._memobj.oem_info.oem2) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem2", "OEM String 2", val) oem_grp.append(rs) _str = _str_decode(self._memobj.oem_info.unknown1) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("unknown1", "Unknown String 1", val) oem_grp.append(rs) _str = _str_decode(self._memobj.oem_info.unknown2) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("unknown2", "Unknown String 2", val) oem_grp.append(rs) _str = _str_decode(self._memobj.oem_info.unknown3) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("unknown3", "Unknown String 3", val) oem_grp.append(rs) return group def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def set_settings(self, settings): for group in settings: for element in group: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() # # Special Configuration Settings # if group.get_name() == 'cfg_grp': if name == 'roger_begin': value = _roger_encode(element[0].get_value()) for i in range(0, 4): obj.roger_begin[i] = ord(value[i]) continue elif name == 'roger_end': value = _roger_encode(element[0].get_value()) for i in range(0, 4): obj.roger_end[i] = ord(value[i]) continue elif name == 'pri_ch': value = _chnum_encode(element[0].get_value()) setattr(obj, setting, value) continue # # Special UI Settings # if group.get_name() == 'ui_grp': if name == 'ponmsg.left': value = _str_encode(element[0].get_value()) for i in range(0, 8): self._memobj.ponmsg.left[i] = value[i] continue elif name == 'ponmsg.right': value = _str_encode(element[0].get_value()) for i in range(0, 8): self._memobj.ponmsg.right[i] = value[i] continue # # Special VFO A Settings # if (group.get_name() == 'vfoa_grp') or \ (group.get_name() == 'vfob_grp'): if (setting == 'rxfreq') or \ (setting == 'txoffset'): value = _freq_encode(element[0].get_value()) setattr(obj, setting, value) continue elif (setting == 'work_cha') or \ (setting == 'work_chb'): value = _chnum_encode(element[0].get_value()) setattr(obj, setting, value) continue # # Special VFO B Settings # if group.get_name() == 'vfob_grp': pass # # Special Scan settings # if group.get_name() == 'scn_grp': pass # # Special Repeater settings # if group.get_name() == 'rpt_grp': pass # # Special Remote settings # if group.get_name() == 'rmt_grp': if name == 'ani': value = _ani_encode(element[0].get_value()) for i in range(0, 3): obj.ani[i] = ord(value[i]) continue elif name == 'ani_mcc': value = _ani_encode(element[0].get_value()) for i in range(0, 3): obj.ani_mcc[i] = ord(value[i]) continue elif name == 'ani_scc': value = _ani_encode(element[0].get_value()) for i in range(0, 3): obj.ani_scc[i] = ord(value[i]) continue elif name == 'ani_ctrl': value = _ani_encode(element[0].get_value()) for i in range(0, 3): obj.ani_ctrl[i] = ord(value[i]) continue # # FM Radio Presets Settings # if group.get_name() == 'fmp_grp': value = int(element[0].get_value() * 100) self._memobj.fm_preset[int(name)-1].freq = value continue # # Generic Settings # if element[0].__class__ is RadioSettingValueList: value = element[0].get_options().index( element[0].get_value()) setattr(obj, setting, value) elif element[0].__class__ is RadioSettingValueMap: value = element[0].get_mem_val() setattr(obj, setting, value) elif element[0].__class__ is RadioSettingValueBoolean: value = element[0].get_value() setattr(obj, setting, value) elif element[0].__class__ is RadioSettingValueInteger: value = element[0].get_value() setattr(obj, setting, value) else: LOG.debug("Unable to set_setting %s" % name) chirp-20240224/chirp/drivers/tk760.py0000644000175000017500000006552514522657251016072 0ustar hibbyhibby# Copyright 2016 Pavel Milanes CO7WT, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettings import time import struct import logging LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; } memory[32]; #seekto 0x0100; struct { lbcd rx_tone[2]; lbcd tx_tone[2]; } tone[32]; #seekto 0x0180; struct { u8 unknown0:1, unknown1:1, wide:1, // wide: 1 = wide, 0 = narrow power:1, // power: 1 = high, 0 = low busy_lock:1, // busy lock: 1 = off, 0 = on pttid:1, // ptt id: 1 = off, 0 = on dtmf:1, // dtmf signaling: 1 = off, 0 = on twotone:1; // 2-tone signaling: 1 = off, 0 = on } ch_settings[32]; #seekto 0x02B0; struct { u8 unknown10[16]; // x02b0 u8 unknown11[16]; // x02c0 u8 active[4]; // x02d0 u8 scan[4]; // x02d4 u8 unknown12[8]; // x02d8 u8 unknown13; // x02e0 u8 kMON; // 0x02d1 MON Key u8 kA; // 0x02d2 A Key u8 kSCN; // 0x02d3 SCN Key u8 kDA; // 0x02d4 D/A Key u8 unknown14; // x02e5 u8 min_vol; // x02e6 byte 0-31 0 = off u8 poweron_tone; // x02e7 power on tone 0 = off, 1 = on u8 tot; // x02e8 Time out Timer 0 = off, 1 = 30s (max 300) u8 unknown15[3]; // x02e9-x02eb u8 dealer_tuning; // x02ec ? bit 0? 0 = off, 1 = on u8 clone; // x02ed ? bit 0? 0 = off, 1 = on u8 unknown16[2]; // x02ee-x2ef u8 unknown17[16]; // x02f0 u8 unknown18[5]; // x0300 u8 clear2transpond; // x0305 byte 0 = off, 1 = on u8 off_hook_decode; // x0306 byte 0 = off, 1 = on u8 off_hook_hornalert; // x0307 byte 0 = off, 1 = on u8 unknown19[8]; // x0308-x030f u8 unknown20[16]; // x0310 } settings; """ KEYS = { 0x00: "Disabled", 0x01: "Monitor", 0x02: "Talk Around", 0x03: "Horn Alert", 0x04: "Public Address", 0x05: "Auxiliary", 0x06: "Scan", 0x07: "Scan Del/Add", 0x08: "Home Channel", 0x09: "Operator Selectable Tone", 0x0C: "Unknown" } MEM_SIZE = 0x400 BLOCK_SIZE = 8 MEM_BLOCKS = list(range(0, (MEM_SIZE // BLOCK_SIZE))) ACK_CMD = b"\x06" TIMEOUT = 1 POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1), chirp_common.PowerLevel("High", watts=5)] MODES = ["NFM", "FM"] SKIP_VALUES = ["", "S"] TONES = list(chirp_common.TONES) TONES.remove(254.1) DTCS_CODES = chirp_common.DTCS_CODES TOT = ["off"] + ["%s" % x for x in range(30, 330, 30)] VOL = ["off"] + ["%s" % x for x in range(1, 32)] debug = False def rawrecv(radio, amount): """Raw read from the radio device""" data = b"" try: data = radio.pipe.read(amount) if debug: print("<= %02i: %s" % (len(data), util.hexprint(data))) except: raise errors.RadioError("Error reading data from radio") return data def rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) if debug: print("=> %02i: %s" % (len(data), util.hexprint(data))) except: raise errors.RadioError("Error sending data from radio") def send(radio, frame): """Generic send data to the radio""" rawsend(radio, frame) def make_frame(cmd, addr, data=b""): """Pack the info in the format it likes""" ts = struct.pack(">BHB", ord(cmd), addr, 8) if data == b"": return ts else: if len(data) == 8: return ts + data else: raise errors.InvalidValueError("Data length of unexpected length") def handshake(radio, msg="", full=False): """Make a full handshake, if not full just hals""" # send ACK if commandes if full is True: rawsend(radio, ACK_CMD) # receive ACK ack = rawrecv(radio, 1) # check ACK if ack != ACK_CMD: # close_radio(radio) mesg = "Handshake failed: " + msg raise errors.RadioError(mesg) def recv(radio): """Receive data from the radio, 12 bytes, 4 in the header, 8 as data""" rxdata = rawrecv(radio, 12) if len(rxdata) != 12: raise errors.RadioError( "Received a length of data that is not possible") cmd, addr, length = struct.unpack(">BHB", rxdata[0:4]) data = "" if length == 8: data = rxdata[4:] return data def open_radio(radio): """Open the radio into program mode and check if it's the correct model""" # Set serial discipline try: radio.pipe.baudrate = 9600 radio.pipe.parity = "N" radio.pipe.timeout = 0.5 LOG.debug("Serial port open successful") except: msg = "Serial error: Can't set serial line discipline" raise errors.RadioError(msg) magic = b"PROGRAM" LOG.debug("Sending MAGIC") exito = False # The radio sends a continuous stream of 0xFF while idling in normal # operating mode. Chew those up so we can pace it below. devnull = rawrecv(radio, 256) # "Pace" the radio's output by sending one byte of the magic string for # every 0xFF we get from the radio for b in magic: rawrecv(radio, 1) rawsend(radio, bytes([b])) # Read more than we need here because we may have received additional bytes # in between the flush and the start of the magic. Consider it successful # if we see ACK anywhere in the response resp = rawrecv(radio, 256) if ACK_CMD not in resp: raise errors.RadioError('Radio did not respond to program mode') # 0x02 Means "show me your ident" rawsend(radio, b"\x02") ident = rawrecv(radio, 8) # validate the input if len(ident) != 8: LOG.debug("Wrong ID, get only %s bytes, we expect 8" % len(ident)) LOG.debug(util.hexprint(ident)) msg = "Bad ID received, just %s bytes, we want 8" % len(ident) raise errors.RadioError(msg) handshake(radio, "Comm error after ident", True) LOG.debug("Correct get ident and handshake") if not (radio.TYPE in ident): LOG.debug("Incorrect model ID:") LOG.debug(util.hexprint(ident)) msg = "Incorrect model ID, got %s, it not contains %s" % \ (ident[0:5], radio.TYPE) raise errors.RadioError(msg) LOG.debug("Full ident string is:") LOG.debug(util.hexprint(ident)) def do_download(radio): """This is your download function""" open_radio(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data = b"" LOG.debug("Starting the download") for addr in MEM_BLOCKS: send(radio, make_frame(b"R", addr * BLOCK_SIZE)) data += recv(radio) handshake(radio, "Rx error in block %03i" % addr, True) LOG.debug("Block: %04x, Pos: %06x" % (addr, addr * BLOCK_SIZE)) # UI Update status.cur = addr status.msg = "Cloning from radio..." radio.status_fn(status) return memmap.MemoryMapBytes(data) def do_upload(radio): """Upload info to radio""" open_radio(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) count = 0 for addr in MEM_BLOCKS: # UI Update status.cur = addr status.msg = "Cloning to radio..." radio.status_fn(status) pos = addr * BLOCK_SIZE if pos > 0x0378: # it seems that from this point forward is read only !?!?!? continue data = radio.get_mmap()[pos:pos + BLOCK_SIZE] send(radio, make_frame(b"W", pos, data)) LOG.debug("Block: %04x, Pos: %06x" % (addr, pos)) time.sleep(0.1) handshake(radio, "Rx error in block %04x" % addr) def get_rid(data): """Extract the radio identification from the firmware""" rid = data[0x0378:0x0380] # we have to invert rid nrid = rid[::-1] return nrid def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = get_rid(data) if debug: print("Full ident string is %s" % util.hexprint(rid)) if (rid in cls.VARIANTS): # correct model return True else: return False class Kenwood_M60_Radio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Kenwood Mobile Family 60 Radios""" VENDOR = "Kenwood" _range = [136000000, 500000000] # don't mind, it will be overwritten _upper = 32 VARIANT = "" MODEL = "" NEEDS_COMPAT_SERIAL = False @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ 'This driver is experimental: Use at your own risk!' rp.pre_download = _( "Follow these instructions to read your radio:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Click OK to start\n") rp.pre_upload = _( "Follow these instructions to write your radio:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Click OK to start\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.has_name = False rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = MODES rf.valid_duplexes = ["", "-", "+", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_skips = SKIP_VALUES rf.valid_dtcs_codes = DTCS_CODES rf.valid_bands = [self._range] rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [5., 6.25, 10., 12.5] return rf def sync_in(self): """Download from radio""" try: self._mmap = do_download(self) except Exception as e: LOG.exception('Failed to download: %s', e) rawsend(self, b'E') raise errors.RadioError('Error downloading from radio') self.process_mmap() def sync_out(self): """Upload to radio""" # Get the data ready for upload try: self._prep_data() except Exception as e: LOG.exception('Failed to prep data: %s', e) raise errors.RadioError("Error processing the radio data") # do the upload try: do_upload(self) except Exception as e: LOG.exception('Failed to upload: %s', e) rawsend(self, b'E') raise errors.RadioError("Error uploading data to radio") def set_variant(self): """Select and set the correct variables for the class according to the correct variant of the radio""" rid = get_rid(self._mmap) # identify the radio variant and set the environment to its values try: self._upper, low, high, self._kind = self.VARIANTS[rid] # Frequency ranges: some model/variants are able to work the near # ham bands, even if they are outside the OEM ranges. # By experimentation we found that a +/- 4% at the edges is in most # cases safe and will cover the near ham band in full self._range = [low * 1000000 * 0.96, high * 1000000 * 1.04] # put the VARIANT in the class, clean the model / CHs / Type # in the same layout as the KPG program self._VARIANT = self.MODEL + " [" + str(self._upper) + "CH]: " # In the OEM string we show the real OEM ranges self._VARIANT += self._kind + ", %d - %d MHz" % (low, high) except KeyError: LOG.debug("Wrong Kenwood radio, ID or unknown variant") LOG.debug(util.hexprint(rid)) raise errors.RadioError( "Wrong Kenwood radio, ID or unknown variant, see LOG output.") def _prep_data(self): """Prepare the areas in the memmap to do a consistent write it has to make an update on the x200 flag data""" achs = 0 for i in range(0, self._upper): if self.get_active(i) is True: achs += 1 # The x0200 area has the settings for the DTMF/2-Tone per channel, # as by default any of this radios has the DTMF IC installed; # we clean this areas fldata = b"\x00\xf0\xff\xff\xff" * achs + \ b"\xff" * (5 * (self._upper - achs)) self._fill(0x0200, fldata) def _fill(self, offset, data): """Fill an specified area of the memmap with the passed data""" self._mmap[offset] = data def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # to set the vars on the class to the correct ones self.set_variant() def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_scan(self, chan): """Get the channel scan status from the 4 bytes array on the eeprom then from the bits on the byte, return '' or 'S' as needed""" result = "S" byte = int(chan/8) bit = chan % 8 res = self._memobj.settings.scan[byte] & (pow(2, bit)) if res > 0: result = "" return result def set_scan(self, chan, value): """Set the channel scan status from UI to the mem_map""" byte = int(chan/8) bit = chan % 8 # get the actual value to see if I need to change anything actual = self.get_scan(chan) if actual != value: # I have to flip the value rbyte = self._memobj.settings.scan[byte] rbyte = rbyte ^ pow(2, bit) self._memobj.settings.scan[byte] = rbyte def get_active(self, chan): """Get the channel active status from the 4 bytes array on the eeprom then from the bits on the byte, return True/False""" byte = int(chan/8) bit = chan % 8 res = self._memobj.settings.active[byte] & (pow(2, bit)) return bool(res) def set_active(self, chan, value=True): """Set the channel active status from UI to the mem_map""" byte = int(chan/8) bit = chan % 8 # get the actual value to see if I need to change anything actual = self.get_active(chan) if actual != bool(value): # I have to flip the value rbyte = self._memobj.settings.active[byte] rbyte = rbyte ^ pow(2, bit) self._memobj.settings.active[byte] = rbyte def get_memory(self, number): """Get the mem representation from the radio image""" _mem = self._memobj.memory[number - 1] _tone = self._memobj.tone[number - 1] _ch = self._memobj.ch_settings[number - 1] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Memory number mem.number = number if (_mem.get_raw(asbytes=False)[0] == "\xFF" or not self.get_active(number - 1)): mem.empty = True # but is not enough, you have to clear the memory in the mmap # to get it ready for the sync_out process _mem.set_raw("\xFF" * 8) return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if _mem.get_raw(asbytes=False)[4] == "\xFF": # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX feq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 # power mem.power = POWER_LEVELS[_ch.power] # wide/marrow mem.mode = MODES[_ch.wide] # skip mem.skip = self.get_scan(number - 1) # tone data rxtone = txtone = None txtone = self.decode_tone(_tone.tx_tone) rxtone = self.decode_tone(_tone.rx_tone) chirp_common.split_tone_decode(mem, txtone, rxtone) # Extra # bank and number in the channel mem.extra = RadioSettingGroup("extra", "Extra") bl = RadioSetting("busy_lock", "Busy Channel lock", RadioSettingValueBoolean( not bool(_ch.busy_lock))) mem.extra.append(bl) return mem def set_memory(self, mem): """Set the memory data in the eeprom img from the UI not ready yet, so it will return as is""" # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] _tone = self._memobj.tone[mem.number - 1] _ch = self._memobj.ch_settings[mem.number - 1] # Empty memory if mem.empty: _mem.set_raw("\xFF" * 8) # empty the active bit self.set_active(mem.number - 1, False) return # freq rx _mem.rxfreq = mem.freq / 10 # freq tx if mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 elif mem.duplex == "off": for byte in _mem.txfreq: byte.set_raw("\xFF") else: _mem.txfreq = mem.freq / 10 # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_tone.tx_tone, txmode, txtone, txpol) self.encode_tone(_tone.rx_tone, rxmode, rxtone, rxpol) # power, default power is low if mem.power is None: mem.power = POWER_LEVELS[0] _ch.power = POWER_LEVELS.index(mem.power) # wide/marrow _ch.wide = MODES.index(mem.mode) # skip self.set_scan(mem.number - 1, mem.skip) # extra settings for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) # set the mem a active in the _memmap self.set_active(mem.number - 1) return mem @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == MEM_SIZE: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" sett = self._memobj.settings # basic features of the radio basic = RadioSettingGroup("basic", "Basic Settings") # buttons fkeys = RadioSettingGroup("keys", "Front keys config") top = RadioSettings(basic, fkeys) # Basic val = RadioSettingValueString(0, 35, self._VARIANT) val.set_mutable(False) mod = RadioSetting("not.mod", "Radio version", val) basic.append(mod) tot = RadioSetting("settings.tot", "Time Out Timer (TOT)", RadioSettingValueList(TOT, sett.tot)) basic.append(tot) minvol = RadioSetting("settings.min_vol", "Minimum volume", RadioSettingValueList(VOL, sett.min_vol)) basic.append(minvol) ptone = RadioSetting("settings.poweron_tone", "Power On tone", RadioSettingValueBoolean( bool(sett.poweron_tone))) basic.append(ptone) sprog = RadioSetting("settings.dealer_tuning", "Dealer Tuning", RadioSettingValueBoolean( bool(sett.dealer_tuning))) basic.append(sprog) clone = RadioSetting("settings.clone", "Allow clone", RadioSettingValueBoolean( bool(sett.clone))) basic.append(clone) # front keys rs = RadioSettingValueList(KEYS.values(), KEYS[int(sett.kMON)]) mon = RadioSetting("settings.kMON", "MON", rs) fkeys.append(mon) rs = RadioSettingValueList(KEYS.values(), KEYS[int(sett.kA)]) a = RadioSetting("settings.kA", "A", rs) fkeys.append(a) rs = RadioSettingValueList(KEYS.values(), KEYS[int(sett.kSCN)]) scn = RadioSetting("settings.kSCN", "SCN", rs) fkeys.append(scn) rs = RadioSettingValueList(KEYS.values(), KEYS[int(sett.kDA)]) da = RadioSetting("settings.kDA", "D/A", rs) fkeys.append(da) return top def set_settings(self, settings): """Translate the settings in the UI into bit in the mem_struct I don't understand well the method used in many drivers so, I used mine, ugly but works ok""" mobj = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue # Let's roll the ball if "." in element.get_name(): inter, setting = element.get_name().split(".") # you must ignore the settings with "not" # this are READ ONLY attributes if inter == "not": continue obj = getattr(mobj, inter) value = element.value # case keys, with special config if setting[0] == "k": value = list(KEYS.keys())[ list(KEYS.values()).index(str(value))] # integers case + special case if setting in ["tot", "min_vol"]: # catching the "off" values as zero try: value = int(value) except: value = 0 # Bool types + inverted if setting in ["poweron_tone", "dealer_tuning", "clone"]: value = bool(value) # Apply al configs done # DEBUG # print("%s: %s" % (setting, value)) setattr(obj, setting, value) # This are the oldest family 60 models (Black keys), just mobiles support here @directory.register class TK760_Radio(Kenwood_M60_Radio): """Kenwood TK-760 Radios""" MODEL = "TK-760" TYPE = b"M0760" VARIANTS = { b"M0760\x01\x00\x00": (32, 136, 156, "K2"), b"M0760\x00\x00\x00": (32, 148, 174, "K") } @directory.register class TK762_Radio(Kenwood_M60_Radio): """Kenwood TK-762 Radios""" MODEL = "TK-762" TYPE = b"M0762" VARIANTS = { b"M0762\x01\x00\x00": (2, 136, 156, "K2"), b"M0762\x00\x00\x00": (2, 148, 174, "K") } @directory.register class TK768_Radio(Kenwood_M60_Radio): """Kenwood TK-768 Radios""" MODEL = "TK-768" TYPE = b"M0768" VARIANTS = { b"M0768\x21\x00\x00": (32, 136, 156, "K2"), b"M0768\x20\x00\x00": (32, 148, 174, "K") } @directory.register class TK860_Radio(Kenwood_M60_Radio): """Kenwood TK-860 Radios""" MODEL = "TK-860" TYPE = b"M0860" VARIANTS = { b"M0860\x05\x00\x00": (32, 406, 430, "F4"), b"M0860\x04\x00\x00": (32, 488, 512, "F3"), b"M0860\x03\x00\x00": (32, 470, 496, "F2"), b"M0860\x02\x00\x00": (32, 450, 476, "F1") } @directory.register class TK862_Radio(Kenwood_M60_Radio): """Kenwood TK-862 Radios""" MODEL = "TK-862" TYPE = b"M0862" VARIANTS = { b"M0862\x05\x00\x00": (2, 406, 430, "F4"), b"M0862\x04\x00\x00": (2, 488, 512, "F3"), b"M0862\x03\x00\x00": (2, 470, 496, "F2"), b"M0862\x02\x00\x00": (2, 450, 476, "F1") } @directory.register class TK868_Radio(Kenwood_M60_Radio): """Kenwood TK-868 Radios""" MODEL = "TK-868" TYPE = b"M0868" VARIANTS = { b"M0868\x25\x00\x00": (32, 406, 430, "F4"), b"M0868\x24\x00\x00": (32, 488, 512, "F3"), b"M0868\x23\x00\x00": (32, 470, 496, "F2"), b"M0868\x22\x00\x00": (32, 450, 476, "F1") } chirp-20240224/chirp/drivers/kenwood_live.py0000644000175000017500000015034614537544540017702 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import threading import os import sys import time import logging from chirp import chirp_common, errors, directory, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettingValueList, RadioSettings LOG = logging.getLogger(__name__) NOCACHE = "CHIRP_NOCACHE" in os.environ DUPLEX = {0: "", 1: "+", 2: "-"} MODES = {0: "FM", 1: "AM"} STEPS = list(chirp_common.TUNING_STEPS) STEPS.append(100.0) KENWOOD_TONES = list(chirp_common.TONES) KENWOOD_TONES.remove(159.8) KENWOOD_TONES.remove(165.5) KENWOOD_TONES.remove(171.3) KENWOOD_TONES.remove(177.3) KENWOOD_TONES.remove(183.5) KENWOOD_TONES.remove(189.9) KENWOOD_TONES.remove(196.6) KENWOOD_TONES.remove(199.5) THF6_MODES = ["FM", "WFM", "AM", "LSB", "USB", "CW"] RADIO_IDS = { "ID019": "TS-2000", "ID009": "TS-850", "ID020": "TS-480_LiveMode", "ID021": "TS-590S/SG_LiveMode", # S-model uses same class "ID023": "TS-590S/SG_LiveMode" # as SG } LOCK = threading.Lock() COMMAND_RESP_BUFSIZE = 8 LAST_BAUD = 4800 LAST_DELIMITER = ("\r", " ") # The Kenwood TS-2000, TS-480, TS-590 & TS-850 use ";" # as a CAT command message delimiter, and all others use "\n". # Also, TS-2000 and TS-590 don't space delimite the command # fields, but others do. def _command(ser, cmd, *args): """Send @cmd to radio via @ser""" global LOCK, LAST_DELIMITER, COMMAND_RESP_BUFSIZE start = time.time() # TODO: This global use of LAST_DELIMITER breaks reentrancy # and needs to be fixed. if args: cmd += LAST_DELIMITER[1] + LAST_DELIMITER[1].join(args) cmd += LAST_DELIMITER[0] LOG.debug("PC->RADIO: %s" % cmd.strip()) ser.write(cmd.encode('cp1252')) result = "" while not result.endswith(LAST_DELIMITER[0]): result += ser.read(COMMAND_RESP_BUFSIZE).decode('cp1252') if (time.time() - start) > 1: # TXH sometimes takes longer on TH-D7G LOG.error("Timeout waiting for data") break if result.endswith(LAST_DELIMITER[0]): LOG.debug("RADIO->PC: %r" % result.strip()) result = result[:-1] else: LOG.error("Giving up") return result.strip() def command(ser, cmd, *args): with LOCK: return _command(ser, cmd, *args) def get_id(ser): """Get the ID of the radio attached to @ser""" global LAST_BAUD bauds = [4800, 9600, 19200, 38400, 57600, 115200] bauds.remove(LAST_BAUD) # Make sure LAST_BAUD is last so that it is tried first below bauds.append(LAST_BAUD) global LAST_DELIMITER command_delimiters = [("\r", " "), (";", "")] for delimiter in command_delimiters: # Process the baud options in reverse order so that we try the # last one first, and then start with the high-speed ones next for i in reversed(bauds): LAST_DELIMITER = delimiter LOG.info("Trying ID at baud %i with delimiter \"%s\"" % (i, repr(delimiter))) ser.baudrate = i ser.write(LAST_DELIMITER[0].encode()) ser.read(25) try: resp = command(ser, "ID") except UnicodeDecodeError: # If we got binary here, we are using the wrong rate # or not talking to a Kenwood live radio. continue # most Kenwood radios if " " in resp: LAST_BAUD = i return resp.split(" ")[1] # Radio responded in the right baud rate, # but threw an error because of all the crap # we have been hurling at it. Retry the ID at this # baud rate, which will almost definitely work. if "?" in resp: resp = command(ser, "ID") LAST_BAUD = i if " " in resp: return resp.split(" ")[1] # Kenwood radios that return ID numbers if resp in list(RADIO_IDS.keys()): return RADIO_IDS[resp] raise errors.RadioError("No response from radio") def get_tmode(tone, ctcss, dcs): """Get the tone mode based on the values of the tone, ctcss, dcs""" if dcs and int(dcs) == 1: return "DTCS" elif int(ctcss): return "TSQL" elif int(tone): return "Tone" else: return "" def iserr(result): """Returns True if the @result from a radio is an error""" return result in ["N", "?"] class KenwoodLiveRadio(chirp_common.LiveRadio): """Base class for all live-mode Kenwood radios""" BAUD_RATE = 9600 VENDOR = "Kenwood" MODEL = "" NEEDS_COMPAT_SERIAL = False # Lots of Kenwood radios actually require RTS, even some of the ones with # USB integrated HARDWARE_FLOW = True _vfo = 0 _upper = 200 _kenwood_split = False _kenwood_valid_tones = list(chirp_common.TONES) _has_name = True def __init__(self, *args, **kwargs): chirp_common.LiveRadio.__init__(self, *args, **kwargs) self._memcache = {} if self.pipe: self.pipe.timeout = 0.1 radio_id = get_id(self.pipe) if radio_id != self.MODEL.split(" ")[0]: raise Exception("Radio reports %s (not %s)" % (radio_id, self.MODEL)) command(self.pipe, "AI", "0") def _cmd_get_memory(self, number): return "MR", "%i,0,%03i" % (self._vfo, number) def _cmd_get_memory_name(self, number): return "MNA", "%i,%03i" % (self._vfo, number) def _cmd_get_split(self, number): return "MR", "%i,1,%03i" % (self._vfo, number) def _cmd_set_memory(self, number, spec): if spec: spec = "," + spec return "MW", "%i,0,%03i%s" % (self._vfo, number, spec) def _cmd_set_memory_name(self, number, name): return "MNA", "%i,%03i,%s" % (self._vfo, number, name) def _cmd_set_split(self, number, spec): return "MW", "%i,1,%03i,%s" % (self._vfo, number, spec) def get_raw_memory(self, number): return command(self.pipe, *self._cmd_get_memory(number)) def get_memory(self, number): if number < 0 or number > self._upper: raise errors.InvalidMemoryLocation( "Number must be between 0 and %i" % self._upper) if number in self._memcache and not NOCACHE: return self._memcache[number] result = command(self.pipe, *self._cmd_get_memory(number)) if result == "N" or result == "E": mem = chirp_common.Memory() mem.number = number mem.empty = True self._memcache[mem.number] = mem return mem elif " " not in result: LOG.error("Not sure what to do with this: `%s'" % result) raise errors.RadioError("Unexpected result returned from radio") value = result.split(" ")[1] spec = value.split(",") mem = self._parse_mem_spec(spec) self._memcache[mem.number] = mem if self._has_name: result = command(self.pipe, *self._cmd_get_memory_name(number)) if " " in result: value = result.split(" ", 1)[1] if value.count(",") == 2: _zero, _loc, mem.name = value.split(",") else: _loc, mem.name = value.split(",") if mem.duplex == "" and self._kenwood_split: result = command(self.pipe, *self._cmd_get_split(number)) if " " in result: value = result.split(" ", 1)[1] self._parse_split_spec(mem, value.split(",")) return mem def _make_mem_spec(self, mem): pass def _parse_mem_spec(self, spec): pass def _parse_split_spec(self, mem, spec): mem.duplex = "split" mem.offset = int(spec[2]) def _make_split_spec(self, mem): return ("%011i" % mem.offset, "0") def set_memory(self, memory): if memory.number < 0 or memory.number > self._upper: raise errors.InvalidMemoryLocation( "Number must be between 0 and %i" % self._upper) spec = self._make_mem_spec(memory) spec = ",".join(spec) r1 = command(self.pipe, *self._cmd_set_memory(memory.number, spec)) if not iserr(r1) and self._has_name: time.sleep(0.5) r2 = command(self.pipe, *self._cmd_set_memory_name(memory.number, memory.name)) if not iserr(r2): memory.name = memory.name.rstrip() self._memcache[memory.number] = memory.dupe() else: raise errors.InvalidDataError("Radio refused name %i: %s" % (memory.number, repr(memory.name))) elif self._has_name: raise errors.InvalidDataError("Radio refused %i" % memory.number) if memory.duplex == "split" and self._kenwood_split: spec = ",".join(self._make_split_spec(memory)) result = command(self.pipe, *self._cmd_set_split(memory.number, spec)) if iserr(result): raise errors.InvalidDataError("Radio refused %i" % memory.number) def erase_memory(self, number): if number not in self._memcache: return resp = command(self.pipe, *self._cmd_set_memory(number, "")) if iserr(resp): raise errors.RadioError("Radio refused delete of %i" % number) del self._memcache[number] def _kenwood_get(self, cmd): resp = command(self.pipe, cmd) if " " in resp: return resp.split(" ", 1) else: if resp == cmd: return [resp, ""] else: raise errors.RadioError("Radio refused to return %s" % cmd) def _kenwood_set(self, cmd, value): resp = command(self.pipe, cmd, value) if resp[:len(cmd)] == cmd: return raise errors.RadioError("Radio refused to set %s" % cmd) def _kenwood_get_bool(self, cmd): _cmd, result = self._kenwood_get(cmd) return result == "1" def _kenwood_set_bool(self, cmd, value): return self._kenwood_set(cmd, str(int(value))) def _kenwood_get_int(self, cmd): _cmd, result = self._kenwood_get(cmd) return int(result) def _kenwood_set_int(self, cmd, value, digits=1): return self._kenwood_set(cmd, ("%%0%ii" % digits) % value) def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue if isinstance(element.value, RadioSettingValueBoolean): self._kenwood_set_bool(element.get_name(), element.value) elif isinstance(element.value, RadioSettingValueList): options = self._get_setting_options(element.get_name()) if len(options) > 9: digits = 2 else: digits = 1 self._kenwood_set_int(element.get_name(), options.index(str(element.value)), digits) elif isinstance(element.value, RadioSettingValueInteger): if element.value.get_max() > 9: digits = 2 else: digits = 1 self._kenwood_set_int(element.get_name(), element.value, digits) elif isinstance(element.value, RadioSettingValueString): self._kenwood_set(element.get_name(), str(element.value)) else: LOG.error("Unknown type %s" % element.value) class KenwoodOldLiveRadio(KenwoodLiveRadio): _kenwood_valid_tones = list(chirp_common.OLD_TONES) def set_memory(self, memory): supported_tones = list(chirp_common.OLD_TONES) supported_tones.remove(69.3) if memory.rtone not in supported_tones: raise errors.UnsupportedToneError("This radio does not support " + "tone %.1fHz" % memory.rtone) if memory.ctone not in supported_tones: raise errors.UnsupportedToneError("This radio does not support " + "tone %.1fHz" % memory.ctone) return KenwoodLiveRadio.set_memory(self, memory) @directory.register class TMV7Radio(KenwoodOldLiveRadio): """Kenwood TM-V7""" MODEL = "TM-V7" mem_upper_limit = 200 # Will be updated def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_mode = False rf.has_tuning_step = False rf.valid_modes = ["FM"] rf.valid_tmodes = ["", "Tone", "TSQL"] rf.valid_characters = chirp_common.CHARSET_ALPHANUMERIC rf.valid_name_length = 7 rf.valid_tuning_steps = STEPS rf.has_sub_devices = True rf.memory_bounds = (1, self._upper) return rf def _make_mem_spec(self, mem): spec = ( "%011i" % mem.freq, "%X" % STEPS.index(mem.tuning_step), "%i" % util.get_dict_rev(DUPLEX, mem.duplex), "0", "%i" % (mem.tmode == "Tone"), "%i" % (mem.tmode == "TSQL"), "0", "%02i" % (self._kenwood_valid_tones.index(mem.rtone) + 1), "000", "%02i" % (self._kenwood_valid_tones.index(mem.ctone) + 1), "", "0") return spec def _parse_mem_spec(self, spec): mem = chirp_common.Memory() mem.number = int(spec[2]) mem.freq = int(spec[3]) mem.tuning_step = STEPS[int(spec[4], 16)] mem.duplex = DUPLEX[int(spec[5])] if int(spec[7]): mem.tmode = "Tone" elif int(spec[8]): mem.tmode = "TSQL" mem.rtone = self._kenwood_valid_tones[int(spec[10]) - 1] mem.ctone = self._kenwood_valid_tones[int(spec[12]) - 1] return mem def get_sub_devices(self): return [TMV7RadioVHF(self.pipe), TMV7RadioUHF(self.pipe)] def __test_location(self, loc): mem = self.get_memory(loc) if not mem.empty: # Memory was not empty, must be valid return True # Mem was empty (or invalid), try to set it if self._vfo == 0: mem.freq = 144000000 else: mem.freq = 440000000 mem.empty = False try: self.set_memory(mem) except Exception: # Failed, so we're past the limit return False # Erase what we did try: self.erase_memory(loc) except Exception: pass # V7A Can't delete just yet return True def _detect_split(self): return 50 class TMV7RadioSub(TMV7Radio): """Base class for the TM-V7 sub devices""" def __init__(self, pipe): TMV7Radio.__init__(self, pipe) self._detect_split() class TMV7RadioVHF(TMV7RadioSub): """TM-V7 VHF subdevice""" VARIANT = "VHF" _vfo = 0 class TMV7RadioUHF(TMV7RadioSub): """TM-V7 UHF subdevice""" VARIANT = "UHF" _vfo = 1 @directory.register class TMG707Radio(TMV7Radio): """Kenwood TM-G707""" MODEL = "TM-G707" def get_features(self): rf = TMV7Radio.get_features(self) rf.has_sub_devices = False rf.memory_bounds = (1, 180) rf.valid_bands = [(118000000, 174000000), (300000000, 520000000), (800000000, 999000000)] return rf THG71_STEPS = [5, 6.25, 10, 12.5, 15, 20, 25, 30, 50, 100] @directory.register class THG71Radio(TMV7Radio): """Kenwood TH-G71""" MODEL = "TH-G71" def get_features(self): rf = TMV7Radio.get_features(self) rf.has_tuning_step = True rf.valid_tuning_steps = list(THG71_STEPS) rf.valid_name_length = 6 rf.has_sub_devices = False rf.valid_bands = [(118000000, 174000000), (320000000, 470000000), (800000000, 945000000)] return rf def _make_mem_spec(self, mem): spec = ( "%011i" % mem.freq, "%X" % THG71_STEPS.index(mem.tuning_step), "%i" % util.get_dict_rev(DUPLEX, mem.duplex), "0", "%i" % (mem.tmode == "Tone"), "%i" % (mem.tmode == "TSQL"), "0", "%02i" % (self._kenwood_valid_tones.index(mem.rtone) + 1), "000", "%02i" % (self._kenwood_valid_tones.index(mem.ctone) + 1), "%09i" % mem.offset, "%i" % ((mem.skip == "S") and 1 or 0)) return spec def _parse_mem_spec(self, spec): mem = chirp_common.Memory() mem.number = int(spec[2]) mem.freq = int(spec[3]) mem.tuning_step = THG71_STEPS[int(spec[4], 16)] mem.duplex = DUPLEX[int(spec[5])] if int(spec[7]): mem.tmode = "Tone" elif int(spec[8]): mem.tmode = "TSQL" mem.rtone = self._kenwood_valid_tones[int(spec[10]) - 1] mem.ctone = self._kenwood_valid_tones[int(spec[12]) - 1] if spec[13]: mem.offset = int(spec[13]) else: mem.offset = 0 return mem THF6A_STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] THF6A_DUPLEX = dict(DUPLEX) THF6A_DUPLEX[3] = "split" @directory.register class THF6ARadio(KenwoodLiveRadio): """Kenwood TH-F6""" MODEL = "TH-F6" HARDWARE_FLOW = False _charset = chirp_common.CHARSET_ASCII _upper = 399 _kenwood_split = True _kenwood_valid_tones = list(KENWOOD_TONES) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.has_bank = False rf.can_odd_split = True rf.valid_modes = list(THF6_MODES) rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_tuning_steps = list(THF6A_STEPS) rf.valid_bands = [(1000, 1300000000)] rf.valid_skips = ["", "S"] rf.valid_duplexes = list(THF6A_DUPLEX.values()) rf.valid_characters = self._charset rf.valid_name_length = 8 rf.memory_bounds = (0, self._upper) rf.has_settings = True return rf def _cmd_set_memory(self, number, spec): if spec: spec = "," + spec return "MW", "0,%03i%s" % (number, spec) def _cmd_get_memory(self, number): return "MR", "0,%03i" % number def _cmd_get_memory_name(self, number): return "MNA", "%03i" % number def _cmd_set_memory_name(self, number, name): return "MNA", "%03i,%s" % (number, name) def _cmd_get_split(self, number): return "MR", "1,%03i" % number def _cmd_set_split(self, number, spec): return "MW", "1,%03i,%s" % (number, spec) def _parse_mem_spec(self, spec): mem = chirp_common.Memory() mem.number = int(spec[1]) mem.freq = int(spec[2]) mem.tuning_step = THF6A_STEPS[int(spec[3], 16)] mem.duplex = THF6A_DUPLEX[int(spec[4])] mem.tmode = get_tmode(spec[6], spec[7], spec[8]) mem.rtone = self._kenwood_valid_tones[int(spec[9])] mem.ctone = self._kenwood_valid_tones[int(spec[10])] if spec[11] and spec[11].isdigit(): mem.dtcs = chirp_common.DTCS_CODES[int(spec[11])] else: LOG.warn("Unknown or invalid DCS: %s" % spec[11]) if spec[12]: mem.offset = int(spec[12]) else: mem.offset = 0 mem.mode = THF6_MODES[int(spec[13])] if spec[14] == "1": mem.skip = "S" return mem def _make_mem_spec(self, mem): if mem.duplex in " +-": duplex = util.get_dict_rev(THF6A_DUPLEX, mem.duplex) offset = mem.offset elif mem.duplex == "split": duplex = 0 offset = 0 else: LOG.warn("Bug: unsupported duplex `%s'" % mem.duplex) spec = ( "%011i" % mem.freq, "%X" % THF6A_STEPS.index(mem.tuning_step), "%i" % duplex, "0", "%i" % (mem.tmode == "Tone"), "%i" % (mem.tmode == "TSQL"), "%i" % (mem.tmode == "DTCS"), "%02i" % (self._kenwood_valid_tones.index(mem.rtone)), "%02i" % (self._kenwood_valid_tones.index(mem.ctone)), "%03i" % (chirp_common.DTCS_CODES.index(mem.dtcs)), "%09i" % offset, "%i" % (THF6_MODES.index(mem.mode)), "%i" % (mem.skip == "S")) return spec _SETTINGS_OPTIONS = { "APO": ["Off", "30min", "60min"], "BAL": ["100%:0%", "75%:25%", "50%:50%", "25%:75%", "%0:100%"], "BAT": ["Lithium", "Alkaline"], "CKEY": ["Call", "1750 Hz"], "DATP": ["1200bps", "9600bps"], "LAN": ["English", "Japanese"], "MNF": ["Name", "Frequency"], "MRM": ["All Band", "Current Band"], "PT": ["100ms", "250ms", "500ms", "750ms", "1000ms", "1500ms", "2000ms"], "SCR": ["Time", "Carrier", "Seek"], "SV": ["Off", "0.2s", "0.4s", "0.6s", "0.8s", "1.0s", "2s", "3s", "4s", "5s"], "VXD": ["250ms", "500ms", "750ms", "1s", "1.5s", "2s", "3s"], } def get_settings(self): main = RadioSettingGroup("main", "Main") aux = RadioSettingGroup("aux", "Aux") save = RadioSettingGroup("save", "Save") display = RadioSettingGroup("display", "Display") dtmf = RadioSettingGroup("dtmf", "DTMF") top = RadioSettings(main, aux, save, display, dtmf) lists = [("APO", save, "Automatic Power Off"), ("BAL", main, "Balance"), ("BAT", save, "Battery Type"), ("CKEY", aux, "CALL Key Set Up"), ("DATP", aux, "Data Packet Speed"), ("LAN", display, "Language"), ("MNF", main, "Memory Display Mode"), ("MRM", main, "Memory Recall Method"), ("PT", dtmf, "DTMF Speed"), ("SCR", main, "Scan Resume"), ("SV", save, "Battery Save"), ("VXD", aux, "VOX Drop Delay"), ] bools = [("ANT", aux, "Bar Antenna"), ("ATT", main, "Attenuator Enabled"), ("ARO", main, "Automatic Repeater Offset"), ("BEP", aux, "Beep for keypad"), ("DL", main, "Dual"), ("DLK", dtmf, "DTMF Lockout On Transmit"), ("ELK", aux, "Enable Locked Tuning"), ("LK", main, "Lock"), ("LMP", display, "Lamp"), ("NSFT", aux, "Noise Shift"), ("TH", aux, "Tx Hold for 1750"), ("TSP", dtmf, "DTMF Fast Transmission"), ("TXH", dtmf, "TX Hold DTMF"), ("TXS", main, "Transmit Inhibit"), ("VOX", aux, "VOX Enable"), ("VXB", aux, "VOX On Busy"), ] ints = [("CNT", display, "Contrast", 1, 16), ("VXG", aux, "VOX Gain", 0, 9), ] strings = [("MES", display, "Power-on Message", 8), ] for setting, group, name in bools: value = self._kenwood_get_bool(setting) rs = RadioSetting(setting, name, RadioSettingValueBoolean(value)) group.append(rs) for setting, group, name in lists: value = self._kenwood_get_int(setting) options = self._SETTINGS_OPTIONS[setting] rs = RadioSetting(setting, name, RadioSettingValueList(options, options[value])) group.append(rs) for setting, group, name, minv, maxv in ints: value = self._kenwood_get_int(setting) rs = RadioSetting(setting, name, RadioSettingValueInteger(minv, maxv, value)) group.append(rs) for setting, group, name, length in strings: _cmd, value = self._kenwood_get(setting) rs = RadioSetting(setting, name, RadioSettingValueString(0, length, value)) group.append(rs) return top @directory.register class THF7ERadio(THF6ARadio): """Kenwood TH-F7""" MODEL = "TH-F7" _charset = chirp_common.CHARSET_1252 D710_DUPLEX = ["", "+", "-", "split"] D710_MODES = ["FM", "NFM", "AM"] D710_SKIP = ["", "S"] D710_STEPS = [5.0, 6.25, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] @directory.register class TMD710Radio(KenwoodLiveRadio): """Kenwood TM-D710""" MODEL = "TM-D710" _upper = 999 _kenwood_valid_tones = list(KENWOOD_TONES) def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = True rf.has_dtcs_polarity = False rf.has_bank = False rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_modes = D710_MODES rf.valid_duplexes = D710_DUPLEX rf.valid_tuning_steps = D710_STEPS rf.valid_characters = chirp_common.CHARSET_ASCII.replace(',', '') rf.valid_name_length = 8 rf.valid_skips = D710_SKIP rf.memory_bounds = (0, 999) return rf def _cmd_get_memory(self, number): return "ME", "%03i" % number def _cmd_get_memory_name(self, number): return "MN", "%03i" % number def _cmd_set_memory(self, number, spec): return "ME", "%03i,%s" % (number, spec) def _cmd_set_memory_name(self, number, name): return "MN", "%03i,%s" % (number, name) def _parse_mem_spec(self, spec): mem = chirp_common.Memory() mem.number = int(spec[0]) mem.freq = int(spec[1]) mem.tuning_step = D710_STEPS[int(spec[2], 16)] mem.duplex = D710_DUPLEX[int(spec[3])] # Reverse if int(spec[5]): mem.tmode = "Tone" elif int(spec[6]): mem.tmode = "TSQL" elif int(spec[7]): mem.tmode = "DTCS" mem.rtone = self._kenwood_valid_tones[int(spec[8])] mem.ctone = self._kenwood_valid_tones[int(spec[9])] mem.dtcs = chirp_common.DTCS_CODES[int(spec[10])] mem.offset = int(spec[11]) mem.mode = D710_MODES[int(spec[12])] # TX Frequency if int(spec[13]): mem.duplex = "split" mem.offset = int(spec[13]) # Unknown mem.skip = D710_SKIP[int(spec[15])] # Memory Lockout return mem def _make_mem_spec(self, mem): spec = ( "%010i" % mem.freq, "%X" % D710_STEPS.index(mem.tuning_step), "%i" % (0 if mem.duplex == "split" else D710_DUPLEX.index(mem.duplex)), "0", # Reverse "%i" % (mem.tmode == "Tone" and 1 or 0), "%i" % (mem.tmode == "TSQL" and 1 or 0), "%i" % (mem.tmode == "DTCS" and 1 or 0), "%02i" % (self._kenwood_valid_tones.index(mem.rtone)), "%02i" % (self._kenwood_valid_tones.index(mem.ctone)), "%03i" % (chirp_common.DTCS_CODES.index(mem.dtcs)), "%08i" % (0 if mem.duplex == "split" else mem.offset), # Offset "%i" % D710_MODES.index(mem.mode), "%010i" % (mem.offset if mem.duplex == "split" else 0), # TX Freq "0", # Unknown "%i" % D710_SKIP.index(mem.skip), # Memory Lockout ) return spec @directory.register class THD72Radio(TMD710Radio): """Kenwood TH-D72""" MODEL = "TH-D72 (live mode)" HARDWARE_FLOW = sys.platform == "darwin" # only OS X driver needs hw flow def _parse_mem_spec(self, spec): mem = chirp_common.Memory() mem.number = int(spec[0]) mem.freq = int(spec[1]) mem.tuning_step = D710_STEPS[int(spec[2], 16)] mem.duplex = D710_DUPLEX[int(spec[3])] # Reverse if int(spec[5]): mem.tmode = "Tone" elif int(spec[6]): mem.tmode = "TSQL" elif int(spec[7]): mem.tmode = "DTCS" mem.rtone = self._kenwood_valid_tones[int(spec[9])] mem.ctone = self._kenwood_valid_tones[int(spec[10])] mem.dtcs = chirp_common.DTCS_CODES[int(spec[11])] mem.offset = int(spec[13]) mem.mode = D710_MODES[int(spec[14])] # TX Frequency if int(spec[15]): mem.duplex = "split" mem.offset = int(spec[15]) # Lockout mem.skip = D710_SKIP[int(spec[17])] # Memory Lockout return mem def _make_mem_spec(self, mem): spec = ( "%010i" % mem.freq, "%X" % D710_STEPS.index(mem.tuning_step), "%i" % (0 if mem.duplex == "split" else D710_DUPLEX.index(mem.duplex)), "0", # Reverse "%i" % (mem.tmode == "Tone" and 1 or 0), "%i" % (mem.tmode == "TSQL" and 1 or 0), "%i" % (mem.tmode == "DTCS" and 1 or 0), "0", "%02i" % (self._kenwood_valid_tones.index(mem.rtone)), "%02i" % (self._kenwood_valid_tones.index(mem.ctone)), "%03i" % (chirp_common.DTCS_CODES.index(mem.dtcs)), "0", "%08i" % (0 if mem.duplex == "split" else mem.offset), # Offset "%i" % D710_MODES.index(mem.mode), "%010i" % (mem.offset if mem.duplex == "split" else 0), # TX Freq "0", # Unknown "%i" % D710_SKIP.index(mem.skip), # Memory Lockout ) return spec @directory.register class THD74Radio(TMD710Radio): """Kenwood TH_D74""" MODEL = "TH-D74 (live mode)" HARDWARE_FLOW = sys.platform == "darwin" STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] MODES = ['FM', 'DV', 'AM', 'LSB', 'USB', 'CW', 'NFM', 'DR', 'WFM', 'R-CW'] CROSS_MODES = ['DTCS->', 'Tone->DTCS', 'DTCS->Tone', 'Tone->Tone'] DUPLEX = ['', '+', '-', 'split'] _has_name = False @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This driver is incomplete as the D74 lacks " "the full serial command set of older radios. " "As such, this should be considered permanently " "experimental.") return rp def _cmd_get_memory_name(self, number): return '' def get_features(self): rf = super(THD74Radio, self).get_features() rf.valid_tuning_steps = self.STEPS rf.valid_modes = self.MODES rf.valid_cross_modes = self.CROSS_MODES rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.has_name = False # Radio has it, but no command to retrieve rf.has_cross = True return rf def _parse_mem_spec(self, spec): mem = chirp_common.Memory() mem.number = int(spec[0]) mem.freq = int(spec[1]) mem.offset = int(spec[2]) mem.tuning_step = self.STEPS[int(spec[3])] mem.mode = self.MODES[int(spec[5])] if int(spec[11]): mem.tmode = "Cross" mem.cross_mode = self.CROSS_MODES[int(spec[18])] elif int(spec[8]): mem.tmode = "Tone" elif int(spec[9]): mem.tmode = "TSQL" elif int(spec[10]): mem.tmode = "DTCS" mem.duplex = self.DUPLEX[int(spec[14])] mem.rtone = chirp_common.TONES[int(spec[15])] mem.ctone = chirp_common.TONES[int(spec[16])] mem.dtcs = chirp_common.DTCS_CODES[int(spec[17])] mem.skip = int(spec[22]) and 'S' or '' return mem def _make_mem_spec(self, mem): spec = ( "%010i" % mem.freq, "%010i" % mem.offset, "%X" % self.STEPS.index(mem.tuning_step), "%X" % self.STEPS.index(mem.tuning_step), "%i" % self.MODES.index(mem.mode), "0", # Fine mode "0", # Fine step "%i" % (mem.tmode == "Tone" and 1 or 0), "%i" % (mem.tmode == "TSQL" and 1 or 0), "%i" % (mem.tmode == "DTCS" and 1 or 0), "%i" % (mem.tmode == 'Cross'), "0", # Reverse "0", # Odd split channel "%i" % self.DUPLEX.index(mem.duplex), "%02i" % (chirp_common.TONES.index(mem.rtone)), "%02i" % (chirp_common.TONES.index(mem.ctone)), "%03i" % (chirp_common.DTCS_CODES.index(mem.dtcs)), "%i" % self.CROSS_MODES.index(mem.cross_mode), "CQCQCQ", # URCALL "0", # D-STAR squelch type "00", # D-STAR squelch code "%i" % D710_SKIP.index(mem.skip), # Memory Lockout ) return spec @directory.register class TMV71Radio(TMD710Radio): """Kenwood TM-V71""" MODEL = "TM-V71" def get_features(self): rf = super().get_features() rf.valid_characters = ''.join(c for c in rf.valid_characters if not c.isalpha() or c not in rf.valid_characters.lower()) return rf @directory.register class TMD710GRadio(TMD710Radio): """Kenwood TM-D710G""" MODEL = "TM-D710G" @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is currently under development, " "and supports the same features as the TM-D710A/E. " "There are no known issues with it, but you should " "proceed with caution.") return rp THK2_DUPLEX = ["", "+", "-"] THK2_MODES = ["FM", "NFM"] THK2_CHARS = chirp_common.CHARSET_UPPER_NUMERIC + "-/" @directory.register class THK2Radio(KenwoodLiveRadio): """Kenwood TH-K2""" MODEL = "TH-K2" _kenwood_valid_tones = list(KENWOOD_TONES) def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_tuning_step = False rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_modes = THK2_MODES rf.valid_duplexes = THK2_DUPLEX rf.valid_characters = THK2_CHARS rf.valid_name_length = 6 rf.valid_bands = [(136000000, 173990000)] rf.valid_skips = ["", "S"] rf.valid_tuning_steps = [5.0] rf.memory_bounds = (0, 49) return rf def _cmd_get_memory(self, number): return "ME", "%02i" % number def _cmd_get_memory_name(self, number): return "MN", "%02i" % number def _cmd_set_memory(self, number, spec): return "ME", "%02i,%s" % (number, spec) def _cmd_set_memory_name(self, number, name): return "MN", "%02i,%s" % (number, name) def _parse_mem_spec(self, spec): mem = chirp_common.Memory() mem.number = int(spec[0]) mem.freq = int(spec[1]) # mem.tuning_step = mem.duplex = THK2_DUPLEX[int(spec[3])] if int(spec[5]): mem.tmode = "Tone" elif int(spec[6]): mem.tmode = "TSQL" elif int(spec[7]): mem.tmode = "DTCS" mem.rtone = self._kenwood_valid_tones[int(spec[8])] mem.ctone = self._kenwood_valid_tones[int(spec[9])] mem.dtcs = chirp_common.DTCS_CODES[int(spec[10])] mem.offset = int(spec[11]) mem.mode = THK2_MODES[int(spec[12])] mem.skip = int(spec[16]) and "S" or "" return mem def _make_mem_spec(self, mem): try: rti = self._kenwood_valid_tones.index(mem.rtone) cti = self._kenwood_valid_tones.index(mem.ctone) except ValueError: raise errors.UnsupportedToneError() spec = ( "%010i" % mem.freq, "0", "%i" % THK2_DUPLEX.index(mem.duplex), "0", "%i" % int(mem.tmode == "Tone"), "%i" % int(mem.tmode == "TSQL"), "%i" % int(mem.tmode == "DTCS"), "%02i" % rti, "%02i" % cti, "%03i" % chirp_common.DTCS_CODES.index(mem.dtcs), "%08i" % mem.offset, "%i" % THK2_MODES.index(mem.mode), "0", "%010i" % 0, "0", "%i" % int(mem.skip == "S") ) return spec TM271_STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] @directory.register class TM271Radio(THK2Radio): """Kenwood TM-271""" MODEL = "TM-271" def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_tuning_step = False rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_modes = THK2_MODES rf.valid_duplexes = THK2_DUPLEX rf.valid_characters = THK2_CHARS rf.valid_name_length = 6 rf.valid_bands = [(137000000, 173990000)] rf.valid_skips = ["", "S"] rf.valid_tuning_steps = list(TM271_STEPS) rf.memory_bounds = (0, 99) return rf def _cmd_get_memory(self, number): return "ME", "%03i" % number def _cmd_get_memory_name(self, number): return "MN", "%03i" % number def _cmd_set_memory(self, number, spec): return "ME", "%03i,%s" % (number, spec) def _cmd_set_memory_name(self, number, name): return "MN", "%03i,%s" % (number, name) @directory.register class TM281Radio(TM271Radio): """Kenwood TM-281""" MODEL = "TM-281" # seems that this is a perfect clone of TM271 with just a different model @directory.register class TM471Radio(THK2Radio): """Kenwood TM-471""" MODEL = "TM-471" def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_tuning_step = False rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_modes = THK2_MODES rf.valid_duplexes = THK2_DUPLEX rf.valid_characters = THK2_CHARS rf.valid_name_length = 6 rf.valid_bands = [(444000000, 479990000)] rf.valid_skips = ["", "S"] rf.valid_tuning_steps = [5.0] rf.memory_bounds = (0, 99) return rf def _cmd_get_memory(self, number): return "ME", "%03i" % number def _cmd_get_memory_name(self, number): return "MN", "%03i" % number def _cmd_set_memory(self, number, spec): return "ME", "%03i,%s" % (number, spec) def _cmd_set_memory_name(self, number, name): return "MN", "%03i,%s" % (number, name) @directory.register class TS590Radio(KenwoodLiveRadio): """Kenwood TS-590S/SG""" MODEL = "TS-590S/SG_LiveMode" _kenwood_valid_tones = list(KENWOOD_TONES) _kenwood_valid_tones.append(1750) _upper = 99 _duplex = ["", "-", "+"] _skip = ["", "S"] _modes = ["LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R", "Data+LSB", "Data+USB", "Data+FM"] _bands = [(1800000, 2000000), # 160M Band (3500000, 4000000), # 80M Band (5167500, 5450000), # 60M Band (7000000, 7300000), # 40M Band (10100000, 10150000), # 30M Band (14000000, 14350000), # 20M Band (18068000, 18168000), # 17M Band (21000000, 21450000), # 15M Band (24890000, 24990000), # 12M Band (28000000, 29700000), # 10M Band (50000000, 54000000)] # 6M Band def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = False rf.has_bank = False rf.has_ctone = True rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_name = True rf.has_settings = False rf.has_offset = True rf.has_mode = True rf.has_tuning_step = False rf.has_nostep_tuning = True rf.has_cross = True rf.has_comment = False rf.memory_bounds = (0, self._upper) rf.valid_bands = self._bands rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "*+-/" rf.valid_duplexes = ["", "-", "+"] rf.valid_modes = self._modes rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "->Tone"] rf.valid_name_length = 8 # 8 character channel names return rf def _my_val_list(setting, opts, obj, atrb): """Callback:from ValueList. Set the integer index.""" value = opts.index(str(setting.value)) setattr(obj, atrb, value) return def get_memory(self, number): """Convert ascii channel data spec into UI columns (mem)""" mem = chirp_common.Memory() mem.extra = RadioSettingGroup("extra", "Extra") # Read the base and split MR strings mem.number = number spec0 = command(self.pipe, "MR0 %02i" % mem.number) spec1 = command(self.pipe, "MR1 %02i" % mem.number) mem.name = spec0[41:49] # Max 8-Char Name if assigned mem.name = mem.name.strip() mem.name = mem.name.upper() _p4 = int(spec0[6:17]) # Rx Frequency _p4s = int(spec1[6:17]) # Offset freq (Tx) _p5 = int(spec0[17]) # Mode _p6 = int(spec0[18]) # Data Mode _p7 = int(spec0[19]) # Tone Mode _p8 = int(spec0[20:22]) # Tone Frequency Index _p9 = int(spec0[22:24]) # CTCSS Frequency Index _p11 = int(spec0[27]) # Filter A/B _p14 = int(spec0[38:40]) # FM Mode _p15 = int(spec0[40]) # Chan Lockout (Skip) if _p4 == 0: mem.empty = True return mem mem.empty = False mem.freq = _p4 mem.duplex = self._duplex[0] # None by default mem.offset = 0 if _p4 < _p4s: # + shift mem.duplex = self._duplex[2] mem.offset = _p4s - _p4 if _p4 > _p4s: # - shift mem.duplex = self._duplex[1] mem.offset = _p4 - _p4s mx = _p5 - 1 # CAT modes start at 1 if _p5 == 9: # except CAT FSK-R is 9, there is no 8 mx = 7 if _p6: # LSB+Data= 8, USB+Data= 9, FM+Data= 10 if _p5 == 1: # CAT LSB mx = 8 elif _p5 == 2: # CAT USB mx = 9 elif _p5 == 4: # CAT FM mx = 10 mem.mode = self._modes[mx] mem.tmode = "" mem.cross_mode = "Tone->Tone" mem.ctone = self._kenwood_valid_tones[_p9] mem.rtone = self._kenwood_valid_tones[_p8] if _p7 == 1: mem.tmode = "Tone" elif _p7 == 2: mem.tmode = "TSQL" elif _p7 == 3: mem.tmode = "Cross" mem.skip = self._skip[_p15] rx = RadioSettingValueBoolean(bool(_p14)) rset = RadioSetting("fmnrw", "FM Narrow mode (off = Wide)", rx) mem.extra.append(rset) return mem def erase_memory(self, number): """ Send the blank string to MW0 """ mem = chirp_common.Memory() mem.empty = True mem.freq = 0 mem.offset = 0 spx = "MW0%03i00000000000000000000000000000000000" % number rx = command(self.pipe, spx) # Send MW0 return mem def set_memory(self, mem): """Send UI column data (mem) to radio""" pfx = "MW0%03i" % mem.number xmode = 0 xtmode = 0 xrtone = 8 xctone = 8 xdata = 0 xfltr = 0 xfm = 0 xskip = 0 xfreq = mem.freq if xfreq > 0: # if empty; use those defaults ix = self._modes.index(mem.mode) xmode = ix + 1 # stored as CAT values, LSB= 1 if ix == 7: # FSK-R xmode = 9 # There is no CAT 8 if ix > 7: # a Data mode xdata = 1 if ix == 8: xmode = 1 # LSB elif ix == 9: xmode = 2 # USB elif ix == 10: xmode = 4 # FM if mem.tmode == "Tone": xtmode = 1 xrtone = self._kenwood_valid_tones.index(mem.rtone) if mem.tmode == "TSQL" or mem.tmode == "Cross": xtmode = 2 if mem.tmode == "Cross": xtmode = 3 xctone = self._kenwood_valid_tones.index(mem.ctone) for setting in mem.extra: if setting.get_name() == "fmnrw": xfm = setting.value if mem.skip == "S": xskip = 1 spx = "%011i%1i%1i%1i%02i%02i000%1i0000000000%02i%1i%s" \ % (xfreq, xmode, xdata, xtmode, xrtone, xctone, xfltr, xfm, xskip, mem.name) rx = command(self.pipe, pfx, spx) # Send MW0 if mem.offset != 0: pfx = "MW1%03i" % mem.number xfreq = mem.freq - mem.offset if mem.duplex == "+": xfreq = mem.freq + mem.offset spx = "%011i%1i%1i%1i%02i%02i000%1i0000000000%02i%1i%s" \ % (xfreq, xmode, xdata, xtmode, xrtone, xctone, xfltr, xfm, xskip, mem.name) rx = command(self.pipe, pfx, spx) # Send MW1 @directory.register class TS480Radio(KenwoodLiveRadio): """Kenwood TS-480""" MODEL = "TS-480_LiveMode" _kenwood_valid_tones = list(KENWOOD_TONES) _kenwood_valid_tones.append(1750) _upper = 99 _duplex = ["", "-", "+"] _skip = ["", "S"] _modes = ["LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "N/A", "FSK-R"] _bands = [(1800000, 2000000), # 160M Band (3500000, 4000000), # 80M Band (5167500, 5450000), # 60M Band (7000000, 7300000), # 40M Band (10100000, 10150000), # 30M Band (14000000, 14350000), # 20M Band (18068000, 18168000), # 17M Band (21000000, 21450000), # 15M Band (24890000, 24990000), # 12M Band (28000000, 29700000), # 10M Band (50000000, 54000000)] # 6M Band _tsteps = [0.5, 1.0, 2.5, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = False rf.has_bank = False rf.has_ctone = True rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_name = True rf.has_settings = False rf.has_offset = True rf.has_mode = True rf.has_tuning_step = True rf.has_nostep_tuning = True rf.has_cross = True rf.has_comment = False rf.memory_bounds = (0, self._upper) rf.valid_bands = self._bands rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "*+-/" rf.valid_duplexes = ["", "-", "+"] rf.valid_modes = self._modes rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "->Tone"] rf.valid_name_length = 8 # 8 character channel names rf.valid_tuning_steps = self._tsteps return rf def _my_val_list(setting, opts, obj, atrb): """Callback:from ValueList. Set the integer index.""" value = opts.index(str(setting.value)) setattr(obj, atrb, value) return def get_memory(self, number): """Convert ascii channel data spec into UI columns (mem)""" mem = chirp_common.Memory() # Read the base and split MR strings mem.number = number spec0 = command(self.pipe, "MR0%03i" % mem.number) spec1 = command(self.pipe, "MR1%03i" % mem.number) # Add 1 to string idecis if referring to CAT manual mem.name = spec0[41:49] # Max 8-Char Name if assigned mem.name = mem.name.strip() mem.name = mem.name.upper() _p4 = int(spec0[6:17]) # Rx Frequency _p4s = int(spec1[6:17]) # Offset freq (Tx) _p5 = int(spec0[17]) # Mode _p6 = int(spec0[18]) # Chan Lockout (Skip) _p7 = int(spec0[19]) # Tone Mode _p8 = int(spec0[20:22]) # Tone Frequency Index _p9 = int(spec0[22:24]) # CTCSS Frequency Index _p14 = int(spec0[38:40]) # Tune Step if _p4 == 0: mem.empty = True return mem mem.empty = False mem.freq = _p4 mem.duplex = self._duplex[0] # None by default mem.offset = 0 if _p4 < _p4s: # + shift mem.duplex = self._duplex[2] mem.offset = _p4s - _p4 if _p4 > _p4s: # - shift mem.duplex = self._duplex[1] mem.offset = _p4 - _p4s mx = _p5 - 1 # CAT modes start at 1 mem.mode = self._modes[mx] mem.tmode = "" mem.cross_mode = "Tone->Tone" mem.ctone = self._kenwood_valid_tones[_p9] mem.rtone = self._kenwood_valid_tones[_p8] if _p7 == 1: mem.tmode = "Tone" elif _p7 == 2: mem.tmode = "TSQL" elif _p7 == 3: mem.tmode = "Cross" mem.skip = self._skip[_p6] # Tuning step depends on mode options = [0.5, 1.0, 2.5, 5.0, 10.0] # SSB/CS/FSK if _p14 == 4 or _p14 == 5: # AM/FM options = self._tsteps[3:] mem.tuning_step = options[_p14] return mem def erase_memory(self, number): mem = chirp_common.Memory() mem.empty = True mem.freq = 0 mem.offset = 0 spx = "MW0%03i00000000000000000000000000000000000" % number rx = command(self.pipe, spx) # Send MW0 return mem def set_memory(self, mem): """Send UI column data (mem) to radio""" pfx = "MW0%03i" % mem.number xtmode = 0 xdata = 0 xrtone = 8 xctone = 8 xskip = 0 xstep = 0 xfreq = mem.freq if xfreq > 0: # if empty, use those defaults ix = self._modes.index(mem.mode) xmode = ix + 1 # stored as CAT values, LSB= 1 if ix == 7: # FSK-R xmode = 9 # There is no CAT 8 if mem.tmode == "Tone": xtmode = 1 xrtone = self._kenwood_valid_tones.index(mem.rtone) if mem.tmode == "TSQL" or mem.tmode == "Cross": xtmode = 2 if mem.tmode == "Cross": xtmode = 3 xctone = self._kenwood_valid_tones.index(mem.ctone) if mem.skip == "S": xskip = 1 options = [0.5, 1.0, 2.5, 5.0, 10.0] # SSB/CS/FSK if xmode == 4 or xmode == 5: options = self._tsteps[3:] xstep = options.index(mem.tuning_step) spx = "%011i%1i%1i%1i%02i%02i00000000000000%02i%s" \ % (xfreq, xmode, xskip, xtmode, xrtone, xctone, xstep, mem.name) rx = command(self.pipe, pfx, spx) # Send MW0 if mem.offset != 0: # Don't send MW1 if empty pfx = "MW1%03i" % mem.number xfreq = mem.freq - mem.offset if mem.duplex == "+": xfreq = mem.freq + mem.offset spx = "%011i%1i%1i%1i%02i%02i00000000000000%02i%s" \ % (xfreq, xmode, xskip, xtmode, xrtone, xctone, xstep, mem.name) rx = command(self.pipe, pfx, spx) # Send MW1 chirp-20240224/chirp/drivers/ft8100.py0000644000175000017500000002175314516677264016145 0ustar hibbyhibby# Copyright 2010 Eric Allen # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import time from chirp import chirp_common, directory, bitwise, errors from chirp.drivers import yaesu_clone LOG = logging.getLogger(__name__) TONES = chirp_common.OLD_TONES TMODES = ["", "Tone"] MODES = ['FM', 'AM'] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0] DUPLEX = ["", "-", "+", "split"] # "M" for masked memories, which are invisible until un-masked SKIPS = ["", "S", "M"] POWER_LEVELS_VHF = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=20), chirp_common.PowerLevel("High", watts=50)] POWER_LEVELS_UHF = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=20), chirp_common.PowerLevel("High", watts=35)] SPECIALS = {'1L': -1, '1U': -2, '2L': -3, '2U': -4, 'Home': -5} MEM_FORMAT = """ #seekto 0x{skips:X}; u8 skips[13]; #seekto 0x{enables:X}; u8 enables[13]; struct mem_struct {{ u8 unknown4:2, baud9600:1, am:1, unknown4b:4; u8 power:2, duplex:2, unknown1b:4; u8 unknown2:1, tone_enable:1, tone:6; bbcd freq[3]; bbcd offset[3]; }}; #seekto 0x{memories:X}; struct mem_struct memory[99]; """ @directory.register class FT8100Radio(yaesu_clone.YaesuCloneModeRadio): """Implementation for Yaesu FT-8100""" MODEL = "FT-8100" _memstart = 0 _memsize = 2968 _block_lengths = [10, 32, 114, 101, 101, 97, 128, 128, 128, 128, 128, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1] @classmethod def match_model(cls, data, path): if (len(data) == cls._memsize and data[1:10] == b'\x01\x01\x07\x08\x02\x01\x01\x00\x01'): return True return False def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 99) rf.has_ctone = False rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_name = False rf.valid_tones = list(TONES) rf.valid_modes = list(MODES) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_power_levels = POWER_LEVELS_VHF rf.has_sub_devices = self.VARIANT == '' rf.valid_tuning_steps = list(STEPS) # This is not implemented properly, so don't expose it rf.valid_tuning_steps.remove(12.5) # This driver doesn't properly support the upper bound of 1300MHz # so limit us to 999MHz if self.VARIANT == 'VHF': rf.valid_bands = [(110000000, 280000000)] else: rf.valid_bands = [(280000000, 550000000), (750000000, 999000000)] # This is not actually implemented, so don't expose it # rf.valid_skips = SKIPS rf.valid_skips = [] # TODO # rf.valid_special_chans = SPECIALS.keys() # TODO # rf.has_tuning_step = False rf.can_odd_split = True return rf def sync_in(self): super(FT8100Radio, self).sync_in() self.pipe.write(bytes([yaesu_clone.CMD_ACK])) self.pipe.read(1) def sync_out(self): self.update_checksums() return _clone_out(self) def process_mmap(self): if not self._memstart: return mem_format = MEM_FORMAT.format(memories=self._memstart, skips=self._skipstart, enables=self._enablestart) self._memobj = bitwise.parse(mem_format, self._mmap) def get_sub_devices(self): return [FT8100RadioVHF(self._mmap), FT8100RadioUHF(self._mmap)] def get_memory(self, number): bit, byte = self._bit_byte(number) _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.freq) * 1000 if _mem.tone >= len(TONES) or _mem.duplex >= len(DUPLEX): mem.empty = True return mem else: mem.rtone = TONES[_mem.tone] mem.tmode = TMODES[_mem.tone_enable] mem.mode = MODES[_mem.am] mem.duplex = DUPLEX[_mem.duplex] mem.offset = int(_mem.offset) * 1000 if mem.freq // 100 == 4: mem.power = POWER_LEVELS_UHF[_mem.power] else: mem.power = POWER_LEVELS_VHF[_mem.power] # M01 can't be disabled if not self._memobj.enables[byte] & bit and number != 1: mem.empty = True elif number == 1: mem.immutable = ['empty'] return mem def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def set_memory(self, mem): bit, byte = self._bit_byte(mem.number) _mem = self._memobj.memory[mem.number - 1] _mem.freq = mem.freq // 1000 _mem.tone = TONES.index(mem.rtone) _mem.tone_enable = TMODES.index(mem.tmode) _mem.am = MODES.index(mem.mode) _mem.duplex = DUPLEX.index(mem.duplex) _mem.offset = mem.offset // 1000 if mem.power: _mem.power = POWER_LEVELS_VHF.index(mem.power) else: _mem.power = 0 if mem.empty: self._memobj.enables[byte] &= ~bit else: self._memobj.enables[byte] |= bit # TODO expose these options _mem.baud9600 = 0 # These need to be cleared, otherwise strange things happen _mem.unknown4 = 0 _mem.unknown4b = 0 _mem.unknown1b = 0 _mem.unknown2 = 0 def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x0B96)] # I didn't believe this myself, but it seems that there's a bit for # enabling VHF M01, but no bit for UHF01, and the enables are shifted down, # so that the first bit is for M02 def _bit_byte(self, number): if self.VARIANT == 'VHF': bit = 1 << ((number - 1) % 8) byte = (number - 1) // 8 else: bit = 1 << ((number - 2) % 8) byte = (number - 2) // 8 return bit, byte class FT8100RadioVHF(FT8100Radio): """Yaesu FT-8100 VHF subdevice""" VARIANT = "VHF" _memstart = 0x447 _skipstart = 0x02D _enablestart = 0x04D class FT8100RadioUHF(FT8100Radio): """Yaesu FT-8100 UHF subdevice""" VARIANT = "UHF" _memstart = 0x7E6 _skipstart = 0x03A _enablestart = 0x05A def _clone_out(radio): try: return __clone_out(radio) except Exception as e: raise errors.RadioError("Failed to communicate with the radio: %s" % e) def __clone_out(radio): pipe = radio.pipe block_lengths = radio._block_lengths total_written = 0 def _status(): status = chirp_common.Status() status.msg = "Cloning to radio" status.max = sum(block_lengths) status.cur = total_written radio.status_fn(status) start = time.time() pos = 0 for block in radio._block_lengths: LOG.debug("\nSending %i-%i" % (pos, pos + block)) out = radio.get_mmap()[pos:pos + block] # need to chew byte-by-byte here or else we lose the ACK...not sure why for b in out: pipe.write(bytes([b])) pipe.read(1) # chew the echo ack = pipe.read(1) if ack[0] != yaesu_clone.CMD_ACK: raise Exception("block not ack'ed: %s" % repr(ack)) total_written += len(out) _status() pos += block LOG.debug("Clone completed in %i seconds" % (time.time() - start)) return True chirp-20240224/chirp/drivers/iradio_uv_5118.py0000644000175000017500000012416314551723752017652 0ustar hibbyhibby# Copyright 2022 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueFloat, \ RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { u8 range174_180; // 174-180 MHz u8 range180_190; // 180-190 MHz u8 range190_200; // 190-200 MHz u8 range200_210; // 200-210 MHz u8 range210_220; // 210-220 MHz u8 range220_230; // 220-230 MHz u8 range230_240; // 230-240 MHz u8 range240_250; // 240-250 MHz u8 range250_260; // 240-250 MHz u8 range260_270; // 260-270 MHz u8 range270_280; // 270-280 MHz u8 range280_290; // 280-290 MHz u8 range290_300; // 290-300 MHz u8 range300_310; // 300-310 MHz u8 range310_320; // 310-320 MHz u8 range320_330; // 320-330 MHz u8 range330_340; // 330-340 MHz u8 range340_350; // 340-350 MHz u8 range350_360; // 350-360 MHz u8 range360_370; // 360-370 MHz u8 range370_380; // 370-380 MHz u8 range380_390; // 380-390 MHz u8 range390_400; // 290-400 MHz u8 range520_530; // 520-530 MHz u8 range530_540; // 530-540 MHz u8 range540_550; // 540-550 MHz u8 range550_560; // 550-560 MHz u8 range560_570; // 560-570 MHz u8 range570_580; // 570-580 MHz u8 range580_590; // 580-590 MHz u8 range590_600; // 590-600 MHz u8 range600_610; // 600-610 MHz u8 range610_620; // 610-620 MHz u8 range620_630; // 620-630 MHz u8 range630_640; // 630-640 MHz u8 range640_650; // 640-650 MHz u8 range650_660; // 650-660 MHz } txallow; #seekto 0x0039; struct { u8 display_timer; // 0x0039 Display Timer u8 led_timer; // 0x003A LED Timer u8 auto_lock; // 0x003B Auto Lock u8 pfkey1short; // 0x003C FS1 Short u8 pfkey1long; // 0x003D FS1 Long u8 pfkey2short; // 0x003E FS2 Short u8 pfkey2long; // 0x003F FS2 Long u8 unknown_0; // 0x0040 u8 voice:2, // 0x0041 Voice Prompt beep:1, // Beep Switch roger:2, // Roger Tone save:3; // Power Save u8 dispmode:1, // 0x0042 Display Mode dstandby:1, // Dual Standby unknown_1:1, standby:1, // Radio Standby squelch:4; // Squelch Level u8 vox_level:4, // 0x0043 VOX Level vox_delay:4; // VOX Delay u8 brightness:2, // 0x0044 Screen Light unknown_2:1, alarm:1, // Alarm scramble:4; // Scramble u8 screen:1, // 0x0045 Screen On-off led:1, // LED On-off key_lock:1, // Key Lock radio:1, // Radio On-off compander:1, // Compander rp:1, // Offset freq_lock:1, // Freq Lock vox:1; // VOX On-off u8 unknown_4:4, // 0x0046 txpri:1, // TX PRI unknown_5:1, tail_tone:2; // Tail Tone ul16 fmcur; // 0x0047 Radio Freq u8 unknown_49; // 0x0049 u8 unknown_4A; // 0x004A u8 unknown_4B; // 0x004B u8 unknown_4C; // 0x004C u8 dsrangea; // 0x004D Dual Standby Range A u8 dsrangeb; // 0x004E Dual Standby Range B u8 tot; // 0x004F } settings; struct memory { ul32 rxfreq; // 00-03 ul16 rx_tone; // PL/DPL Decode // 04-05 ul32 txfreq; // 06-09 ul16 tx_tone; // PL/DPL Encode // 0a-0b u8 lowpower:1, // Power Level // 0c isnarrow:1, // Bandwidth unknown1:1, unknown2:3, bcl:1, // Busy Channel Lockout scan:1; // Scan Add u8 unknown3[3]; // 0d-0f }; // #seekto 0x0050; struct memory channels[128]; """ CMD_ACK = b"\x06" RB15_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) _STEP_LIST = [0.25, 1.25, 2.5, 5., 6.25, 10., 12.5, 25., 50., 100.] LIST_ALARM = ["Local", "Remote"] LIST_BRIGHT = ["Low", "Middle", "High"] LIST_DISPM = ["Frequency", "Channel Number"] LIST_ROGER = ["Off", "Start", "End", "Start and End"] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4", "1:5"] LIST_SCRAMBLE = ["Off"] + ["%s" % x for x in range(1, 9)] LIST_SKEY = ["None", "Monitor", "Local Alarm", "Remote Alarm", "Screen On/Off", "Frequency Lock"] LIST_TIMER = ["Off"] + ["%s seconds" % x for x in range(15, 615, 15)] LIST_TXPRI = ["Edit", "Busy"] LIST_VOICE = ["Off", "Chinese", "English"] TXALLOW_CHOICES = ["RX Only", "TX/RX"] TXALLOW_VALUES = [0xFF, 0x00] def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def _enter_programming_mode(radio): serial = radio.pipe # lengthen the timeout here as these radios are resetting due to timeout radio.pipe.timeout = 0.75 exito = False for i in range(0, 5): serial.write(radio.magic) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except: LOG.debug("Attempt #%s, failed, trying again" % i) pass # return timeout to default value radio.pipe.timeout = 0.25 # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) def _exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"93" + b"\x05\xEE\x5F") except: raise errors.RadioError("Radio refused to exit programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">BH", ord(b'R'), block_addr + 0x0340) ccs = bytes([_checksum(cmd)]) expectedresponse = b"R" + cmd[1:] cmd = cmd + ccs LOG.debug("Reading block %04x..." % (block_addr + 0x0340)) try: serial.write(cmd) response = serial.read(3 + block_size + 1) cs = _checksum(response[:-1]) if response[:3] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr + 0x0340)) chunk = response[3:] if chunk[-1] != cs: raise Exception("Block failed checksum!") block_data = chunk[:-1] except: raise errors.RadioError("Failed to read block at %04x" % block_addr + 0x0340) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe data = radio.get_mmap()[block_addr:block_addr + block_size] cmd = struct.pack(">BH", ord(b'W'), block_addr + 0x0340) cs = bytes([_checksum(cmd + data)]) data += cs LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % (block_addr + 0x0340)) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) _write_block(radio, addr, radio.BLOCK_SIZE) _exit_programming_mode(radio) def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True class IradioUV5118(chirp_common.CloneModeRadio): """IRADIO UV5118""" VENDOR = "Iradio" MODEL = "UV-5118" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x10 magic = b"93" + b"\x05\x10\x81" VALID_BANDS = [(20000000, 64000000), # RX only (108000000, 136000000), # RX only (Air Band) (136000000, 174000000), # TX/RX (VHF) (174000000, 400000000), # TX/RX (400000000, 520000000), # TX/RX (UHF) (520000000, 660000000)] # TX/RX POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] # Radio's memory starts at 0x0340 # Radio's memory ends at 0x0B90 _ranges = [ (0x0000, 0x0850), ] _memsize = 0x0850 _upper = 128 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_dtcs_codes = RB15_DTCS rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = _STEP_LIST rf.valid_bands = self.VALID_BANDS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) @staticmethod def _decode_tone(toneval): # DCS examples: # D023N - 1013 - 0001 0000 0001 0011 # ^-DCS # D023I - 2013 - 0010 0000 0001 0100 # ^--DCS inverted # D754I - 21EC - 0010 0001 1110 1100 # code in octal-------^^^^^^^^^^^ if toneval == 0x3000: return '', None, None elif toneval & 0x1000: # DTCS N code = int('%o' % (toneval & 0x1FF)) return 'DTCS', code, 'N' elif toneval & 0x2000: # DTCS R code = int('%o' % (toneval & 0x1FF)) return 'DTCS', code, 'R' else: return 'Tone', toneval / 10.0, None @staticmethod def _encode_tone(mode, val, pol): if not mode: return 0x3000 elif mode == 'Tone': return int(val * 10) elif mode == 'DTCS': code = int('%i' % val, 8) if pol == 'N': code |= 0x1800 if pol == 'R': code |= 0x2800 return code else: raise errors.RadioError('Unsupported tone mode %r' % mode) def get_memory(self, number): mem = chirp_common.Memory() _mem = self._memobj.channels[number - 1] mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if _mem.get_raw() == (b"\xFF" * 16): LOG.debug("Initializing empty memory") _mem.set_raw("\xFF" * 4 + "\x00\x30" + "\xFF" * 4 + "\x00\x30" + "\x00" * 4) # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 mem.mode = _mem.isnarrow and "NFM" or "FM" chirp_common.split_tone_decode(mem, self._decode_tone(_mem.tx_tone), self._decode_tone(_mem.rx_tone)) mem.power = self.POWER_LEVELS[_mem.lowpower] if not _mem.scan: mem.skip = "S" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) return mem def set_memory(self, mem): LOG.debug("Setting %i(%s)" % (mem.number, mem.extd_number)) _mem = self._memobj.channels[mem.number - 1] # if empty memory if mem.empty: _mem.set_raw("\xFF" * 16) return _mem.set_raw("\xFF" * 4 + "\x00\x30" + "\xFF" * 4 + "\x00\x30" + "\x00" * 4) _mem.rxfreq = mem.freq / 10 if mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.scan = mem.skip != "S" _mem.isnarrow = mem.mode == "NFM" txtone, rxtone = chirp_common.split_tone_encode(mem) _mem.tx_tone = self._encode_tone(*txtone) _mem.rx_tone = self._encode_tone(*rxtone) _mem.lowpower = mem.power == self.POWER_LEVELS[1] for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings _txallow = self._memobj.txallow basic = RadioSettingGroup("basic", "Basic Settings") sidekey = RadioSettingGroup("sidekey", "Side Key Settings") dwatch = RadioSettingGroup("dwatch", "Dual Watch Settings") txallow = RadioSettingGroup("txallow", "TX Allow") top = RadioSettings(basic, sidekey, dwatch, txallow) voice = RadioSetting("voice", "Language", RadioSettingValueList( LIST_VOICE, LIST_VOICE[_settings.voice])) basic.append(voice) beep = RadioSetting("beep", "Key Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(beep) roger = RadioSetting("roger", "Roger Tone", RadioSettingValueList( LIST_ROGER, LIST_ROGER[_settings.roger])) basic.append(roger) save = RadioSetting("save", "Battery Save", RadioSettingValueList( LIST_SAVE, LIST_SAVE[_settings.save])) basic.append(save) dispmode = RadioSetting("dispmode", "Display Mode", RadioSettingValueList( LIST_DISPM, LIST_DISPM[_settings.dispmode])) basic.append(dispmode) brightness = RadioSetting("brightness", "Screen Light", RadioSettingValueList( LIST_BRIGHT, LIST_BRIGHT[_settings.brightness])) basic.append(brightness) screen = RadioSetting("screen", "Screen", RadioSettingValueBoolean(_settings.screen)) basic.append(screen) display_timer = RadioSetting("display_timer", "Display Timer", RadioSettingValueList( LIST_TIMER, LIST_TIMER[_settings.display_timer])) basic.append(display_timer) led = RadioSetting("led", "LED", RadioSettingValueBoolean(_settings.led)) basic.append(led) led_timer = RadioSetting("led_timer", "LED Timer", RadioSettingValueList( LIST_TIMER, LIST_TIMER[_settings.led_timer])) basic.append(led_timer) squelch = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger( 0, 9, _settings.squelch)) basic.append(squelch) vox = RadioSetting("vox", "VOX", RadioSettingValueBoolean(_settings.vox)) basic.append(vox) vox_level = RadioSetting("vox_level", "VOX Level", RadioSettingValueInteger( 0, 9, _settings.vox_level)) basic.append(vox_level) vox_delay = RadioSetting("vox_delay", "VOX Delay", RadioSettingValueInteger( 0, 9, _settings.vox_delay)) basic.append(vox_delay) compander = RadioSetting("compander", "Compander", RadioSettingValueBoolean(_settings.compander)) basic.append(compander) scramble = RadioSetting("scramble", "Scramble", RadioSettingValueList( LIST_SCRAMBLE, LIST_SCRAMBLE[_settings.scramble])) basic.append(scramble) rp = RadioSetting("rp", "Offset", RadioSettingValueBoolean(_settings.rp)) basic.append(rp) txpri = RadioSetting("txpri", "TX Priority", RadioSettingValueList( LIST_TXPRI, LIST_TXPRI[_settings.txpri])) basic.append(txpri) tot = RadioSetting("tot", "Time-out Timer", RadioSettingValueList( LIST_TIMER, LIST_TIMER[_settings.tot])) basic.append(tot) tail_tone = RadioSetting("tail_tone", "Tail Tone", RadioSettingValueInteger( 0, 3, _settings.tail_tone)) basic.append(tail_tone) alarm = RadioSetting("alarm", "Alarm", RadioSettingValueList( LIST_ALARM, LIST_ALARM[_settings.alarm])) basic.append(alarm) freq_lock = RadioSetting("freq_lock", "Frequency Lock", RadioSettingValueBoolean(_settings.freq_lock)) basic.append(freq_lock) key_lock = RadioSetting("key_lock", "Key Lock", RadioSettingValueBoolean(_settings.key_lock)) basic.append(key_lock) auto_lock = RadioSetting("auto_lock", "Auto Lock Timer", RadioSettingValueList( LIST_TIMER, LIST_TIMER[_settings.auto_lock])) basic.append(auto_lock) radio = RadioSetting("radio", "Broadcast FM Radio", RadioSettingValueBoolean(_settings.radio)) basic.append(radio) standby = RadioSetting("standby", "Radio Standby", RadioSettingValueBoolean(_settings.standby)) basic.append(standby) def myset_freq(setting, obj, atrb, mult): """ Callback to set frequency by applying multiplier""" value = int(float(str(setting.value)) * mult) setattr(obj, atrb, value) return # FM Broadcast Settings val = _settings.fmcur val = val / 10.0 if val < 87.5 or val > 108.0: val = 90.4 rx = RadioSettingValueFloat(87.5, 108.0, val, 0.1, 1) rset = RadioSetting("fmcur", "Broadcast FM Freq (MHz)", rx) rset.set_apply_callback(myset_freq, _settings, "fmcur", 10) basic.append(rset) # Side Key Settings pfkey1short = RadioSetting("pfkey1short", "Side Key 1 - Short Press", RadioSettingValueList( LIST_SKEY, LIST_SKEY[_settings.pfkey1short])) sidekey.append(pfkey1short) pfkey1long = RadioSetting("pfkey1long", "Side Key 1 - Long Press", RadioSettingValueList( LIST_SKEY, LIST_SKEY[_settings.pfkey1long])) sidekey.append(pfkey1long) pfkey2short = RadioSetting("pfkey2short", "Side Key 2 - Short Press", RadioSettingValueList( LIST_SKEY, LIST_SKEY[_settings.pfkey2short])) sidekey.append(pfkey2short) pfkey2long = RadioSetting("pfkey2long", "Side Key 2 - Long Press", RadioSettingValueList( LIST_SKEY, LIST_SKEY[_settings.pfkey2long])) sidekey.append(pfkey2long) dstandby = RadioSetting("dstandby", "Dual Standby", RadioSettingValueBoolean(_settings.dstandby)) dwatch.append(dstandby) dsrangea = RadioSetting("dsrangea", "Dual Standby Range A", RadioSettingValueInteger( 1, 128, _settings.dsrangea + 1)) dwatch.append(dsrangea) dsrangeb = RadioSetting("dsrangeb", "Dual Standby Range B", RadioSettingValueInteger( 1, 128, _settings.dsrangeb + 1)) dwatch.append(dsrangeb) def apply_txallow_listvalue(setting, obj): LOG.debug("Setting value: " + str( setting.value) + " from list") val = str(setting.value) index = TXALLOW_CHOICES.index(val) val = TXALLOW_VALUES[index] obj.set_value(val) if _txallow.range174_180 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range174_180) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range174_180", "174-180 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range174_180) txallow.append(rset) if _txallow.range180_190 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range180_190) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range180_190", "180-190 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range180_190) txallow.append(rset) if _txallow.range190_200 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range190_200) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range190_200", "190-200 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range190_200) txallow.append(rset) if _txallow.range200_210 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range200_210) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range200_210", "200-210 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range200_210) txallow.append(rset) if _txallow.range210_220 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range210_220) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range210_220", "210-220 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range210_220) txallow.append(rset) if _txallow.range220_230 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range220_230) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range220_230", "220-230 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range220_230) txallow.append(rset) if _txallow.range230_240 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range230_240) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range230_240", "230-240 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range230_240) txallow.append(rset) if _txallow.range240_250 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range240_250) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range240_250", "240-250 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range240_250) txallow.append(rset) if _txallow.range250_260 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range250_260) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range250_260", "250-260 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range250_260) txallow.append(rset) if _txallow.range260_270 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range260_270) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range260_270", "260-270 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range260_270) txallow.append(rset) if _txallow.range270_280 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range270_280) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range270_280", "270-280 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range270_280) txallow.append(rset) if _txallow.range280_290 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range280_290) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range280_290", "280-290 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range280_290) txallow.append(rset) if _txallow.range290_300 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range290_300) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range290_300", "290-300 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range290_300) txallow.append(rset) if _txallow.range300_310 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range300_310) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range300_310", "300-310 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range300_310) txallow.append(rset) if _txallow.range310_320 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range310_320) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range310_320", "310-320 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range310_320) txallow.append(rset) if _txallow.range320_330 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range320_330) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range320_330", "320-330 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range320_330) txallow.append(rset) if _txallow.range330_340 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range330_340) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range330_340", "330-340 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range330_340) txallow.append(rset) if _txallow.range340_350 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range340_350) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range340_350", "340-350 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range340_350) txallow.append(rset) if _txallow.range350_360 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range350_360) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range350_360", "350-360 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range350_360) txallow.append(rset) if _txallow.range360_370 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range360_370) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range360_370", "360-370 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range360_370) txallow.append(rset) if _txallow.range370_380 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range370_380) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range370_380", "370-380 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range370_380) txallow.append(rset) if _txallow.range380_390 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range380_390) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range380_390", "380-390 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range380_390) txallow.append(rset) if _txallow.range390_400 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range390_400) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range390_400", "390-400 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range390_400) txallow.append(rset) if _txallow.range520_530 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range520_530) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range520_530", "520-530 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range520_530) txallow.append(rset) if _txallow.range530_540 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range530_540) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range530_540", "530-540 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range530_540) txallow.append(rset) if _txallow.range540_550 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range540_550) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range540_550", "540-550 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range540_550) txallow.append(rset) if _txallow.range550_560 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range550_560) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range550_560", "550-560 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range550_560) txallow.append(rset) if _txallow.range560_570 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range560_570) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range560_570", "560-570 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range560_570) txallow.append(rset) if _txallow.range570_580 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range570_580) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range570_580", "570-580 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range570_580) txallow.append(rset) if _txallow.range580_590 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range580_590) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range580_590", "580-590 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range580_590) txallow.append(rset) if _txallow.range590_600 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range590_600) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range590_600", "590-600 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range590_600) txallow.append(rset) if _txallow.range600_610 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range600_610) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range600_610", "600-610 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range600_610) txallow.append(rset) if _txallow.range610_620 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range610_620) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range610_620", "610-620 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range610_620) txallow.append(rset) if _txallow.range620_630 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range620_630) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range620_630", "620-630 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range620_630) txallow.append(rset) if _txallow.range630_640 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range630_640) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range630_640", "630-640 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range630_640) txallow.append(rset) if _txallow.range640_650 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range640_650) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range640_650", "640-650 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range640_650) txallow.append(rset) if _txallow.range650_660 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_txallow.range650_660) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("txallow.range650_660", "650-660 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _txallow.range650_660) txallow.append(rset) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "dsrangea": setattr(obj, setting, int(element.value) - 1) elif setting == "dsrangeb": setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class AbbreeAR518Radio(IradioUV5118): """ABBREE AR518""" VENDOR = "Abbree" MODEL = "AR-518" chirp-20240224/chirp/drivers/ic2100.py0000644000175000017500000001631414522657251016105 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, util, directory, bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean MEM_FORMAT = """ struct { bbcd freq[2]; u8 freq_10khz:4, freq_1khz:3, zero:1; u8 unknown1; bbcd offset[2]; u8 is_12_5:1, unknownbit1:1, anm:1, unknownbit2:1, duplex:2, tmode:2; u8 ctone; u8 rtone; char name[6]; u8 unknown3; } memory[100]; #seekto 0x0640; struct { bbcd freq[2]; u8 freq_10khz:4, freq_1khz:3, zero:1; u8 unknown1; bbcd offset[2]; u8 is_12_5:1, unknownbit1:1, anm:1, unknownbit2:1, duplex:2, tmode:2; u8 ctone; u8 rtone; } special[7]; #seekto 0x0680; struct { bbcd freq[2]; u8 freq_10khz:4, freq_1khz:3, zero:1; u8 unknown1; bbcd offset[2]; u8 is_12_5:1, unknownbit1:1, anm:1, unknownbit2:1, duplex:2, tmode:2; u8 ctone; u8 rtone; } call[2]; #seekto 0x06F0; struct { u8 flagbits; } skipflags[14]; #seekto 0x0700; struct { u8 flagbits; } usedflags[14]; """ TMODES = ["", "Tone", "", "TSQL"] DUPLEX = ["", "", "+", "-"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0] def _get_special(): special = {"C": 506} for i in range(0, 3): ida = "%iA" % (i + 1) idb = "%iB" % (i + 1) num = 500 + (i * 2) special[ida] = num special[idb] = num + 1 return special def _get_freq(mem): freq = (int(mem.freq) * 100000) + \ (mem.freq_10khz * 10000) + \ (mem.freq_1khz * 1000) if mem.is_12_5: if chirp_common.is_12_5(freq): pass elif mem.freq_1khz == 2: freq += 500 elif mem.freq_1khz == 5: freq += 2500 elif mem.freq_1khz == 7: freq += 500 else: raise Exception("Unable to resolve 12.5 kHz: %i" % freq) return freq def _set_freq(mem, freq): mem.freq = freq / 100000 mem.freq_10khz = (freq / 10000) % 10 khz = (freq / 1000) % 10 mem.freq_1khz = khz mem.is_12_5 = chirp_common.is_12_5(freq) def _get_offset(mem): raw = bytearray(mem.get_raw()) if raw[5] & 0x0A: raw[5] = raw[5] & 0xF0 mem.set_raw(raw) offset = int(mem.offset) * 1000 + 5000 raw[5] = raw[5] | 0x0A mem.set_raw(bytes(raw)) return offset else: return int(mem.offset) * 1000 def _set_offset(mem, offset): if (offset % 10) == 5000: extra = 0x0A offset -= 5000 else: extra = 0x00 mem.offset = offset / 1000 raw = bytearray(mem.get_raw()) raw[5] = raw[5] | extra mem.set_raw(bytes(raw)) def _wipe_memory(mem, char): mem.set_raw(char * (mem.size() / 8)) @directory.register class IC2100Radio(icf.IcomCloneModeRadio): """Icom IC-2100""" VENDOR = "Icom" MODEL = "IC-2100H" _model = "\x20\x88\x00\x01" _memsize = 2016 _endframe = "Icom Inc\x2e" _ranges = [(0x0000, 0x07E0, 32)] def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 100) rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_tuning_step = False rf.has_mode = False rf.valid_modes = ["FM"] rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(118000000, 174000000)] rf.valid_skips = ["", "S"] rf.valid_special_chans = sorted(_get_special().keys()) return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_memory(self, number): mem = chirp_common.Memory() if isinstance(number, str): if number == "C": number = _get_special()[number] _mem = self._memobj.call[0] else: number = _get_special()[number] _mem = self._memobj.special[number - 500] empty = False else: number -= 1 _mem = self._memobj.memory[number] _emt = self._memobj.usedflags[number / 8].flagbits empty = (1 << (number % 8)) & int(_emt) if not empty: mem.name = str(_mem.name).rstrip() _skp = self._memobj.skipflags[number / 8].flagbits isskip = (1 << (number % 8)) & int(_skp) mem.number = number + 1 if number <= 100: mem.skip = isskip and "S" or "" else: mem.extd_number = util.get_dict_rev(_get_special(), number) mem.immutable = ["number", "skip", "extd_number"] if empty: mem.empty = True return mem mem.freq = _get_freq(_mem) mem.offset = _get_offset(_mem) mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("anm", "Alphanumeric Name", RadioSettingValueBoolean(_mem.anm)) mem.extra.append(rs) return mem def set_memory(self, mem): number = mem.extd_number or mem.number if number == "C": _mem = self._memobj.call[0] elif isinstance(number, str): _mem = self._memobj.special[_get_special()[number] - 500] else: number = number - 1 _mem = self._memobj.memory[number] _emt = self._memobj.usedflags[number / 8].flagbits mask = 1 << (number % 8) if mem.empty: _emt |= mask else: _emt &= ~mask _skp = self._memobj.skipflags[number / 8].flagbits if mem.skip == "S": _skp |= mask else: _skp &= ~mask _mem.name = mem.name.ljust(6) _mem.anm = mem.name.strip() != "" _set_freq(_mem, mem.freq) _set_offset(_mem, mem.offset) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) chirp-20240224/chirp/drivers/retevis_rt76p.py0000644000175000017500000010070514522657251017730 0ustar hibbyhibby# Copyright 2021-2022 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import struct from chirp import ( bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueInteger, RadioSettingValueList, RadioSettingValueString, ) LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // 0-3 lbcd txfreq[4]; // 4-7 ul16 rxtone; // 8-9 ul16 txtone; // A-B u8 unknown1:4, // C scode:4; // Signal u8 unknown2:6, // D pttid:2; // PTT-ID u8 unknown3:7, // E lowpower:1; // Power Level 0 = High, 1 = Low u8 ani:1, // F ANI narrow:1, // Bandwidth 0 = Wide, 1 = Narrow unknown4:2, bcl:1, // BCL scan:1, // Scan 0 = Skip, 1 = Scan unknown5:1, compand:1; // Compand } memory[128]; #seekto 0x0C00; struct { char name[10]; // 10-character Alpha Tag u8 unused[6]; } names[128]; #seekto 0x1A00; struct { u8 unknown:4, // 1A00 squelch:4; // Squelch Level u8 unknown_1a01:7, // 1A01 save:1; // Save Mode u8 unknown_1a02:4, // 1A04 vox:4; // 1A02 VOX Level u8 unknown_1a03:4, // 1A03 abr:4; // Auto Backlight Time-out u8 unknown_1a04:7, // 1A04 tdr:1; // Dual Standby u8 tot; // 1A05 Time-out Timer u8 unknown_1a06:7, // 1A06 beep:1; // Beep u8 unknown_1a07:7, // 1A07 voice:1; // Voice Switch u8 unknown_1a08:7, // 1A08 language:1; // Language u8 unknown_1a09:6, // 1A09 dtmfst:2; // DTMF ST u8 unknown_101a:6, // 1A0A scmode:2; // Scan Mode u8 unknown_1a0a; // 1A0B u8 pttlt; // 1A0C PTT Delay u8 unknown_1a0d:6, // 1A0D mdfa:2; // Channel A Display u8 unknown_1a0e:6, // 1A0E mdfb:2; // Channel B Display u8 unknown_1a0f:7, // 1A0F bcl:1; // BCL u8 unknown_1a10:7, // 1A10 autolock:1; // AutoLock u8 unknown_1a11:6, // 1A11 almod:2; // Alarm Mode u8 unknown_1a12:7, // 1A12 alarm:1; // Alarm Sound u8 unknown_1a13:6, // 1A13 tdrab:2; // Tx Under TDR Start u8 unknown_1a14:7, // 1A14 ste:1; // Tail Noise Clear u8 unknown_1a15:4, // 1A15 rpste:4; // Pass Repeat Noise u8 unknown_1a16:4, // 1A16 rptrl:4; // Pass Repeat Noise u8 unknown_1a17:7, // 1A17 roger:1; // Roger u8 unknown_1a18; // 1A18 u8 unknown_1a19:7, // 1A19 fmradio:1; // FM Radio (inverted) u8 unknown_1a1a:7, // 1A1A workmode:1; // Work Mode u8 unknown_1a1b:7, // 1A1B kblock:1; // KB_Lock u8 unknown_1a1c:6, // 1A1C pwronmsg:2; // Pwr On Msg u8 unknown_1a1d; // 1A1D u8 unknown_1a1e:6, // 1A1E tone:2; // Tone u8 unknown_1a1f; // 1A1F u8 unknown_1a20[7]; // 1A20-1A26 u8 unknown_1a27:6, // 1A27 wtled:2; // Wait Backlight Color u8 unknown_1a28:6, // 1A28 rxled:2; // Rx Backlight Color u8 unknown_1a29:6, // 1A29 txled:2; // Tx Backlight Color } settings; #seekto 0x1A80; struct { u8 shortp; // 1A80 Skey Short u8 longp; // 1A81 Skey Long } skey; #seekto 0x1B00; struct { u8 code[6]; // 6-character PTT-ID Code u8 unused[10]; } pttid[15]; #seekto 0x1BF0; struct { u8 code[6]; // ANI Code u8 unknown111; u8 dtmfon; // DTMF Speed (on time) u8 dtmfoff; // DTMR Speed (off time) u8 unused222[7]; u8 killword[6]; // Kill Word u8 unused333[2]; u8 revive[6]; // Revive u8 unused444[2]; } dtmf; #seekto 0x1FE0; struct { char line1[16]; // Power-on Message Line 1 char line2[16]; // Power-on Message Line 2 } poweron_msg; """ CMD_ACK = b"\x06" RT76P_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) DTMF_CHARS = "0123456789 *#ABCD" ALMOD_LIST = ["On Site", "Send Sound", "Send Code"] BACKLIGHT_LIST = ["Off", "Blue", "Orange", "Purple"] DTMFSPEED_LIST = ["%s ms" % x for x in range(50, 2010, 10)] DTMFST_LIST = ["Off", "KeyBboard Side Tone", "ANI Side Tone", "KB ST + ANI ST"] LANGUAGE_LIST = ["English", "China"] MDF_LIST = ["Name", "Frequency", "Number"] OFF1TO10_LIST = ["Off"] + ["%s" % x for x in range(1, 11)] PTTID_LIST = ["Off", "BOT", "EOT", "Both"] PTTIDCODE_LIST = ["%s" % x for x in range(1, 16)] PWRONMSG_LIST = ["Picture", "Message", "Voltage"] RPSTE_LIST = ["Off"] + ["%s" % x for x in range(100, 1100, 100)] SCMODE_LIST = ["Time (TO)", "Carrier (CO)", "Search (SE)"] TDRAB_LIST = ["Off", "A Band", "B Band"] TIMEOUTTIMER_LIST = ["%s seconds" % x for x in range(15, 615, 15)] TONE_LIST = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] VOICE_LIST = ["Off", "On"] WORKMODE_LIST = ["VFO Mode", "Channel Mode"] SKEY_CHOICES = ["FM", "Tx Power", "Moni", "Scan", "Offline", "Weather"] SKEY_VALUES = [0x07, 0x0A, 0x05, 0x1C, 0x0B, 0x0C] GMRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] GMRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] GMRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] GMRS_FREQS = GMRS_FREQS1 + GMRS_FREQS2 + GMRS_FREQS3 * 2 def _rt76p_enter_programming_mode(radio): serial = radio.pipe exito = False for i in range(0, 5): serial.write(radio._magic) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) try: serial.write(b"F") ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") if not ident == radio._fingerprint: LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") def _rt76p_exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _rt76p_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"R" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] except: raise errors.RadioError("Failed to read block at %04x" % block_addr) return block_data def _rt76p_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): serial = radio.pipe LOG.debug("download") _rt76p_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _rt76p_read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _rt76p_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _rt76p_enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE_UP): status.cur = addr + radio.BLOCK_SIZE_UP radio.status_fn(status) _rt76p_write_block(radio, addr, radio.BLOCK_SIZE_UP) _rt76p_exit_programming_mode(radio) @directory.register class RT76PRadio(chirp_common.CloneModeRadio): """RETEVIS RT76P""" VENDOR = "Retevis" MODEL = "RT76P" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x40 BLOCK_SIZE_UP = 0x20 RT76P_POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PROGROMCD2U" _fingerprint = b"\x01\x36\x01\x74\x04\x00\x05\x20" _ranges = [ (0x0000, 0x0820), (0x0C00, 0x1400), (0x1A00, 0x1C20), ] _memsize = 0x2000 _valid_chars = chirp_common.CHARSET_ALPHANUMERIC + \ "`~!@#$%^&*()-=_+[]\\{}|;':\",./<>?" def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.valid_name_length = 10 rf.valid_characters = self._valid_chars rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = self.RT76P_POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_dtcs_codes = RT76P_DTCS rf.memory_bounds = (1, 128) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 20., 25., 50.] rf.valid_bands = [(136000000, 174000000), (400000000, 480000000)] return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def _is_txinh(self, _mem): raw_tx = "" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw(asbytes=False) return raw_tx == "\xFF\xFF\xFF\xFF" def get_memory(self, number): _mem = self._memobj.memory[number - 1] _nam = self._memobj.names[number - 1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if self._is_txinh(_mem): # TX freq not set mem.duplex = "off" mem.offset = 0 else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if offset > 0: mem.duplex = "+" mem.offset = 5000000 else: mem.duplex = "" mem.offset = 0 for char in _nam.name: if str(char) == "\xFF": char = " " # may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() dtcs_pol = ["N", "N"] if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 elif _mem.txtone <= 0x0258: txmode = "DTCS" if _mem.txtone > 0x69: index = _mem.txtone - 0x6A dtcs_pol[0] = "R" else: index = _mem.txtone - 1 mem.dtcs = RT76P_DTCS[index] else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 elif _mem.rxtone <= 0x0258: rxmode = "DTCS" if _mem.rxtone >= 0x6A: index = _mem.rxtone - 0x6A dtcs_pol[1] = "R" else: index = _mem.rxtone - 1 mem.rx_dtcs = RT76P_DTCS[index] else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) if not _mem.scan: mem.skip = "S" mem.power = self.RT76P_POWER_LEVELS[_mem.lowpower] mem.mode = _mem.narrow and "NFM" or "FM" mem.extra = RadioSettingGroup("Extra", "extra") # BCL (Busy Channel Lockout) rs = RadioSettingValueBoolean(_mem.bcl) rset = RadioSetting("bcl", "BCL", rs) mem.extra.append(rset) # PTT-ID rs = RadioSettingValueList(PTTID_LIST, PTTID_LIST[_mem.pttid]) rset = RadioSetting("pttid", "PTT ID", rs) mem.extra.append(rset) # Signal (DTMF Encoder Group #) rs = RadioSettingValueList(PTTIDCODE_LIST, PTTIDCODE_LIST[_mem.scode]) rset = RadioSetting("scode", "PTT ID Code", rs) mem.extra.append(rset) # Compand rs = RadioSettingValueBoolean(_mem.compand) rset = RadioSetting("compand", "Compand", rs) mem.extra.append(rset) # ANI rs = RadioSettingValueBoolean(_mem.ani) rset = RadioSetting("ani", "ANI", rs) mem.extra.append(rset) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _nam = self._memobj.names[mem.number - 1] if mem.empty: _mem.set_raw("\xff" * 16) _nam.set_raw("\xff" * 16) return _mem.set_raw("\x00" * 16) if mem.freq in GMRS_FREQS1: mem.duplex == '' mem.offset = 0 elif mem.freq in GMRS_FREQS2: mem.duplex == '' mem.offset = 0 mem.mode = "NFM" mem.power = self.RT76P_POWER_LEVELS[1] elif mem.freq in GMRS_FREQS3: if mem.duplex == '+': mem.offset = 5000000 else: mem.duplex == '' mem.offset = 0 else: mem.duplex = 'off' mem.offset = 0 _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": rxmode = txmode = "DTCS" _mem.txtone = RT76P_DTCS.index(mem.dtcs) + 1 _mem.rxtone = RT76P_DTCS.index(mem.dtcs) + 1 elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) elif txmode == "DTCS": _mem.txtone = RT76P_DTCS.index(mem.dtcs) + 1 else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCS": _mem.rxtone = RT76P_DTCS.index(mem.rx_dtcs) + 1 else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 if txmode == "DTCS" and mem.dtcs_polarity[0] == "R": _mem.txtone += 0x69 if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R": _mem.rxtone += 0x69 _mem.scan = mem.skip != "S" _mem.narrow = mem.mode == "NFM" _mem.lowpower = mem.power == self.RT76P_POWER_LEVELS[1] for setting in mem.extra: if setting.get_name() == "scramble_type": setattr(_mem, setting.get_name(), int(setting.value) + 8) setattr(_mem, "scramble_type2", int(setting.value) + 8) else: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _dtmf = self._memobj.dtmf _settings = self._memobj.settings _skey = self._memobj.skey basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) # Menu 00: Squelch (Squelch Level) rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) basic.append(rset) # Menu 01: Step (VFO setting) # Menu 02: Tx Power (VFO setting - not available) # Menu 03: Power save (Save Mode) rs = RadioSettingValueBoolean(_settings.save) rset = RadioSetting("save", "Power Save", rs) basic.append(rset) # Menu 04: Vox Level (VOX) rs = RadioSettingValueList(OFF1TO10_LIST, OFF1TO10_LIST[_settings.vox]) rset = RadioSetting("vox", "VOX Level", rs) basic.append(rset) # Menu 05: Bandwidth # Menu 06: Backlight (Auto Backlight) rs = RadioSettingValueList(OFF1TO10_LIST, OFF1TO10_LIST[_settings.abr]) rset = RadioSetting("abr", "Backlight Time-out", rs) basic.append(rset) # Menu 07: Dual Standby (TDR) rs = RadioSettingValueBoolean(_settings.tdr) rset = RadioSetting("tdr", "Dual Standby", rs) basic.append(rset) # Menu 08: Beep Prompt rs = RadioSettingValueBoolean(_settings.beep) rset = RadioSetting("beep", "Beep Prompt", rs) basic.append(rset) # Menu 09: Voice (Voice Switch) rs = RadioSettingValueBoolean(_settings.voice) rset = RadioSetting("voice", "Voice Prompts", rs) basic.append(rset) # Menu 10: Tx over time (Time Out) rs = RadioSettingValueList(TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[_settings.tot - 1]) rset = RadioSetting("tot", "Time-out Timer", rs) basic.append(rset) # Menu 11: Rx DCS # Menu 12: Rx CTCSS # Menu 13: Tx DCS # Menu 14: Tx CTCSS # Menu 15: Voice Compand # Menu 16: DTMFST (DTMF ST) rs = RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[_settings.dtmfst]) rset = RadioSetting("dtmfst", "DTMF Side Tone", rs) basic.append(rset) # Mneu 17: R-TONE (Tone) rs = RadioSettingValueList(TONE_LIST, TONE_LIST[_settings.tone]) rset = RadioSetting("tone", "Tone-burst Frequency", rs) basic.append(rset) # Menu 18: S-CODE # Menu 19: Scan Mode rs = RadioSettingValueList(SCMODE_LIST, SCMODE_LIST[_settings.scmode]) rset = RadioSetting("scmode", "Scan Resume Method", rs) basic.append(rset) # Menu 20: ANI Match # Menu 21: PTT-ID # Menu 22: MDF-A (Channle_A Display) rs = RadioSettingValueList(MDF_LIST, MDF_LIST[_settings.mdfa]) rset = RadioSetting("mdfa", "Memory Display Format A", rs) basic.append(rset) # Menu 23: MDF-B (Channle_B Display) rs = RadioSettingValueList(MDF_LIST, MDF_LIST[_settings.mdfb]) rset = RadioSetting("mdfb", "Memory Display Format B", rs) basic.append(rset) # Menu 24: Busy Lockout # Menu 25: Key Auto Lock (AutoLock) rs = RadioSettingValueBoolean(_settings.autolock) rset = RadioSetting("autolock", "Keypad Auto Lock", rs) basic.append(rset) # Menu 26: WT-LED (Wait Backlight) rs = RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.wtled]) rset = RadioSetting("wtled", "Wait Backlight Color", rs) basic.append(rset) # Menu 27: RX-LED (Rx Backlight) rs = RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.rxled]) rset = RadioSetting("rxled", "RX Backlight Color", rs) basic.append(rset) # Menu 28: TX-LED (Tx Backlight) rs = RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.txled]) rset = RadioSetting("txled", "TX Backlight Color", rs) basic.append(rset) # Menu 29: Alarm Mode rs = RadioSettingValueList(ALMOD_LIST, ALMOD_LIST[_settings.almod]) rset = RadioSetting("almod", "Alarm Mode", rs) basic.append(rset) # Menu 30: TAIL (Tail Noise Clear) rs = RadioSettingValueBoolean(_settings.ste) rset = RadioSetting("ste", "Squelch Tail Eliminate", rs) basic.append(rset) # Menu 31: PROGRE (Roger) rs = RadioSettingValueBoolean(_settings.roger) rset = RadioSetting("roger", "Roger Beep", rs) basic.append(rset) # Menu 32: Language rs = RadioSettingValueList(LANGUAGE_LIST, LANGUAGE_LIST[_settings.language]) rset = RadioSetting("language", "Language", rs) basic.append(rset) # Menu 33: OPENMGS (Pwr On Msg) rs = RadioSettingValueList(PWRONMSG_LIST, PWRONMSG_LIST[_settings.pwronmsg]) rset = RadioSetting("pwronmsg", "Power On Message", rs) basic.append(rset) dtmfchars = "0123456789ABCD*#" # Menu 34: ANI ID (display only) _codeobj = self._memobj.dtmf.code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(dtmfchars) val.set_mutable(False) rs = RadioSetting("dtmf.code", "Query ANI ID", val) basic.append(rs) # Menu 35: Reset advanced = RadioSettingGroup("advanced", "Advanced Settings") group.append(advanced) # Work Mode rs = RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[_settings.workmode]) rset = RadioSetting("workmode", "Work Mode", rs) advanced.append(rset) # PTT Delay rs = RadioSettingValueInteger(0, 30, _settings.pttlt) rset = RadioSetting("pttlt", "PTT ID Delay", rs) advanced.append(rset) def apply_skey_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = SKEY_CHOICES.index(val) val = SKEY_VALUES[index] obj.set_value(val) # Skey Short if _skey.shortp in SKEY_VALUES: idx = SKEY_VALUES.index(_skey.shortp) else: idx = SKEY_VALUES.index(0x0C) rs = RadioSettingValueList(SKEY_CHOICES, SKEY_CHOICES[idx]) rset = RadioSetting("skey.shortp", "Side Key (Short Press)", rs) rset.set_apply_callback(apply_skey_listvalue, _skey.shortp) advanced.append(rset) # Skey Long if _skey.longp in SKEY_VALUES: idx = SKEY_VALUES.index(_skey.longp) else: idx = SKEY_VALUES.index(0x0C) rs = RadioSettingValueList(SKEY_CHOICES, SKEY_CHOICES[idx]) rset = RadioSetting("skey.longp", "Side Key (Long Press)", rs) rset.set_apply_callback(apply_skey_listvalue, _skey.longp) advanced.append(rset) # Pass Repeat Noise rs = RadioSettingValueList(RPSTE_LIST, RPSTE_LIST[_settings.rpste]) rset = RadioSetting("rpste", "Squelch Tail Eliminate (repeater)", rs) advanced.append(rset) # Pass Repeat Noise rs = RadioSettingValueList(RPSTE_LIST, RPSTE_LIST[_settings.rptrl]) rset = RadioSetting("rptrl", "STE Repeater Delay", rs) advanced.append(rset) # KB_Lock rs = RadioSettingValueBoolean(_settings.kblock) rset = RadioSetting("kblock", "Keypad Lock", rs) advanced.append(rset) # FM Radio Enable rs = RadioSettingValueBoolean(not _settings.fmradio) rset = RadioSetting("fmradio", "Broadcast FM Radio", rs) advanced.append(rset) # Alarm Sound rs = RadioSettingValueBoolean(_settings.alarm) rset = RadioSetting("alarm", "Alarm Sound", rs) advanced.append(rset) # Tx Under TDR Start rs = RadioSettingValueList(TDRAB_LIST, TDRAB_LIST[_settings.tdrab]) rset = RadioSetting("tdrab", "Dual Standby TX Priority", rs) advanced.append(rset) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = self._memobj.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 16, _filter(_msg.line1))) advanced.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 16, _filter(_msg.line2))) advanced.append(rs) dtmf = RadioSettingGroup("dtmf", "DTMF Settings") group.append(dtmf) def apply_code(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(DTMF_CHARS) pttid = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) pttid.set_apply_callback(apply_code, self._memobj.pttid[i], 6) dtmf.append(pttid) _codeobj = self._memobj.dtmf.killword _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("dtmf.killword", "Kill Word", val) rs.set_apply_callback(apply_code, self._memobj.dtmf, 6) dtmf.append(rs) _codeobj = self._memobj.dtmf.revive _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("dtmf.revive", "Revive Word", val) rs.set_apply_callback(apply_code, self._memobj.dtmf, 6) dtmf.append(rs) _codeobj = self._memobj.dtmf.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("dtmf.code", "ANI Code", val) rs.set_apply_callback(apply_code, self._memobj.dtmf, 6) dtmf.append(rs) if _dtmf.dtmfon > 0xC3: val = 0x00 else: val = _dtmf.dtmfon rs = RadioSetting("dtmf.dtmfon", "DTMF Speed (on)", RadioSettingValueList(DTMFSPEED_LIST, DTMFSPEED_LIST[val])) dtmf.append(rs) if _dtmf.dtmfoff > 0xC3: val = 0x00 else: val = _dtmf.dtmfoff rs = RadioSetting("dtmf.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(DTMFSPEED_LIST, DTMFSPEED_LIST[val])) dtmf.append(rs) return group def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "fmradio": setattr(obj, setting, not int(element.value)) elif setting == "tot": setattr(obj, setting, int(element.value) + 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False chirp-20240224/chirp/drivers/bf_t8.py0000644000175000017500000007503414551723752016217 0ustar hibbyhibby# Copyright 2022 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import ( bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueFloat, RadioSettingValueInteger, RadioSettingValueList, ) LOG = logging.getLogger(__name__) MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency lbcd txfreq[4]; // TX Frequency u8 rx_tmode; // RX Tone Mode u8 rx_tone; // PL/DPL Decode u8 tx_tmode; // TX Tone Mode u8 tx_tone; // PL/DPL Encode u8 unknown1:3, // skip:1, // Scan Add: 1 = Skip, 0 = Scan unknown2:2, isnarrow:1, // W/N: 1 = Narrow, 0 = Wide lowpower:1; // TX Power: 1 = Low, 0 = High u8 unknown3[3]; // } memory[%d]; // #seekto 0x0630; struct { u8 squelch; // SQL u8 vox; // Vox Lv u8 tot; // TOT u8 unk1:3, // ste:1, // Tail Clear bcl:1, // BCL save:1, // Save tdr:1, // TDR beep:1; // Beep u8 voice; // Voice u8 abr; // Back Light u8 ring; // Ring u8 mdf; // Display Type u8 mra; // MR Channel A u8 mrb; // MR Channel B u8 disp_ab; // Display A/B Selected } settings; """ MEM_FORMAT_PT2 = """ // #seekto 0x063D; struct { u8 workmode; // Work Mode u8 wx; // NOAA WX ch# u8 area; // Area Selected } settings2; #seekto 0x0D00; struct { char name[6]; u8 unknown1[2]; } names[%d]; """ MEM_FM_U_FORMAT = """ // #seekto 0x063B; struct { u16 fmcur; // Broadcast FM station } fmpreset; """ MEM_FM_UL_FORMAT = """ // #seekto 0x063B; struct { ul16 fmcur; // Broadcast FM station } fmpreset; """ CMD_ACK = b"\x06" TONES = chirp_common.TONES TMODES = ["", "Tone", "DTCS", "DTCS"] AB_LIST = ["A", "B"] ABR_LIST = ["OFF", "ON", "Key"] AREA_LIST = ["China", "Japan", "Korea", "Malaysia", "American", "Australia", "Iran", "Taiwan", "Europe", "Russia"] MDF_LIST = ["Frequency", "Channel #", "Name"] RING_LIST = ["OFF"] + ["%s" % x for x in range(1, 11)] TOT_LIST = ["OFF"] + ["%s seconds" % x for x in range(30, 210, 30)] TOT2_LIST = ["OFF"] + ["%s seconds" % x for x in range(60, 240, 30)] VOICE_LIST = ["Off", "Chinese", "English"] VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 6)] WORKMODE_LIST = ["General", "PMR"] WX_LIST = ["CH01 - 162.550", "CH02 - 162.400", "CH03 - 162.475", "CH04 - 162.425", "CH05 - 162.450", "CH06 - 162.500", "CH07 - 162.525", "CH08 - 161.650", "CH09 - 161.775", "CH10 - 161.750", "CH11 - 162.000" ] FRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] FRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] FRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] FRS_FREQS = FRS_FREQS1 + FRS_FREQS2 + FRS_FREQS3 GMRS_FREQS = FRS_FREQS + FRS_FREQS3 MURS_FREQS = [151820000, 151880000, 151940000, 154570000, 154600000] PMR_FREQS1 = [446006250, 446018750, 446031250, 446043750, 446056250, 446068750, 446081250, 446093750] PMR_FREQS2 = [446106250, 446118750, 446131250, 446143750, 446156250, 446168750, 446181250, 446193750] PMR_FREQS = PMR_FREQS1 + PMR_FREQS2 VOICE_CHOICES = ["Off", "On"] VOICE_VALUES = [0x00, 0x02] def _enter_programming_mode(radio): serial = radio.pipe exito = False for i in range(0, 5): serial.write(radio._magic) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: _exit_programming_mode(radio) msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) try: serial.write(b"\x02") ident = serial.read(len(radio._fingerprint)) except: _exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if not ident == radio._fingerprint: _exit_programming_mode(radio) LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: serial.write(CMD_ACK) ack = serial.read(1) except: _exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: _exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") def _exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] serial.write(CMD_ACK) ack = serial.read(1) except: _exit_programming_mode(radio) raise errors.RadioError("Failed to read block at %04x" % block_addr) if ack != CMD_ACK: _exit_programming_mode(radio) raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: _exit_programming_mode(radio) raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE_UP): status.cur = addr + radio.BLOCK_SIZE_UP radio.status_fn(status) _write_block(radio, addr, radio.BLOCK_SIZE_UP) _exit_programming_mode(radio) class BFT8Radio(chirp_common.CloneModeRadio): """Baofeng BF-T8""" VENDOR = "Baofeng" MODEL = "BF-T8" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = BLOCK_SIZE_UP = 0x10 ODD_SPLIT = True HAS_NAMES = False NAME_LENGTH = 0 VALID_CHARS = "" CH_OFFSET = False SKIP_VALUES = [] DTCS_CODES = sorted(chirp_common.DTCS_CODES) DUPLEXES = ["", "-", "+", "split", "off"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(400000000, 470000000)] _magic = b"\x02" + b"PROGRAM" _fingerprint = b"\x2E" + b"BF-T6" + b"\x2E" _upper = 99 _mem_params = (_upper, # number of channels _upper # number of names ) _frs = _gmrs = _murs = _pmr = False _ranges = [ (0x0000, 0x0B60), ] _memsize = 0x0B60 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.has_name = self.HAS_NAMES rf.can_odd_split = self.ODD_SPLIT rf.valid_name_length = self.NAME_LENGTH rf.valid_characters = self.VALID_CHARS rf.valid_skips = self.SKIP_VALUES rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_dtcs_codes = self.DTCS_CODES rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = self.DUPLEXES rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] rf.valid_bands = self.VALID_BANDS return rf def process_mmap(self): mem_format = MEM_FORMAT + MEM_FM_UL_FORMAT + MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, mem, _mem): rx_tone = tx_tone = None tx_tmode = TMODES[_mem.tx_tmode] rx_tmode = TMODES[_mem.rx_tmode] if tx_tmode == "Tone": tx_tone = TONES[_mem.tx_tone] elif tx_tmode == "DTCS": tx_tone = self.DTCS_CODES[_mem.tx_tone] if rx_tmode == "Tone": rx_tone = TONES[_mem.rx_tone] elif rx_tmode == "DTCS": rx_tone = self.DTCS_CODES[_mem.rx_tone] tx_pol = _mem.tx_tmode == 0x03 and "R" or "N" rx_pol = _mem.rx_tmode == 0x03 and "R" or "N" chirp_common.split_tone_decode(mem, (tx_tmode, tx_tone, tx_pol), (rx_tmode, rx_tone, rx_pol)) def _is_txinh(self, _mem): raw_tx = b"" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw() return raw_tx == b"\xFF\xFF\xFF\xFF" def _get_mem(self, number): return self._memobj.memory[number - 1] def _get_nam(self, number): return self._memobj.names[number - 1] def get_memory(self, number): _mem = self._get_mem(number) if self.HAS_NAMES: _nam = self._get_nam(number) mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if _mem.get_raw() == (b"\xFF" * 16): LOG.debug("Initializing empty memory") _mem.set_raw("\x00" * 13 + "\xFF" * 3) if self._is_txinh(_mem): mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 # wide/narrow mem.mode = _mem.isnarrow and "NFM" or "FM" mem.skip = _mem.skip and "S" or "" if self.HAS_NAMES: for char in _nam.name: if str(char) == "\xFF": char = " " # The OEM software may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() # tone data self._get_tone(mem, _mem) # tx power levels = self.POWER_LEVELS try: mem.power = levels[_mem.lowpower] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.lowpower, levels)) mem.power = levels[0] immutable = [] if self._frs: if mem.freq in FRS_FREQS: if mem.number >= 1 and mem.number <= 22: FRS_FREQ = FRS_FREQS[mem.number - 1] mem.freq = FRS_FREQ mem.duplex == '' mem.offset = 0 mem.mode = "NFM" if mem.number >= 8 and mem.number <= 14: mem.power = self.POWER_LEVELS[1] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] else: immutable = ["empty", "freq", "duplex", "offset", "mode"] elif self._murs: if mem.freq in MURS_FREQS: if mem.number >= 1 and mem.number <= 5: MURS_FREQ = MURS_FREQS[mem.number - 1] mem.freq = MURS_FREQ mem.duplex = '' mem.offset = 0 if mem.number <= 3: mem.mode = "NFM" immutable = ["empty", "freq", "duplex", "offset", "mode"] else: immutable = ["empty", "freq", "duplex", "offset"] elif self._pmr: if mem.freq in PMR_FREQS: if mem.number >= 1 and mem.number <= 16: PMR_FREQ = PMR_FREQS[mem.number - 1] mem.freq = PMR_FREQ mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] elif self._gmrs: if mem.freq in GMRS_FREQS: if mem.number >= 1 and mem.number <= 30: GMRS_FREQ = GMRS_FREQS[mem.number - 1] mem.freq = GMRS_FREQ immutable = ["empty", "freq"] if mem.number >= 1 and mem.number <= 7: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 8 and mem.number <= 14: mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable += ["duplex", "offset", "mode", "power"] elif mem.number >= 15 and mem.number <= 22: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 23 and mem.number <= 30: mem.duplex = '+' mem.offset = 5000000 immutable += ["duplex", "offset"] elif mem.freq in FRS_FREQS1: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.freq in FRS_FREQS2: mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable += ["duplex", "offset", "mode", "power"] elif mem.freq in FRS_FREQS3: if mem.duplex == '': mem.offset = 0 if mem.duplex == '+': mem.offset = 5000000 else: if mem.freq not in GMRS_FREQS: mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] mem.immutable = immutable return mem def _set_tone(self, mem, _mem): ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) _mem.tx_tmode = TMODES.index(txmode) _mem.rx_tmode = TMODES.index(rxmode) if txmode == "Tone": _mem.tx_tone = TONES.index(txtone) elif txmode == "DTCS": _mem.tx_tmode = txpol == "R" and 0x03 or 0x02 _mem.tx_tone = self.DTCS_CODES.index(txtone) if rxmode == "Tone": _mem.rx_tone = TONES.index(rxtone) elif rxmode == "DTCS": _mem.rx_tmode = rxpol == "R" and 0x03 or 0x02 _mem.rx_tone = self.DTCS_CODES.index(rxtone) def _set_mem(self, number): return self._memobj.memory[number - 1] def _set_nam(self, number): return self._memobj.names[number - 1] def set_memory(self, mem): _mem = self._set_mem(mem.number) if self.HAS_NAMES: _nam = self._set_nam(mem.number) # if empty memory if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) if self.HAS_NAMES: for i in range(0, self.NAME_LENGTH): _nam.name[i].set_raw("\xFF") return mem _mem.set_raw("\x00" * 13 + "\xFF" * 3) # frequency _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 # wide/narrow _mem.isnarrow = mem.mode == "NFM" _mem.skip = mem.skip == "S" if self.HAS_NAMES: for i in range(self.NAME_LENGTH): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" # tone data self._set_tone(mem, _mem) # tx power if str(mem.power) == "High": _mem.lowpower = 0 elif str(mem.power) == "Low": _mem.lowpower = 1 else: _mem.lowpower = 0 return mem def get_settings(self): _fmpreset = self._memobj.fmpreset _settings = self._memobj.settings _settings2 = self._memobj.settings2 basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) # Menu 03 rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) basic.append(rset) model_list = ["RB27B", "RB27V", "RB627B"] if self.MODEL in model_list: # Menu 09 (RB27x/RB627x) rs = RadioSettingValueList(TOT2_LIST, TOT2_LIST[_settings.tot]) else: # Menu 11 / 09 (RB27) rs = RadioSettingValueList(TOT_LIST, TOT_LIST[_settings.tot]) rset = RadioSetting("tot", "Time-out timer", rs) basic.append(rset) # Menu 06 rs = RadioSettingValueList(VOX_LIST, VOX_LIST[_settings.vox]) rset = RadioSetting("vox", "VOX Level", rs) basic.append(rset) # Menu 15 (BF-T8) / Menu 14 (FRS-A1) if self.MODEL == "FRS-A1": # Menu 14 (FRS-A1) def apply_voice_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = VOICE_CHOICES.index(val) val = VOICE_VALUES[index] obj.set_value(val) if _settings.voice in VOICE_VALUES: idx = VOICE_VALUES.index(_settings.voice) else: idx = VOICE_VALUES.index(0x00) rs = RadioSettingValueList(VOICE_CHOICES, VOICE_CHOICES[idx]) rset = RadioSetting("voice", "Voice", rs) rset.set_apply_callback(apply_voice_listvalue, _settings.voice) basic.append(rset) else: # Menu 15 (BF-T8) rs = RadioSettingValueList(VOICE_LIST, VOICE_LIST[_settings.voice]) rset = RadioSetting("voice", "Voice", rs) basic.append(rset) # Menu 12 rs = RadioSettingValueBoolean(_settings.bcl) rset = RadioSetting("bcl", "Busy Channel Lockout", rs) basic.append(rset) # Menu 10 / 08 (RB27/RB627) rs = RadioSettingValueBoolean(_settings.save) rset = RadioSetting("save", "Battery Saver", rs) basic.append(rset) # Menu 08 / 07 (RB-27/RB627) rs = RadioSettingValueBoolean(_settings.tdr) rset = RadioSetting("tdr", "Dual Watch", rs) basic.append(rset) # Menu 05 rs = RadioSettingValueBoolean(_settings.beep) rset = RadioSetting("beep", "Beep", rs) basic.append(rset) # Menu 04 rs = RadioSettingValueList(ABR_LIST, ABR_LIST[_settings.abr]) rset = RadioSetting("abr", "Back Light", rs) basic.append(rset) # Menu 13 / 11 (RB-27/RB627) rs = RadioSettingValueList(RING_LIST, RING_LIST[_settings.ring]) rset = RadioSetting("ring", "Ring", rs) basic.append(rset) rs = RadioSettingValueBoolean(not _settings.ste) rset = RadioSetting("ste", "Squelch Tail Eliminate", rs) basic.append(rset) # Menu 15 (FRS-A1) if self.MODEL == "FRS-A1": rs = RadioSettingValueList(MDF_LIST, MDF_LIST[_settings.mdf]) rset = RadioSetting("mdf", "Display Type", rs) basic.append(rset) if self.CH_OFFSET: rs = RadioSettingValueInteger(1, self._upper, _settings.mra + 1) else: rs = RadioSettingValueInteger(1, self._upper, _settings.mra) rset = RadioSetting("mra", "MR A Channel #", rs) basic.append(rset) if self.CH_OFFSET: rs = RadioSettingValueInteger(1, self._upper, _settings.mrb + 1) else: rs = RadioSettingValueInteger(1, self._upper, _settings.mrb) rset = RadioSetting("mrb", "MR B Channel #", rs) basic.append(rset) rs = RadioSettingValueList(AB_LIST, AB_LIST[_settings.disp_ab]) rset = RadioSetting("disp_ab", "Selected Display Line", rs) basic.append(rset) if not self.MODEL.startswith("RB627"): if self.MODEL == "FRS-A1": del WX_LIST[7:] rs = RadioSettingValueList(WX_LIST, WX_LIST[_settings2.wx]) rset = RadioSetting("settings2.wx", "NOAA WX Radio", rs) basic.append(rset) def myset_freq(setting, obj, atrb, mult): """ Callback to set frequency by applying multiplier""" value = int(float(str(setting.value)) * mult) setattr(obj, atrb, value) return # FM Broadcast Settings val = _fmpreset.fmcur val = val / 10.0 val_low = 76.0 if self.MODEL == "FRS-A1": val_low = 87.0 if val < val_low or val > 108.0: val = 90.4 rx = RadioSettingValueFloat(val_low, 108.0, val, 0.1, 1) rset = RadioSetting("fmpreset.fmcur", "Broadcast FM Radio (MHz)", rx) rset.set_apply_callback(myset_freq, _fmpreset, "fmcur", 10) basic.append(rset) model_list = ["BF-T8", "BF-U9", "AR-8"] if self.MODEL in model_list: rs = RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[_settings2.workmode]) rset = RadioSetting("settings2.workmode", "Work Mode", rs) basic.append(rset) rs = RadioSettingValueList(AREA_LIST, AREA_LIST[_settings2.area]) rs.set_mutable(False) rset = RadioSetting("settings2.area", "Area", rs) basic.append(rset) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "mra" and self.CH_OFFSET: setattr(obj, setting, int(element.value) - 1) elif setting == "mrb" and self.CH_OFFSET: setattr(obj, setting, int(element.value) - 1) elif setting == "ste": setattr(obj, setting, not int(element.value)) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False class BFU9Alias(chirp_common.Alias): VENDOR = "Baofeng" MODEL = "BF-U9" class AR8Alias(chirp_common.Alias): VENDOR = "Arcshell" MODEL = "AR-8" @directory.register class BaofengBFT8Generic(BFT8Radio): ALIASES = [BFU9Alias, AR8Alias, ] @directory.register class RetevisRT16(BFT8Radio): VENDOR = "Retevis" MODEL = "RT16" _upper = 22 _frs = True @directory.register class RetevisRB27B(BFT8Radio): VENDOR = "Retevis" MODEL = "RB27B" DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) HAS_NAMES = True NAME_LENGTH = 6 VALID_CHARS = chirp_common.CHARSET_UPPER_NUMERIC + "-" CH_OFFSET = True SKIP_VALUES = ["", "S"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(400000000, 520000000)] _upper = 22 _frs = True _gmrs = _murs = _pmr = False _ranges = [ (0x0000, 0x0640), (0x0D00, 0x1040), ] _memsize = 0x1040 def process_mmap(self): mem_format = MEM_FORMAT + MEM_FM_U_FORMAT + MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) @directory.register class RetevisRB27(RetevisRB27B): VENDOR = "Retevis" MODEL = "RB27" DUPLEXES = ['', '-', '+', 'off'] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(136000000, 174000000), (400000000, 520000000)] ODD_SPLIT = False _upper = 99 _gmrs = False # sold as GMRS radio but supports full band TX/RX _frs = _murs = _pmr = False def process_mmap(self): mem_format = MEM_FORMAT + MEM_FM_U_FORMAT + MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) @directory.register class RetevisRB27V(RetevisRB27B): VENDOR = "Retevis" MODEL = "RB27V" VALID_BANDS = [(136000000, 174000000)] _upper = 5 _murs = True _frs = _gmrs = _pmr = False def process_mmap(self): mem_format = MEM_FORMAT + MEM_FM_U_FORMAT + MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) @directory.register class RetevisRB627B(RetevisRB27B): VENDOR = "Retevis" MODEL = "RB627B" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=0.50), chirp_common.PowerLevel("Low", watts=0.50)] _upper = 16 _pmr = True _frs = _gmrs = _murs = False @directory.register class FRSA1Radio(BFT8Radio): """BTECH FRS-A1""" VENDOR = "BTECH" MODEL = "FRS-A1" ODD_SPLIT = False HAS_NAMES = True NAME_LENGTH = 6 SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) DUPLEXES = ['', '-', '+', 'off'] _fingerprint = b"BF-T8A" + b"\x2E" _upper = 22 _frs = _upper == 22 _ranges = [ (0x0000, 0x0640), (0x0D00, 0x0DC0), ] _memsize = 0x0DC0 def get_features(self): rf = BFT8Radio.get_features(self) rf.valid_name_length = 6 rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-" return rf chirp-20240224/chirp/drivers/retevis_rt1.py0000644000175000017500000005716414566340166017470 0ustar hibbyhibby# Copyright 2016 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 bcl:1, // Busy Lock epilogue:1, // Epilogue (STE) scramble:1, // Scramble compander:1, // Compander skip:1, // Scan Add wide:1, // Bandwidth unknown1:1, highpower:1; // Power Level u8 unknown2[3]; } memory[16]; #seekto 0x0120; struct { u8 hivoltnotx:1, // TX Inhibit when voltage too high lovoltnotx:1, // TX Inhibit when voltage too low unknown1:1, alarm:1, // Incept Alarm scan:1, // Scan tone:1, // Tone voice:2; // Voice u8 unknown2:1, ssave:3, // Super Battery Save unknown3:1, save:3; // Battery Save u8 squelch; // Squelch u8 tot; // Time Out Timer u8 voxi:1, // VOX Inhibit on Receive voxd:2, // VOX Delay voxc:1, // VOX Control voxg:4; // VOX Gain u8 unknown4:4, scanspeed:4; // Scan Speed u8 unknown5:3, scandelay:5; // Scan Delay u8 unknown6:3, prioritych:5; // Priority Channel u8 k1shortp; // Key 1 Short Press u8 k2shortp; // Key 2 Short Press u8 k1longp; // Key 1 Long Press u8 k2longp; // Key 2 Long Press u8 lpt; // Long Press Time u8 unknown7:6, txtone:2; // TX Tone } settings; #seekto 0x0170; struct { char fp[8]; } fingerprint; """ CMD_ACK = b"\x06" RT1_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5.00), chirp_common.PowerLevel("High", watts=9.00)] RT1_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) LIST_LPT = ["0.5", "1.0", "1.5", "2.0", "2.5"] LIST_SHORT_PRESS = ["Off", "Monitor On/Off", "Power High/Low", "Alarm", "Volt"] LIST_LONG_PRESS = ["Off", "Monitor On/Off", "Monitor(momentary)", "Power High/Low", "Alarm", "Volt", "TX 1750 Hz"] LIST_VOXDELAY = ["0.5", "1.0", "2.0", "3.0"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_TIMEOUTTIMER = ["Off"] + ["%s" % x for x in range(30, 330, 30)] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SSAVE = ["Off"] + ["%s" % x for x in range(1, 7)] LIST_PRIORITYCH = ["Off"] + ["%s" % x for x in range(1, 17)] LIST_SCANSPEED = ["%s" % x for x in range(100, 550, 50)] LIST_SCANDELAY = ["%s" % x for x in range(3, 31)] LIST_TXTONE = ["Off", "BOT", "EOT", "Both"] # Retevis RT1 fingerprints RT1_VHF_fp = b"PXT8K" + b"\xF0\x00\x00" # RT1 VHF model RT1_UHF_fp = b"PXT8K" + b"\xF3\x00\x00" # RT1 UHF model MODELS = [RT1_VHF_fp, RT1_UHF_fp] def _model_from_data(data): return data[0x0170:0x0178] def _model_from_image(radio): return _model_from_data(radio.get_mmap()) def _get_radio_model(radio): block = _rt1_read_block(radio, 0x0170, 0x10) version = block[0:8] return version def _rt1_enter_programming_mode(radio): serial = radio.pipe magic = [b"PROGRAMa", b"PROGRAMb"] for i in range(0, 2): try: LOG.debug("sending " + magic[i].decode()) serial.write(magic[i]) ack = serial.read(1) except: _rt1_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if not ack: _rt1_exit_programming_mode(radio) raise errors.RadioError("No response from radio") elif ack != CMD_ACK: LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ack)) _rt1_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") try: LOG.debug("sending " + util.hexprint("\x02")) serial.write(b"\x02") ident = serial.read(16) except: _rt1_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if not ident.startswith(b"PXT8K"): LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ident)) _rt1_exit_programming_mode(radio) LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: LOG.debug("sending " + util.hexprint("MXT8KCUMHS1X7BN/")) serial.write(b"MXT8KCUMHS1X7BN/") ack = serial.read(1) except: _rt1_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != b"\xB2": LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ack)) _rt1_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") try: LOG.debug("sending " + util.hexprint(CMD_ACK)) serial.write(CMD_ACK) ack = serial.read(1) except: _rt1_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ack)) _rt1_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") # DEBUG LOG.info("Positive ident, this is a %s %s" % (radio.VENDOR, radio.MODEL)) def _rt1_exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _rt1_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: _rt1_exit_programming_mode(radio) raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] serial.write(CMD_ACK) ack = serial.read(1) except: _rt1_exit_programming_mode(radio) raise errors.RadioError("Failed to read block at %04x" % block_addr) if ack != CMD_ACK: _rt1_exit_programming_mode(radio) raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _rt1_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: _rt1_exit_programming_mode(radio) raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _rt1_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio._block_size): status.cur = addr + radio._block_size radio.status_fn(status) block = _rt1_read_block(radio, addr, radio._block_size) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _rt1_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _rt1_enter_programming_mode(radio) image_model = _model_from_image(radio) LOG.info("Image Version is %s" % repr(image_model)) radio_model = _get_radio_model(radio) LOG.info("Radio Version is %s" % repr(radio_model)) bands = ["VHF", "UHF"] image_band = radio_band = "unknown" for i in range(0, 2): if image_model == MODELS[i]: image_band = bands[i] if radio_model == MODELS[i]: radio_band = bands[i] if image_model != radio_model: _rt1_exit_programming_mode(radio) msg = ("The upload was stopped because the band supported by " "the image (%s) does not match the band supported by " "the radio (%s).") raise errors.RadioError(msg % (image_band, radio_band)) status.cur = 0 status.max = 0x0190 for start_addr, end_addr, block_size in radio._ranges: for addr in range(start_addr, end_addr, block_size): status.cur = addr + block_size radio.status_fn(status) _rt1_write_block(radio, addr, block_size) _rt1_exit_programming_mode(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0x0170:0x0176] return rid.startswith(b"PXT8K") @directory.register class RT1Radio(chirp_common.CloneModeRadio): """Retevis RT1""" VENDOR = "Retevis" MODEL = "RT1" BAUD_RATE = 2400 NEEDS_COMPAT_SERIAL = False _ranges = [ (0x0000, 0x0190, 0x10), ] _memsize = 0x0400 _block_size = 0x10 _vhf_range = (134000000, 175000000) _uhf_range = (400000000, 521000000) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = RT1_POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["NFM", "FM"] # 12.5 kHz, 25 kHz. rf.valid_dtcs_codes = RT1_DTCS rf.memory_bounds = (1, 16) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] if self._mmap is None: rf.valid_bands = [self._vhf_range, self._uhf_range] elif self._my_band() == RT1_VHF_fp: rf.valid_bands = [self._vhf_range] elif self._my_band() == RT1_UHF_fp: rf.valid_bands = [self._uhf_range] return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): self._mmap = do_download(self) self.process_mmap() def sync_out(self): do_upload(self) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def _my_band(self): model_tag = _model_from_image(self) return model_tag def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = _mem.wide and "FM" or "NFM" rxtone = txtone = None txtone = self.decode_tone(_mem.txtone) rxtone = self.decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) mem.power = RT1_POWER_LEVELS[_mem.highpower] if _mem.skip: mem.skip = "S" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(not _mem.bcl)) mem.extra.append(rs) rs = RadioSetting("epilogue", "Epilogue(STE)", RadioSettingValueBoolean(not _mem.epilogue)) mem.extra.append(rs) rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(not _mem.compander)) mem.extra.append(rs) rs = RadioSetting("scramble", "Scramble", RadioSettingValueBoolean(not _mem.scramble)) mem.extra.append(rs) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) return _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq.fill_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.wide = mem.mode == "FM" ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_mem.txtone, txmode, txtone, txpol) self.encode_tone(_mem.rxtone, rxmode, rxtone, rxpol) _mem.highpower = mem.power == RT1_POWER_LEVELS[1] _mem.skip = mem.skip == "S" for setting in mem.extra: setattr(_mem, setting.get_name(), not int(setting.value)) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) rs = RadioSetting("lpt", "Long Press Time[s]", RadioSettingValueList( LIST_LPT, LIST_LPT[_settings.lpt])) basic.append(rs) if _settings.k1shortp > 4: val = 1 else: val = _settings.k1shortp rs = RadioSetting("k1shortp", "Key 1 Short Press", RadioSettingValueList( LIST_SHORT_PRESS, LIST_SHORT_PRESS[val])) basic.append(rs) if _settings.k1longp > 6: val = 3 else: val = _settings.k1longp rs = RadioSetting("k1longp", "Key 1 Long Press", RadioSettingValueList( LIST_LONG_PRESS, LIST_LONG_PRESS[val])) basic.append(rs) if _settings.k2shortp > 4: val = 4 else: val = _settings.k2shortp rs = RadioSetting("k2shortp", "Key 2 Short Press", RadioSettingValueList( LIST_SHORT_PRESS, LIST_SHORT_PRESS[val])) basic.append(rs) if _settings.k2longp > 6: val = 4 else: val = _settings.k2longp rs = RadioSetting("k2longp", "Key 2 Long Press", RadioSettingValueList( LIST_LONG_PRESS, LIST_LONG_PRESS[val])) basic.append(rs) rs = RadioSetting("voxc", "VOX Control", RadioSettingValueBoolean(not _settings.voxc)) basic.append(rs) if _settings.voxg > 8: val = 4 else: val = _settings.voxg + 1 rs = RadioSetting("voxg", "VOX Gain", RadioSettingValueInteger(1, 9, val)) basic.append(rs) rs = RadioSetting("voxd", "VOX Delay Time", RadioSettingValueList( LIST_VOXDELAY, LIST_VOXDELAY[_settings.voxd])) basic.append(rs) rs = RadioSetting("voxi", "VOX Inhibit on Receive", RadioSettingValueBoolean(not _settings.voxi)) basic.append(rs) if _settings.squelch > 8: val = 4 else: val = _settings.squelch rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, val)) basic.append(rs) if _settings.voice == 3: val = 1 else: val = _settings.voice rs = RadioSetting("voice", "Voice Prompts", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("tone", "Tone", RadioSettingValueBoolean(_settings.tone)) basic.append(rs) rs = RadioSetting("lovoltnotx", "TX Inhibit (when battery < 6 volts)", RadioSettingValueBoolean(_settings.lovoltnotx)) basic.append(rs) rs = RadioSetting("hivoltnotx", "TX Inhibit (when battery > 9 volts)", RadioSettingValueBoolean(_settings.hivoltnotx)) basic.append(rs) if _settings.tot > 10: val = 6 else: val = _settings.tot rs = RadioSetting("tot", "Time-out Timer[s]", RadioSettingValueList( LIST_TIMEOUTTIMER, LIST_TIMEOUTTIMER[val])) basic.append(rs) if _settings.save < 3: val = 0 else: val = _settings.save - 3 rs = RadioSetting("save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) rs = RadioSetting("ssave", "Super Battery Saver[s]", RadioSettingValueList( LIST_SSAVE, LIST_SSAVE[_settings.ssave])) basic.append(rs) rs = RadioSetting("alarm", "Incept Alarm", RadioSettingValueBoolean(_settings.alarm)) basic.append(rs) rs = RadioSetting("scan", "Scan Function", RadioSettingValueBoolean(_settings.scan)) basic.append(rs) if _settings.prioritych > 15: val = 0 else: val = _settings.prioritych + 1 rs = RadioSetting("prioritych", "Priority Channel", RadioSettingValueList( LIST_PRIORITYCH, LIST_PRIORITYCH[val])) basic.append(rs) if _settings.scanspeed > 8: val = 4 else: val = _settings.scanspeed rs = RadioSetting("scanspeed", "Scan Speed[ms]", RadioSettingValueList( LIST_SCANSPEED, LIST_SCANSPEED[val])) basic.append(rs) if _settings.scandelay > 27: val = 12 else: val = _settings.scandelay rs = RadioSetting("scandelay", "Scan Droupout Delay Time[s]", RadioSettingValueList( LIST_SCANDELAY, LIST_SCANDELAY[val])) basic.append(rs) rs = RadioSetting("txtone", "Tx Tone", RadioSettingValueList( LIST_TXTONE, LIST_TXTONE[_settings.txtone])) basic.append(rs) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if setting == "voxc": setattr(obj, setting, not int(element.value)) elif setting == "voxg": setattr(obj, setting, int(element.value) - 1) elif setting == "voxi": setattr(obj, setting, not int(element.value)) elif setting == "voice": if int(element.value) == 2: setattr(obj, setting, int(element.value) + 1) else: setattr(obj, setting, int(element.value)) elif setting == "save": setattr(obj, setting, int(element.value) + 3) elif setting == "prioritych": if int(element.value) == 0: setattr(obj, setting, int(element.value) + 31) else: setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) in [0x0400, ]: match_size = True # testing the model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/thuv1f.py0000644000175000017500000003536214522657251016430 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, errors, util, directory, memmap from chirp import bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) def uvf1_identify(radio): """Do identify handshake with TYT TH-UVF1""" radio.pipe.write(b"PROG333") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio did not respond") radio.pipe.write(b"\x02") ident = radio.pipe.read(16) LOG.info("Ident:\n%s" % util.hexprint(ident)) radio.pipe.write(b"\x06") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio did not ack identification") return ident def uvf1_download(radio): """Download from TYT TH-UVF1""" data = uvf1_identify(radio) for i in range(0, 0x1000, 0x10): msg = struct.pack(">cHB", b"R", i, 0x10) radio.pipe.write(msg) block = radio.pipe.read(0x10 + 4) if len(block) != (0x10 + 4): raise errors.RadioError("Radio sent a short block") radio.pipe.write(b"\x06") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio NAKed block") data += block[4:] status = chirp_common.Status() status.cur = i status.max = 0x1000 status.msg = "Cloning from radio" radio.status_fn(status) radio.pipe.write(b"\x45") return memmap.MemoryMapBytes(data) def uvf1_upload(radio): """Upload to TYT TH-UVF1""" data = uvf1_identify(radio) radio.pipe.timeout = 1 if data != radio._mmap[0:16]: raise errors.RadioError("Unable to talk to this model") for i in range(0, 0x1000, 0x10): addr = i + 0x10 msg = struct.pack(">cHB", b"W", i, 0x10) msg += radio._mmap[addr:addr+0x10] radio.pipe.write(msg) ack = radio.pipe.read(1) if ack != b"\x06": LOG.debug(repr(ack)) raise errors.RadioError("Radio did not ack block %i" % i) status = chirp_common.Status() status.cur = i status.max = 0x1000 status.msg = "Cloning to radio" radio.status_fn(status) # End of clone? radio.pipe.write(b"\x45") THUV1F_MEM_FORMAT = """ struct mem { bbcd rx_freq[4]; bbcd tx_freq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 unknown1:1, pttid:2, unknown2:2, ishighpower:1, unknown3:2; u8 unknown4:4, isnarrow:1, vox:1, bcl:2; u8 unknown5:1, scan:1, unknown6:3, scramble_code:3; u8 unknown7; }; struct name { char name[7]; }; #seekto 0x0020; struct mem memory[128]; #seekto 0x0840; struct { u8 scans:2, autolk:1, unknown1:5; u8 light:2, unknown6:2, disnm:1, voice:1, beep:1, rxsave:1; u8 led:2, unknown5:3, ani:1, roger:1, dw:1; u8 opnmsg:2, unknown4:1, dwait:1, unknown9:4; u8 squelch; u8 unknown2:4, tot:4; u8 unknown3:4, vox_level:4; u8 pad[10]; char ponmsg[6]; } settings; #seekto 0x08D0; struct name names[128]; """ LED_LIST = ["Off", "On", "Auto"] LIGHT_LIST = ["Purple", "Orange", "Blue"] VOX_LIST = ["1", "2", "3", "4", "5", "6", "7", "8"] TOT_LIST = ["Off", "30s", "60s", "90s", "120s", "150s", "180s", "210s", "240s", "270s"] SCANS_LIST = ["Time", "Carry", "Seek"] OPNMSG_LIST = ["Off", "DC", "Message"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5), chirp_common.PowerLevel("Low", watts=1), ] PTTID_LIST = ["Off", "BOT", "EOT", "Both"] BCL_LIST = ["Off", "CSQ", "QT/DQT"] CODES_LIST = [x for x in range(1, 9)] STEPS = [5.0, 6.25, 7.5, 10.0, 12.5, 25.0, 37.5, 50.0, 100.0] @directory.register class TYTTHUVF1Radio(chirp_common.CloneModeRadio): """TYT TH-UVF1""" VENDOR = "TYT" MODEL = "TH-UVF1" NEEDS_COMPAT_SERIAL = False def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 128) rf.has_bank = False rf.has_ctone = True rf.has_tuning_step = False rf.has_cross = True rf.has_rx_dtcs = True rf.has_settings = True rf.can_odd_split = True rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-" rf.valid_bands = [(136000000, 174000000), (420000000, 470000000)] rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS rf.valid_modes = ["FM", "NFM"] rf.valid_tuning_steps = STEPS rf.valid_name_length = 7 rf.valid_cross_modes = ["Tone->Tone", "DTCS->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->"] return rf def sync_in(self): try: self._mmap = uvf1_download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: uvf1_upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) @classmethod def match_model(cls, filedata, filename): # TYT TH-UVF1 original if filedata.startswith(b"\x13\x60\x17\x40\x40\x00\x48\x00" + b"\x35\x00\x39\x00\x47\x00\x52\x00"): return True # TYT TH-UVF1 V2 elif filedata.startswith(b"\x14\x40\x14\x80\x43\x00\x45\x00" + b"\x13\x60\x17\x40\x40\x00\x47\x00"): return True else: return False def process_mmap(self): self._memobj = bitwise.parse(THUV1F_MEM_FORMAT, self._mmap) def _decode_tone(self, toneval): pol = "N" rawval = (toneval[1].get_bits(0xFF) << 8) | toneval[0].get_bits(0xFF) if toneval[0].get_bits(0xFF) == 0xFF: mode = "" val = 0 elif toneval[1].get_bits(0xC0) == 0xC0: mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) pol = "R" elif toneval[1].get_bits(0x80): mode = "DTCS" val = int("%x" % (rawval & 0x3FFF)) else: mode = "Tone" val = int(toneval) / 10.0 return mode, val, pol def _encode_tone(self, _toneval, mode, val, pol): toneval = 0 if mode == "Tone": toneval = int("%i" % (val * 10), 16) elif mode == "DTCS": toneval = int("%i" % val, 16) toneval |= 0x8000 if pol == "R": toneval |= 0x4000 else: toneval = 0xFFFF _toneval[0].set_raw(toneval & 0xFF) _toneval[1].set_raw((toneval >> 8) & 0xFF) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _is_txinh(self, _mem): raw_tx = "" for i in range(0, 4): raw_tx += _mem.tx_freq[i].get_raw(asbytes=False) return raw_tx == "\xFF\xFF\xFF\xFF" def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False).startswith("\xFF\xFF\xFF\xFF"): mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 txfreq = int(_mem.tx_freq) * 10 if self._is_txinh(_mem): mem.duplex = "off" mem.offset = 0 elif txfreq == mem.freq: mem.duplex = "" elif abs(txfreq - mem.freq) > 70000000: mem.duplex = "split" mem.offset = txfreq elif txfreq < mem.freq: mem.duplex = "-" mem.offset = mem.freq - txfreq elif txfreq > mem.freq: mem.duplex = "+" mem.offset = txfreq - mem.freq txmode, txval, txpol = self._decode_tone(_mem.tx_tone) rxmode, rxval, rxpol = self._decode_tone(_mem.rx_tone) chirp_common.split_tone_decode( mem, (txmode, txval, txpol), (rxmode, rxval, rxpol)) mem.name = str(self._memobj.names[number - 1].name) mem.name = mem.name.replace("\xFF", " ").rstrip() mem.skip = not _mem.scan and "S" or "" mem.mode = _mem.isnarrow and "NFM" or "FM" mem.power = POWER_LEVELS[1 - _mem.ishighpower] mem.extra = RadioSettingGroup("extra", "Extra Settings") rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueBoolean(_mem.vox)) mem.extra.append(rs) rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueList(BCL_LIST, BCL_LIST[_mem.bcl])) mem.extra.append(rs) rs = RadioSetting("scramble_code", "Scramble Code", RadioSettingValueList( CODES_LIST, CODES_LIST[_mem.scramble_code])) mem.extra.append(rs) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw(b"\xFF" * 16) return if _mem.get_raw(asbytes=False) == ("\xFF" * 16): LOG.debug("Initializing empty memory") _mem.set_raw(b"\x00" * 16) _mem.rx_freq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.tx_freq[i].set_raw(b"\xFF") elif mem.duplex == "split": _mem.tx_freq = mem.offset / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 else: _mem.tx_freq = mem.freq / 10 (txmode, txval, txpol), (rxmode, rxval, rxpol) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.tx_tone, txmode, txval, txpol) self._encode_tone(_mem.rx_tone, rxmode, rxval, rxpol) self._memobj.names[mem.number - 1].name = mem.name.ljust(7, "\xFF") _mem.scan = mem.skip == "" _mem.isnarrow = mem.mode == "NFM" _mem.ishighpower = mem.power == POWER_LEVELS[0] for element in mem.extra: setattr(_mem, element.get_name(), element.value) def get_settings(self): _settings = self._memobj.settings group = RadioSettingGroup("basic", "Basic") top = RadioSettings(group) group.append( RadioSetting("led", "LED Mode", RadioSettingValueList(LED_LIST, LED_LIST[_settings.led]))) group.append( RadioSetting("light", "Light Color", RadioSettingValueList(LIGHT_LIST, LIGHT_LIST[_settings.light]))) group.append( RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch))) group.append( RadioSetting("vox_level", "VOX Level", RadioSettingValueList(VOX_LIST, VOX_LIST[_settings.vox_level]))) group.append( RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep))) group.append( RadioSetting("ani", "ANI", RadioSettingValueBoolean(_settings.ani))) group.append( RadioSetting("dwait", "D.WAIT", RadioSettingValueBoolean(_settings.dwait))) group.append( RadioSetting("tot", "Timeout Timer", RadioSettingValueList(TOT_LIST, TOT_LIST[_settings.tot]))) group.append( RadioSetting("roger", "Roger Beep", RadioSettingValueBoolean(_settings.roger))) group.append( RadioSetting("dw", "Dual Watch", RadioSettingValueBoolean(_settings.dw))) group.append( RadioSetting("rxsave", "RX Save", RadioSettingValueBoolean(_settings.rxsave))) group.append( RadioSetting("scans", "Scans", RadioSettingValueList(SCANS_LIST, SCANS_LIST[_settings.scans]))) group.append( RadioSetting("autolk", "Auto Lock", RadioSettingValueBoolean(_settings.autolk))) group.append( RadioSetting("voice", "Voice", RadioSettingValueBoolean(_settings.voice))) group.append( RadioSetting("opnmsg", "Opening Message", RadioSettingValueList(OPNMSG_LIST, OPNMSG_LIST[_settings.opnmsg]))) group.append( RadioSetting("disnm", "Display Name", RadioSettingValueBoolean(_settings.disnm))) def _filter(name): LOG.debug(repr(str(name))) return str(name).rstrip("\xFF").rstrip() group.append( RadioSetting("ponmsg", "Power-On Message", RadioSettingValueString(0, 6, _filter(_settings.ponmsg)))) return top def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue setattr(_settings, element.get_name(), element.value) chirp-20240224/chirp/drivers/id800.py0000644000175000017500000002607014476041037016030 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, errors, directory, bitwise MEM_FORMAT = """ #seekto 0x0020; struct { u24 freq; u16 offset; u8 power:2, rtone:6; u8 duplex:2, ctone:6; u8 dtcs; u8 tuning_step:4, unknown1:4; u8 unknown2; u8 mult_flag:1, unknown3:5, tmode:2; u16 dtcs_polarity:2, usealpha:1, empty:1, name1:6, name2:6; u24 name3:6, name4:6, name5:6, name6:6; u8 unknown5; u8 unknown6:1, digital_code:7; u8 urcall; u8 rpt1call; u8 rpt2call; u8 unknown7:1, mode:3, unknown8:4; } memory[512]; #seekto 0x2BF4; struct { u8 unknown1:1, empty:1, pskip:1, skip:1, bank:4; } flags[512]; #seekto 0x3220; struct { char call[8]; } mycalls[8]; #seekto 0x3250; struct { char call[8]; } urcalls[99]; #seekto 0x3570; struct { char call[8]; } rptcalls[59]; """ MODES = ["FM", "NFM", "AM", "NAM", "DV", "FM", "FM", "FM"] TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "", "-", "+"] DTCS_POL = ["NN", "NR", "RN", "RR"] STEPS = [5.0, 10.0, 12.5, 15, 20.0, 25.0, 30.0, 50.0, 100.0, 200.0, 6.25] POWER_LEVELS = [chirp_common.PowerLevel('High', watts=50), chirp_common.PowerLevel('Low', watts=5), chirp_common.PowerLevel('Mid', watts=15)] ID800_SPECIAL = { "C2": 510, "C1": 511, } ID800_SPECIAL_REV = { 510: "C2", 511: "C1", } for i in range(0, 5): idA = "%iA" % (i + 1) idB = "%iB" % (i + 1) num = 500 + i * 2 ID800_SPECIAL[idA] = num ID800_SPECIAL[idB] = num + 1 ID800_SPECIAL_REV[num] = idA ID800_SPECIAL_REV[num+1] = idB ALPHA_CHARSET = " ABCDEFGHIJKLMNOPQRSTUVWXYZ" NUMERIC_CHARSET = "0123456789+-=*/()|" def get_name(_mem): """Decode the name from @_mem""" def _get_char(val): if val == 0: return " " elif val & 0x20: return ALPHA_CHARSET[val & 0x1F] else: return NUMERIC_CHARSET[val & 0x0F] name_bytes = [_mem.name1, _mem.name2, _mem.name3, _mem.name4, _mem.name5, _mem.name6] name = "" for val in name_bytes: name += _get_char(val) return name.rstrip() def set_name(_mem, name): """Encode @name in @_mem""" def _get_index(char): if char == " ": return 0 elif char.isalpha(): return ALPHA_CHARSET.index(char) | 0x20 else: return NUMERIC_CHARSET.index(char) | 0x10 name = name.ljust(6)[:6] _mem.usealpha = bool(name.strip()) # The element override calling convention makes this harder to automate. # It's just six, so do it manually _mem.name1 = _get_index(name[0]) _mem.name2 = _get_index(name[1]) _mem.name3 = _get_index(name[2]) _mem.name4 = _get_index(name[3]) _mem.name5 = _get_index(name[4]) _mem.name6 = _get_index(name[5]) @directory.register class ID800v2Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): """Icom ID800""" VENDOR = "Icom" MODEL = "ID-800H" VARIANT = "v2" _model = "\x27\x88\x02\x00" _memsize = 14528 _endframe = "Icom Inc\x2eCB" _can_hispeed = True _memories = [] _ranges = [(0x0020, 0x2B18, 32), (0x2B18, 0x2B20, 8), (0x2B20, 0x2BE0, 32), (0x2BE0, 0x2BF4, 20), (0x2BF4, 0x2C00, 12), (0x2C00, 0x2DE0, 32), (0x2DE0, 0x2DF4, 20), (0x2DF4, 0x2E00, 12), (0x2E00, 0x2E20, 32), (0x2F00, 0x3070, 32), (0x30D0, 0x30E0, 16), (0x30E0, 0x3160, 32), (0x3160, 0x3180, 16), (0x3180, 0x31A0, 32), (0x31A0, 0x31B0, 16), (0x3220, 0x3240, 32), (0x3240, 0x3260, 16), (0x3260, 0x3560, 32), (0x3560, 0x3580, 16), (0x3580, 0x3720, 32), (0x3720, 0x3780, 8), (0x3798, 0x37A0, 8), (0x37A0, 0x37B0, 16), (0x37B0, 0x37B1, 1), (0x37D8, 0x37E0, 8), (0x37E0, 0x3898, 32), (0x3898, 0x389A, 2), (0x38A8, 0x38C0, 16), ] MYCALL_LIMIT = (1, 7) URCALL_LIMIT = (1, 99) RPTCALL_LIMIT = (1, 59) def _get_bank(self, loc): _flg = self._memobj.flags[loc-1] if _flg.bank >= 0x0A: return None else: return _flg.bank def _set_bank(self, loc, bank): _flg = self._memobj.flags[loc-1] if bank is None: _flg.bank = 0x0A else: _flg.bank = bank def get_features(self): rf = chirp_common.RadioFeatures() rf.has_implicit_calls = True rf.has_settings = True rf.has_bank = True rf.valid_modes = [x for x in MODES if x] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_duplexes = ["", "-", "+"] rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(118000000, 173995000), (230000000, 549995000), (810000000, 999990000)] rf.valid_skips = ["", "S", "P"] rf.valid_name_length = 6 rf.valid_special_chans = sorted(ID800_SPECIAL.keys()) rf.valid_power_levels = list(POWER_LEVELS) rf.memory_bounds = (1, 499) return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_memory(self, number): if isinstance(number, str): try: number = ID800_SPECIAL[number] + 1 # Because we subtract below except KeyError: raise errors.InvalidMemoryLocation("Unknown channel %s" % number) _mem = self._memobj.memory[number-1] _flg = self._memobj.flags[number-1] if MODES[_mem.mode] == "DV": urcalls = self.get_urcall_list() rptcalls = self.get_repeater_call_list() mem = chirp_common.DVMemory() mem.dv_urcall = urcalls[_mem.urcall] mem.dv_rpt1call = rptcalls[_mem.rpt1call] mem.dv_rpt2call = rptcalls[_mem.rpt2call] mem.dv_code = _mem.digital_code else: mem = chirp_common.Memory() mem.number = number if _flg.empty: mem.empty = True return mem mult = _mem.mult_flag and 6250 or 5000 mem.freq = _mem.freq * mult mem.offset = _mem.offset * 5000 mem.duplex = DUPLEX[_mem.duplex] mem.mode = MODES[_mem.mode] mem.tmode = TMODES[_mem.tmode] mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POL[_mem.dtcs_polarity] mem.tuning_step = STEPS[_mem.tuning_step] mem.name = get_name(_mem) mem.power = POWER_LEVELS[_mem.power] mem.skip = _flg.pskip and "P" or _flg.skip and "S" or "" return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] _flg = self._memobj.flags[mem.number-1] _flg.empty = mem.empty if mem.empty: self._set_bank(mem.number, None) return mult = chirp_common.is_fractional_step(mem.freq) and 6250 or 5000 _mem.mult_flag = mult == 6250 _mem.freq = mem.freq / mult _mem.offset = mem.offset / 5000 _mem.duplex = DUPLEX.index(mem.duplex) _mem.mode = MODES.index(mem.mode) _mem.tmode = TMODES.index(mem.tmode) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = DTCS_POL.index(mem.dtcs_polarity) _mem.tuning_step = STEPS.index(mem.tuning_step) if mem.power in POWER_LEVELS: _mem.power = POWER_LEVELS.index(mem.power) set_name(_mem, mem.name) _flg.pskip = mem.skip == "P" _flg.skip = mem.skip == "S" if mem.mode == "DV": urcalls = self.get_urcall_list() rptcalls = self.get_repeater_call_list() if not isinstance(mem, chirp_common.DVMemory): raise errors.InvalidDataError("DV mode is not a DVMemory!") try: err = mem.dv_urcall _mem.urcall = urcalls.index(mem.dv_urcall) err = mem.dv_rpt1call _mem.rpt1call = rptcalls.index(mem.dv_rpt1call) err = mem.dv_rpt2call _mem.rpt2call = rptcalls.index(mem.dv_rpt2call) except IndexError: raise errors.InvalidDataError("DV Call %s not in list" % err) else: _mem.urcall = 0 _mem.rpt1call = 0 _mem.rpt2call = 0 def sync_in(self): icf.IcomCloneModeRadio.sync_in(self) self.process_mmap() def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def get_urcall_list(self): calls = ["CQCQCQ"] for i in range(*self.URCALL_LIMIT): calls.append(str(self._memobj.urcalls[i-1].call).rstrip()) return calls def get_repeater_call_list(self): calls = ["*NOTUSE*"] for i in range(*self.RPTCALL_LIMIT): calls.append(str(self._memobj.rptcalls[i-1].call).rstrip()) return calls def get_mycall_list(self): calls = [] for i in range(*self.MYCALL_LIMIT): calls.append(str(self._memobj.mycalls[i-1].call).rstrip()) return calls def set_urcall_list(self, calls): for i in range(*self.URCALL_LIMIT): try: call = calls[i].upper() # Skip the implicit CQCQCQ except IndexError: call = " " * 8 self._memobj.urcalls[i-1].call = call.ljust(8)[:8] def set_repeater_call_list(self, calls): for i in range(*self.RPTCALL_LIMIT): try: call = calls[i].upper() # Skip the implicit blank except IndexError: call = " " * 8 self._memobj.rptcalls[i-1].call = call.ljust(8)[:8] def set_mycall_list(self, calls): for i in range(*self.MYCALL_LIMIT): try: call = calls[i-1].upper() except IndexError: call = " " * 8 self._memobj.mycalls[i-1].call = call.ljust(8)[:8] chirp-20240224/chirp/drivers/ft817.py0000644000175000017500000013615014466370044016060 0ustar hibbyhibby# # Copyright 2012 Filippi Marco # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """FT817 - FT817ND - FT817ND/US management module""" from builtins import bytes from chirp.drivers import yaesu_clone from chirp import chirp_common, util, memmap, errors, directory, bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings import time import logging LOG = logging.getLogger(__name__) CMD_ACK = 0x06 @directory.register class FT817Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT-817""" BAUD_RATE = 9600 MODEL = "FT-817" NEEDS_COMPAT_SERIAL = False _model = "" _US_model = False DUPLEX = ["", "-", "+", "split"] # narrow modes has to be at end MODES = ["LSB", "USB", "CW", "CWR", "AM", "FM", "DIG", "PKT", "NCW", "NCWR", "NFM"] TMODES = ["", "Tone", "TSQL", "DTCS"] STEPSFM = [5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0] STEPSAM = [2.5, 5.0, 9.0, 10.0, 12.5, 25.0] STEPSSSB = [1.0, 2.5, 5.0] # warning ranges has to be in this exact order VALID_BANDS = [(100000, 33000000), (33000000, 56000000), (76000000, 108000000), (108000000, 137000000), (137000000, 154000000), (420000000, 470000000)] CHARSET = list(chirp_common.CHARSET_ASCII) CHARSET.remove("\\") _memsize = 6509 # block 9 (130 Bytes long) is to be repeated 40 times _block_lengths = [2, 40, 208, 182, 208, 182, 198, 53, 130, 118, 118] MEM_FORMAT = """ struct mem_struct { u8 tag_on_off:1, tag_default:1, unknown1:3, mode:3; u8 duplex:2, is_duplex:1, is_cwdig_narrow:1, is_fm_narrow:1, freq_range:3; u8 skip:1, unknown2:1, ipo:1, att:1, unknown3:4; u8 ssb_step:2, am_step:3, fm_step:3; u8 unknown4:6, tmode:2; u8 unknown5:2, tx_mode:3, tx_freq_range:3; u8 unknown6:1, unknown_toneflag:1, tone:6; u8 unknown7:1, dcs:7; ul16 rit; u32 freq; u32 offset; u8 name[8]; }; #seekto 0x4; struct { u8 fst:1, lock:1, nb:1, pbt:1, unknownb:1, dsp:1, agc:2; u8 vox:1, vlt:1, bk:1, kyr:1, unknown5:1, cw_paddle:1, pwr_meter_mode:2; u8 vfob_band_select:4, vfoa_band_select:4; u8 unknowna; u8 backlight:2, color:2, contrast:4; u8 beep_freq:1, beep_volume:7; u8 arts_beep:2, main_step:1, cw_id:1, scope:1, pkt_rate:1, resume_scan:2; u8 op_filter:2, lock_mode:2, cw_pitch:4; u8 sql_rf_gain:1, ars_144:1, ars_430:1, cw_weight:5; u8 cw_delay; u8 unknown8:1, sidetone:7; u8 batt_chg:2, cw_speed:6; u8 disable_amfm_dial:1, vox_gain:7; u8 cat_rate:2, emergency:1, vox_delay:5; u8 dig_mode:3, mem_group:1, unknown9:1, apo_time:3; u8 dcs_inv:2, unknown10:1, tot_time:5; u8 mic_scan:1, ssb_mic:7; u8 mic_key:1, am_mic:7; u8 unknown11:1, fm_mic:7; u8 unknown12:1, dig_mic:7; u8 extended_menu:1, pkt_mic:7; u8 unknown14:1, pkt9600_mic:7; il16 dig_shift; il16 dig_disp; i8 r_lsb_car; i8 r_usb_car; i8 t_lsb_car; i8 t_usb_car; u8 unknown15:2, menu_item:6; u8 unknown16:4, menu_sel:4; u16 unknown17; u8 art:1, scn_mode:2, dw:1, pri:1, unknown18:1, tx_power:2; u8 spl:1, unknown:1, uhf_antenna:1, vhf_antenna:1, air_antenna:1, bc_antenna:1, sixm_antenna:1, hf_antenna:1; } settings; #seekto 0x2A; struct mem_struct vfoa[15]; struct mem_struct vfob[15]; struct mem_struct home[4]; struct mem_struct qmb; struct mem_struct mtqmb; struct mem_struct mtune; #seekto 0x3FD; u8 visible[25]; u8 pmsvisible; #seekto 0x417; u8 filled[25]; u8 pmsfilled; #seekto 0x431; struct mem_struct memory[200]; struct mem_struct pms[2]; #seekto 0x18cf; u8 callsign[7]; #seekto 0x1979; struct mem_struct sixtymeterchannels[5]; """ _CALLSIGN_CHARSET = [chr(x) for x in list(range(ord("0"), ord("9") + 1)) + list(range(ord("A"), ord("Z") + 1)) + [ord(" ")]] _CALLSIGN_CHARSET_REV = dict( list(zip(_CALLSIGN_CHARSET, list(range(0, len(_CALLSIGN_CHARSET)))))) # WARNING Index are hard wired in memory management code !!! SPECIAL_MEMORIES = { "VFOa-1.8M": -35, "VFOa-3.5M": -34, "VFOa-7M": -33, "VFOa-10M": -32, "VFOa-14M": -31, "VFOa-18M": -30, "VFOa-21M": -29, "VFOa-24M": -28, "VFOa-28M": -27, "VFOa-50M": -26, "VFOa-FM": -25, "VFOa-AIR": -24, "VFOa-144": -23, "VFOa-430": -22, "VFOa-HF": -21, "VFOb-1.8M": -20, "VFOb-3.5M": -19, "VFOb-7M": -18, "VFOb-10M": -17, "VFOb-14M": -16, "VFOb-18M": -15, "VFOb-21M": -14, "VFOb-24M": -13, "VFOb-28M": -12, "VFOb-50M": -11, "VFOb-FM": -10, "VFOb-AIR": -9, "VFOb-144M": -8, "VFOb-430M": -7, "VFOb-HF": -6, "HOME HF": -5, "HOME 50M": -4, "HOME 144M": -3, "HOME 430M": -2, "QMB": -1, } FIRST_VFOB_INDEX = -6 LAST_VFOB_INDEX = -20 FIRST_VFOA_INDEX = -21 LAST_VFOA_INDEX = -35 SPECIAL_PMS = { "PMS-L": -37, "PMS-U": -36, } LAST_PMS_INDEX = -37 SPECIAL_MEMORIES.update(SPECIAL_PMS) SPECIAL_MEMORIES_REV = dict(list(zip(list(SPECIAL_MEMORIES.values()), list(SPECIAL_MEMORIES.keys())))) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to ACC jack.\n" "3. Press and hold in the [MODE <] and [MODE >] keys" " while\n" " turning the radio on (\"CLONE MODE\" will appear on the\n" " display).\n" "4. After clicking OK, press the [A] key to send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to ACC jack.\n" "3. Press and hold in the [MODE <] and [MODE >] keys" " while\n" " turning the radio on (\"CLONE MODE\" will appear on the\n" " display).\n" "4. Press the [C] key (\"RX\" will appear on the LCD).\n") return rp def _read(self, block, blocknum, lastblock): # be very patient at first block if blocknum == 0: attempts = 60 else: attempts = 5 for _i in range(0, attempts): data = self.pipe.read(block + 2) if data: break time.sleep(0.5) if len(data) == block + 2 and data[0] == blocknum: checksum = yaesu_clone.YaesuChecksum(1, block) if checksum.get_existing(data) != \ checksum.get_calculated(data): raise Exception("Checksum Failed [%02X<>%02X] block %02X" % (checksum.get_existing(data), checksum.get_calculated(data), blocknum)) # Chew away the block number and the checksum data = data[1:block + 1] else: if lastblock and self._US_model: raise Exception(_("Unable to read last block. " "This often happens when the selected model " "is US but the radio is a non-US one (or " "widebanded). Please choose the correct " "model and try again.")) else: raise Exception("Unable to read block %02X expected %i got %i" % (blocknum, block + 2, len(data))) LOG.debug("Read %i" % len(data)) return data def _clone_in(self): # Be very patient with the radio self.pipe.timeout = 2 start = time.time() data = bytes(b"") blocks = 0 status = chirp_common.Status() status.msg = _("Cloning from radio") nblocks = len(self._block_lengths) + 39 status.max = nblocks for block in self._block_lengths: if blocks == 8: # repeated read of 40 block same size (memory area) repeat = 40 else: repeat = 1 for _i in range(0, repeat): data += self._read(block, blocks, blocks == nblocks - 1) self.pipe.write(bytes([CMD_ACK])) blocks += 1 status.cur = blocks self.status_fn(status) if not self._US_model: status.msg = _("Clone completed, checking for spurious bytes") self.status_fn(status) moredata = self.pipe.read(2) if moredata: raise Exception( _("Radio sent data after the last awaited block, " "this happens when the selected model is a non-US " "but the radio is a US one. " "Please choose the correct model and try again.")) LOG.info("Clone completed in %i seconds" % (time.time() - start)) return memmap.MemoryMapBytes(data) def _clone_out(self): delay = 0.5 start = time.time() blocks = 0 pos = 0 status = chirp_common.Status() status.msg = _("Cloning to radio") status.max = len(self._block_lengths) + 39 mmap = self.get_mmap().get_byte_compatible() for block in self._block_lengths: if blocks == 8: # repeated read of 40 block same size (memory area) repeat = 40 else: repeat = 1 for _i in range(0, repeat): time.sleep(0.01) checksum = yaesu_clone.YaesuChecksum(pos, pos + block - 1) LOG.debug("Block %i - will send from %i to %i byte " % (blocks, pos, pos + block)) LOG.debug(util.hexprint(chr(blocks))) LOG.debug(util.hexprint(self.get_mmap()[pos:pos + block])) LOG.debug(util.hexprint(chr(checksum.get_calculated(mmap)))) self.pipe.write(bytes([blocks])) self.pipe.write(mmap[pos:pos + block]) self.pipe.write(bytes([checksum.get_calculated( self.get_mmap())])) buf = self.pipe.read(1) if not buf or buf[0] != CMD_ACK: time.sleep(delay) buf = self.pipe.read(1) if not buf or buf[0] != CMD_ACK: LOG.debug(util.hexprint(buf)) raise Exception(_("Radio did not ack block %i") % blocks) pos += block blocks += 1 status.cur = blocks self.status_fn(status) LOG.info("Clone completed in %i seconds" % (time.time() - start)) def sync_in(self): try: self._mmap = self._clone_in() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: self._clone_out() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_dtcs_polarity = False rf.has_nostep_tuning = True rf.valid_modes = list(set(self.MODES)) rf.valid_tmodes = list(self.TMODES) rf.valid_duplexes = list(self.DUPLEX) rf.valid_tuning_steps = list(self.STEPSFM) rf.valid_bands = self.VALID_BANDS rf.valid_skips = ["", "S"] rf.valid_power_levels = [] rf.valid_characters = "".join(self.CHARSET) rf.valid_name_length = 8 rf.valid_special_chans = sorted(self.SPECIAL_MEMORIES.keys()) rf.memory_bounds = (1, 200) rf.can_odd_split = True rf.has_ctone = False rf.has_settings = True return rf def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_duplex(self, mem, _mem): if _mem.is_duplex == 1: mem.duplex = self.DUPLEX[_mem.duplex] else: mem.duplex = "" def _get_tmode(self, mem, _mem): mem.tmode = self.TMODES[_mem.tmode] mem.rtone = chirp_common.TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] def _set_duplex(self, mem, _mem): _mem.duplex = self.DUPLEX.index(mem.duplex) _mem.is_duplex = mem.duplex != "" def _set_tmode(self, mem, _mem): _mem.tmode = self.TMODES.index(mem.tmode) # have to put this bit to 0 otherwise we get strange display in tone # frequency (menu 83). See bug #88 and #163 _mem.unknown_toneflag = 0 _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) def get_memory(self, number): if isinstance(number, str): return self._get_special(number) elif number < 0: # I can't stop delete operation from losing extd_number but # I know how to get it back return self._get_special(self.SPECIAL_MEMORIES_REV[number]) else: return self._get_normal(number) def set_memory(self, memory): if memory.number < 0: return self._set_special(memory) else: return self._set_normal(memory) def _get_special(self, number): mem = chirp_common.Memory() mem.number = self.SPECIAL_MEMORIES[number] mem.extd_number = number if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX - 1, -1): _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number] immutable = ["number", "skip", "extd_number", "name", "dtcs_polarity", "power"] elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX - 1, -1): _mem = self._memobj.vfob[-self.LAST_VFOB_INDEX + mem.number] immutable = ["number", "skip", "extd_number", "name", "dtcs_polarity", "power"] elif mem.number in range(-2, -6, -1): _mem = self._memobj.home[5 + mem.number] immutable = ["number", "skip", "extd_number", "name", "dtcs_polarity", "power"] elif mem.number == -1: _mem = self._memobj.qmb immutable = ["number", "skip", "extd_number", "name", "dtcs_polarity", "power"] elif mem.number in list(self.SPECIAL_PMS.values()): bitindex = -self.LAST_PMS_INDEX + mem.number used = (self._memobj.pmsvisible >> bitindex) & 0x01 valid = (self._memobj.pmsfilled >> bitindex) & 0x01 if not used: mem.empty = True if not valid: mem.empty = True return mem _mem = self._memobj.pms[-self.LAST_PMS_INDEX + mem.number] immutable = ["number", "skip", "rtone", "ctone", "extd_number", "dtcs", "tmode", "cross_mode", "dtcs_polarity", "power", "duplex", "offset"] else: raise Exception("Sorry, special memory index %i " % mem.number + "unknown you hit a bug!!") mem = self._get_memory(mem, _mem) mem.immutable = immutable return mem def _set_special(self, mem): if mem.empty and mem.number not in list(self.SPECIAL_PMS.values()): # can't delete special memories! raise Exception("Sorry, special memory can't be deleted") cur_mem = self._get_special(self.SPECIAL_MEMORIES_REV[mem.number]) # TODO add frequency range check for vfo and home memories if mem.number in range(self.FIRST_VFOA_INDEX, self.LAST_VFOA_INDEX - 1, -1): _mem = self._memobj.vfoa[-self.LAST_VFOA_INDEX + mem.number] elif mem.number in range(self.FIRST_VFOB_INDEX, self.LAST_VFOB_INDEX - 1, -1): _mem = self._memobj.vfob[-self.LAST_VFOB_INDEX + mem.number] elif mem.number in range(-2, -6, -1): _mem = self._memobj.home[5 + mem.number] elif mem.number == -1: _mem = self._memobj.qmb elif mem.number in list(self.SPECIAL_PMS.values()): # this case has to be last because 817 pms keys overlap with # 857 derived class other special memories bitindex = -self.LAST_PMS_INDEX + mem.number wasused = (self._memobj.pmsvisible >> bitindex) & 0x01 wasvalid = (self._memobj.pmsfilled >> bitindex) & 0x01 if mem.empty: if wasvalid and not wasused: # pylint get confused by &= operator self._memobj.pmsfilled = self._memobj.pmsfilled & \ ~ (1 << bitindex) # pylint get confused by &= operator self._memobj.pmsvisible = self._memobj.pmsvisible & \ ~ (1 << bitindex) return # pylint get confused by |= operator self._memobj.pmsvisible = self._memobj.pmsvisible | 1 << bitindex self._memobj.pmsfilled = self._memobj.pmsfilled | 1 << bitindex _mem = self._memobj.pms[-self.LAST_PMS_INDEX + mem.number] else: raise Exception("Sorry, special memory index %i " % mem.number + "unknown you hit a bug!!") for key in cur_mem.immutable: if key != "extd_number": if cur_mem.__dict__[key] != mem.__dict__[key]: raise errors.RadioError("Editing field `%s' " % key + "is not supported on this channel") self._set_memory(mem, _mem) def _get_normal(self, number): _mem = self._memobj.memory[number - 1] used = (self._memobj.visible[(number - 1) / 8] >> (number - 1) % 8) \ & 0x01 valid = (self._memobj.filled[(number - 1) / 8] >> (number - 1) % 8) \ & 0x01 mem = chirp_common.Memory() mem.number = number if not used: mem.empty = True if not valid or _mem.freq == 0xffffffff: return mem if mem.number == 1: mem.immutable = ['empty'] return self._get_memory(mem, _mem) def _set_normal(self, mem): _mem = self._memobj.memory[mem.number - 1] wasused = (self._memobj.visible[(mem.number - 1) / 8] >> (mem.number - 1) % 8) & 0x01 wasvalid = (self._memobj.filled[(mem.number - 1) / 8] >> (mem.number - 1) % 8) & 0x01 if mem.empty: if mem.number == 1: # as Dan says "yaesus are not good about that :(" # if you upload an empty image you can brick your radio raise Exception("Sorry, can't delete first memory") if wasvalid and not wasused: self._memobj.filled[(mem.number - 1) // 8] &= \ ~(1 << (mem.number - 1) % 8) _mem.set_raw("\xFF" * (_mem.size() // 8)) # clean up self._memobj.visible[(mem.number - 1) // 8] &= \ ~(1 << (mem.number - 1) % 8) return if not wasvalid: _mem.set_raw("\x00" * (_mem.size() // 8)) # clean up self._memobj.visible[(mem.number - 1) // 8] |= ( 1 << (mem.number - 1) % 8) self._memobj.filled[(mem.number - 1) // 8] |= ( 1 << (mem.number - 1) % 8) self._set_memory(mem, _mem) def _get_memory(self, mem, _mem): mem.freq = int(_mem.freq) * 10 mem.offset = int(_mem.offset) * 10 self._get_duplex(mem, _mem) mem.mode = self.MODES[_mem.mode] if mem.mode == "FM": if _mem.is_fm_narrow == 1: mem.mode = "NFM" mem.tuning_step = self.STEPSFM[_mem.fm_step] elif mem.mode == "AM": mem.tuning_step = self.STEPSAM[_mem.am_step] elif mem.mode == "CW" or mem.mode == "CWR": if _mem.is_cwdig_narrow == 1: mem.mode = "N" + mem.mode mem.tuning_step = self.STEPSSSB[_mem.ssb_step] else: try: mem.tuning_step = self.STEPSSSB[_mem.ssb_step] except IndexError: pass mem.skip = _mem.skip and "S" or "" self._get_tmode(mem, _mem) if _mem.tag_on_off == 1: for i in _mem.name: if i == 0xFF: break if chr(i) in self.CHARSET: mem.name += chr(i) else: # radio have some graphical chars that are not supported # we replace those with a * LOG.info("Replacing char %x with *" % i) mem.name += "*" mem.name = mem.name.rstrip() else: mem.name = "" mem.extra = RadioSettingGroup("extra", "Extra") ipo = RadioSetting("ipo", "IPO", RadioSettingValueBoolean(bool(_mem.ipo))) ipo.set_doc("Bypass preamp") mem.extra.append(ipo) att = RadioSetting("att", "ATT", RadioSettingValueBoolean(bool(_mem.att))) att.set_doc("10dB front end attenuator") mem.extra.append(att) return mem def _set_memory(self, mem, _mem): # not supported in chirp so I make label visible if have one if len(mem.name) > 0: _mem.tag_on_off = 1 else: _mem.tag_on_off = 0 _mem.tag_default = 0 # never use default label "CH-nnn" self._set_duplex(mem, _mem) if mem.mode[0] == "N": # is it narrow? _mem.mode = self.MODES.index(mem.mode[1:]) # here I suppose it's safe to set both _mem.is_fm_narrow = _mem.is_cwdig_narrow = 1 else: _mem.mode = self.MODES.index(mem.mode) # here I suppose it's safe to set both _mem.is_fm_narrow = _mem.is_cwdig_narrow = 0 i = 0 for lo, hi in self.VALID_BANDS: if mem.freq > lo and mem.freq < hi: break i += 1 _mem.freq_range = i # all this should be safe also when not in split but ... if mem.duplex == "split": _mem.tx_mode = _mem.mode i = 0 for lo, hi in self.VALID_BANDS: if mem.offset >= lo and mem.offset < hi: break i += 1 _mem.tx_freq_range = i _mem.skip = mem.skip == "S" self._set_tmode(mem, _mem) try: _mem.ssb_step = self.STEPSSSB.index(mem.tuning_step) except ValueError: pass try: _mem.am_step = self.STEPSAM.index(mem.tuning_step) except ValueError: pass try: _mem.fm_step = self.STEPSFM.index(mem.tuning_step) except ValueError: pass _mem.rit = 0 # not supported in chirp _mem.freq = mem.freq / 10 _mem.offset = mem.offset / 10 # there are ft857D that have problems with short labels, see bug #937 # some of the radio fill with 0xff and some with blanks # the latter is safe for all ft8x7 radio # so why should i do it only for some? for i in range(0, 8): _mem.name[i] = ord(mem.name.ljust(8)[i]) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def validate_memory(self, mem): msgs = yaesu_clone.YaesuCloneModeRadio.validate_memory(self, mem) lo, hi = self.VALID_BANDS[2] # this is fm broadcasting if mem.freq >= lo and mem.freq <= hi: if mem.mode != "FM": msgs.append(chirp_common.ValidationError( "Only FM is supported in this band")) # TODO check that step is valid in current mode return msgs @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") cw = RadioSettingGroup("cw", "CW") packet = RadioSettingGroup("packet", "Digital & packet") panel = RadioSettingGroup("panel", "Panel settings") extended = RadioSettingGroup("extended", "Extended") antenna = RadioSettingGroup("antenna", "Antenna selection") panelcontr = RadioSettingGroup("panelcontr", "Panel controls") top = RadioSettings(basic, cw, packet, panelcontr, panel, extended, antenna) rs = RadioSetting("ars_144", "144 ARS", RadioSettingValueBoolean(_settings.ars_144)) basic.append(rs) rs = RadioSetting("ars_430", "430 ARS", RadioSettingValueBoolean(_settings.ars_430)) basic.append(rs) rs = RadioSetting("pkt9600_mic", "Packet 9600 mic level", RadioSettingValueInteger(0, 100, _settings.pkt9600_mic)) packet.append(rs) options = ["enable", "disable"] rs = RadioSetting("disable_amfm_dial", "AM&FM Dial", RadioSettingValueList(options, options[ _settings.disable_amfm_dial ])) panel.append(rs) rs = RadioSetting("am_mic", "AM mic level", RadioSettingValueInteger(0, 100, _settings.am_mic)) basic.append(rs) options = ["OFF", "1h", "2h", "3h", "4h", "5h", "6h"] rs = RadioSetting("apo_time", "APO time", RadioSettingValueList(options, options[_settings.apo_time])) basic.append(rs) options = ["OFF", "Range", "All"] rs = RadioSetting("arts_beep", "ARTS beep", RadioSettingValueList(options, options[_settings.arts_beep])) basic.append(rs) options = ["OFF", "ON", "Auto"] rs = RadioSetting("backlight", "Backlight", RadioSettingValueList(options, options[_settings.backlight])) panel.append(rs) options = ["6h", "8h", "10h"] rs = RadioSetting("batt_chg", "Battery charge", RadioSettingValueList(options, options[_settings.batt_chg])) basic.append(rs) options = ["440 Hz", "880 Hz"] rs = RadioSetting("beep_freq", "Beep frequency", RadioSettingValueList(options, options[_settings.beep_freq])) panel.append(rs) rs = RadioSetting("beep_volume", "Beep volume", RadioSettingValueInteger(0, 100, _settings.beep_volume)) panel.append(rs) options = ["4800", "9600", "38400"] rs = RadioSetting("cat_rate", "CAT rate", RadioSettingValueList(options, options[_settings.cat_rate])) basic.append(rs) options = ["Blue", "Amber", "Violet"] rs = RadioSetting("color", "Color", RadioSettingValueList(options, options[_settings.color])) panel.append(rs) rs = RadioSetting("contrast", "Contrast", RadioSettingValueInteger(1, 12, _settings.contrast - 1)) panel.append(rs) rs = RadioSetting("cw_delay", "CW delay (*10 ms)", RadioSettingValueInteger(1, 250, _settings.cw_delay)) cw.append(rs) rs = RadioSetting("cw_id", "CW id", RadioSettingValueBoolean(_settings.cw_id)) cw.append(rs) options = ["Normal", "Reverse"] rs = RadioSetting("cw_paddle", "CW paddle", RadioSettingValueList(options, options[_settings.cw_paddle])) cw.append(rs) options = ["%i Hz" % i for i in range(300, 1001, 50)] rs = RadioSetting("cw_pitch", "CW pitch", RadioSettingValueList(options, options[_settings.cw_pitch])) cw.append(rs) options = ["%i wpm" % i for i in range(4, 61)] rs = RadioSetting("cw_speed", "CW speed", RadioSettingValueList(options, options[_settings.cw_speed])) cw.append(rs) options = ["1:%1.1f" % (i / 10) for i in range(25, 46, 1)] rs = RadioSetting("cw_weight", "CW weight", RadioSettingValueList(options, options[_settings.cw_weight])) cw.append(rs) rs = RadioSetting("dig_disp", "Dig disp (*10 Hz)", RadioSettingValueInteger(-300, 300, _settings.dig_disp)) packet.append(rs) rs = RadioSetting("dig_mic", "Dig mic", RadioSettingValueInteger(0, 100, _settings.dig_mic)) packet.append(rs) options = ["RTTY", "PSK31-L", "PSK31-U", "USER-L", "USER-U"] rs = RadioSetting("dig_mode", "Dig mode", RadioSettingValueList(options, options[_settings.dig_mode])) packet.append(rs) rs = RadioSetting("dig_shift", "Dig shift (*10 Hz)", RadioSettingValueInteger(-300, 300, _settings.dig_shift)) packet.append(rs) rs = RadioSetting("fm_mic", "FM mic", RadioSettingValueInteger(0, 100, _settings.fm_mic)) basic.append(rs) options = ["Dial", "Freq", "Panel"] rs = RadioSetting("lock_mode", "Lock mode", RadioSettingValueList(options, options[_settings.lock_mode])) panel.append(rs) options = ["Fine", "Coarse"] rs = RadioSetting("main_step", "Main step", RadioSettingValueList(options, options[_settings.main_step])) panel.append(rs) rs = RadioSetting("mem_group", "Mem group", RadioSettingValueBoolean(_settings.mem_group)) basic.append(rs) rs = RadioSetting("mic_key", "Mic key", RadioSettingValueBoolean(_settings.mic_key)) cw.append(rs) rs = RadioSetting("mic_scan", "Mic scan", RadioSettingValueBoolean(_settings.mic_scan)) basic.append(rs) options = ["Off", "SSB", "CW"] rs = RadioSetting("op_filter", "Optional filter", RadioSettingValueList(options, options[_settings.op_filter])) basic.append(rs) rs = RadioSetting("pkt_mic", "Packet mic", RadioSettingValueInteger(0, 100, _settings.pkt_mic)) packet.append(rs) options = ["1200", "9600"] rs = RadioSetting("pkt_rate", "Packet rate", RadioSettingValueList(options, options[_settings.pkt_rate])) packet.append(rs) options = ["Off", "3 sec", "5 sec", "10 sec"] rs = RadioSetting("resume_scan", "Resume scan", RadioSettingValueList(options, options[_settings.resume_scan]) ) basic.append(rs) options = ["Cont", "Chk"] rs = RadioSetting("scope", "Scope", RadioSettingValueList(options, options[_settings.scope])) basic.append(rs) rs = RadioSetting("sidetone", "Sidetone", RadioSettingValueInteger(0, 100, _settings.sidetone)) cw.append(rs) options = ["RF-Gain", "Squelch"] rs = RadioSetting("sql_rf_gain", "Squelch/RF-Gain", RadioSettingValueList(options, options[_settings.sql_rf_gain]) ) panel.append(rs) rs = RadioSetting("ssb_mic", "SSB Mic", RadioSettingValueInteger(0, 100, _settings.ssb_mic)) basic.append(rs) options = ["%i" % i for i in range(0, 21)] options[0] = "Off" rs = RadioSetting("tot_time", "Time-out timer", RadioSettingValueList(options, options[_settings.tot_time])) basic.append(rs) rs = RadioSetting("vox_delay", "VOX delay (*100 ms)", RadioSettingValueInteger(1, 25, _settings.vox_delay)) basic.append(rs) rs = RadioSetting("vox_gain", "VOX Gain", RadioSettingValueInteger(0, 100, _settings.vox_gain)) basic.append(rs) rs = RadioSetting("extended_menu", "Extended menu", RadioSettingValueBoolean(_settings.extended_menu)) extended.append(rs) options = ["Tn-Rn", "Tn-Riv", "Tiv-Rn", "Tiv-Riv"] rs = RadioSetting("dcs_inv", "DCS coding", RadioSettingValueList(options, options[_settings.dcs_inv])) extended.append(rs) rs = RadioSetting("r_lsb_car", "LSB Rx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.r_lsb_car)) extended.append(rs) rs = RadioSetting("r_usb_car", "USB Rx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.r_usb_car)) extended.append(rs) rs = RadioSetting("t_lsb_car", "LSB Tx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.t_lsb_car)) extended.append(rs) rs = RadioSetting("t_usb_car", "USB Tx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.t_usb_car)) extended.append(rs) options = ["Hi", "L3", "L2", "L1"] rs = RadioSetting("tx_power", "TX power", RadioSettingValueList(options, options[_settings.tx_power])) basic.append(rs) options = ["Front", "Rear"] rs = RadioSetting("hf_antenna", "HF", RadioSettingValueList(options, options[_settings.hf_antenna])) antenna.append(rs) rs = RadioSetting("sixm_antenna", "6M", RadioSettingValueList(options, options[_settings.sixm_antenna] )) antenna.append(rs) rs = RadioSetting("bc_antenna", "Broadcasting", RadioSettingValueList(options, options[_settings.bc_antenna])) antenna.append(rs) rs = RadioSetting("air_antenna", "Air band", RadioSettingValueList(options, options[_settings.air_antenna]) ) antenna.append(rs) rs = RadioSetting("vhf_antenna", "VHF", RadioSettingValueList(options, options[_settings.vhf_antenna]) ) antenna.append(rs) rs = RadioSetting("uhf_antenna", "UHF", RadioSettingValueList(options, options[_settings.uhf_antenna]) ) antenna.append(rs) st = RadioSettingValueString(0, 7, ''.join([self._CALLSIGN_CHARSET[x] for x in self._memobj. callsign])) st.set_charset(self._CALLSIGN_CHARSET) rs = RadioSetting("callsign", "Callsign", st) cw.append(rs) rs = RadioSetting("spl", "Split", RadioSettingValueBoolean(_settings.spl)) panelcontr.append(rs) options = ["None", "Up", "Down", "PMS"] rs = RadioSetting("scn_mode", "Scan mode", RadioSettingValueList(options, options[_settings.scn_mode])) panelcontr.append(rs) rs = RadioSetting("pri", "Priority", RadioSettingValueBoolean(_settings.pri)) panelcontr.append(rs) rs = RadioSetting("dw", "Dual watch", RadioSettingValueBoolean(_settings.dw)) panelcontr.append(rs) rs = RadioSetting("art", "Auto-range transponder", RadioSettingValueBoolean(_settings.art)) panelcontr.append(rs) rs = RadioSetting("nb", "Noise blanker", RadioSettingValueBoolean(_settings.nb)) panelcontr.append(rs) options = ["Auto", "Fast", "Slow", "Off"] rs = RadioSetting("agc", "AGC", RadioSettingValueList(options, options[_settings.agc] )) panelcontr.append(rs) options = ["PWR", "ALC", "SWR", "MOD"] rs = RadioSetting("pwr_meter_mode", "Power meter mode", RadioSettingValueList(options, options[ _settings.pwr_meter_mode ])) panelcontr.append(rs) rs = RadioSetting("vox", "Vox", RadioSettingValueBoolean(_settings.vox)) panelcontr.append(rs) rs = RadioSetting("bk", "Semi break-in", RadioSettingValueBoolean(_settings.bk)) cw.append(rs) rs = RadioSetting("kyr", "Keyer", RadioSettingValueBoolean(_settings.kyr)) cw.append(rs) options = ["enabled", "disabled"] rs = RadioSetting("fst", "Fast", RadioSettingValueList(options, options[_settings.fst] )) panelcontr.append(rs) options = ["enabled", "disabled"] rs = RadioSetting("lock", "Lock", RadioSettingValueList(options, options[_settings.lock])) panelcontr.append(rs) return top def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() try: LOG.debug("Setting %s(%s) <= %s" % (setting, getattr(obj, setting), element.value)) except AttributeError: LOG.debug("Setting %s <= %s" % (setting, element.value)) if setting == "contrast": setattr(obj, setting, int(element.value) + 1) elif setting == "callsign": self._memobj.callsign = \ [self._CALLSIGN_CHARSET_REV[x] for x in str(element.value)] else: setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @directory.register class FT817NDRadio(FT817Radio): """Yaesu FT-817ND""" MODEL = "FT-817ND" _model = "" _memsize = 6521 # block 9 (130 Bytes long) is to be repeated 40 times _block_lengths = [2, 40, 208, 182, 208, 182, 198, 53, 130, 118, 130] @directory.register class FT817NDUSRadio(FT817Radio): """Yaesu FT-817ND (US version)""" # seems that radios configured for 5 MHz operations send one packet # more than others so we have to distinguish sub models MODEL = "FT-817ND (US)" _model = "" _US_model = True _memsize = 6651 # block 9 (130 Bytes long) is to be repeated 40 times _block_lengths = [2, 40, 208, 182, 208, 182, 198, 53, 130, 118, 130, 130] SPECIAL_60M = { "M-601": -42, "M-602": -41, "M-603": -40, "M-604": -39, "M-605": -38, } LAST_SPECIAL60M_INDEX = -42 SPECIAL_MEMORIES = dict(FT817Radio.SPECIAL_MEMORIES) SPECIAL_MEMORIES.update(SPECIAL_60M) SPECIAL_MEMORIES_REV = dict(list(zip(list(SPECIAL_MEMORIES.values()), list(SPECIAL_MEMORIES.keys())))) def _get_special_60m(self, number): mem = chirp_common.Memory() mem.number = self.SPECIAL_60M[number] mem.extd_number = number _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number] mem = self._get_memory(mem, _mem) mem.immutable = ["number", "rtone", "ctone", "extd_number", "name", "dtcs", "tmode", "cross_mode", "dtcs_polarity", "power", "duplex", "offset", "empty"] return mem def _set_special_60m(self, mem): if mem.empty: # can't delete 60M memories! raise Exception("Sorry, 60M memory can't be deleted") cur_mem = self._get_special_60m(self.SPECIAL_MEMORIES_REV[mem.number]) for key in cur_mem.immutable: if cur_mem.__dict__[key] != mem.__dict__[key]: raise errors.RadioError("Editing field `%s' " % key + "is not supported on M-60x channels") if mem.mode not in ["USB", "LSB", "CW", "CWR", "NCW", "NCWR", "DIG"]: raise errors.RadioError("Mode {mode} is not valid " "in 60m channels".format(mode=mem.mode)) _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number] self._set_memory(mem, _mem) def get_memory(self, number): if number in self.SPECIAL_60M.keys(): return self._get_special_60m(number) elif (isinstance(number, int) and number < 0 and self.SPECIAL_MEMORIES_REV[number] in list(self.SPECIAL_60M.keys())): # I can't stop delete operation from losing extd_number but # I know how to get it back return self._get_special_60m(self.SPECIAL_MEMORIES_REV[number]) else: return FT817Radio.get_memory(self, number) def set_memory(self, memory): if memory.number in list(self.SPECIAL_60M.values()): return self._set_special_60m(memory) else: return FT817Radio.set_memory(self, memory) def get_settings(self): top = FT817Radio.get_settings(self) basic = top[0] rs = RadioSetting("emergency", "Emergency", RadioSettingValueBoolean( self._memobj.settings.emergency)) basic.append(rs) return top chirp-20240224/chirp/drivers/ft90.py0000644000175000017500000005551714520142245015767 0ustar hibbyhibby# Copyright 2011 Dan Smith # Copyright 2013 Jens Jensen AF5MI # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import yaesu_clone from chirp import chirp_common, bitwise, memmap, directory, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettings import time import traceback import string import re import logging LOG = logging.getLogger(__name__) CMD_ACK = b'\x06' FT90_STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0] FT90_MODES = ["AM", "FM", "Auto"] # idx 3 (Bell) not supported yet FT90_TMODES = ["", "Tone", "TSQL", "", "DTCS"] FT90_TONES = list(chirp_common.TONES) for tone in [165.5, 171.3, 177.3]: FT90_TONES.remove(tone) FT90_POWER_LEVELS_VHF = [chirp_common.PowerLevel("Hi", watts=50), chirp_common.PowerLevel("Mid1", watts=20), chirp_common.PowerLevel("Mid2", watts=10), chirp_common.PowerLevel("Low", watts=5)] FT90_POWER_LEVELS_UHF = [chirp_common.PowerLevel("Hi", watts=35), chirp_common.PowerLevel("Mid1", watts=20), chirp_common.PowerLevel("Mid2", watts=10), chirp_common.PowerLevel("Low", watts=5)] FT90_DUPLEX = ["", "-", "+", "split"] FT90_CWID_CHARS = list(string.digits) + list(string.ascii_uppercase) \ + list(" ") FT90_DTMF_CHARS = list("0123456789ABCD*#") FT90_SPECIAL = ["vfo_vhf", "home_vhf", "vfo_uhf", "home_uhf", "pms_1L", "pms_1U", "pms_2L", "pms_2U"] @directory.register class FT90Radio(yaesu_clone.YaesuCloneModeRadio): VENDOR = "Yaesu" MODEL = "FT-90" ID = b"\x8E\xF6" NEEDS_COMPAT_SERIAL = False _memsize = 4063 # block 03 (200 Bytes long) repeats 18 times; channel memories _block_lengths = [2, 232, 24] + ([200] * 18) + [205] mem_format = """ u16 id; #seekto 0x22; struct { u8 dtmf_active; u8 dtmf1_len; u8 dtmf2_len; u8 dtmf3_len; u8 dtmf4_len; u8 dtmf5_len; u8 dtmf6_len; u8 dtmf7_len; u8 dtmf8_len; u8 dtmf1[8]; u8 dtmf2[8]; u8 dtmf3[8]; u8 dtmf4[8]; u8 dtmf5[8]; u8 dtmf6[8]; u8 dtmf7[8]; u8 dtmf8[8]; char cwid[7]; u8 unk1; u8 scan1:2, beep:1, unk3:3, rfsqlvl:2; u8 unk4:2, scan2:1, cwid_en:1, txnarrow:1, dtmfspeed:1, pttlock:2; u8 dtmftxdelay:3, fancontrol:2, unk5:3; u8 dimmer:3, unk6:1, lcdcontrast:4; u8 dcsmode:2, unk16:2, tot:4; u8 unk14; u8 unk8:1, ars:1, lock:1, txpwrsave:1, apo:4; u8 unk15; u8 unk9:4, key_lt:4; u8 unk10:4, key_rt:4; u8 unk11:4, key_p1:4; u8 unk12:4, key_p2:4; u8 unk13:4, key_acc:4; } settings; struct mem_struct { u8 mode:2, isUhf1:1, unknown1:2, step:3; u8 artsmode:2, unknown2:1, isUhf2:1, power:2, shift:2; u8 skip:1, showname:1, unknown3:1, isUhfHi:1, unknown4:1, tmode:3; u32 rxfreq; u32 txfreqoffset; u8 UseDefaultName:1, ars:1, tone:6; u8 packetmode:1, dcstone:7; char name[7]; }; #seekto 0x86; struct mem_struct vfo_vhf; struct mem_struct home_vhf; struct mem_struct vfo_uhf; struct mem_struct home_uhf; #seekto 0xEB; u8 chan_enable[23]; #seekto 0x101; struct { u8 pms_2U_enable:1, pms_2L_enable:1, pms_1U_enable:1, pms_1L_enable:1, unknown6:4; } special_enables; #seekto 0x102; struct mem_struct memory[180]; #seekto 0xf12; struct mem_struct pms_1L; struct mem_struct pms_1U; struct mem_struct pms_2L; struct mem_struct pms_2U; #seekto 0x0F7B; struct { char demomsg1[50]; char demomsg2[50]; } demomsg; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect mic and hold [ACC] on mic while powering on.\n" " (\"CLONE\" will appear on the display)\n" "3. Replace mic with PC programming cable.\n" "4. After clicking OK, press the [SET] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect mic and hold [ACC] on mic while powering on.\n" " (\"CLONE\" will appear on the display)\n" "3. Replace mic with PC programming cable.\n" "4. Press the [DISP/SS] key\n" " (\"R\" will appear on the lower left of LCD).\n") rp.display_pre_upload_prompt_before_opening_port = False return rp @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = False rf.has_bank = False rf.has_dtcs_polarity = False rf.has_dtcs = True rf.can_odd_split = True rf.valid_modes = FT90_MODES rf.valid_tmodes = FT90_TMODES rf.valid_duplexes = FT90_DUPLEX rf.valid_tuning_steps = FT90_STEPS[1:] rf.valid_power_levels = FT90_POWER_LEVELS_VHF rf.valid_name_length = 7 rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_skips = ["", "S"] rf.valid_special_chans = FT90_SPECIAL rf.valid_tones = FT90_TONES rf.memory_bounds = (1, 180) rf.valid_bands = [(100000000, 230000000), (300000000, 530000000), (810000000, 999975000)] return rf def _read(self, blocksize, blocknum): data = self.pipe.read(blocksize+2) # chew echo'd ack self.pipe.write(CMD_ACK) time.sleep(0.02) self.pipe.read(1) # chew echoed ACK from 1-wire serial if len(data) == blocksize + 2 and data[0] == blocknum: checksum = yaesu_clone.YaesuChecksum(1, blocksize) if checksum.get_existing(data) != checksum.get_calculated(data): raise Exception("Checksum Failed [%02X<>%02X] block %02X, " "data len: %i" % (checksum.get_existing(data), checksum.get_calculated(data), blocknum, len(data))) data = data[1:blocksize + 1] # Chew blocknum and checksum else: raise Exception("Unable to read blocknum %02X " "expected blocksize %i got %i." % (blocknum, blocksize+2, len(data))) return data def _clone_in(self): # Be very patient with the radio self.pipe.timeout = 4 start = time.time() data = b"" blocknum = 0 status = chirp_common.Status() status.msg = "Cloning..." self.status_fn(status) status.max = len(self._block_lengths) for blocksize in self._block_lengths: data += self._read(blocksize, blocknum) blocknum += 1 status.cur = blocknum self.status_fn(status) LOG.info("Clone completed in %i seconds, blocks read: %i" % (time.time() - start, blocknum)) return memmap.MemoryMapBytes(data) def _clone_out(self): looppredelay = 0.4 looppostdelay = 1.9 self.pipe.timeout = 4 start = time.time() blocknum = 0 pos = 0 status = chirp_common.Status() status.msg = "Cloning to radio..." self.status_fn(status) status.max = len(self._block_lengths) for blocksize in self._block_lengths: checksum = yaesu_clone.YaesuChecksum(pos, pos+blocksize-1) blocknumbyte = bytes([blocknum]) payloadbytes = self.get_mmap()[pos:pos+blocksize] checksumbyte = bytes([checksum.get_calculated(self.get_mmap())]) LOG.debug("Block %i - will send from %i to %i byte " % (blocknum, pos, pos + blocksize)) LOG.debug(util.hexprint(blocknumbyte)) LOG.debug(util.hexprint(payloadbytes)) LOG.debug(util.hexprint(checksumbyte)) # send wrapped bytes time.sleep(looppredelay) self.pipe.write(blocknumbyte) self.pipe.write(payloadbytes) self.pipe.write(checksumbyte) tmp = self.pipe.read(blocksize + 2) # chew echo LOG.debug("bytes echoed: ") LOG.debug(util.hexprint(tmp)) # radio is slow to write/ack: time.sleep(looppostdelay) buf = self.pipe.read(1) LOG.debug("ack recd:") LOG.debug(util.hexprint(buf)) if buf != CMD_ACK: raise Exception("Radio did not ack block %i" % blocknum) pos += blocksize blocknum += 1 status.cur = blocknum self.status_fn(status) LOG.info("Clone completed in %i seconds" % (time.time() - start)) def sync_in(self): try: self._mmap = self._clone_in() except errors.RadioError: raise except Exception: trace = traceback.format_exc() raise errors.RadioError( "Failed to communicate with radio: %s" % trace) self.process_mmap() def sync_out(self): try: self._clone_out() except errors.RadioError: raise except Exception: trace = traceback.format_exc() raise errors.RadioError( "Failed to communicate with radio: %s" % trace) def process_mmap(self): self._memobj = bitwise.parse(self.mem_format, self._mmap) def _get_chan_enable(self, number): number = number - 1 bytepos = number // 8 bitpos = number % 8 chan_enable = self._memobj.chan_enable[bytepos] if chan_enable & (1 << bitpos): return True else: return False def _set_chan_enable(self, number, enable): number = number - 1 bytepos = number // 8 bitpos = number % 8 chan_enable = self._memobj.chan_enable[bytepos] if enable: chan_enable = chan_enable | (1 << bitpos) # enable else: chan_enable = chan_enable & ~(1 << bitpos) # disable self._memobj.chan_enable[bytepos] = chan_enable def get_memory(self, number): mem = chirp_common.Memory() if isinstance(number, str): # special channel _mem = getattr(self._memobj, number) mem.number = - len(FT90_SPECIAL) + FT90_SPECIAL.index(number) mem.extd_number = number if re.match('^pms', mem.extd_number): # enable pms_XY channel flag _special_enables = self._memobj.special_enables # Disabled in 2023 because this doesn't pass tests and I'm # not sure what it is really trying to accomplish. # mem.empty = not getattr(_special_enables, # mem.extd_number + "_enable") else: # regular memory _mem = self._memobj.memory[number-1] mem.number = number mem.empty = not self._get_chan_enable(number) if mem.empty: return mem # bail out, do not parse junk mem.freq = _mem.rxfreq * 10 mem.offset = _mem.txfreqoffset * 10 if not _mem.tmode < len(FT90_TMODES): _mem.tmode = 0 mem.tmode = FT90_TMODES[_mem.tmode] mem.rtone = FT90_TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dcstone] mem.mode = FT90_MODES[_mem.mode] mem.duplex = FT90_DUPLEX[_mem.shift] if mem.freq / 1000000 > 300: mem.power = FT90_POWER_LEVELS_UHF[_mem.power] else: mem.power = FT90_POWER_LEVELS_VHF[_mem.power] # radio has a known bug with 5 kHz step and squelch if _mem.step == 0 or _mem.step > len(FT90_STEPS)-1: _mem.step = 2 mem.tuning_step = FT90_STEPS[_mem.step] mem.skip = _mem.skip and "S" or "" if not all(char in chirp_common.CHARSET_ASCII for char in str(_mem.name)): # don't display blank/junk name mem.name = "" else: mem.name = str(_mem.name).rstrip() return mem def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def set_memory(self, mem): if mem.number < 0: # special channels _mem = getattr(self._memobj, mem.extd_number) if re.match('^pms', mem.extd_number): # enable pms_XY channel flag _special_enables = self._memobj.special_enables setattr(_special_enables, mem.extd_number + "_enable", True) else: _mem = self._memobj.memory[mem.number - 1] self._set_chan_enable(mem.number, not mem.empty) _mem.skip = mem.skip == "S" # radio has a known bug with 5 kHz step and dead squelch if not mem.tuning_step or mem.tuning_step == FT90_STEPS[0]: _mem.step = 2 else: _mem.step = FT90_STEPS.index(mem.tuning_step) _mem.rxfreq = mem.freq / 10 # vfo will unlock if not in right band? if mem.freq > 300000000: # uhf _mem.isUhf1 = 1 _mem.isUhf2 = 1 if mem.freq > 810000000: # uhf hiband _mem.isUhfHi = 1 else: _mem.isUhfHi = 0 else: # vhf _mem.isUhf1 = 0 _mem.isUhf2 = 0 _mem.isUhfHi = 0 _mem.txfreqoffset = mem.offset / 10 _mem.tone = FT90_TONES.index(mem.rtone) _mem.tmode = FT90_TMODES.index(mem.tmode) _mem.mode = FT90_MODES.index(mem.mode) _mem.shift = FT90_DUPLEX.index(mem.duplex) _mem.dcstone = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.step = FT90_STEPS.index(mem.tuning_step) _mem.shift = FT90_DUPLEX.index(mem.duplex) if mem.power: try: _mem.power = FT90_POWER_LEVELS_VHF.index(mem.power) except ValueError: _mem.power = FT90_POWER_LEVELS_UHF.index(mem.power) else: _mem.power = 3 # default to low power if (len(mem.name) == 0): _mem.name = bytearray.fromhex("80ffffffffffff") _mem.showname = 0 else: _mem.name = str(mem.name).ljust(7) _mem.showname = 1 _mem.UseDefaultName = 0 def _decode_cwid(self, cwidarr): cwid = "" LOG.debug("@ +_decode_cwid:") for byte in cwidarr.get_value(): char = int(byte) LOG.debug(char) # bitwise wraps in quotes! get rid of those if char < len(FT90_CWID_CHARS): cwid += FT90_CWID_CHARS[char] return cwid def _encode_cwid(self, cwidarr): cwid = "" LOG.debug("@ _encode_cwid:") for char in cwidarr.get_value(): cwid += chr(FT90_CWID_CHARS.index(char)) LOG.debug(cwid) return cwid def _bbcd2dtmf(self, bcdarr, strlen=16): # doing bbcd, but with support for ABCD*# LOG.debug(bcdarr.get_value()) string = ''.join("%02X" % b for b in bcdarr) LOG.debug("@_bbcd2dtmf, received: %s" % string) string = string.replace('E', '*').replace('F', '#') if strlen <= 16: string = string[:strlen] return string def _dtmf2bbcd(self, dtmf): dtmfstr = dtmf.get_value() dtmfstr = dtmfstr.replace('*', 'E').replace('#', 'F') dtmfstr = str.ljust(dtmfstr.strip(), 16, "0") bcdarr = list(bytearray.fromhex(dtmfstr)) LOG.debug("@_dtmf2bbcd, sending: %s" % bcdarr) return bcdarr def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") autodial = RadioSettingGroup("autodial", "AutoDial") keymaps = RadioSettingGroup("keymaps", "KeyMaps") top = RadioSettings(basic, keymaps, autodial) rs = RadioSetting( "beep", "Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) rs = RadioSetting( "lock", "Lock", RadioSettingValueBoolean(_settings.lock)) basic.append(rs) rs = RadioSetting( "ars", "Auto Repeater Shift", RadioSettingValueBoolean(_settings.ars)) basic.append(rs) rs = RadioSetting( "txpwrsave", "TX Power Save", RadioSettingValueBoolean(_settings.txpwrsave)) basic.append(rs) rs = RadioSetting( "txnarrow", "TX Narrow", RadioSettingValueBoolean(_settings.txnarrow)) basic.append(rs) options = ["Off", "S-3", "S-5", "S-Full"] rs = RadioSetting( "rfsqlvl", "RF Squelch Level", RadioSettingValueList(options, options[_settings.rfsqlvl])) basic.append(rs) options = ["Off", "Band A", "Band B", "Both"] rs = RadioSetting( "pttlock", "PTT Lock", RadioSettingValueList(options, options[_settings.pttlock])) basic.append(rs) rs = RadioSetting( "cwid_en", "CWID Enable", RadioSettingValueBoolean(_settings.cwid_en)) basic.append(rs) cwid = RadioSettingValueString(0, 7, self._decode_cwid(_settings.cwid)) cwid.set_charset(FT90_CWID_CHARS) rs = RadioSetting("cwid", "CWID", cwid) basic.append(rs) options = ["OFF"] + [str(x) for x in (range(1, 12+1))] rs = RadioSetting( "apo", "APO time (hrs)", RadioSettingValueList(options, options[_settings.apo])) basic.append(rs) options = ["Off"] + [str(x) for x in (range(1, 60+1))] rs = RadioSetting( "tot", "Time Out Timer (mins)", RadioSettingValueList(options, options[_settings.tot])) basic.append(rs) options = ["off", "Auto/TX", "Auto", "TX"] rs = RadioSetting( "fancontrol", "Fan Control", RadioSettingValueList(options, options[_settings.fancontrol])) basic.append(rs) keyopts = ["Scan Up", "Scan Down", "Repeater", "Reverse", "Tone Burst", "Tx Power", "Home Ch", "VFO/MR", "Tone", "Priority"] rs = RadioSetting( "key_lt", "Left Key", RadioSettingValueList(keyopts, keyopts[_settings.key_lt])) keymaps.append(rs) rs = RadioSetting( "key_rt", "Right Key", RadioSettingValueList(keyopts, keyopts[_settings.key_rt])) keymaps.append(rs) rs = RadioSetting( "key_p1", "P1 Key", RadioSettingValueList(keyopts, keyopts[_settings.key_p1])) keymaps.append(rs) rs = RadioSetting( "key_p2", "P2 Key", RadioSettingValueList(keyopts, keyopts[_settings.key_p2])) keymaps.append(rs) rs = RadioSetting( "key_acc", "ACC Key", RadioSettingValueList(keyopts, keyopts[_settings.key_acc])) keymaps.append(rs) options = [str(x) for x in range(0, 12+1)] rs = RadioSetting( "lcdcontrast", "LCD Contrast", RadioSettingValueList(options, options[_settings.lcdcontrast])) basic.append(rs) options = ["off", "d4", "d3", "d2", "d1"] rs = RadioSetting( "dimmer", "Dimmer", RadioSettingValueList(options, options[_settings.dimmer])) basic.append(rs) options = ["TRX Normal", "RX Reverse", "TX Reverse", "TRX Reverse"] rs = RadioSetting( "dcsmode", "DCS Mode", RadioSettingValueList(options, options[_settings.dcsmode])) basic.append(rs) options = ["50 ms", "100 ms"] rs = RadioSetting( "dtmfspeed", "DTMF Speed", RadioSettingValueList(options, options[_settings.dtmfspeed])) autodial.append(rs) options = ["50 ms", "250 ms", "450 ms", "750 ms", "1 sec"] rs = RadioSetting( "dtmftxdelay", "DTMF TX Delay", RadioSettingValueList(options, options[_settings.dtmftxdelay])) autodial.append(rs) options = [str(x) for x in range(1, 8 + 1)] rs = RadioSetting( "dtmf_active", "DTMF Active", RadioSettingValueList(options, options[_settings.dtmf_active])) autodial.append(rs) # setup 8 dtmf autodial entries for i in range(1, 9): objname = "dtmf" + str(i) dtmfsetting = getattr(_settings, objname) dtmflen = getattr(_settings, objname + "_len") dtmfstr = self._bbcd2dtmf(dtmfsetting, dtmflen) dtmf = RadioSettingValueString(0, 16, dtmfstr) dtmf.set_charset(FT90_DTMF_CHARS + list(" ")) rs = RadioSetting(objname, objname.upper(), dtmf) autodial.append(rs) return top def set_settings(self, uisettings): _settings = self._memobj.settings for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() oldval = getattr(_settings, setting) newval = element.value if setting == "cwid": newval = self._encode_cwid(newval) if re.match(r'dtmf\d', setting): # set dtmf length field and then get bcd dtmf dtmfstrlen = len(str(newval).strip()) setattr(_settings, setting + "_len", dtmfstrlen) newval = self._dtmf2bbcd(newval) LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/ft1802.py0000644000175000017500000002015414430171343016117 0ustar hibbyhibby# Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # FT-1802 Clone Procedure # 1. Turn radio off. # 2. Connect cable to mic jack. # 3. Press and hold in the [LOW(A/N)] key while turning the radio on. # 4. In Chirp, choose Download from Radio. # 5. Press the [MHz(SET)] key to send image. # or # 4. Press the [D/MR(MW)] key ("--WAIT--" will appear on the LCD). # 5. In Chirp, choose Upload to Radio. from chirp.drivers import yaesu_clone from chirp import chirp_common, bitwise, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean MEM_FORMAT = """ #seekto 0x06ea; struct { u8 odd_pskip:1, odd_skip:1, odd_visible:1, odd_valid:1, even_pskip:1, even_skip:1, even_visible:1, even_valid:1; } flags[100]; #seekto 0x076a; struct { u8 unknown1a:1, step_changed:1, narrow:1, clk_shift:1, unknown1b:4; u8 unknown2a:2, duplex:2, unknown2b:1, tune_step:3; bbcd freq[3]; u8 power:2, unknown3:3, tmode:3; u8 name[6]; bbcd offset[3]; u8 tone; u8 dtcs; u8 unknown4; } memory[200]; """ MODES = ["FM", "NFM"] TMODES = ["", "Tone", "TSQL", "DTCS", "TSQL-R", "Cross"] CROSS_MODES = ["DTCS->", "Tone->DTCS", "DTCS->Tone"] DUPLEX = ["", "-", "+", "split"] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] POWER_LEVELS = [chirp_common.PowerLevel("LOW1", watts=5), chirp_common.PowerLevel("LOW2", watts=10), chirp_common.PowerLevel("LOW3", watts=25), chirp_common.PowerLevel("HIGH", watts=50), ] CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ +-/?()?_" @directory.register class FT1802Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT-1802""" VENDOR = "Yaesu" MODEL = "FT-1802M" BAUD_RATE = 19200 _model = b"AH023" _block_lengths = [10, 8001] _memsize = 8011 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to mic jack.\n" "3. Press and hold in the [LOW(A/N)] key while turning the radio" " on.\n" "4. After clicking OK, press the [MHz(SET)] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to mic jack.\n" "3. Press and hold in the [LOW(A/N)] key while turning the radio" " on.\n" "4. Press the [D/MR(MW)] key (\"--WAIT--\" will appear on the" " LCD).\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.can_odd_split = True rf.has_ctone = False rf.has_tuning_step = True rf.has_dtcs_polarity = False # in radio settings, not per memory rf.has_bank = False # has banks, but not implemented rf.valid_tuning_steps = STEPS rf.valid_modes = MODES rf.valid_tmodes = TMODES rf.valid_bands = [(137000000, 174000000)] rf.valid_power_levels = POWER_LEVELS rf.valid_duplexes = DUPLEX rf.valid_skips = ["", "S", "P"] rf.valid_name_length = 6 rf.valid_characters = CHARSET rf.has_cross = True rf.valid_cross_modes = list(CROSS_MODES) return rf def _checksums(self): return [yaesu_clone.YaesuChecksum(0, self._memsize-2)] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) + \ repr(self._memobj.flags[number/2]) def get_memory(self, number): _mem = self._memobj.memory[number] _flag = self._memobj.flags[number/2] nibble = (number % 2) and "odd" or "even" visible = _flag["%s_visible" % nibble] valid = _flag["%s_valid" % nibble] pskip = _flag["%s_pskip" % nibble] skip = _flag["%s_skip" % nibble] mem = chirp_common.Memory() mem.number = number if not visible: mem.empty = True if not valid: mem.empty = True return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = chirp_common.fix_rounded_step(int(_mem.offset) * 1000) mem.duplex = DUPLEX[_mem.duplex] mem.tuning_step = _mem.step_changed and \ STEPS[_mem.tune_step] or STEPS[0] if _mem.tmode < TMODES.index("Cross"): mem.tmode = TMODES[_mem.tmode] mem.cross_mode = CROSS_MODES[0] else: mem.tmode = "Cross" mem.cross_mode = CROSS_MODES[_mem.tmode - TMODES.index("Cross")] mem.rtone = chirp_common.TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] for i in _mem.name: if i == 0xFF: break if i & 0x80 == 0x80: # first bit in name is "show name" mem.name += CHARSET[0x80 ^ int(i)] else: mem.name += CHARSET[i] mem.name = mem.name.rstrip() mem.mode = _mem.narrow and "NFM" or "FM" mem.skip = pskip and "P" or skip and "S" or "" mem.power = POWER_LEVELS[_mem.power] mem.extra = RadioSettingGroup("extra", "Extra Settings") rs = RadioSetting("clk_shift", "Clock Shift", RadioSettingValueBoolean(_mem.clk_shift)) mem.extra.append(rs) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _flag = self._memobj.flags[mem.number/2] nibble = (mem.number % 2) and "odd" or "even" valid = _flag["%s_valid" % nibble] visible = _flag["%s_visible" % nibble] if not mem.empty and not valid: _flag["%s_valid" % nibble] = True _mem.unknown1a = 0x00 _mem.clk_shift = 0x00 _mem.unknown1b = 0x00 _mem.unknown2a = 0x00 _mem.unknown2b = 0x00 _mem.unknown3 = 0x00 _mem.unknown4 = 0x00 if mem.empty and valid and not visible: _flag["%s_valid" % nibble] = False return _flag["%s_visible" % nibble] = not mem.empty if mem.empty: return _flag["%s_valid" % nibble] = True _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 1000 _mem.duplex = DUPLEX.index(mem.duplex) _mem.tune_step = STEPS.index(mem.tuning_step) _mem.step_changed = mem.tuning_step != STEPS[0] if mem.tmode != "Cross": _mem.tmode = TMODES.index(mem.tmode) else: _mem.tmode = TMODES.index("Cross") + \ CROSS_MODES.index(mem.cross_mode) _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.name = [0xFF] * 6 for i in range(0, len(mem.name)): try: _mem.name[i] = CHARSET.index(mem.name[i]) except IndexError: raise Exception("Character `%s' not supported") if _mem.name[0] != 0xFF: _mem.name[0] += 0x80 # show name instead of frequency _mem.narrow = MODES.index(mem.mode) _mem.power = 3 if mem.power is None else POWER_LEVELS.index(mem.power) _flag["%s_pskip" % nibble] = mem.skip == "P" _flag["%s_skip" % nibble] = mem.skip == "S" for element in mem.extra: setattr(_mem, element.get_name(), element.value) chirp-20240224/chirp/drivers/ts590.py0000644000175000017500000017076314466370044016103 0ustar hibbyhibby# Copyright 2019 Rick DeWitt # Version 1.0: CatClone- Implementing fake memory image # Version 2.0: No Live Mode library links. Implementing mem as Clone Mode # Having fun with Dictionaries # Version 2.1: Adding match_model function to fix File>New issue #7409 # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging import threading from chirp import chirp_common, directory, memmap from chirp import bitwise, errors from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0000; struct { // 20 bytes per chan u32 rxfreq; u32 txfreq; u8 xmode:4, // param stored as CAT value data:2, tmode:2; u8 rtone; u8 ctone; u8 filter:1, fmnrw:1, skip:1, nu:5; char name[8]; } ch_mem[120]; // 100 normal + 10 P-type + 10 EXT struct { // 5 bytes each u32 asfreq; u8 asmode:4, // param stored as CAT value asdata:2, asnu:2; } asf[32]; struct { // 10 x 5 4-byte frequencies u32 ssfreq; } ssf[50]; struct { // 16 bytes u8 txeq; u8 rxeq; } eqx[8]; struct { // Common to S and SG models u8 ag; u8 an1:2, an2:2, an3:2, anu:2; u32 fa; u32 fb; char fv[4]; u8 mf; u8 mg; u8 pc; u8 rg; u8 tp; } settings; struct { // Menu A/B settings by TS-590SG names char ex001[8]; // 590S values get put in SG equiv u8 ex002; // These params stored as nibbles u8 ex003; u8 ex005; u8 ex006; u8 ex007; u8 ex008; u8 ex009; u8 ex010; u8 ex011; u8 ex012; u8 ex013; u8 ex016; u8 ex017; u8 ex018; u8 ex019; u8 ex021; u8 ex022; u8 ex023; u8 ex024; u8 ex025; u8 ex026; u8 ex054; u8 ex055; u8 ex076; u8 ex077; u8 ex087; u8 ex088; u8 ex089; u8 ex090; u8 ex091; u8 ex092; u8 ex093; u8 ex094; u8 ex095; u8 ex096; u8 ex097; u8 ex098; u8 ex099; } exset[2]; char mdl_name[9]; // appended model name, first 9 chars """ STIMEOUT = 2 LOCK = threading.Lock() BAUD = 0 # Initial baud rate MEMSEL = 0 # Default Menu A BEEPVOL = 4 # Default beep volume W8S = 0.01 # short wait, secs W8L = 0.05 # long wait TS590_DUPLEX = ["", "-", "+"] TS590_SKIP = ["", "S"] # start at 0:LSB TS590_MODES = ["LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R", "Data+LSB", "Data+USB", "Data+FM"] EX_MODES = ["FSK-R", "CW-R", "Data+LSB", "Data+USB", "Data+FM"] TS590_TONES = list(chirp_common.TONES) TS590_TONES.append(1750.0) RADIO_IDS = { # From kenwood_live.py; used to report wrong radio "ID019;": "TS-2000", "ID009;": "TS-850", "ID020;": "TS-480", "ID021;": "TS-590S", "ID023;": "TS-590SG" } def command(ser, cmd, rsplen, w8t=0.01, exts=""): """Send @cmd to radio via @ser""" # cmd is output string without ; terminator # rsplen is expected response char count, including terminator # If rsplen = 0 then do not read after write start = time.time() # LOCK.acquire() stx = cmd # preserve cmd for response check stx = stx + exts + ";" # append arguments ser.write(stx) LOG.debug("PC->RADIO [%s]" % stx) ts = time.time() # implement the wait after command while (time.time() - ts) < w8t: ix = 0 # NOP result = "" if rsplen > 0: # read response result = ser.read(rsplen) LOG.debug("RADIO->PC [%s]" % result) result = result[:-1] # remove terminator # LOCK.release() return result.strip() def _connect_radio(radio): """Determine baud rate and verify radio on-line""" global BAUD # Allows modification bauds = [115200, 57600, 38400, 19200, 9600, 4800] if BAUD > 0: bauds.insert(0, BAUD) # Make the detected one first # Flush the input buffer radio.pipe.timeout = 0.005 radio.pipe.baudrate = 9600 junk = radio.pipe.read(256) radio.pipe.timeout = STIMEOUT for bd in bauds: radio.pipe.baudrate = bd BAUD = bd radio.pipe.write(";") radio.pipe.write(";") resp = radio.pipe.read(4) radio.pipe.write("ID;") resp = radio.pipe.read(6) if resp == radio.ID: # Good comms resp = command(radio.pipe, "AI0", 0, W8L) return elif resp in RADIO_IDS.keys(): msg = "Radio reported as model %s, not %s!" % \ (RADIO_IDS[resp], radio.MODEL) raise errors.RadioError(msg) raise errors.RadioError("No response from radio") def read_str(radio, trm=";"): """ Read chars until terminator """ stq = "" ctq = "" while ctq != trm: ctq = radio.pipe.read(1) stq += ctq LOG.debug(" + [%s]" % stq) return stq[:-1] # Return without trm def _read_mem(radio): """Get the memory map""" global BEEPVOL # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._upper + 20 # 10 P chans and 10 EXT status.msg = "Reading Channel Memory..." radio.status_fn(status) result0 = command(radio.pipe, "EX0050000", 9, W8S) result0 += read_str(radio) BEEPVOL = int(result0[6:]) result0 = command(radio.pipe, "EX005000000", 0, W8L) # Silence beeps data = "" mrlen = 41 # Expected fixed return string length for chn in range(0, (radio._upper + 21)): # Loop stops at +20 # Request this mem chn r0ch = 999 r1ch = r0ch # return results can come back out of order while (r0ch != chn): # simplex if chn < 100: result0 = command(radio.pipe, "MR0 %02i" % chn, mrlen, W8S) result0 += read_str(radio) else: result0 = command(radio.pipe, "MR0%03i" % chn, mrlen, W8S) result0 += read_str(radio) r0ch = int(result0[3:6]) while (r1ch != chn): # split if chn < 100: result1 = command(radio.pipe, "MR1 %02i" % chn, mrlen, W8S) result1 += read_str(radio) else: result1 = command(radio.pipe, "MR1%03i" % chn, mrlen, W8S) result1 += read_str(radio) r1ch = int(result1[3:6]) data += radio._parse_mem_spec(result0, result1) # UI Update status.cur = chn status.msg = "Reading Channel Memory..." radio.status_fn(status) if len(data) == 0: # To satisfy run_tests raise errors.RadioError('No data received.') return data def _make_dat(sx, nb): """ Split the string sx into nb binary bytes """ vx = int(sx) dx = "" if nb > 3: dx += chr((vx >> 24) & 0xFF) if nb > 2: dx += chr((vx >> 16) & 0xFF) if nb > 1: dx += chr((vx >> 8) & 0xFF) dx += chr(vx & 0xFF) return dx def _sets_val(stx, nv=3, nb=2): """ Split string stx into nv nb-bit values in 1 byte """ # Right now: hardcoded for nv:3 values of nb:2 bits each v1 = int(stx[0]) << 6 v1 = v1 | (int(stx[1]) << 4) v1 = v1 | (int(stx[2]) << 2) return chr(v1) def _sets_asf(stx): """ Process AS0 auto-mode setting """ asm = _make_dat(stx[0:11], 4) # 11-bit freq a1 = int(stx[11]) # 4-bit mode a2 = int(stx[12]) # 2-bit data asm += chr((a1 << 4) | (a2 << 2)) return asm def my_val_list(setting, opts, obj, atrb, fix=0, ndx=-1): """Callback:from ValueList. Set the integer index.""" # This function is here to be available to get_mem and get_set # fix is optional additive offset to the list index # ndx is optional obj[ndx] array index value = opts.index(str(setting.value)) value += fix if ndx >= 0: # indexed obj setattr(obj[ndx], atrb, value) else: setattr(obj, atrb, value) return def _read_settings(radio): """ Continue filling memory map""" global MEMSEL # setc: the list of CAT commands for downloaded settings # Block parameters first. In the exact order of MEM_FORMAT setc = radio.SETC setc.extend(radio.EX) # Menu A EX params setc.extend(radio.EX) # Menu B status = chirp_common.Status() status.cur = 0 status.max = 32 + 50 + 8 + 11 + 39 + 39 status.msg = "Reading Settings..." radio.status_fn(status) setts = "" nc = 0 for cmc in setc: skipme = False argx = "" # Extended arguments if cmc == "AS0": skipme = True # flag to disable further processing for ix in range(32): # 32 AS params result0 = command(radio.pipe, cmc, 19, W8S, "%02i" % ix) xc = len(cmc) + 2 result0 = result0[xc:] setts += _sets_asf(result0) nc += 1 status.cur = nc radio.status_fn(status) elif cmc == "SS": skipme = True for ix in range(10): # 10 chans for nx in range(5): # 5 spots result0 = command(radio.pipe, cmc, 16, W8S, "%1i%1i" % (ix, nx)) setts += _make_dat(result0[4:], 4) nc += 1 status.cur = nc radio.status_fn(status) elif cmc == "EQ": skipme = True for ix in range(8): result0 = command(radio.pipe, cmc, 6, W8S, "0%1i" % ix) # Tx eq setts += chr(int(result0[4:])) # 'EQ13x", want the x result0 = command(radio.pipe, cmc, 6, W8S, "1%1i" % ix) # Rx eq setts += chr(int(result0[4:])) nc += 1 status.cur = nc radio.status_fn(status) elif ((not radio.SG) and (cmc == "EX087")) \ or (radio.SG and (cmc == "EX001")): result0 = command(radio.pipe, cmc, 9, W8S, "0000") result0 += read_str(radio) # Read pwron message result0 = result0[8:] nx = len(result0) for ix in range(8): if ix < nx: sx = result0[ix] # may need to test valid char setts += sx else: setts += chr(0) skipme = True nc += 1 status.cur = nc radio.status_fn(status) elif (cmc == "MF0") or (cmc == "MF1"): result0 = command(radio.pipe, cmc, 0, W8S) skipme = True # cmd only, no response else: # issue the cmc cmd as-is with argx if str(cmc).startswith("EX"): argx = "0000" result0 = command(radio.pipe, cmc, 0, W8S, argx) result0 = read_str(radio) # various length responses # strip the cmd echo xc = len(cmc) result0 = result0[xc:] # Cmd has been sent, process the result if cmc == "FV": # all chars skipme = True setts += result0 elif cmc == "AN": # Antenna selection has 3 values skipme = True setts += _sets_val(result0, 3, 2) # store as 2-bits each elif (cmc == "FA") or (cmc == "FB"): # Response is 11-bit frq skipme = True setts += _make_dat(result0, 4) # 11-bit freq elif (cmc == "MF0") or (cmc == "MF1"): # No stored response skipme = True # Generic single byte processing if not skipme: setts += chr(int(result0)) if cmc == "MF": # Save the initial Menu selection MEMSEL = int(result0) nc += 1 status.cur = nc radio.status_fn(status) setts += radio.MODEL.ljust(9) # Now set the inidial menu selection back result0 = command(radio.pipe, "MF", 0, W8L, "%1i" % MEMSEL) # And the original Beep Volume result0 = command(radio.pipe, "EX0050000%2i" % BEEPVOL, 0, W8L) return setts def _write_mem(radio): """ Send MW commands for each channel """ global BEEPVOL # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._upper + 20 # 10 P chans and 10 EXT status.msg = "Writing Channel Memory" radio.status_fn(status) result0 = command(radio.pipe, "EX0050000", 9, W8S) result0 += read_str(radio) BEEPVOL = int(result0[6:]) result0 = command(radio.pipe, "EX005000000", 0, W8L) # Silence beeps for chn in range(0, (radio._upper + 21)): # Loop stops at +20 _mem = radio._memobj.ch_mem[chn] cmx = "MW0 %02i" % chn if chn > 99: cmx = "MW0%03i" % chn stm = cmx + radio._make_base_spec(_mem, _mem.rxfreq) result0 = command(radio.pipe, stm, 0, W8L) # No response cmx = "MW1 %02i" % chn if chn > 99: cmx = "MW1%03i" % chn stm = cmx + radio._make_base_spec(_mem, _mem.txfreq) if _mem.rxfreq > 0: # Dont write MW1 if empty result0 = command(radio.pipe, stm, 0, W8L) # UI Update status.cur = chn radio.status_fn(status) return def _write_sets(radio): """ Send settings and Menu a/b """ status = chirp_common.Status() status.cur = 0 status.max = 187 # Total to send status.msg = "Writing Settings" radio.status_fn(status) # Define mem struct shortcuts _sets = radio._memobj.settings _asf = radio._memobj.asf _ssf = radio._memobj.ssf _eqx = radio._memobj.eqx _mex = radio._memobj.exset snx = 0 # Settings status counter stlen = 0 # No response count # Send 32 AS for ix in range(32): scm = "AS0%02i%011i%1i%1i" % (ix, _asf[ix].asfreq, _asf[ix].asmode, _asf[ix].asdata) result0 = command(radio.pipe, scm, stlen, W8S) snx += 1 status.cur = snx radio.status_fn(status) # Send 50 SS for ix in range(10): for kx in range(5): nx = ix * 5 + kx scm = "SS%1i%1i%011i" % (ix, kx, _ssf[nx].ssfreq) result0 = command(radio.pipe, scm, stlen, W8S) snx += 1 status.cur = snx radio.status_fn(status) # Send 16 EQ for ix in range(8): scm = "EQ0%1i%1i" % (ix, _eqx[ix].txeq) result0 = command(radio.pipe, scm, stlen, W8S) scm = "EQ1%1i%1i" % (ix, _eqx[ix].rxeq) result0 = command(radio.pipe, scm, stlen, W8S) snx += 2 status.cur = snx radio.status_fn(status) # Send 11 thingies scm = "AG0%03i" % _sets.ag result0 = command(radio.pipe, scm, stlen, W8S) scm = "AN%1i%1i%1i" % (_sets.an1, _sets.an2, _sets.an3) result0 = command(radio.pipe, scm, stlen, W8S) scm = "FA%011i" % _sets.fa result0 = command(radio.pipe, scm, stlen, W8S) scm = "FB%011i" % _sets.fb result0 = command(radio.pipe, scm, stlen, W8S) scm = "MG%03i" % _sets.mg result0 = command(radio.pipe, scm, stlen, W8S) scm = "PC%03i" % _sets.pc result0 = command(radio.pipe, scm, stlen, W8S) scm = "RG%03i" % _sets.rg result0 = command(radio.pipe, scm, stlen, W8S) scm = "TP%03i" % _sets.tp result0 = command(radio.pipe, scm, stlen, W8S) scm = "MF0" # Select menu A/B result0 = command(radio.pipe, scm, stlen, W8S) snx += 11 status.cur = snx radio.status_fn(status) # Send 38 Menu A EX setc = radio.EX # list of EX cmds for ix in range(2): for cmx in setc: if str(cmx)[0:2] == "MF": scm = cmx else: # The EX cmds # Test for the power-on string if (radio.SG and cmx == "EX001") or \ ((not radio.SG) and cmx == "EX087"): scm = cmx + "0000" for chx in _mex[ix].ex001: # Both get string here scm += chr(chx) scm = scm.strip() scm = scm.strip(chr(0)) # in case any got thru # Now for the other EX cmds else: if radio.SG: scm = "%s0000%i" % (cmx, getattr(_mex[ix], cmx.lower())) else: # Gotta use the cross reference dict for cmd scm = "%s0000%i" % (cmx, getattr(_mex[ix], radio.EX_X[cmx].lower())) result0 = command(radio.pipe, scm, stlen, W8S) snx += 1 status.cur = snx radio.status_fn(status) # Now set the inidial menu selection back result0 = command(radio.pipe, "MF", 0, W8L, "%1i" % _sets.mf) # And the original Beep Volume result0 = command(radio.pipe, "EX0050000%2i" % BEEPVOL, 0, W8L) return @directory.register class TS590Radio(chirp_common.CloneModeRadio): """Kenwood TS-590""" VENDOR = "Kenwood" MODEL = "TS-590SG_CloneMode" ID = "ID023;" SG = True # Settings read/write cmd sequence list SETC = ["AS0", "SS", "EQ", "AG0", "AN", "FA", "FB", "FV", "MF", "MG", "PC", "RG", "TP", "MF0"] # This is the TS-590SG MENU A/B read_settings parameter tuple list # The order is mandatory; to match the Mem_Format sequence EX = ["EX001", "EX002", "EX003", "EX005", "EX006", "EX007", "EX008", "EX009", "EX010", "EX011", "EX012", "EX013", "EX016", "EX017", "EX018", "EX019", "EX021", "EX022", "EX023", "EX024", "EX025", "EX026", "EX054", "EX055", "EX076", "EX077", "EX087", "EX088", "EX089", "EX090", "EX091", "EX092", "EX093", "EX094", "EX095", "EX096", "EX097", "EX098", "EX099", "MF1"] # EX menu settings label dictionary. Key is the EX number EX_LBL = {2: " Display brightness", 1: " Power-On message", 3: " Backlight color", 5: " Beep volume", 6: " Sidetone volume", 7: " Message playback volume", 8: " Voice guide volume", 9: " Voice guide speed", 10: " Voice guide language", 11: " Auto Announcement", 12: " MHz step", 13: " Tuning control adj rate (Hz)", 16: " SSB tune step (kHz)", 17: " CW/FSK tune step (kHz)", 18: " AM tune step (kHz)", 19: " FM tune step (kHz)", 21: " Max number of Quick Mem chans", 22: " Temporary MR Chan freq allowed", 23: " Program Scan slowdown", 24: " Program Scan slowdown range (Hz)", 25: " Program Scan hold", 26: " Scan Resume method", 54: " TX Power fine adjust", 55: " Timeout timer (Secs)", 76: " Data VOX", 77: " Data VOX delay (x30 mSecs)", 87: " Panel PF-A function", 88: " Panel PF-B function", 89: " RIT key function", 90: " XIT key function", 91: " CL key function", 92: " Front panel MULTI/CH key (non-CW mode)", 93: " Front panel MULTI/CH key (CW mode)", 94: " MIC PF1 function", 95: " MIC PF2 function", 96: " MIC PF3 function", 97: " MIC PF4 function", 98: " MIC PF (DWN) function", 99: " MIC PF (UP) function"} BAUD_RATE = 115200 _upper = 99 # Special Channels Declaration # WARNING Indecis are hard wired in get/set_memory code !!! # Channels print in + increasing index order SPECIAL_MEMORIES = {"EXT 0": 110, "EXT 1": 111, "EXT 2": 112, "EXT 3": 113, "EXT 4": 114, "EXT 5": 115, "EXT 6": 116, "EXT 7": 117, "EXT 8": 118, "EXT 9": 119} def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = False rf.has_bank = False rf.has_ctone = True rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_name = True rf.has_settings = True rf.has_offset = True rf.has_mode = True rf.has_tuning_step = False # Not in mem chan rf.has_nostep_tuning = True # Radio accepts any entered freq rf.has_cross = True rf.has_comment = False rf.memory_bounds = (0, self._upper) rf.valid_bands = [(30000, 24999999), (25000000, 59999999)] rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "*+-/" rf.valid_duplexes = TS590_DUPLEX rf.valid_modes = TS590_MODES rf.valid_skips = TS590_SKIP rf.valid_tuning_steps = [0.5, 1.0, 2.5, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] rf.valid_tmodes = ["", "Tone", "TSQL", "Cross"] rf.valid_cross_modes = ["Tone->Tone"] rf.valid_name_length = 8 # 8 character channel names rf.valid_special_chans = sorted(self.SPECIAL_MEMORIES.keys()) return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = _( "Click on the \"Special Channels\" toggle-button of the memory\n" "editor to see/set the EXT channels. P-VFO channels 100-109\n" "are considered Settings.\n" "Only a subset of the over 200 available radio settings\n" "are supported in this release.\n" "Ignore the beeps from the radio on upload and download.\n") rp.pre_download = _( "Follow these instructions to download the radio memory:\n" "1 - Connect your interface cable\n" "2 - Radio > Download from radio: DO NOT mess with the radio\n" "during download!\n" "3 - Disconnect your interface cable\n") rp.pre_upload = _( "Follow these instructions to upload the radio memory:\n" "1 - Connect your interface cable\n" "2 - Radio > Upload to radio: DO NOT mess with the radio\n" "during upload!\n" "3 - Disconnect your interface cable\n") return rp def sync_in(self): """Download from radio""" try: _connect_radio(self) data = _read_mem(self) data += _read_settings(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMap(data) self.process_mmap() return def sync_out(self): """Upload to radio""" try: _connect_radio(self) _write_mem(self) _write_sets(self) except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') return def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) return def get_memory(self, number): """Convert raw channel data (_mem) into UI columns (mem)""" mem = chirp_common.Memory() mem.extra = RadioSettingGroup("extra", "Extra") if isinstance(number, str): mem.name = number # Spcl chns 1st var mem.number = self.SPECIAL_MEMORIES[number] _mem = self._memobj.ch_mem[mem.number] else: # Normal mem chans and VFO edges if number > 99 and number < 110: return # Don't show VFO edges as mem chans _mem = self._memobj.ch_mem[number] mem.number = number mnx = "" for char in _mem.name: mnx += chr(char) mem.name = mnx.strip() mem.name = mem.name.upper() # From here on is common to both types if _mem.rxfreq == 0: _mem.txfreq = 0 mem.empty = True mem.freq = 0 mem.mode = "LSB" mem.offset = 0 return mem mem.empty = False mem.freq = int(_mem.rxfreq) mem.duplex = TS590_DUPLEX[0] # None by default mem.offset = 0 if _mem.rxfreq < _mem.txfreq: # + shift mem.duplex = TS590_DUPLEX[2] mem.offset = _mem.txfreq - _mem.rxfreq if _mem.rxfreq > _mem.txfreq: # - shift mem.duplex = TS590_DUPLEX[1] mem.offset = _mem.rxfreq - _mem.txfreq if _mem.txfreq == 0: # leave offset alone, or run_tests will bomb mem.duplex = TS590_DUPLEX[0] mx = _mem.xmode - 1 # CAT modes start at 1 if _mem.xmode == 9: # except CAT FSK-R is 9, there is no 8 mx = 7 if _mem.data: # LSB+Data= 8, USB+Data= 9, FM+Data= 10 if _mem.xmode == 1: # CAT LSB mx = 8 elif _mem.xmode == 2: # CAT USB mx = 9 elif _mem.xmode == 4: # CAT FM mx = 10 mem.mode = TS590_MODES[mx] mem.tmode = "" mem.cross_mode = "Tone->Tone" mem.ctone = TS590_TONES[_mem.ctone] mem.rtone = TS590_TONES[_mem.rtone] if _mem.tmode == 1: mem.tmode = "Tone" elif _mem.tmode == 2: mem.tmode = "TSQL" elif _mem.tmode == 3: mem.tmode = "Cross" mem.skip = TS590_SKIP[_mem.skip] # Channel Extra settings: Only Boolean & List methods, no call-backs options = ["Wide", "Narrow"] rx = RadioSettingValueList(options, options[_mem.fmnrw]) # NOTE: first param of RadioSetting is the object attribute name rset = RadioSetting("fmnrw", "FM mode", rx) rset.set_apply_callback(my_val_list, options, _mem, "fmnrw") mem.extra.append(rset) options = ["Filter A", "Filter B"] rx = RadioSettingValueList(options, options[_mem.filter]) rset = RadioSetting("filter", "Filter A/B", rx) rset.set_apply_callback(my_val_list, options, _mem, "filter") mem.extra.append(rset) return mem def set_memory(self, mem): """Convert UI column data (mem) into MEM_FORMAT memory (_mem)""" _mem = self._memobj.ch_mem[mem.number] if mem.empty: _mem.rxfreq = 0 _mem.txfreq = 0 _mem.xmode = 0 _mem.data = 0 _mem.tmode = 0 _mem.rtone = 0 _mem.ctone = 0 _mem.filter = 0 _mem.skip = 0 _mem.fmnrw = 0 _mem.name = " " return if mem.number > self._upper: # Specials: No Name changes ix = 0 # LOG.warning("Special Chan set_mem @ %i" % mem.number) else: nx = len(mem.name) for ix in range(8): if ix < nx: _mem.name[ix] = mem.name[ix].upper() else: _mem.name[ix] = " " # assignment needs 8 chrs _mem.rxfreq = mem.freq _mem.txfreq = 0 if mem.duplex == "+": _mem.txfreq = mem.freq + mem.offset if mem.duplex == "-": _mem.txfreq = mem.freq - mem.offset ix = TS590_MODES.index(mem.mode) _mem.data = 0 _mem.xmode = ix + 1 # stored as CAT values, LSB= 1 if ix == 7: # FSK-R _mem.xmode = 9 # There is no CAT 8 if ix > 7: # a Data mode _mem.data = 1 if ix == 8: _mem.xmode = 1 # LSB elif ix == 9: _mem.xmode = 2 # USB elif ix == 10: _mem.xmode = 4 # FM _mem.tmode = 0 _mem.rtone = TS590_TONES.index(mem.rtone) _mem.ctone = TS590_TONES.index(mem.ctone) if mem.tmode == "Tone": _mem.tmode = 1 if mem.tmode == "TSQL": _mem.tmode = 2 if mem.tmode == "Cross" or mem.tmode == "Tone->Tone": _mem.tmode = 3 _mem.skip = 0 if mem.skip == "S": _mem.skip = 1 for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) return def _parse_mem_spec(self, spec0, spec1): """ Extract ascii memory parameters; build data string """ # spec0 is simplex result, spec1 is split # pad string so indexes match Kenwood docs spec0 = "x" + spec0 # match CAT document 1-based description ix = len(spec0) # _pxx variables are STRINGS _p1 = spec0[3] # P1 Split Specification _p3 = spec0[4:7] # P3 Memory Channel _p4 = spec0[7:18] # P4 Frequency _p5 = spec0[18] # P5 Mode _p6 = spec0[19] # P6 Data Mode _p7 = spec0[20] # P7 Tone Mode _p8 = spec0[21:23] # P8 Tone Frequency Index if _p8 == "00": # Can't be 0 at upload _p8 = "08" _p9 = spec0[23:25] # P9 CTCSS Frequency Index if _p9 == "00": _p9 = "08" _p10 = spec0[25:28] # P10 Always 0 _p11 = spec0[28] # P11 Filter A/B _p12 = spec0[29] # P12 Always 0 _p13 = spec0[30:38] # P13 Always 0 _p14 = spec0[38:40] # P14 FM Mode _p15 = spec0[40] # P15 Chan Lockout (Skip) _p16 = spec0[41:49] # P16 Max 8-Char Name if assigned spec1 = "x" + spec1 _p4s = int(spec1[7:18]) # P4: Offset freq datm = "" # Fill in MEM_FORMAT sequence datm += _make_dat(_p4, 4) # rxreq: u32, 4 bytes/chars datm += _make_dat(_p4s, 4) # tx freq v1 = int(_p5) << 4 # xMode: 0-9, upper 4 bits v1 = v1 | (int(_p6) << 2) # Data: 0/1 v1 = v1 | int(_p7) # Tmode: 0-3 datm += chr(v1) datm += chr(int(_p8)) # rtone: 00-42 datm += chr(int(_p9)) # ctone v1 = int(_p11) << 7 # Filter A/B 1 bit msb v1 = v1 | (int(_p14) << 6) # fmwide: 1 bit v1 = v1 | (int(_p15) << 5) # skip: 1 bit datm += chr(v1) v1 = len(_p16) for ix in range(8): if ix < v1: datm += _p16[ix] else: datm += " " return datm def _make_base_spec(self, mem, freq): """ Generate memory channel parameter string """ spec = "%011i%1i%1i%1i%02i%02i000%1i0000000000%02i%1i%s" \ % (freq, mem.xmode, mem.data, mem.tmode, mem.rtone, mem.ctone, mem.filter, mem.fmnrw, mem.skip, mem.name) return spec.strip() def get_settings(self): """Translate the MEM_FORMAT structs into settings in the UI""" # Define mem struct write-back shortcuts _sets = self._memobj.settings _asf = self._memobj.asf _ssf = self._memobj.ssf _eqx = self._memobj.eqx _mex = self._memobj.exset _chm = self._memobj.ch_mem basic = RadioSettingGroup("basic", "Basic Settings") pvfo = RadioSettingGroup("pvfo", "VFO Band Edges") mena = RadioSettingGroup("mena", "Menu A") menb = RadioSettingGroup("menb", "Menu B") equ = RadioSettingGroup("equ", "Equalizers") amode = RadioSettingGroup("amode", "Auto Mode") ssc = RadioSettingGroup("ssc", "Slow Scan") group = RadioSettings(basic, pvfo, mena, menb, equ, amode, ssc) mhz1 = 1000000. nsg = not self.SG if nsg: # Make reverse EX_X dictionary x_ex = {v: k for k, v in self.EX_X.items()} # Callback functions def _my_readonly(setting, obj, atrb): """NOP callback, prevents writing the setting""" vx = 0 return def my_adjraw(setting, obj, atrb, fix=0, ndx=-1): """Callback for Integer add or subtract fix from value.""" vx = int(str(setting.value)) value = vx + int(fix) if value < 0: value = 0 if ndx < 0: setattr(obj, atrb, value) else: setattr(obj[ndx], atrb, value) return def my_mhz_val(setting, obj, atrb, ndx=-1): """ Callback to set freq back to Hz """ vx = float(str(setting.value)) vx = int(vx * mhz1) if ndx < 0: setattr(obj, atrb, vx) else: setattr(obj[ndx], atrb, vx) return def my_bool(setting, obj, atrb, ndx=-1): """ Callback to properly set boolean """ # set_settings is not setting [indexed] booleans??? vx = 0 if str(setting.value) == "True": vx = 1 if ndx < 0: setattr(obj, atrb, vx) else: setattr(obj[ndx], atrb, vx) return def my_asf_mode(setting, obj, nx=0): """ Callback to extract mode and create asmode, asdata """ v1 = TS590_MODES.index(str(setting.value)) v2 = 0 # asdata vx = v1 + 1 # stored as CAT values, same as xmode if v1 == 7: vx = 9 if v1 > 7: # a Data mode v2 = 1 if v1 == 8: vx = 1 # LSB elif v1 == 9: vx = 2 # USB elif v1 == 10: vx = 4 # FM setattr(obj[nx], "asdata", v2) setattr(obj[nx], "asmode", vx) return def my_fnctns(setting, obj, ndx, atrb): """ Filter only valid key function assignments """ vx = int(str(setting.value)) if self.SG: vmx = 210 if (vx > 99 and vx < 120) or (vx > 170 and vx < 200): raise errors.RadioError(" %i Change Ignored for %s." % (vx, atrb)) return # not valid, ignored else: vmx = 208 if (vx > 87 and vx < 100) or (vx > 134 and vx < 200): raise errors.RadioError(" %i Change Ignored for %s." % (vx, atrb)) return if vx > vmx: vx = 255 # Off setattr(obj[ndx], atrb, vx) return def my_labels(kx): # nsg and x_ex defined above lbl = "%03i:" % kx # SG EX number if nsg: lbl = x_ex["EX%03i" % kx][2:] + ":" # S-model EX num lbl += self.EX_LBL[kx] # and the label to match return lbl # ===== BASIC GROUP ===== sx = "" for i in range(4): sx += chr(_sets.fv[i]) rx = RadioSettingValueString(0, 4, sx) rset = RadioSetting("settings.fv", "FirmwareVersion", rx) rset.set_apply_callback(_my_readonly, _sets, "fv") basic.append(rset) rx = RadioSettingValueInteger(0, 255, _sets.ag + 1) rset = RadioSetting("settings.ag", "AF Gain", rx) rset.set_apply_callback(my_adjraw, _sets, "ag", -1) basic.append(rset) rx = RadioSettingValueInteger(0, 255, _sets.rg + 1) rset = RadioSetting("settings.rg", "RF Gain", rx) rset.set_apply_callback(my_adjraw, _sets, "rg", -1) basic.append(rset) options = ["ANT1", "ANT2"] # CAUTION: an1 has value of 1 or 2 rx = RadioSettingValueList(options, options[_sets.an1 - 1]) rset = RadioSetting("settings.an1", "Antenna Selected", rx) # Add 1 to the changed value. S/b 1/2 rset.set_apply_callback(my_val_list, options, _sets, "an1", 1) basic.append(rset) rx = RadioSettingValueBoolean(bool(_sets.an2)) rset = RadioSetting("settings.an2", "Recv Antenna is used", rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(_sets.an3)) rset = RadioSetting("settings.an3", "Drive Out On", rx) basic.append(rset) rx = RadioSettingValueInteger(0, 100, _sets.mg) rset = RadioSetting("settings.mg", "Microphone gain", rx) basic.append(rset) nx = 5 # Coarse step if bool(_mex[0].ex054): # Power Fine enabled in menu A nx = 1 vx = _sets.pc # Trap invalid values from run_tests.py if vx < 5: vx = 5 rx = RadioSettingValueInteger(5, 100, vx, nx) sx = "TX Output power (Watts)" rset = RadioSetting("settings.pc", sx, rx) basic.append(rset) vx = _sets.tp rx = RadioSettingValueInteger(5, 100, vx, nx) sx = "TX Tuning power (Watts)" rset = RadioSetting("settings.tp", sx, rx) basic.append(rset) val = _sets.fa / mhz1 # Allow Rx freq range rx = RadioSettingValueFloat(0.3, 60.0, val, 0.001, 3) sx = "VFO-A Frequency (MHz)" rset = RadioSetting("settings.fa", sx, rx) rset.set_apply_callback(my_mhz_val, _sets, "fa") basic.append(rset) val = _sets.fb / mhz1 rx = RadioSettingValueFloat(0.3, 60.0, val, 0.001, 3) sx = "VFO-B Frequency (MHz)" rset = RadioSetting("settings.fb", sx, rx) rset.set_apply_callback(my_mhz_val, _sets, "fb") basic.append(rset) options = ["Menu A", "Menu B"] rx = RadioSettingValueList(options, options[_sets.mf]) sx = "Menu Selected" rset = RadioSetting("settings.mf", sx, rx) rset.set_apply_callback(my_val_list, options, _sets, "mf") basic.append(rset) # ==== VFO Edges Group ================ for mx in range(100, 110): val = _chm[mx].rxfreq / mhz1 if val < 1.8: # Many operators never use this val = 1.8 # So default is 0.0 rx = RadioSettingValueFloat(1.8, 54.0, val, 0.001, 3) sx = "VFO-Band %i lower limit (MHz)" % (mx - 100) rset = RadioSetting("ch_mem.rxfreq/%d" % mx, sx, rx) rset.set_apply_callback(my_mhz_val, _chm, "rxfreq", mx) pvfo.append(rset) val = _chm[mx].txfreq / mhz1 if val < 1.8: val = 54.0 rx = RadioSettingValueFloat(1.8, 54.0, val, 0.001, 3) sx = " VFO-Band %i upper limit (MHz)" % (mx - 100) rset = RadioSetting("ch_mem.txfreq/%d" % mx, sx, rx) rset.set_apply_callback(my_mhz_val, _chm, "txfreq", mx) pvfo.append(rset) kx = _chm[mx].xmode options = ["None", "LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "N/A", "FSK-R"] rx = RadioSettingValueList(options, options[kx]) sx = " VFO-Band %i Tx/Rx Mode" % (mx - 100) rset = RadioSetting("ch_mem.xmode/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _chm, "xmode", 0, mx) pvfo.append(rset) # ==== Menu A/B Group ================= for mx in range(2): # A/B index sx = "" for i in range(8): if int(_mex[mx].ex001[i]) != 0: sx += chr(_mex[mx].ex001[i]) sx = sx.strip() rx = RadioSettingValueString(0, 8, sx) sx = my_labels(1) # Proper label for EX001 rset = RadioSetting("exset.ex001/%d" % mx, sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) sx = my_labels(2) rx = RadioSettingValueInteger(0, 6, _mex[mx].ex002) rset = RadioSetting("exset.ex002", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) nx = 2 if self.SG: nx = 10 vx = _mex[mx].ex003 + 1 # radio rtns 0-9 rx = RadioSettingValueInteger(1, nx, vx) sx = my_labels(3) rset = RadioSetting("exset.ex003", sx, rx) rset.set_apply_callback(my_adjraw, _mex, "ex003", -1, mx) if mx == 0: mena.append(rset) else: menb.append(rset) nx = 9 if self.SG: nx = 20 rx = RadioSettingValueInteger(0, nx, _mex[mx].ex005) sx = my_labels(5) rset = RadioSetting("exset.ex005", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) sx = my_labels(6) rx = RadioSettingValueInteger(0, nx, _mex[mx].ex006) rset = RadioSetting("exset.ex006", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) sx = my_labels(7) rx = RadioSettingValueInteger(0, nx, _mex[mx].ex007) rset = RadioSetting("exset.ex007", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) nx = 7 if self.SG: nx = 20 sx = my_labels(8) rx = RadioSettingValueInteger(0, nx, _mex[mx].ex008) rset = RadioSetting("exset.ex008", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) sx = my_labels(9) rx = RadioSettingValueInteger(0, 4, _mex[mx].ex009) rset = RadioSetting("exset.ex009", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["English", "Japanese"] rx = RadioSettingValueList(options, options[_mex[mx].ex010]) sx = my_labels(10) rset = RadioSetting("exset.ex010/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex010", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["Off", "1", "2"] rx = RadioSettingValueList(options, options[_mex[mx].ex011]) sx = my_labels(11) rset = RadioSetting("exset.ex011/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex011", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["0.1", "0.5", "1.0"] rx = RadioSettingValueList(options, options[_mex[mx].ex012]) sx = my_labels(12) rset = RadioSetting("exset.ex012", sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex012", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["250", "500", "1000"] rx = RadioSettingValueList(options, options[_mex[mx].ex013]) sx = my_labels(13) rset = RadioSetting("exset.ex013/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex013", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) # S and SG have different ranges for control steps options = ["0.5", "1.0", "2.5", "5.0", "10.0"] if self.SG: options = ["Off", "0.5", "0.5", "1.0", "2.5", "5.0", "10.0"] rx = RadioSettingValueList(options, options[_mex[mx].ex016]) sx = my_labels(16) if nsg: sx = "014: Tuning step for SSB/CW/FSK (kHz)" rset = RadioSetting("exset.ex016/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex016", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) if self.SG: # this setting only for SG rx = RadioSettingValueList(options, options[_mex[mx].ex017]) sx = my_labels(17) rset = RadioSetting("exset.ex017/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex017", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["Off", "5.0", "6.25", "10.0", "12.5", "15.0", "20.0", "25.0", "30.0", "50.0", "100.0"] if self.SG: options.remove("Off") rx = RadioSettingValueList(options, options[_mex[mx].ex018]) sx = my_labels(18) rset = RadioSetting("exset.ex018/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex018", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueList(options, options[_mex[mx].ex019]) sx = my_labels(19) rset = RadioSetting("exset.ex019/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex019", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["3", "5", "10"] rx = RadioSettingValueList(options, options[_mex[mx].ex021]) sx = my_labels(21) rset = RadioSetting("exset.ex021/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex021", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex022)) sx = my_labels(22) rset = RadioSetting("exset.ex022/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex022", mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex023)) sx = my_labels(23) rset = RadioSetting("exset.ex023/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex023", mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["100", "200", "300", "400", "500"] rx = RadioSettingValueList(options, options[_mex[mx].ex024]) sx = my_labels(24) rset = RadioSetting("exset.ex024/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex024", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex025)) sx = my_labels(25) rset = RadioSetting("exset.ex025/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex025", mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["TO", "CO"] rx = RadioSettingValueList(options, options[_mex[mx].ex026]) sx = my_labels(26) rset = RadioSetting("exset.ex026/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex026", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex054)) sx = my_labels(54) rset = RadioSetting("exset.ex054/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex054", mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["Off", "3", "5", "10", "20", "30"] rx = RadioSettingValueList(options, options[_mex[mx].ex055]) sx = my_labels(55) rset = RadioSetting("exset.ex055/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex055", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex076)) sx = my_labels(76) rset = RadioSetting("exset.ex076/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex076", mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 100, _mex[mx].ex077, 5) sx = my_labels(77) rset = RadioSetting("exset.ex077/%d" % mx, sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex087) sx = my_labels(87) rset = RadioSetting("exset.ex087/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex087") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex088) sx = my_labels(88) rset = RadioSetting("exset.ex088/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex088") if mx == 0: mena.append(rset) else: menb.append(rset) if self.SG: # Next 5 settings not supported in 590S rx = RadioSettingValueInteger(0, 256, _mex[mx].ex089) sx = my_labels(89) rset = RadioSetting("exset.ex089/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex089") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex090) sx = my_labels(90) rset = RadioSetting("exset.ex090/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex090") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex091) sx = my_labels(91) rset = RadioSetting("exset.ex091/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex091") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex092) sx = my_labels(92) rset = RadioSetting("exset.ex092/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex092") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex093) sx = my_labels(93) rset = RadioSetting("exset.ex093/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex093") if mx == 0: mena.append(rset) else: menb.append(rset) # Now both S and SG models rx = RadioSettingValueInteger(0, 256, _mex[mx].ex094) sx = my_labels(94) rset = RadioSetting("exset.ex094/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex094") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex095) sx = my_labels(95) rset = RadioSetting("exset.ex095/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex095") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex096) sx = my_labels(96) rset = RadioSetting("exset.ex096/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex096") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex097) sx = my_labels(97) rset = RadioSetting("exset.ex097/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex097") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex098) sx = my_labels(98) rset = RadioSetting("exset.ex098/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex098") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 256, _mex[mx].ex099) sx = my_labels(99) rset = RadioSetting("exset.ex099/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex099") if mx == 0: mena.append(rset) else: menb.append(rset) # End of for mx loop # ==== Auto Scan Params (amode) ============== for ix in range(32): val = _asf[ix].asfreq / mhz1 rx = RadioSettingValueFloat(0.03, 60.0, val, 0.001, 3) rset = RadioSetting("asf.asfreq/%d" % ix, "Scan %02i Freq (MHz)" % ix, rx) rset.set_apply_callback(my_mhz_val, _asf, "asfreq", ix) amode.append(rset) mx = _asf[ix].asmode - 1 # Same logic as xmode if _asf[ix].asmode == 9: mx = 7 if _asf[ix].asdata: if _asf[ix].asmode == 1: mx = 8 elif _asf[ix].asmode == 2: mx = 9 elif _asf[ix].asmode == 4: mx = 10 rx = RadioSettingValueList(TS590_MODES, TS590_MODES[mx]) rset = RadioSetting("asf.asmode/%d" % ix, " Mode", rx) rset.set_apply_callback(my_asf_mode, _asf, ix) amode.append(rset) # ==== Slow Scan Settings === for ix in range(10): # Chans for nx in range(5): # spots px = ((ix * 5) + nx) val = _ssf[px].ssfreq / mhz1 stx = " - - - Slot %02i Freq (MHz)" % nx if nx == 0: stx = "Slow Scan %02i, Slot 0 Freq (MHz" % ix rx = RadioSettingValueFloat(0, 54.0, val, 0.001, 3) rset = RadioSetting("ssf.ssfreq/%d" % px, stx, rx) rset.set_apply_callback(my_mhz_val, _ssf, "ssfreq", px) ssc.append(rset) # ==== Equalizer subgroup ===== mohd = ["SSB", "SSB-DATA", "CW/CW-R", "FM", "FM-DATA", "AM", "AM-DATA", "FSK/FSK-R"] tcurves = ["Off", "HB1", "HB2", "FP", "BB1", "BB2", "C", "U"] rcurves = ["Off", "HB1", "HB2", "FP", "BB1", "BB2", "FLAT", "U"] for ix in range(8): rx = RadioSettingValueList(tcurves, tcurves[_eqx[ix].txeq]) rset = RadioSetting("eqx.txeq/%d" % ix, "TX %s Equalizer" % mohd[ix], rx) rset.set_apply_callback(my_val_list, tcurves, _eqx, "txeq", 0, ix) equ.append(rset) rx = RadioSettingValueList(rcurves, rcurves[_eqx[ix].rxeq]) rset = RadioSetting("eqx.rxeq/%d" % ix, "RX %s Equalizer" % mohd[ix], rx) rset.set_apply_callback(my_val_list, rcurves, _eqx, "rxeq", 0, ix) equ.append(rset) return group # END get_settings() def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, fdata, fyle): """ Included to prevent 'File > New' error """ return False @directory.register class TS590SRadio(TS590Radio): """ Kenwood TS-590S variant of the TS590 """ VENDOR = "Kenwood" MODEL = "TS-590S_CloneMode" ID = "ID021;" SG = False # This is the equivalent Menu A/B list for the TS-590S # The equivalent S param is stored in the SG Mem_Format slot EX = ["EX087", "EX000", "EX001", "EX003", "EX004", "EX005", "EX006", "EX007", "EX008", "EX009", "EX010", "EX011", "EX014", "EX014", "EX015", "EX016", "EX017", "EX018", "EX019", "EX020", "EX021", "EX022", "EX048", "EX049", "EX069", "EX070", "EX079", "EX080", "EX080", "EX080", "EX080", "EX080", "EX080", "EX081", "EX082", "EX083", "EX084", "EX085", "EX086", "MF1"] # EX cross reference dictionary- key is S param, value is the SG EX_X = {"EX087": "EX001", "EX000": "EX002", "EX001": "EX003", "EX003": "EX005", "EX004": "EX006", "EX005": "EX007", "EX006": "EX008", "EX007": "EX009", "EX008": "EX010", "EX009": "EX011", "EX010": "EX012", "EX011": "EX013", "EX014": "EX016", "EX015": "EX018", "EX081": "EX094", "EX016": "EX019", "EX017": "EX021", "EX018": "EX022", "EX019": "EX023", "EX020": "EX024", "EX021": "EX025", "EX022": "EX026", "EX048": "EX054", "EX049": "EX055", "EX069": "EX076", "EX070": "EX077", "EX079": "EX087", "EX080": "EX088", "EX082": "EX095", "EX083": "EX096", "EX084": "EX097", "EX085": "EX098", "EX086": "EX099"} chirp-20240224/chirp/drivers/id31.py0000644000175000017500000002344514435610651015746 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import icf from chirp import directory, bitwise, chirp_common, settings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { u24 freq; u16 offset; u16 rtone:6, ctone:6, unknown2:1, mode:3; u8 dtcs; u8 tune_step:4, dsql_mode:2, unknown5:2; u8 unknown4; u8 tmode:4, duplex:2, dtcs_polarity:2; char name[16]; u8 digcode; u8 urcall[7]; u8 rpt1call[7]; u8 rpt2call[7]; } memory[500]; #seekto 0x69C0; u8 used_flags[70]; #seekto 0x6A06; u8 skip_flags[69]; #seekto 0x6A4B; u8 pskp_flags[69]; #seekto 0x6AC0; struct { u8 bank; u8 index; } banks[500]; #seekto 0x6F50; struct { char name[16]; } bank_names[26]; #seekto 0x74BF; struct { u8 unknown0; u24 freq; u16 offset; u8 unknown1[3]; u8 call[7]; char name[16]; char subname[8]; u8 unknown3[9]; } repeaters[700]; #seekto 0xFABC; struct { u8 call[7]; } rptcall[700]; #seekto 0x10F20; struct { char call[8]; char tag[4]; } mycall[6]; #seekto 0x10F68; struct { char call[8]; } urcall[200]; """ TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS", "TSQL-R", "DTCS-R"] DUPLEX = ["", "-", "+"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] TUNING_STEPS = [5.0, 6.25, 0, 0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 125.0, 200.0] DSQL_MODES = ['', 'DSQL', 'CSQL'] def _decode_call(_call): # Why Icom, why? return ''.join(chr(x) for x in icf.warp_byte_size(_call, 7, 8)) def _encode_call(call): return list(icf.warp_byte_size(call.ljust(8), 8, 7)) def _get_freq(_mem): freq = int(_mem.freq) offs = int(_mem.offset) if freq & 0x00200000: mult = 6250 else: mult = 5000 freq &= 0x0003FFFF return (freq * mult), (offs * mult) def _set_freq(_mem, freq, offset): if chirp_common.is_fractional_step(freq): mult = 6250 flag = 0x00200000 else: mult = 5000 flag = 0x00000000 _mem.freq = (freq // mult) | flag _mem.offset = (offset // mult) class ID31Bank(icf.IcomBank): """A ID-31 Bank""" def get_name(self): _banks = self._model._radio._memobj.bank_names return str(_banks[self.index].name).rstrip() def set_name(self, name): _banks = self._model._radio._memobj.bank_names _banks[self.index].name = str(name).ljust(16)[:16] @directory.register class ID31Radio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): """Icom ID-31""" MODEL = "ID-31A" _memsize = 0x15500 _model = "\x33\x22\x00\x01" _endframe = "Icom Inc\x2E\x41\x38" _num_banks = 26 _bank_class = ID31Bank _can_hispeed = True _icf_data = { 'MapRev': 1, 'EtcData': 0x000005, } _ranges = [(0x00000, 0x15500, 32)] MODES = {0: "FM", 1: "NFM", 5: "DV"} def _get_bank(self, loc): _bank = self._memobj.banks[loc] if _bank.bank == 0xFF: return None else: return _bank.bank def _set_bank(self, loc, bank): _bank = self._memobj.banks[loc] if bank is None: _bank.bank = 0xFF else: _bank.bank = bank def _get_bank_index(self, loc): _bank = self._memobj.banks[loc] return _bank.index def _set_bank_index(self, loc, index): _bank = self._memobj.banks[loc] _bank.index = index def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 499) rf.valid_bands = [(400000000, 479000000)] rf.has_settings = True rf.has_ctone = True rf.has_bank_index = True rf.has_bank_names = True rf.valid_tmodes = list(TMODES) rf.valid_tuning_steps = sorted(list(TUNING_STEPS)) rf.valid_modes = list(self.MODES.values()) rf.valid_skips = ["", "S", "P"] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 16 rf.requires_call_lists = False return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _get_mem_extra(self, _mem, mem): extra = settings.RadioSettingGroup('extra', 'Extra') rs = settings.RadioSetting( 'dsql', 'DSQL Mode', settings.RadioSettingValueList( DSQL_MODES, current_index=int(_mem.dsql_mode))) extra.append(rs) return extra def _set_mem_extra(self, _mem, mem): try: _mem.dsql_mode = DSQL_MODES.index(str(mem.extra['dsql'].value)) except (KeyError, TypeError): # No settings or dsql is not provided pass except ValueError: LOG.error('Invalid extra.dsql_mode: %r' % str( mem.extra['dsql'].value)) def get_memory(self, number): _mem = self._memobj.memory[number] _usd = self._memobj.used_flags[number / 8] _skp = self._memobj.skip_flags[number / 8] _psk = self._memobj.pskp_flags[number / 8] bit = (1 << (number % 8)) if self.MODES[int(_mem.mode)] == "DV": mem = chirp_common.DVMemory() else: mem = chirp_common.Memory() mem.number = number if _usd & bit: mem.empty = True return mem mem.freq, mem.offset = _get_freq(_mem) mem.name = str(_mem.name).rstrip() mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.tuning_step = TUNING_STEPS[_mem.tune_step] mem.mode = self.MODES[int(_mem.mode)] if mem.mode == "DV": mem.dv_urcall = _decode_call(_mem.urcall).rstrip() mem.dv_rpt1call = _decode_call(_mem.rpt1call).rstrip() mem.dv_rpt2call = _decode_call(_mem.rpt2call).rstrip() mem.dv_code = int(_mem.digcode) if _psk & bit: mem.skip = "P" elif _skp & bit: mem.skip = "S" mem.extra = self._get_mem_extra(_mem, mem) return mem def set_memory(self, memory): _mem = self._memobj.memory[memory.number] _usd = self._memobj.used_flags[memory.number / 8] _skp = self._memobj.skip_flags[memory.number / 8] _psk = self._memobj.pskp_flags[memory.number / 8] bit = (1 << (memory.number % 8)) if memory.empty: _usd |= bit self._set_bank(memory.number, None) return _usd &= ~bit _set_freq(_mem, memory.freq, memory.offset) _mem.name = memory.name.ljust(16)[:16] _mem.rtone = chirp_common.TONES.index(memory.rtone) _mem.ctone = chirp_common.TONES.index(memory.ctone) _mem.tmode = TMODES.index(memory.tmode) _mem.duplex = DUPLEX.index(memory.duplex) _mem.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs) _mem.dtcs_polarity = DTCS_POLARITY.index(memory.dtcs_polarity) _mem.tune_step = TUNING_STEPS.index(memory.tuning_step) _mem.mode = next(i for i, mode in list(self.MODES.items()) if mode == memory.mode) if isinstance(memory, chirp_common.DVMemory): _mem.urcall = _encode_call(memory.dv_urcall.ljust(8)) _mem.rpt1call = _encode_call(memory.dv_rpt1call.ljust(8)) _mem.rpt2call = _encode_call(memory.dv_rpt2call.ljust(8)) _mem.digcode = memory.dv_code elif memory.mode == "DV": LOG.debug('Converting Memory to DVMemory with default values') _mem.urcall = _encode_call('CQCQCQ'.ljust(8)) _mem.rpt1call = _encode_call(' ' * 8) _mem.rpt2call = _encode_call(' ' * 8) _mem.digcode = 0 if memory.skip == "S": _skp |= bit _psk &= ~bit elif memory.skip == "P": _skp |= bit _psk |= bit else: _skp &= ~bit _psk &= ~bit self._set_mem_extra(_mem, memory) def get_urcall_list(self): calls = [] for i in range(0, 200): call = str(self._memobj.urcall[i].call) if call == "CALLSIGN": call = "" calls.append(call) return calls def get_mycall_list(self): calls = [] for i in range(0, 6): calls.append(str(self._memobj.mycall[i].call)) return calls def get_repeater_call_list(self): calls = [] for rptcall in self._memobj.rptcall: call = _decode_call(rptcall.call) if call.rstrip() and not call == "CALLSIGN": calls.append(call) for repeater in self._memobj.repeaters: call = _decode_call(repeater.call) if call == "CALLSIGN": call = "" calls.append(call.rstrip()) return calls if __name__ == "__main__": print(repr(_decode_call(_encode_call("KD7REX B")))) print(repr(_decode_call(_encode_call(" B")))) print(repr(_decode_call(_encode_call(" ")))) chirp-20240224/chirp/drivers/anytone.py0000644000175000017500000005617714522657251016677 0ustar hibbyhibby# Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp import errors from chirp import memmap from chirp import util from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings, \ RadioSettingValueList, RadioSettingValueString, RadioSettingValueBoolean LOG = logging.getLogger(__name__) BLOCK_SIZE = 0x10 NUMBER_OF_MEMORY_LOCATIONS = 758 MEMORY_LOCATION_SIZE = 32 ADDR_FIRST_WRITABLE_BYTE = 0x0100 ADDR_LAST_BLOCK_BEFORE_MEMORIES = 0x19F0 ADDR_FIRST_MEMORY_LOCATION = 0x2000 # This _mem_format structure is defined separately from the rest because it # needs to be parsed twice -- once in the middle of downloading data from the # radio, and then again (along with everything else) once the download is # complete. _mem_format = """ #seekto 0x0100; struct { u8 even_unknown:2, even_pskip:1, even_skip:1, odd_unknown:2, odd_pskip:1, odd_skip:1; } flags[379]; """ mem_format = _mem_format + """ struct memory { bbcd freq[4]; bbcd offset[4]; u8 unknownA:4, tune_step:4; u8 rxdcsextra:1, txdcsextra:1, rxinv:1, txinv:1, channel_width:2, rev:1, txoff:1; u8 talkaround:1, compander:1, unknown8:1, is_am:1, power:2, duplex:2; u8 dtmfSlotNum:4, rxtmode:2, txtmode:2; u8 unknown5:2, txtone:6; u8 unknown6:2, rxtone:6; u8 txcode; u8 rxcode; u8 unknown10:2, pttid:2, unknown11:2, bclo:2; u8 unknown7; u8 unknown9:5, sqlMode:3; // [Carrier, CTCSS/DCS Tones, // Opt Sig Only, Tones & Opt Sig, // Tones or Opt Sig] u8 unknown21:6, optsig:2; u8 unknown22:3, twotone:5; u8 unknown23:1, fivetone:7; u8 unknown24:4, scramble:4; char name[7]; ul16 custtone; }; #seekto 0x0030; struct { char serial[16]; } serial_no; #seekto 0x0050; struct { char date[16]; } version; #seekto 0x0280; struct { u8 unknown1:6, display:2; u8 unknown2[11]; // TODO Backlight brightness is in here (RGB) u8 unknown3:3, apo:5; u8 unknown4a[2]; u8 unknown4b:6, mute:2; // TODO Keypad locked is in here (0=unlocked, 1=locked) u8 unknown4; u8 unknown5:5, beep:1, unknown6:2; u8 unknown[334]; // TODO Programmable keys A-D are here char welcome[8]; } settings; #seekto 0x0540; struct memory memblk1[12]; #seekto 0x2000; struct memory memory[758]; // FIXME It's actually only 750 // TODO VFO scan limits are here (after the 750th memory; seekto 0x7DC0) #seekto 0x7ec0; struct memory memblk2[10]; """ class FlagObj(object): def __init__(self, flagobj, which): self._flagobj = flagobj self._which = which def _get(self, flag): return getattr(self._flagobj, "%s_%s" % (self._which, flag)) def _set(self, flag, value): return setattr(self._flagobj, "%s_%s" % (self._which, flag), value) def get_skip(self): return self._get("skip") def set_skip(self, value): self._set("skip", value) skip = property(get_skip, set_skip) def get_pskip(self): return self._get("pskip") def set_pskip(self, value): self._set("pskip", value) pskip = property(get_pskip, set_pskip) def set(self): self._set("unknown", 3) self._set("skip", 1) self._set("pskip", 1) def clear(self): self._set("unknown", 0) self._set("skip", 0) self._set("pskip", 0) def get(self): return (self._get("unknown") << 2 | self._get("skip") << 1 | self._get("pskip")) def __repr__(self): return repr(self._flagobj) def _is_loc_used(memobj, loc): return memobj.flags[loc / 2].get_raw(asbytes=False) != "\xFF" def _addr_to_loc(addr): return (addr - ADDR_FIRST_MEMORY_LOCATION) / MEMORY_LOCATION_SIZE def _should_send_addr(memobj, addr): if addr < ADDR_FIRST_MEMORY_LOCATION or addr >= 0x7EC0: return True else: return _is_loc_used(memobj, _addr_to_loc(addr)) def _echo_write(radio, data): try: radio.pipe.write(data) radio.pipe.read(len(data)) except Exception as e: LOG.error("Error writing to radio: %s" % e) raise errors.RadioError("Unable to write to radio") def _read(radio, length): try: data = radio.pipe.read(length) except Exception as e: LOG.error("Error reading from radio: %s" % e) raise errors.RadioError("Unable to read from radio") if len(data) != length: LOG.error("Short read from radio (%i, expected %i)" % (len(data), length)) LOG.debug(util.hexprint(data)) raise errors.RadioError("Short read from radio") return data valid_model = [b'QX588UV', b'HR-2040', b'DB-50M\x00', b'DB-750X'] def _ident(radio): radio.pipe.timeout = 1 _echo_write(radio, b"PROGRAM") response = radio.pipe.read(3) if response != b"QX\x06": LOG.debug("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Unsupported model or bad connection") _echo_write(radio, b"\x02") response = radio.pipe.read(16) LOG.debug(util.hexprint(response)) if response[1:8] not in valid_model: LOG.debug("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Unsupported model") def _finish(radio): endframe = b"\x45\x4E\x44" _echo_write(radio, endframe) result = radio.pipe.read(1) if result != b"\x06": LOG.debug("Got:\n%s" % util.hexprint(result)) raise errors.RadioError("Radio did not finish cleanly") def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def _send(radio, cmd, addr, length, data=None): frame = struct.pack(">cHb", cmd, addr, length) if data: frame += data frame += struct.pack('BB', _checksum(frame[1:]), 0x06) _echo_write(radio, frame) LOG.debug("Sent:\n%s" % util.hexprint(frame)) if data: result = radio.pipe.read(1) if result != b'\x06': LOG.debug("Ack was: %s" % repr(result)) raise errors.RadioError( "Radio did not accept block at %04x" % addr) return result = _read(radio, length + 6) LOG.debug("Got:\n%s" % util.hexprint(result)) header = result[0:4] data = result[4:-2] ack = result[-1] if ack != 0x06: LOG.debug("Ack was: %s" % repr(ack)) raise errors.RadioError("Radio NAK'd block at %04x" % addr) _cmd, _addr, _length = struct.unpack(">cHb", header) if _addr != addr or _length != _length: LOG.debug("Expected/Received:") LOG.debug(" Length: %02x/%02x" % (length, _length)) LOG.debug(" Addr: %04x/%04x" % (addr, _addr)) raise errors.RadioError("Radio send unexpected block") cs = _checksum(result[1:-2]) if cs != result[-2]: LOG.debug("Calculated: %02x" % cs) LOG.debug("Actual: %02x" % result[-2]) raise errors.RadioError("Block at 0x%04x failed checksum" % addr) return data def _download(radio): _ident(radio) memobj = None data = b"" for start, end in radio._ranges: for addr in range(start, end, BLOCK_SIZE): if memobj is not None and not _should_send_addr(memobj, addr): block = b"\xFF" * BLOCK_SIZE else: block = _send(radio, b'R', addr, BLOCK_SIZE) data += block status = chirp_common.Status() status.cur = len(data) status.max = end status.msg = "Cloning from radio" radio.status_fn(status) if addr == ADDR_LAST_BLOCK_BEFORE_MEMORIES: memobj = bitwise.parse(_mem_format, data) _finish(radio) return memmap.MemoryMapBytes(data) def _upload(radio): _ident(radio) for start, end in radio._ranges: for addr in range(start, end, BLOCK_SIZE): if addr < ADDR_FIRST_WRITABLE_BYTE: continue if not _should_send_addr(radio._memobj, addr): continue block = radio._mmap[addr:addr + BLOCK_SIZE] _send(radio, b'W', addr, len(block), block) status = chirp_common.Status() status.cur = addr status.max = end status.msg = "Cloning to radio" radio.status_fn(status) _finish(radio) TONES = tuple(sorted([62.5] + list(chirp_common.TONES))) TMODES = ['', 'Tone', 'DTCS', ''] DUPLEXES = ['', '-', '+', 'off'] MODES = ["FM", "FM", "NFM"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Mid1", watts=25), chirp_common.PowerLevel("Mid2", watts=10), chirp_common.PowerLevel("Low", watts=5)] BCLO = ['Off', 'Repeater', 'Busy'] DTMF_SLOTS = ['M%d' % x for x in range(1, 17)] # Chose not to expose SCRAMBLE_CODES = ['Off'] + # ['%d' % x for x in range(1, 10)] + ['Define 1', 'Define 2'] TONE2_SLOTS = ['%d' % x for x in range(0, 24)] TONE5_SLOTS = ['%d' % x for x in range(0, 100)] SQL_MODES = ["Carrier", "CTCSS/DCS", "Opt Sig Only", "Tones AND Sig", "Tones OR Sig"] OPT_SIG_SQL = ["Off"] + SQL_MODES[2:] OPT_SIGS = ['Off', 'DTMF', '2Tone', '5Tone'] PTT_IDS = ['Off', 'Begin', 'End', 'Begin & End'] TUNING_STEPS = [2.5, 5, 6.25, 10, 12.5, 15, 20, 25, 30, 50] # FIXME (1) Not sure if 15 is a valid step, (2) 100 might be a valid step @directory.register class AnyTone5888UVRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """AnyTone 5888UV""" VENDOR = "AnyTone" MODEL = "5888UV" BAUD_RATE = 9600 _file_ident = [b"QX588UV", b"588UVN"] NEEDS_COMPAT_SERIAL = False # May try to mirror the OEM behavior later _ranges = [ (0x0000, 0x8000), ] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("The Anytone driver is currently experimental. " "There are no known issues with it, but you should " "proceed with caution.") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_cross = True rf.valid_duplexes = DUPLEXES rf.valid_tuning_steps = TUNING_STEPS rf.has_rx_dtcs = True rf.valid_skips = ["", "S", "P"] rf.valid_modes = ["FM", "NFM", "AM"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ['Tone->DTCS', 'DTCS->Tone', '->Tone', '->DTCS', 'Tone->Tone'] rf.valid_tones = TONES rf.valid_dtcs_codes = chirp_common.ALL_DTCS_CODES rf.valid_bands = [(108000000, 500000000)] rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-" rf.valid_name_length = 7 rf.valid_power_levels = POWER_LEVELS rf.memory_bounds = (1, NUMBER_OF_MEMORY_LOCATIONS) return rf def sync_in(self): self._mmap = _download(self) self.process_mmap() def sync_out(self): _upload(self) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def _get_memobjs(self, number): number -= 1 _mem = self._memobj.memory[number] _flg = FlagObj(self._memobj.flags[number / 2], number % 2 and "even" or "odd") return _mem, _flg def _get_dcs_index(self, _mem, which): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) return (int(extra) << 8) | int(base) def _set_dcs_index(self, _mem, which, index): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) base.set_value(index & 0xFF) extra.set_value(index >> 8) def get_raw_memory(self, number): _mem, _flg = self._get_memobjs(number) return repr(_mem) + repr(_flg) def get_memory(self, number): _mem, _flg = self._get_memobjs(number) mem = chirp_common.Memory() mem.number = number if _flg.get() == 0x0F: mem.empty = True return mem mem.freq = int(_mem.freq) * 100 # compensate for 6.25 and 12.5 kHz tuning steps, add 500 Hz if needed lastdigit = int(_mem.freq) % 10 if (lastdigit == 2 or lastdigit == 7): mem.freq += 50 mem.offset = int(_mem.offset) * 100 mem.name = str(_mem.name).rstrip() mem.duplex = DUPLEXES[_mem.duplex] mem.mode = _mem.is_am and "AM" or MODES[_mem.channel_width] mem.tuning_step = TUNING_STEPS[_mem.tune_step] if _mem.txoff: mem.duplex = DUPLEXES[3] rxtone = txtone = None rxmode = TMODES[_mem.rxtmode] if (_mem.sqlMode == SQL_MODES.index("Carrier") or _mem.sqlMode == SQL_MODES.index("Opt Sig Only")): rxmode = TMODES.index('') txmode = TMODES[_mem.txtmode] if txmode == "Tone": # If custom tone is being used, show as 88.5 (and set # checkbox in extras) Future: Improve chirp_common, so I # can add "CUSTOM" into TONES if _mem.txtone == len(TONES): txtone = 88.5 else: txtone = TONES[_mem.txtone] elif txmode == "DTCS": txtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem, 'tx')] if rxmode == "Tone": # If custom tone is being used, show as 88.5 (and set # checkbox in extras) Future: Improve chirp_common, so I # can add "CUSTOM" into TONES if _mem.rxtone == len(TONES): rxtone = 88.5 else: rxtone = TONES[_mem.rxtone] elif rxmode == "DTCS": rxtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem, 'rx')] rxpol = _mem.rxinv and "R" or "N" txpol = _mem.txinv and "R" or "N" chirp_common.split_tone_decode(mem, (txmode, txtone, txpol), (rxmode, rxtone, rxpol)) mem.skip = _flg.get_skip() and "S" or _flg.get_pskip() and "P" or "" mem.power = POWER_LEVELS[_mem.power] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("rev", "Reverse", RadioSettingValueBoolean(_mem.rev)) mem.extra.append(rs) rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(_mem.compander)) mem.extra.append(rs) rs = RadioSetting("talkaround", "Talkaround", RadioSettingValueBoolean(_mem.talkaround)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTT_IDS, PTT_IDS[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("bclo", "Busy Channel Lockout", RadioSettingValueList(BCLO, BCLO[_mem.bclo])) mem.extra.append(rs) rs = RadioSetting("optsig", "Optional Signaling", RadioSettingValueList(OPT_SIGS, OPT_SIGS[_mem.optsig])) mem.extra.append(rs) rs = RadioSetting("OPTSIGSQL", "Squelch w/Opt Signaling", RadioSettingValueList( OPT_SIG_SQL, SQL_MODES[_mem.sqlMode] if SQL_MODES[_mem.sqlMode] in OPT_SIG_SQL else "Off")) mem.extra.append(rs) rs = RadioSetting("dtmfSlotNum", "DTMF", RadioSettingValueList(DTMF_SLOTS, DTMF_SLOTS[_mem.dtmfSlotNum])) mem.extra.append(rs) rs = RadioSetting("twotone", "2-Tone", RadioSettingValueList(TONE2_SLOTS, TONE2_SLOTS[_mem.twotone])) mem.extra.append(rs) rs = RadioSetting("fivetone", "5-Tone", RadioSettingValueList(TONE5_SLOTS, TONE5_SLOTS[_mem.fivetone])) mem.extra.append(rs) # Chose not to expose scramble rs = RadioSetting("scramble", # "Scrambler Switch", RadioSettingValueList(SCRAMBLE_CODES, # SCRAMBLE_CODES[_mem.scramble])) mem.extra.append(rs) # Memory properties dialog is only capable of Boolean and List # RadioSettingValue classes, so cannot configure it rs = # RadioSetting("custtone", "Custom CTCSS", # RadioSettingValueFloat(min(TONES), max(TONES), _mem.custtone # and _mem.custtone / 10 or 151.1, 0.1, 1)) # mem.extra.append(rs) custToneStr = chirp_common.format_freq(_mem.custtone) rs = RadioSetting("CUSTTONETX", "Use Custom CTCSS (%s) for Tx" % custToneStr, RadioSettingValueBoolean(_mem.txtone == len(TONES))) mem.extra.append(rs) rs = RadioSetting("CUSTTONERX", "Use Custom CTCSS (%s) for Rx" % custToneStr, RadioSettingValueBoolean(_mem.rxtone == len(TONES))) mem.extra.append(rs) return mem def set_memory(self, mem): _mem, _flg = self._get_memobjs(mem.number) if mem.empty: _flg.set() return _flg.clear() _mem.set_raw("\x00" * MEMORY_LOCATION_SIZE) _mem.freq = mem.freq / 100 _mem.offset = mem.offset / 100 _mem.name = mem.name.ljust(7) _mem.is_am = mem.mode == "AM" _mem.tune_step = TUNING_STEPS.index(mem.tuning_step) if mem.duplex == "off": _mem.duplex = DUPLEXES.index("") _mem.txoff = 1 else: _mem.duplex = DUPLEXES.index(mem.duplex) _mem.txoff = 0 try: _mem.channel_width = MODES.index(mem.mode) except ValueError: _mem.channel_width = 0 ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) _mem.txtmode = TMODES.index(txmode) _mem.rxtmode = TMODES.index(rxmode) if rxmode != '': _mem.sqlMode = SQL_MODES.index("CTCSS/DCS") else: _mem.sqlMode = SQL_MODES.index("Carrier") if txmode == "Tone": _mem.txtone = TONES.index(txtone) elif txmode == "DTCS": self._set_dcs_index(_mem, 'tx', chirp_common.ALL_DTCS_CODES.index(txtone)) if rxmode == "Tone": _mem.rxtone = TONES.index(rxtone) elif rxmode == "DTCS": self._set_dcs_index(_mem, 'rx', chirp_common.ALL_DTCS_CODES.index(rxtone)) _mem.txinv = txpol == "R" _mem.rxinv = rxpol == "R" _flg.set_skip(mem.skip == "S") _flg.set_pskip(mem.skip == "P") if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 for setting in mem.extra: if setting.get_name() == "ignore": LOG.debug("*** ignore: %s" % str(setting.value)) # Future: elif setting.get_name() == "custtone": Future: # setattr(_mem, "custtone", setting.value.get_value() * # 10) elif setting.get_name() == "OPTSIGSQL": if str(setting.value) != "Off": _mem.sqlMode = SQL_MODES.index(str(setting.value)) elif setting.get_name() == "CUSTTONETX": if setting.value: _mem.txtone = len(TONES) elif setting.get_name() == "CUSTTONERX": if setting.value: _mem.rxtone = len(TONES) else: setattr(_mem, setting.get_name(), setting.value) return mem def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") settings = RadioSettings(basic) display = ["Frequency", "Channel", "Name"] rs = RadioSetting("display", "Display", RadioSettingValueList(display, display[_settings.display])) basic.append(rs) apo = ["Off"] + ['%.1f hour(s)' % (0.5 * x) for x in range(1, 25)] rs = RadioSetting("apo", "Automatic Power Off", RadioSettingValueList(apo, apo[_settings.apo])) basic.append(rs) def filter(s): s_ = "" for i in range(0, 8): c = str(s[i]) s_ += (c if c in chirp_common.CHARSET_ASCII else "") return s_ welcome_msg = ''.join(filter(_settings.welcome)) rs = RadioSetting("welcome", "Welcome Message", RadioSettingValueString(0, 8, welcome_msg)) basic.append(rs) rs = RadioSetting("beep", "Beep Enabled", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) MUTE_CHOICES = ["Off", "TX", "RX", "TX/RX"] rs = RadioSetting("mute", "Sub Band Mute", RadioSettingValueList(MUTE_CHOICES, MUTE_CHOICES[_settings.mute])) basic.append(rs) return settings def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue name = element.get_name() setattr(_settings, name, element.value) @classmethod def match_model(cls, filedata, filename): for _ident in cls._file_ident: if _ident in filedata[0x20:0x40]: return True return False @directory.register class IntekHR2040Radio(AnyTone5888UVRadio): """Intek HR-2040""" VENDOR = "Intek" MODEL = "HR-2040" _file_ident = [b"HR-2040"] @directory.register class PolmarDB50MRadio(AnyTone5888UVRadio): """Polmar DB-50M""" VENDOR = "Polmar" MODEL = "DB-50M" _file_ident = [b"DB-50M"] @directory.register class PowerwerxDB750XRadio(AnyTone5888UVRadio): """Powerwerx DB-750X""" VENDOR = "Powerwerx" MODEL = "DB-750X" _file_ident = [b"DB-750X"] def get_settings(self): return {} chirp-20240224/chirp/drivers/radioddity_r2.py0000644000175000017500000005213014556146076017747 0ustar hibbyhibby# Copyright August 2018 Klaus Ruebsam # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) # memory map # 0000 copy of channel 16: 0100 - 010F # 0010 Channel 1 # 0020 Channel 2 # 0030 Channel 3 # 0040 Channel 4 # 0050 Channel 5 # 0060 Channel 6 # 0070 Channel 7 # 0080 Channel 8 # 0090 Channel 9 # 00A0 Channel 10 # 00B0 Channel 11 # 00C0 Channel 12 # 00D0 Channel 13 # 00E0 Channel 14 # 00F0 Channel 15 # 0100 Channel 16 # 03C0 various settings # the last three bytes of every channel are identical # to the first three bytes of the next channel in row. # However it will automatically be filled by the radio itself MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 unknown1:1, compand:1, scramb:1, scanadd:1, power:1, mode:1, unknown2:1, bclo:1; u8 reserved[3]; } memory[%(memnum)i]; #seekto 0x03C0; struct { u8 unknown3c08:1, scanmode:1, unknown3c06:1, unknown3c05:1, voice:2, save:1, beep:1; u8 squelch; u8 unknown3c2; u8 timeout; u8 voxgain; u8 specialcode; u8 unknown3c6; u8 voxdelay; } settings; """ CMD_ACK = b"\x06" CMD_ALT_ACK = b"\x53" CMD_STX = b"\x02" CMD_ENQ = b"\x05" POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=0.50), chirp_common.PowerLevel("High", watts=3.00)] TIMEOUT_LIST = ["Off"] + ["%s seconds" % x for x in range(30, 330, 30)] SCANMODE_LIST = ["Carrier", "Timer"] VOICE_LIST = ["Off", "Chinese", "English"] VOX_LIST = ["Off"] + ["%s" % x for x in range(1, 9)] VOXDELAY_LIST = ["0.5", "1.0", "1.5", "2.0", "2.5", "3.0"] MODE_LIST = ["FM", "NFM"] TONES = chirp_common.TONES DTCS_CODES = chirp_common.DTCS_CODES FRS16_FREQS = [462562500, 462587500, 462612500, 462637500, 462662500, 462625000, 462725000, 462687500, 462712500, 462550000, 462575000, 462600000, 462650000, 462675000, 462700000, 462725000] PMR_FREQS1 = [446006250, 446018750, 446031250, 446043750, 446056250, 446068750, 446081250, 446093750] PMR_FREQS2 = [446106250, 446118750, 446131250, 446143750, 446156250, 446168750, 446181250, 446193750] PMR_FREQS = PMR_FREQS1 + PMR_FREQS2 VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`{|}!\"#$%&'()*+,-./:;<=>?@[]^_" def _r2_enter_programming_mode(radio): serial = radio.pipe magic = b"TYOGRAM" exito = False serial.write(CMD_STX) for i in range(0, 5): for j in range(0, len(magic)): serial.write(magic[j:j + 1]) ack = serial.read(1) if ack == CMD_ACK: exito = True break # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check your interface cable and power cycle your radio." raise errors.RadioError(msg) try: serial.write(CMD_STX) ident = serial.read(8) except: _r2_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") # No idea yet what the next 7 bytes stand for # as long as they start with ACK (or ALT_ACK on some devices) we are fine if not ident.startswith(CMD_ACK) and not ident.startswith(CMD_ALT_ACK): _r2_exit_programming_mode(radio) LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: serial.write(CMD_ACK) ack = serial.read(1) except: _r2_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: _r2_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") # the next 6 bytes represent the 6 digit password # they are somehow coded where '1' becomes x01 and 'a' becomes x25 try: serial.write(CMD_ENQ) ack = serial.read(6) except: _r2_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") # we will only read if no password is set if ack != b"\xFF\xFF\xFF\xFF\xFF\xFF": _r2_exit_programming_mode(radio) raise errors.RadioError("Radio is password protected") try: serial.write(CMD_ACK) ack = serial.read(6) except: _r2_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio 2") if ack != CMD_ACK: _r2_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode 2") def _r2_exit_programming_mode(radio): serial = radio.pipe try: serial.write(CMD_ACK) except: raise errors.RadioError("Radio refused to exit programming mode") def _r2_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: for j in range(0, len(cmd)): time.sleep(0.005) serial.write(cmd[j:j + 1]) response = serial.read(4 + block_size) if response[:4] != expectedresponse: _r2_exit_programming_mode(radio) raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] time.sleep(0.005) serial.write(CMD_ACK) ack = serial.read(1) except: _r2_exit_programming_mode(radio) raise errors.RadioError("Failed to read block at %04x" % block_addr) if ack != CMD_ACK: _r2_exit_programming_mode(radio) raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _r2_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing block %04x..." % (block_addr)) LOG.debug(util.hexprint(cmd + data)) try: for j in range(0, len(cmd)): serial.write(cmd[j:j + 1]) for j in range(0, len(data)): serial.write(data[j:j + 1]) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: _r2_exit_programming_mode(radio) raise errors.RadioError("Failed to send block " "%04x to radio" % block_addr) def do_download(radio): LOG.debug("download") _r2_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio._block_size): status.cur = addr + radio._block_size radio.status_fn(status) block = _r2_read_block(radio, addr, radio._block_size) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _r2_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _r2_enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr, block_size in radio._ranges: for addr in range(start_addr, end_addr, block_size): status.cur = addr + block_size radio.status_fn(status) _r2_write_block(radio, addr, block_size) _r2_exit_programming_mode(radio) @directory.register class RadioddityR2(chirp_common.CloneModeRadio): """Radioddity R2""" VENDOR = "Radioddity" MODEL = "R2" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False # definitions on how to read StartAddr EndAddr BlockZize _ranges = [ (0x0000, 0x01F8, 0x08), (0x01F8, 0x03F0, 0x08) ] _memsize = 0x03F0 # never read more than 8 bytes at once _block_size = 0x08 # frequency range is 400-470 MHz _range = [400000000, 470000000] # maximum 16 channels _upper = 16 _mem_params = { 'memnum': _upper, # number of channels } _frs16 = _pmr = False def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.has_name = False rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.can_odd_split = False # FIXME: Is this right? The get_memory() has no checking for # deleted memories, but set_memory() used to reference a missing # variable likely copied from another driver rf.can_delete = False rf.valid_modes = MODE_LIST rf.valid_duplexes = ["", "-", "+", "off"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->DTCS", "DTCS->Tone", "->Tone", "Tone->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_skips = ["", "S"] rf.valid_bands = [self._range] rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0] return rf def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) # to set the vars on the class to the correct ones def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_memory(self, number): bitpos = (1 << ((number - 1) % 8)) bytepos = ((number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rx_freq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rx_freq.get_raw(asbytes=False) == "\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem txfreq = int(_mem.tx_freq) * 10 if txfreq == mem.freq: mem.duplex = "" elif txfreq == 0: mem.duplex = "off" mem.offset = 0 # 166666665*10 is the equivalent for FF FF FF FF # stored in the TX field elif txfreq == 1666666650: mem.duplex = "off" mem.offset = 0 elif txfreq < mem.freq: mem.duplex = "-" mem.offset = mem.freq - txfreq elif txfreq > mem.freq: mem.duplex = "+" mem.offset = txfreq - mem.freq # get bandwidth FM or NFM mem.mode = MODE_LIST[_mem.mode] # tone data txtone = self.decode_tone(_mem.tx_tone) rxtone = self.decode_tone(_mem.rx_tone) chirp_common.split_tone_decode(mem, txtone, rxtone) if not _mem.scanadd: mem.skip = "S" mem.power = POWER_LEVELS[_mem.power] # add extra channel settings to the OTHER tab of the properties # extra settings are unfortunately inverted mem.extra = RadioSettingGroup("extra", "Extra") bclo = RadioSetting("bclo", "Busy Lockout", RadioSettingValueBoolean(not bool(_mem.bclo))) bclo.set_doc("Busy Lockout") mem.extra.append(bclo) scramb = RadioSetting("scramb", "Scramble", RadioSettingValueBoolean(not bool(_mem.scramb))) scramb.set_doc("Scramble Audio Signal") mem.extra.append(scramb) compand = RadioSetting("compand", "Compander", RadioSettingValueBoolean( not bool(_mem.compand))) compand.set_doc("Compress Audio for TX") mem.extra.append(compand) immutable = [] if self._frs16: if mem.freq in FRS16_FREQS: if mem.number >= 1 and mem.number <= 16: FRS_FREQ = FRS16_FREQS[mem.number - 1] mem.freq = FRS_FREQ mem.duplex == '' mem.offset = 0 mem.mode = "NFM" immutable = ["empty", "freq", "duplex", "offset", "mode"] elif self._pmr: if mem.freq in PMR_FREQS: if mem.number >= 1 and mem.number <= 16: PMR_FREQ = PMR_FREQS[mem.number - 1] mem.freq = PMR_FREQ mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = POWER_LEVELS[0] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] mem.immutable = immutable return mem def set_memory(self, mem): bitpos = (1 << ((mem.number - 1) % 8)) bytepos = ((mem.number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] _rsvd = _mem.reserved.get_raw(asbytes=False) if mem.empty: _mem.set_raw("\xFF" * 13 + _rsvd) return _mem.rx_freq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.tx_freq[i].set_raw("\xFF") elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 else: _mem.tx_freq = mem.freq / 10 # power, default power is low if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 # low # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_mem.tx_tone, txmode, txtone, txpol) self.encode_tone(_mem.rx_tone, rxmode, rxtone, rxpol) _mem.scanadd = mem.skip != "S" _mem.mode = MODE_LIST.index(mem.mode) # extra settings are unfortunately inverted for setting in mem.extra: LOG.debug("@set_mem: %s %s", setting.get_name(), setting.value) setattr(_mem, setting.get_name(), not setting.value) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) rs = RadioSetting("settings.squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( TIMEOUT_LIST, TIMEOUT_LIST[_settings.timeout])) basic.append(rs) rs = RadioSetting("settings.scanmode", "Scan Mode", RadioSettingValueList( SCANMODE_LIST, SCANMODE_LIST[_settings.scanmode])) basic.append(rs) rs = RadioSetting("settings.voice", "Voice Prompts", RadioSettingValueList( VOICE_LIST, VOICE_LIST[_settings.voice])) basic.append(rs) rs = RadioSetting("settings.voxgain", "VOX Level", RadioSettingValueList( VOX_LIST, VOX_LIST[_settings.voxgain])) basic.append(rs) rs = RadioSetting("settings.voxdelay", "VOX Delay Time", RadioSettingValueList( VOXDELAY_LIST, VOXDELAY_LIST[_settings.voxdelay])) basic.append(rs) rs = RadioSetting("settings.save", "Battery Save", RadioSettingValueBoolean(_settings.save)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep Tone", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) def _filter(name): filtered = "" for char in str(name): if char in VALID_CHARS: filtered += char else: filtered += " " return filtered return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class RetevisRT24(RadioddityR2): """Retevis RT24""" VENDOR = "Retevis" MODEL = "RT24" _pmr = False # sold as PMR radio but supports full band TX/RX @directory.register class RetevisRT24V(RadioddityR2): """Retevis RT24V""" VENDOR = "Retevis" MODEL = "RT24V" # sold as FreeNet radio but supports full band TX/RX # frequency range is 136-174 MHz _range = [136000000, 174000000] # maximum 6 channels _upper = 6 _mem_params = { 'memnum': _upper, # number of channels } @directory.register class RetevisH777S(RadioddityR2): """Retevis H777S""" VENDOR = "Retevis" MODEL = "H777S" _frs16 = False # sold as FRS radio but supports full band TX/RX chirp-20240224/chirp/drivers/tk270.py0000644000175000017500000007166214522657251016065 0ustar hibbyhibby# Copyright 2016 Pavel Milanes CO7WT, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging LOG = logging.getLogger(__name__) from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettings MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rx_tone[2]; lbcd tx_tone[2]; u8 unknown41:1, unknown42:1, power:1, // high power set (1=off) shift:1, // Shift (1=off) busy:1, // Busy lock (1=off) unknown46:1, unknown47:1, unknown48:1; u8 rxen; // xff if off, x00 if enabled (if chan sel = 00) u8 txen; // xff if off, x00 if enabled u8 unknown7; } memory[32]; #seekto 0x0338; u8 scan[4]; // 4 bytes / bit LSBF for the channel #seekto 0x033C; u8 active[4]; // 4 bytes / bit LSBF for the active cha // active = 0 #seekto 0x0340; struct { u8 kMoni; // monitor key function u8 kScan; // scan key function u8 kDial; // dial key function u8 kTa; // ta key function u8 kLo; // low key function u8 unknown40[7]; // 0x034c u8 tot; // TOT val * 30 steps (x00-0xa) u8 tot_alert; // TOT pre-alert val * 10 steps, (x00-x19) u8 tot_rekey; // TOT rekey val, 0-60, (x00-x3c) u8 tot_reset; // TOT reset val, 0-15, (x00-x0f) // 0x0350 u8 sql; // SQL level val, 0-9 (default 6) u8 unknown50[12]; u8 unknown30:1, unknown31:1, dealer:1, // dealer & test mode (1=on) add:1, // add/del from the scan (1=on) unknown34:1, batt_save:1, // Battery save (1=on) unknown36:1, beep:1; // beep on tone (1=on) u8 unknown51[2]; } settings; #seekto 0x03f0; struct { u8 batt_level; // inverted (ff-val) u8 sq_tight; // sq tight (ff-val) u8 sq_open; // sq open (ff-val) u8 high_power; // High power u8 qt_dev; // QT deviation u8 dqt_dev; // DQT deviation u8 low_power; // low power } tune; """ MEM_SIZE = 0x400 BLOCK_SIZE = 8 MEM_BLOCKS = list(range(0, (MEM_SIZE // BLOCK_SIZE))) ACK_CMD = "\x06" TIMEOUT = 0.05 # from 0.03 up it' s safe, we set in 0.05 for a margin POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1), chirp_common.PowerLevel("High", watts=5)] SKIP_VALUES = ["", "S"] TONES = chirp_common.TONES # TONES.remove(254.1) DTCS_CODES = chirp_common.DTCS_CODES # some vars for the UI off = ["off"] TOT = off + ["%s" % x for x in range(30, 330, 30)] TOT_A = off + ["%s" % x for x in range(10, 260, 10)] TOT_RK = off + ["%s" % x for x in range(1, 61)] TOT_RS = off + ["%s" % x for x in range(1, 16)] SQL = off + ["%s" % x for x in range(1, 10)] # keys MONI = off + ["Monitor momentary", "Monitor lock", "SQ off momentary"] SCAN = off + ["Carrier operated (COS)", "Time operated (TOS)"] YESNO = ["Enabled", "Disabled"] TA = off + ["Turn around", "Reverse"] def rawrecv(radio, amount): """Raw read from the radio device""" data = "" try: data = radio.pipe.read(amount) # print("<= %02i: %s" % (len(data), util.hexprint(data))) except: raise errors.RadioError("Error reading data from radio") return data def rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) # print("=> %02i: %s" % (len(data), util.hexprint(data))) except: raise errors.RadioError("Error sending data from radio") def send(radio, frame): """Generic send data to the radio""" rawsend(radio, frame) def make_frame(cmd, addr, data=""): """Pack the info in the format it likes""" ts = struct.pack(">BHB", ord(cmd), addr, 8) if data == "": return ts else: if len(data) == 8: return ts + data else: raise errors.InvalidValueError("Data of unexpected length to send") def handshake(radio, msg="", full=False): """Make a full handshake, if not full just hals""" # send ACK if commandes if full is True: rawsend(radio, ACK_CMD) # receive ACK ack = rawrecv(radio, 1) # check ACK if ack != ACK_CMD: # close_radio(radio) mesg = "Handshake failed: " + msg raise Exception(mesg) def recv(radio): """Receive data from the radio, 12 bytes, 4 in the header, 8 as data""" rxdata = rawrecv(radio, 12) if len(rxdata) != 12: raise errors.RadioError( "Received a length of data that is not possible") cmd, addr, length = struct.unpack(">BHB", rxdata[0:4]) data = "" if length == 8: data = rxdata[4:] return data def open_radio(radio): """Open the radio into program mode and check if it's the correct model""" # Set serial discipline try: radio.pipe.parity = "N" radio.pipe.timeout = TIMEOUT radio.pipe.flush() except: msg = "Serial error: Can't set serial line discipline" raise errors.RadioError(msg) # we will try to open the radio 5 times, this is an improved mechanism magic = "PROGRAM" exito = False for i in range(0, 5): for i in range(0, len(magic)): ack = rawrecv(radio, 1) time.sleep(0.05) send(radio, magic[i]) try: handshake(radio, "Radio not entering Program mode") exito = True break except: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) rawsend(radio, "\x02") ident = rawrecv(radio, 8) handshake(radio, "Comm error after ident", True) if not (radio.TYPE in ident): LOG.debug("Incorrect model ID, got %s" % util.hexprint(ident)) msg = "Incorrect model ID, got %s, it not contains %s" % \ (ident[0:5], radio.TYPE) raise errors.RadioError(msg) def do_download(radio): """This is your download function""" open_radio(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE / BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data = "" for addr in MEM_BLOCKS: send(radio, make_frame("R", addr * BLOCK_SIZE)) data += recv(radio) handshake(radio, "Rx error in block %03i" % addr, True) # DEBUG # print("Block: %04x, Pos: %06x" % (addr, addr * BLOCK_SIZE)) # UI Update status.cur = addr status.msg = "Cloning from radio..." radio.status_fn(status) return memmap.MemoryMap(data) def do_upload(radio): """Upload info to radio""" open_radio(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE / BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) count = 0 for addr in MEM_BLOCKS: # UI Update status.cur = addr status.msg = "Cloning to radio..." radio.status_fn(status) block = addr * BLOCK_SIZE # Beyond 0x03d0 the data is not writable if block > 0x3d0: continue data = radio.get_mmap()[block:block + BLOCK_SIZE] send(radio, make_frame("W", block, data)) time.sleep(0.02) handshake(radio, "Rx error in block %03i" % addr) def get_radio_id(data): """Extract the radio identification from the firmware""" # Reverse the radio id string. MemoryMap does not support the step/stride # slice argument, so it is first sliced to a str then reversed. return data[0x03d0:0x03d8][::-1] def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = get_radio_id(data) # DEBUG # print("Full ident string is %s" % util.hexprint(rid)) if (rid in cls.VARIANTS): # correct model return True else: return False class Kenwood_P60_Radio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Kenwood Mobile Family 60 Radios""" VENDOR = "Kenwood" _range = [350000000, 512000000] # don't mind, it will be overited _upper = 32 VARIANT = "" MODEL = "" _kind = "" @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is experimental; not all features have been ' 'implemented, but it has those features most used by hams.\n' '\n' 'This radios are able to work slightly outside the OEM ' 'frequency limits. After testing, the limit in Chirp has ' 'been set 4% outside the OEM limit. This allows you to use ' 'some models on the ham bands.\n' '\n' 'Nevertheless, each radio has its own hardware limits and ' 'your mileage may vary.\n' ) rp.pre_download = _( "Follow this instructions to read your radio:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to write your radio:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.has_name = False rf.has_offset = True rf.has_mode = False rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = ["FM"] rf.valid_duplexes = ["", "-", "+", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_skips = SKIP_VALUES rf.valid_dtcs_codes = DTCS_CODES rf.valid_bands = [self._range] rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0] return rf def sync_in(self): """Download from radio""" self._mmap = do_download(self) self.process_mmap() def sync_out(self): """Upload to radio""" # Get the data ready for upload try: self._prep_data() except: raise errors.RadioError("Error processing the radio data") # do the upload try: do_upload(self) except: raise errors.RadioError("Error uploading data to radio") def set_variant(self): """Select and set the correct variables for the class according to the correct variant of the radio""" rid = get_radio_id(self._mmap) # identify the radio variant and set the environment to its values try: self._upper, low, high, self._kind = self.VARIANTS[rid] # Frequency ranges: some model/variants are able to work the near # ham bands, even if they are outside the OEM ranges. # By experimentation we found that a +/- 4% at the edges is in most # cases safe and will cover the near ham band in full self._range = [low * 1000000 * 0.96, high * 1000000 * 1.04] # put the VARIANT in the class, clean the model / CHs / Type # in the same layout as the KPG program self._VARIANT = self.MODEL + " [" + str(self._upper) + "CH]: " # In the OEM string we show the real OEM ranges self._VARIANT += self._kind + ", %d - %d MHz" % (low, high) # DEBUG # print self._VARIANT except KeyError: LOG.debug("Wrong Kenwood radio, ID or unknown variant") LOG.debug(util.hexprint(rid)) raise errors.RadioError( "Wrong Kenwood radio, ID or unknown variant, see LOG output.") def _prep_data(self): """Prepare the areas in the memmap to do a consistent write it has to make an update on the x280 flag data""" achs = 0 for i in range(0, self._upper): if self.get_active(i) is True: achs += 1 # The x0280 area has the settings for the DTMF/2-Tone per channel, # as we don't support this feature yet, # we disabled by cleaning the data # fldata = "\x00\xf0\xff\xff\xff" * achs + \ # "\xff" * (5 * (self._upper - achs)) fldata = "\xFF" * 5 * self._upper self._fill(0x0280, fldata) def _fill(self, offset, data): """Fill an specified area of the memmap with the passed data""" for addr in range(0, len(data)): self._mmap[offset + addr] = data[addr] def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # to set the vars on the class to the correct ones self.set_variant() def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_active(self, chan): """Get the channel active status from the 4 bytes array on the eeprom""" byte = int(chan/8) bit = chan % 8 res = self._memobj.active[byte] & (pow(2, bit)) res = not bool(res) return res def set_active(self, chan, value=True): """Set the channel active status from UI to the mem_map""" byte = int(chan/8) bit = chan % 8 # DEBUG # print("SET Chan %s, Byte %s, Bit % s" % (chan, byte, bit)) # get the actual value to see if I need to change anything actual = self.get_active(chan) if actual != bool(value): # DEBUG # print "VALUE %s flipping" % int(not value) # I have to flip the value rbyte = self._memobj.active[byte] rbyte = rbyte ^ pow(2, bit) self._memobj.active[byte] = rbyte def decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_scan(self, chan): """Get the channel scan status from the 4 bytes array on the eeprom then from the bits on the byte, return '' or 'S' as needed""" result = "S" byte = int(chan/8) bit = chan % 8 res = self._memobj.scan[byte] & (pow(2, bit)) if res > 0: result = "" return result def set_scan(self, chan, value): """Set the channel scan status from UI to the mem_map""" byte = int(chan/8) bit = chan % 8 # get the actual value to see if I need to change anything actual = self.get_scan(chan) if actual != value: # I have to flip the value rbyte = self._memobj.scan[byte] rbyte = rbyte ^ pow(2, bit) self._memobj.scan[byte] = rbyte def get_memory(self, number): """Get the mem representation from the radio image""" _mem = self._memobj.memory[number - 1] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Memory number mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xFF": mem.empty = True # but is not enough, you have to clear the memory in the mmap # to get it ready for the sync_out process, just in case _mem.set_raw("\xFF" * 16) # set the channel to inactive state self.set_active(number - 1, False) return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if _mem.get_raw(asbytes=False)[4] == "\xFF" or int(_mem.txen) == 255: # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX feq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 # power mem.power = POWER_LEVELS[int(_mem.power)] # skip mem.skip = self.get_scan(number - 1) # tone data rxtone = txtone = None txtone = self.decode_tone(_mem.tx_tone) rxtone = self.decode_tone(_mem.rx_tone) chirp_common.split_tone_decode(mem, txtone, rxtone) # Extra # bank and number in the channel mem.extra = RadioSettingGroup("extra", "Extra") bl = RadioSetting("busy", "Busy Channel lock", RadioSettingValueBoolean( not bool(_mem.busy))) mem.extra.append(bl) sf = RadioSetting("shift", "Beat Shift", RadioSettingValueBoolean( not bool(_mem.shift))) mem.extra.append(sf) return mem def set_memory(self, mem): """Set the memory data in the eeprom img from the UI not ready yet, so it will return as is""" # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] # Empty memory if mem.empty: _mem.set_raw("\xFF" * 16) self.set_active(mem.number - 1, False) return # freq rx _mem.rxfreq = mem.freq / 10 # rx enabled if valid channel, # set tx to on, we decide if off after duplex = off _mem.rxen = 0 _mem.txen = 0 # freq tx if mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 elif mem.duplex == "off": # set tx freq on the memap to xff for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") # erase the txen flag _mem.txen = 255 else: _mem.txfreq = mem.freq / 10 # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_mem.tx_tone, txmode, txtone, txpol) self.encode_tone(_mem.rx_tone, rxmode, rxtone, rxpol) # power, default power is high, as the low is configurable via a key if mem.power is None: mem.power = POWER_LEVELS[1] _mem.power = POWER_LEVELS.index(mem.power) # skip self.set_scan(mem.number - 1, mem.skip) # set as active self.set_active(mem.number - 1, True) # extra settings for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) return mem @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == MEM_SIZE: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" sett = self._memobj.settings # basic features of the radio basic = RadioSettingGroup("basic", "Basic Settings") # keys fkeys = RadioSettingGroup("keys", "Function keys") top = RadioSettings(basic, fkeys) # Basic val = RadioSettingValueString(0, 35, self._VARIANT) val.set_mutable(False) mod = RadioSetting("not.mod", "Radio version", val) basic.append(mod) beep = RadioSetting("settings.beep", "Beep tone", RadioSettingValueBoolean( bool(sett.beep))) basic.append(beep) bsave = RadioSetting("settings.batt_save", "Battery save", RadioSettingValueBoolean( bool(sett.batt_save))) basic.append(bsave) deal = RadioSetting("settings.dealer", "Dealer & Test", RadioSettingValueBoolean( bool(sett.dealer))) basic.append(deal) add = RadioSetting("settings.add", "Del / Add feature", RadioSettingValueBoolean( bool(sett.add))) basic.append(add) # In some cases the values that follows can be 0xFF (HARD RESET) # so we need to take and validate that if int(sett.tot) == 0xff: # 120 sec sett.tot = 4 if int(sett.tot_alert) == 0xff: # 10 secs sett.tot_alert = 1 if int(sett.tot_rekey) == 0xff: # off sett.tot_rekey = 0 if int(sett.tot_reset) == 0xff: # off sett.tot_reset = 0 if int(sett.sql) == 0xff: # a comfortable level ~6 sett.sql = 6 tot = RadioSetting("settings.tot", "Time Out Timer (TOT)", RadioSettingValueList(TOT, TOT[int(sett.tot)])) basic.append(tot) tota = RadioSetting("settings.tot_alert", "TOT pre-plert", RadioSettingValueList(TOT_A, TOT_A[int(sett.tot_alert)])) basic.append(tota) totrk = RadioSetting("settings.tot_rekey", "TOT rekey time", RadioSettingValueList(TOT_RK, TOT_RK[int(sett.tot_rekey)])) basic.append(totrk) totrs = RadioSetting("settings.tot_reset", "TOT reset time", RadioSettingValueList(TOT_RS, TOT_RS[int(sett.tot_reset)])) basic.append(totrs) sql = RadioSetting("settings.sql", "Squelch level", RadioSettingValueList(SQL, SQL[int(sett.sql)])) basic.append(sql) # front keys m = int(sett.kMoni) if m > 3: m = 1 mon = RadioSetting("settings.kMoni", "Monitor", RadioSettingValueList(MONI, MONI[m])) fkeys.append(mon) s = int(sett.kScan) if s > 3: s = 1 scn = RadioSetting("settings.kScan", "Scan", RadioSettingValueList(SCAN, SCAN[s])) fkeys.append(scn) d = int(sett.kDial) if d > 1: d = 0 dial = RadioSetting("settings.kDial", "Dial", RadioSettingValueList(YESNO, YESNO[d])) fkeys.append(dial) t = int(sett.kTa) if t > 2: t = 2 ta = RadioSetting("settings.kTa", "Ta", RadioSettingValueList(TA, TA[t])) fkeys.append(ta) l = int(sett.kLo) if l > 1: l = 0 low = RadioSetting("settings.kLo", "Low", RadioSettingValueList(YESNO, YESNO[l])) fkeys.append(low) return top def set_settings(self, settings): """Translate the settings in the UI into bit in the mem_struct I don't understand well the method used in many drivers so, I used mine, ugly but works ok""" mobj = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue # Let's roll the ball if "." in element.get_name(): inter, setting = element.get_name().split(".") # you must ignore the settings with "not" # this are READ ONLY attributes if inter == "not": continue obj = getattr(mobj, inter) value = element.value # integers case + special case if setting in ["tot", "tot_alert", "tot_rekey", "tot_reset", "sql", "kMoni", "kScan", "kDial", "kTa", "kLo"]: # catching the "off" values as zero try: value = int(value) except: value = 0 # Bool types + inverted if setting in ["beep", "batt_save", "dealer", "add"]: value = bool(value) # Apply al configs done # DEBUG # print("%s: %s" % (setting, value)) setattr(obj, setting, value) # This are the oldest family 60 models just portables support here # Info striped from a hexdump inside the preogram and hack over a # tk-270 @directory.register class TK260_Radio(Kenwood_P60_Radio): """Kenwood TK-260 Radios""" MODEL = "TK-260" TYPE = "P0260" VARIANTS = { b"P0260\x20\x00\x00": (4, 136, 150, "F2"), b"P0260\x21\x00\x00": (4, 150, 174, "F1"), } @directory.register class TK270_Radio(Kenwood_P60_Radio): """Kenwood TK-270 Radios""" MODEL = "TK-270" TYPE = "P0270" VARIANTS = { b"P0270\x10\x00\x00": (32, 136, 150, "F2"), b"P0270\x11\x00\x00": (32, 150, 174, "F1"), } @directory.register class TK272_Radio(Kenwood_P60_Radio): """Kenwood TK-272 Radios""" MODEL = "TK-272" TYPE = "P0272" VARIANTS = { b"P0272\x10\x00\x00": (10, 136, 150, "F2"), b"P0272\x11\x00\x00": (10, 150, 174, "F1"), } @directory.register class TK278_Radio(Kenwood_P60_Radio): """Kenwood TK-278 Radios""" MODEL = "TK-278" TYPE = "P0278" VARIANTS = { b"P0278\x00\x00\x00": (32, 136, 150, "F2"), b"P0278\x01\x00\x00": (32, 150, 174, "F1"), } @directory.register class TK360_Radio(Kenwood_P60_Radio): """Kenwood TK-360 Radios""" MODEL = "TK-360" TYPE = "P0360" VARIANTS = { b"P0360\x24\x00\x00": (4, 450, 470, "F1"), b"P0360\x25\x00\x00": (4, 470, 490, "F2"), b"P0360\x26\x00\x00": (4, 490, 512, "F3"), b"P0360\x23\x00\x00": (4, 406, 430, "F4"), } @directory.register class TK370_Radio(Kenwood_P60_Radio): """Kenwood TK-370 Radios""" MODEL = "TK-370" TYPE = "P0370" VARIANTS = { b"P0370\x14\x00\x00": (32, 450, 470, "F1"), b"P0370\x15\x00\x00": (32, 470, 490, "F2"), b"P0370\x16\x00\x00": (32, 490, 512, "F3"), b"P0370\x13\x00\x00": (32, 406, 430, "F4"), } @directory.register class TK372_Radio(Kenwood_P60_Radio): """Kenwood TK-372 Radios""" MODEL = "TK-372" TYPE = "P0372" VARIANTS = { b"P0372\x14\x00\x00": (10, 450, 470, "F1"), b"P0372\x15\x00\x00": (10, 470, 490, "F2"), } @directory.register class TK378_Radio(Kenwood_P60_Radio): """Kenwood TK-378 Radios""" MODEL = "TK-378" TYPE = "P0378" VARIANTS = { b"P0378\x04\x00\x00": (32, 370, 470, "SP1"), b"P0378\x02\x00\x00": (32, 350, 427, "SP2"), } chirp-20240224/chirp/drivers/retevis_rt21.py0000644000175000017500000023277214566340166017552 0ustar hibbyhibby# Copyright 2021-2023 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import ( bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueInteger, RadioSettingValueList, ) LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 unknown1:3, // C bcl:2, // Busy Lock unknown2:3; u8 unknown3:2, // D highpower:1, // Power Level wide:1, // Bandwidth unknown4:4; u8 unknown7:1, // E scramble_type:3, // Scramble Type unknown5:4; u8 unknown6:5, scramble_type2:3; // Scramble Type 2 F } memory[%d]; #seekto 0x011D; struct { u8 unused:4, pf1:4; // Programmable Function Key 1 } keys; #seekto 0x012C; struct { u8 use_scramble; // Scramble Enable u8 unknown1[2]; u8 voice; // Voice Annunciation u8 tot; // Time-out Timer u8 totalert; // Time-out Timer Pre-alert u8 unknown2[2]; u8 squelch; // Squelch Level u8 save; // Battery Saver u8 unknown3[3]; u8 use_vox; // VOX Enable u8 vox; // VOX Gain } settings; #seekto 0x017E; u8 skipflags[2]; // SCAN_ADD """ MEM_FORMAT_RB17A = """ struct memory { lbcd rxfreq[4]; // 0-3 lbcd txfreq[4]; // 4-7 ul16 rx_tone; // 8-9 ul16 tx_tone; // A-B u8 unknown1:1, // C compander:1, // Compand bcl:2, // Busy Channel Lock-out cdcss:1, // Cdcss Mode scramble_type:3; // Scramble Type u8 unknown2:4, // D middlepower:1, // Power Level-Middle unknown3:1, // highpower:1, // Power Level-High/Low wide:1; // Bandwidth u8 unknown4; // E u8 unknown5; // F }; #seekto 0x0010; struct memory lomems[16]; #seekto 0x0200; struct memory himems[14]; #seekto 0x011D; struct { u8 pf1; // 011D PF1 Key u8 topkey; // 011E Top Key } keys; #seekto 0x012C; struct { u8 use_scramble; // 012C Scramble Enable u8 channel; // 012D Channel Number u8 alarm; // 012E Alarm Type u8 voice; // 012F Voice Annunciation u8 tot; // 0130 Time-out Timer u8 totalert; // 0131 Time-out Timer Pre-alert u8 unknown2[2]; u8 squelch; // 0134 Squelch Level u8 save; // 0135 Battery Saver u8 unknown3[3]; u8 use_vox; // 0139 VOX Enable u8 vox; // 013A VOX Gain } settings; #seekto 0x017E; u8 skipflags[4]; // Scan Add """ MEM_FORMAT_RB26 = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 compander:1, // Compander C unknown1:1, // highpower:1, // Power Level wide:1, // Bandwidth bcl:1, // Busy Lock OFF=0 ON=1 unknown2:3; // u8 reserved[3]; // Reserved D-F } memory[30]; #seekto 0x002D; struct { u8 unknown_1:1, // 002D chnumberd:1, // Channel Number Disable gain:1, // MIC Gain savem:1, // Battery Save Mode save:1, // Battery Save beep:1, // Beep voice:1, // Voice Prompts unknown_2:1; // u8 squelch; // Squelch 002E u8 tot; // Time-out Timer 002F u8 channel_4[13]; // 0030-003C u8 unknown_3[3]; // 003D-003F u8 channel_5[13]; // 0040-004C u8 unknown_4; // 004D u8 unknown_5[2]; // 004E-004F u8 channel_6[13]; // 0050-005C u8 unknown_6; // 005D u8 unknown_7[2]; // 005E-005F u8 channel_7[13]; // 0060-006C u8 warn; // Warn Mode 006D u8 pf1; // Key Set PF1 006E u8 pf2; // Key Set PF2 006F u8 channel_8[13]; // 0070-007C u8 unknown_8; // 007D u8 tail; // QT/DQT Tail(inverted) 007E } settings; #seekto 0x01F0; u8 skipflags[4]; // Scan Add #seekto 0x029F; struct { u8 chnumber; // Channel Number 029F } settings2; #seekto 0x031D; struct { u8 unused:7, // 031D vox:1; // Vox u8 voxl; // Vox Level 031E u8 voxd; // Vox Delay 031F } settings3; """ MEM_FORMAT_RT76 = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 compander:1, // Compander C hop:1, // Frequency Hop highpower:1, // Power Level wide:1, // Bandwidth scramble:4; // Scramble u8 reserved[3]; // Reserved D-F } memory[30]; #seekto 0x002D; struct { u8 unknown_1:1, // 002D chnumberd:1, // Channel Number Disable gain:1, // MIC Gain --- savem:1, // Battery Save Mode --- save:1, // Battery Save --- beep:1, // Beep --- voice:2; // Voice Prompts --- u8 squelch; // Squelch 002E --- u8 tot; // Time-out Timer 002F --- u8 channel_4[13]; // 0030-003C u8 unused:7, // 003D vox:1; // Vox --- u8 voxl; // Vox Level 003E --- u8 voxd; // Vox Delay 003F --- u8 channel_5[13]; // 0040-004C u8 unknown_4; // 004D u8 unknown_5[2]; // 004E-004F u8 channel_6[13]; // 0050-005C u8 chnumber; // Channel Number 005D --- u8 unknown_7[2]; // 005E-005F u8 channel_7[13]; // 0060-006C u8 warn; // 006D --- u8 scan; // 006E u8 unknown_8; // 006F u8 channel_8[13]; // 0070-007C u8 unknown_9[3]; // 007D-007F u8 channel_9[13]; // 0080-008C u8 unknown_a; // 008D u8 tailmode; // DCS Tail Mode 008E u8 hop; // Hop Mode 008F } settings; #seekto 0x004E; u8 skipflags[2]; // SCAN_ADD """ MEM_FORMAT_RT29 = """ #seekto 0x0010; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 unknown1:2, // C compander:1, // Compander bcl:2, // Busy Lock unknown2:3; u8 unknown3:1, // D txpower:2, // Power Level wide:1, // Bandwidth unknown4:3, cdcss:1; // Cdcss Mode u8 unknown5; // E u8 unknown6:5, scramble_type:3; // Scramble Type F } memory[16]; #seekto 0x011D; struct { u8 unused1:4, pf1:4; // Programmable Function Key 1 u8 unused2:4, pf2:4; // Programmable Function Key 2 } keys; #seekto 0x012C; struct { u8 use_scramble; // Scramble Enable u8 unknown1[2]; u8 voice; // Voice Annunciation u8 tot; // Time-out Timer u8 totalert; // Time-out Timer Pre-alert u8 unknown2[2]; u8 squelch; // Squelch Level u8 save; // Battery Saver u8 unknown3[3]; u8 use_vox; // VOX Enable u8 vox; // VOX Gain u8 voxd; // Vox Delay } settings; #seekto 0x017E; u8 skipflags[2]; // SCAN_ADD #seekto 0x01B8; u8 fingerprint[5]; // Fingerprint """ MEM_FORMAT_RT19 = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 function:2, // Function C highpower:1, // Power Level wide:1, // Bandwidth unknown_1:1, // scramble_type:3; // Scramble # u8 reserved[3]; // Reserved D-F } memory[%d]; #seekto 0x002D; struct { u8 bootsel:1, // Boot Select 002D unknown_1:2, // savem:1, // Battery Save Mode save:1, // Battery Save beep:1, // Beep voice:2; // Voice Prompts u8 squelch; // Squelch 002E u8 tot; // Time-out Timer 002F u8 channel_4[13]; // 0030-003C u8 unused:7, // 003D vox:1; // Vox u8 voxl; // Vox Level 003E u8 voxd; // Vox Delay 003F u8 channel_5[13]; // 0040-004C u8 unknown_4; // 004D u8 unknown_5[2]; // 004E-004F u8 channel_6[13]; // 0050-005C u8 unknown_6; // 005D u8 unknown_7[2]; // 005E-005F u8 channel_7[13]; // 0060-006C u8 voicel:4, // Voice Level 006D unknown_9:3, // warn:1; // Warn Mode } settings; #seekto 0x%X; struct { u8 freqhop; // Frequency Hop } freqhops[%d]; """ MEM_FORMAT_RT40B = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 compander:1, // Compander C unknown1:1, // highpower:1, // Power Level wide:1, // Bandwidth unknown2:4; // u8 reserved[3]; // Reserved D-F } memory[%d]; #seekto 0x002D; struct { u8 unknown_1:1, // 002D unknown_2:1, // savem:2, // Battery Save Mode save:1, // Battery Save beep:1, // Beep voice:2; // Voice Prompts u8 squelch; // Squelch 002E u8 tot; // Time-out Timer 002F u8 channel_4[13]; // 0030-003C u8 unknown_3:7, // 003D vox:1; // Vox u8 voxl; // Vox Level 003E u8 voxd; // Vox Delay 003F u8 channel_5[13]; // 0040-004C u8 unknown_4[2]; // 004D-004F u8 channel_6[13]; // 0050-005C u8 chnumber; // Channel Number 005D u8 unknown_5[2]; // 005E-005F u8 channel_7[13]; // 0060-006C u8 unknown_6:7, // 006D pttstone:1; // PTT Start Tone u8 unknown_7:7, // 006E pttetone:1; // PTT End Tone } settings; #seekto 0x00AD; u8 skipflags[3]; // SCAN_ADD """ MEM_FORMAT_RB28B = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 compander:1, // Compander C unused_1:1, // highpower:1, // Power Level wide:1, // Bandwidth bcl:1, // Busy Lock unused_2:3; // u8 reserved[3]; // Reserved D-F } memory[30]; #seekto 0x002D; struct { u8 unknown_1:1, // 002D unknown_2:1, // gain:1, // MIC Gain savem:1, // Battery Save Mode save:1, // Battery Save voice:1, // Voice Prompts beep:1, // Beep unused_3:1; // Power on Type u8 squelch; // Squelch 002E u8 tot; // Time-out Timer 002F u8 channel_4[13]; // 0030-003C u8 unused_3d:7, // 003D vox:1; // Vox u8 voxl; // Vox Level 003E u8 voxd; // Vox Delay 003F u8 channel_5[13]; // 0040-004C u8 unknown_3[3]; // 004D-004F u8 channel_6[13]; // 0050-005C u8 unknown_4[3]; // 005D-005F u8 channel_7[13]; // 0060-006C u8 volume; // Volume 006D u8 pfkey_lt; // Key Set < 006E u8 pfkey_gt; // Key Set > 006F u8 channel_8[13]; // 0070-007C u8 unknown_5; // 007D u8 unused_7e6:7, // 007E pwrontype:1; // Power on Type u8 unused_7f:7, // 007F keylock:1; // Key Lock u8 channel_9[13]; // 0080-008C u8 unknown_7; // 008D u8 chnumber; // Channel 008E } settings; """ MEM_FORMAT_RT86 = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 ul16 rx_tone; // PL/DPL Decode 8-9 ul16 tx_tone; // PL/DPL Encode A-B u8 audio:2, // Audio C highpower:1, // Power Level wide:1, // Bandwidth bcl:1, // Busy Lock OFF=0 ON=1 scramble_type:3; // Scramble u8 reserved[3]; // Reserved D-F } memory[16]; #seekto 0x002D; struct { u8 unknown_1:1, // 002D chnumberd:1, // Channel Number Disable gain:1, // MIC Gain savem:1, // Battery Save Mode save:1, // Battery Save beep:1, // Beep voice:1, // Voice Prompts unknown_2:1; // u8 squelch; // Squelch 002E u8 tot; // Time-out Timer 002F u8 channel_4[13]; // 0030-003C u8 unused_3d:7, // 003D vox:1; // Vox u8 voxl; // Vox Level 003E u8 voxd; // Vox Delay 003F u8 channel_5[13]; // 0040-004C u8 unknown_4; // 004D u8 unknown_5[2]; // 004E-004F u8 channel_6[13]; // 0050-005C u8 unknown_6; // 005D u8 unknown_7[2]; // 005E-005F u8 channel_7[13]; // 0060-006C u8 warn; // Warn Mode 006D u8 pf1; // Key Set PF1 006E u8 pf2; // Key Set PF2 006F u8 channel_8[13]; // 0070-007C u8 unknown_8; // 007D u8 tail; // QT/DQT Tail(inverted) 007E u8 tailmode; // QT/DQT Tail Mode 007F u8 channel_9[13]; // 0080-008C u8 unknown_9[3]; // 008D-008F u8 channel_10[13]; // 0090-009C u8 unknown_10[3]; // 009D-009F u8 channel_11[13]; // 00A0-00AC u8 unknown_11[2]; // 00AD-00AE u8 chnumber; // Channel Number 00AF } settings; #seekto 0x004E; u8 skipflags[2]; // SCAN_ADD #seekto 0x0100; struct { u8 freqhop; // Frequency Hop } freqhops[16]; """ CMD_ACK = b"\x06" ALARM_LIST = ["Local Alarm", "Remote Alarm"] BCL_LIST = ["Off", "Carrier", "QT/DQT"] BOOTSEL_LIST = ["Channel Mode", "Voice Mode"] CDCSS_LIST = ["Normal Code", "Special Code 2", "Special Code 1"] CDCSS2_LIST = ["Normal Code", "Special Code"] # RT29 UHF and RT29 VHF FREQHOP_LIST = ["Off", "Hopping 1", "Hopping 2", "Hopping 3"] FUNCTION_LIST = ["Off", "Scramble", "Compand"] GAIN_LIST = ["Standard", "Enhanced"] HOP_LIST = ["Mode A", "Mode B", "Mode C", "Mode D", "Mode E"] HOP86_LIST = ["Off", "Mode 1", "Mode 2", "Mode 3", "Mode 4"] PFKEY_LIST = ["None", "Monitor", "Lamp", "Warn", "VOX", "VOX Delay", "Key Lock", "Scan"] PFKEY28B_LIST = ["None", "Scan", "Warn", "TX Power", "Monitor"] PFKEY86_LIST = ["None", "Monitor", "Lamp", "Warn", "VOX", "VOX Delay", "Key Lock", "TX Power", "Scan"] POT_LIST = ["Channel Type", "Volume Type"] SAVE_LIST = ["Standard", "Super"] SAVEM_LIST = ["1-5", "1-8", "1-10", "1-15"] SCRAMBLE_LIST = ["OFF"] + ["%s" % x for x in range(1, 9)] SPECIAL_LIST = ["Standard", "Special"] TAIL_LIST = ["134.4 Hz", "55 Hz"] TIMEOUTTIMER_LIST = ["Off"] + ["%s seconds" % x for x in range(15, 615, 15)] TOTALERT_LIST = ["Off"] + ["%s seconds" % x for x in range(1, 11)] VOICE_LIST = ["Off", "Chinese", "English"] VOICE_LIST2 = ["Off", "English"] VOICE_LIST3 = VOICE_LIST2 + ["Chinese"] VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 17)] VOXD_LIST = ["0.5", "1.0", "1.5", "2.0", "2.5", "3.0"] VOXL_LIST = ["OFF"] + ["%s" % x for x in range(1, 10)] WARN_LIST = ["OFF", "Native Warn", "Remote Warn"] PF1_CHOICES = ["None", "Monitor", "Scan", "Scramble", "Alarm"] PF1_VALUES = [0x0F, 0x04, 0x06, 0x08, 0x0C] PF1_17A_CHOICES = ["None", "Monitor", "Scan", "Scramble"] PF1_17A_VALUES = [0x0F, 0x04, 0x06, 0x08] PFKEY23_CHOICES = ["None", "Monitor", "Warn", "VOX", "VOX Delay", "Scan"] PFKEY23_VALUES = [0x00, 0x01, 0x03, 0x04, 0x05, 0x07] PFKEY_CHOICES = ["None", "Monitor", "Scan", "Scramble", "VOX", "Alarm"] PFKEY_VALUES = [0x0F, 0x04, 0x06, 0x08, 0x09, 0x0A] TOPKEY_CHOICES = ["None", "Alarming"] TOPKEY_VALUES = [0xFF, 0x0C] GMRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] GMRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] GMRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] GMRS_FREQS = GMRS_FREQS1 + GMRS_FREQS2 + GMRS_FREQS3 * 2 FRS_FREQS = GMRS_FREQS1 + GMRS_FREQS2 + GMRS_FREQS3 PMR_FREQS1 = [446006250, 446018750, 446031250, 446043750, 446056250, 446068750, 446081250, 446093750] PMR_FREQS2 = [446106250, 446118750, 446131250, 446143750, 446156250, 446168750, 446181250, 446193750] PMR_FREQS = PMR_FREQS1 + PMR_FREQS2 DTCS_EXTRA = tuple(sorted(chirp_common.DTCS_CODES + (645,))) def _enter_programming_mode(radio): serial = radio.pipe _magic = radio._magic try: serial.write(_magic) if radio._echo: chew = serial.read(len(_magic)) # Chew the echo for i in range(1, 5): ack = serial.read(1) if ack == CMD_ACK: break except: raise errors.RadioError("Error communicating with radio") if not ack: raise errors.RadioError("No response from radio") elif ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") try: serial.write(b"\x02") if radio._echo: serial.read(1) # Chew the echo ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") # check if ident is OK itis = False for fp in radio._fingerprint: if fp in ident: # got it! itis = True break if itis is False: LOG.debug("Incorrect model ID, got this:\n\n" + util.hexprint(ident)) raise errors.RadioError("Radio identification failed.") try: serial.write(CMD_ACK) if radio._echo: serial.read(1) # Chew the echo ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") if radio._echo: chew = serial.read(1) # Chew the echo except: raise errors.RadioError("Radio refused to exit programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) if radio._echo: serial.read(4) # Chew the echo response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] if block_addr != 0 or radio._ack_1st_block: serial.write(CMD_ACK) if radio._echo: serial.read(1) # Chew the echo ack = serial.read(1) except: raise errors.RadioError("Failed to read block at %04x" % block_addr) if block_addr != 0 or radio._ack_1st_block: if ack != CMD_ACK: raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if radio._echo: serial.read(4 + len(data)) # Chew the echo if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE_UP): status.cur = addr + radio.BLOCK_SIZE_UP radio.status_fn(status) _write_block(radio, addr, radio.BLOCK_SIZE_UP) _exit_programming_mode(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0x01B8:0x01BE] return rid.startswith(b"P3207") @directory.register class RT21Radio(chirp_common.CloneModeRadio): """RETEVIS RT21""" VENDOR = "Retevis" MODEL = "RT21" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x10 BLOCK_SIZE_UP = 0x10 DTCS_CODES = sorted(chirp_common.DTCS_CODES + (17, 50, 645)) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.50), chirp_common.PowerLevel("Low", watts=1.00)] VALID_BANDS = [(400000000, 480000000)] _magic = b"PRMZUNE" _fingerprint = [b"P3207s\xF8\xFF", ] _upper = 16 _mem_params = (_upper, # number of channels ) _ack_1st_block = True _skipflags = True _reserved = False _gmrs = _frs = _pmr = False _echo = False _ranges = [ (0x0000, 0x0400), ] _memsize = 0x0400 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False if self.MODEL == "RT76" or \ self.MODEL == "RT19" or self.MODEL == "RT619" or \ self.MODEL == "RB28B" or self.MODEL == "RB628B": rf.valid_skips = [] else: rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_dtcs_codes = self.DTCS_CODES rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] rf.valid_bands = self.VALID_BANDS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol tpol = False if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2000: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" elif _mem.tx_tone != 0xFFFF: mem.rtone = _mem.tx_tone / 10.0 txmode = "Tone" else: txmode = "" rpol = False if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2000: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rx_tone != 0xFFFF: mem.ctone = _mem.rx_tone / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.tx_tone, rxmode, _mem.rx_tone)) def get_memory(self, number): if self._skipflags: bitpos = (1 << ((number - 1) % 8)) bytepos = ((number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) _skp = self._memobj.skipflags[bytepos] mem = chirp_common.Memory() mem.number = number if self.MODEL == "RB17A": if mem.number < 17: _mem = self._memobj.lomems[number - 1] else: _mem = self._memobj.himems[number - 17] else: _mem = self._memobj.memory[number - 1] if self._reserved: _rsvd = _mem.reserved.get_raw(asbytes=False) mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = _mem.wide and "FM" or "NFM" self._get_tone(_mem, mem) if self.MODEL == "RT29_UHF" or self.MODEL == "RT29_VHF": # set the power level if _mem.txpower == self.TXPOWER_LOW: mem.power = self.POWER_LEVELS[2] elif _mem.txpower == self.TXPOWER_MED: mem.power = self.POWER_LEVELS[1] elif _mem.txpower == self.TXPOWER_HIGH: mem.power = self.POWER_LEVELS[0] else: LOG.error('%s: get_mem: unhandled power level: 0x%02x' % (mem.name, _mem.txpower)) else: mem.power = self.POWER_LEVELS[1 - _mem.highpower] if self._skipflags: mem.skip = "" if (_skp & bitpos) else "S" LOG.debug("mem.skip %s" % mem.skip) mem.extra = RadioSettingGroup("Extra", "extra") if self.MODEL == "RT21" or self.MODEL == "RB17A" or \ self.MODEL == "RT29_UHF" or self.MODEL == "RT29_VHF" or \ self.MODEL == "RT21V": rs = RadioSettingValueList(BCL_LIST, BCL_LIST[_mem.bcl]) rset = RadioSetting("bcl", "Busy Channel Lockout", rs) mem.extra.append(rset) rs = RadioSettingValueInteger(1, 8, _mem.scramble_type + 1) rset = RadioSetting("scramble_type", "Scramble Type", rs) mem.extra.append(rset) if self.MODEL == "RB17A": rs = RadioSettingValueList(CDCSS_LIST, CDCSS_LIST[_mem.cdcss]) rset = RadioSetting("cdcss", "Cdcss Mode", rs) mem.extra.append(rset) if self.MODEL == "RT29_UHF" or self.MODEL == "RT29_VHF": rs = RadioSettingValueList(CDCSS2_LIST, CDCSS2_LIST[_mem.cdcss]) rset = RadioSetting("cdcss", "Cdcss Mode", rs) mem.extra.append(rset) if self.MODEL == "RB17A" or self.MODEL == "RT29_UHF" or \ self.MODEL == "RT29_VHF": rs = RadioSettingValueBoolean(_mem.compander) rset = RadioSetting("compander", "Compander", rs) mem.extra.append(rset) if self.MODEL == "RB26" or self.MODEL == "RT76" \ or self.MODEL == "RB23" or self.MODEL == "AR-63": if self.MODEL == "RB26" or self.MODEL == "RB23": rs = RadioSettingValueBoolean(_mem.bcl) rset = RadioSetting("bcl", "Busy Channel Lockout", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(_mem.compander) rset = RadioSetting("compander", "Compander", rs) mem.extra.append(rset) if self.MODEL == "AR-63": rs = RadioSettingValueList(SCRAMBLE_LIST, SCRAMBLE_LIST[_mem.scramble]) rset = RadioSetting("scramble", "Scramble", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(not _mem.hop) rset = RadioSetting("hop", "Frequency Hop", rs) mem.extra.append(rset) if self.MODEL == "RT19" or self.MODEL == "RT619": _freqhops = self._memobj.freqhops[number - 1] rs = RadioSettingValueList(FUNCTION_LIST, FUNCTION_LIST[_mem.function]) rset = RadioSetting("function", "Function", rs) mem.extra.append(rset) rs = RadioSettingValueInteger(1, 8, _mem.scramble_type + 1) rset = RadioSetting("scramble_type", "Scramble Type", rs) mem.extra.append(rset) rs = RadioSettingValueList(FREQHOP_LIST, FREQHOP_LIST[_freqhops.freqhop]) rset = RadioSetting("freqhop", "Frequency Hop", rs) mem.extra.append(rset) if self.MODEL == "RT40B": rs = RadioSettingValueBoolean(_mem.compander) rset = RadioSetting("compander", "Compander", rs) mem.extra.append(rset) if self.MODEL == "RB28B" or self.MODEL == "RB628B": rs = RadioSettingValueBoolean(_mem.compander) rset = RadioSetting("compander", "Compander", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(_mem.bcl) rset = RadioSetting("bcl", "Busy Channel Lockout", rs) mem.extra.append(rset) if self.MODEL == "RT86": _freqhops = self._memobj.freqhops[number - 1] rs = RadioSettingValueList(FUNCTION_LIST, FUNCTION_LIST[_mem.audio]) rset = RadioSetting("audio", "Audio", rs) mem.extra.append(rset) rs = RadioSettingValueInteger(1, 8, _mem.scramble_type + 1) rset = RadioSetting("scramble_type", "Scramble", rs) mem.extra.append(rset) rs = RadioSettingValueList(HOP86_LIST, HOP86_LIST[_freqhops.freqhop]) rset = RadioSetting("freqhop", "Frequency Hop", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(_mem.bcl) rset = RadioSetting("bcl", "Busy Lock", rs) mem.extra.append(rset) immutable = [] if self._frs: if mem.number >= 1 and mem.number <= 22: FRS_FREQ = FRS_FREQS[mem.number - 1] mem.freq = FRS_FREQ mem.duplex == '' mem.offset = 0 mem.mode = "NFM" if mem.number >= 8 and mem.number <= 14: mem.power = self.POWER_LEVELS[1] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] else: immutable = ["empty", "freq", "duplex", "offset", "mode"] elif self._pmr: if mem.number >= 1 and mem.number <= 16: PMR_FREQ = PMR_FREQS[mem.number - 1] mem.freq = PMR_FREQ mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] elif self._gmrs: if mem.number >= 1 and mem.number <= 30: GMRS_FREQ = GMRS_FREQS[mem.number - 1] mem.freq = GMRS_FREQ immutable = ["empty", "freq"] if mem.number >= 1 and mem.number <= 7: mem.duplex == '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 8 and mem.number <= 14: mem.duplex == '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable += ["duplex", "offset", "mode", "power"] elif mem.number >= 15 and mem.number <= 22: mem.duplex == '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 23 and mem.number <= 30: mem.duplex == '+' mem.offset = 5000000 immutable += ["duplex", "offset"] elif mem.freq in FRS_FREQS1: mem.duplex == '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.freq in FRS_FREQS2: mem.duplex == '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable += ["duplex", "offset", "mode", "power"] elif mem.freq in FRS_FREQS3: if mem.duplex == '': mem.offset = 0 if mem.duplex == '+': mem.offset = 5000000 else: if mem.freq not in GMRS_FREQS: immutable = ["duplex", "offset"] mem.immutable = immutable return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2000 if pol == "R": val += 0x8000 return val rx_mode = tx_mode = None rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None tx_tone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = int(mem.rtone * 10) if rx_mode == "DTCS": rx_tone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = int(mem.ctone * 10) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.tx_tone, rx_mode, _mem.rx_tone)) def set_memory(self, mem): if self._skipflags: bitpos = (1 << ((mem.number - 1) % 8)) bytepos = ((mem.number - 1) / 8) LOG.debug("bitpos %s" % bitpos) LOG.debug("bytepos %s" % bytepos) _skp = self._memobj.skipflags[bytepos] if self.MODEL == "RB17A": if mem.number < 17: _mem = self._memobj.lomems[mem.number - 1] else: _mem = self._memobj.himems[mem.number - 17] elif self.MODEL == "RT19" or self.MODEL == "RT619": _mem = self._memobj.memory[mem.number - 1] _freqhops = self._memobj.freqhops[mem.number - 1] else: _mem = self._memobj.memory[mem.number - 1] if self._reserved: _rsvd = _mem.reserved.get_raw(asbytes=False) if self.MODEL == "RT86": _freqhops = self._memobj.freqhops[mem.number - 1] if mem.empty: if self.MODEL in ["RB23", "RB26", "RT40B", "RT76", "RT86", ]: _mem.set_raw("\xFF" * 13 + _rsvd) elif self.MODEL in ["RT19", "RT86", "RT619", ]: _mem.set_raw("\xFF" * 13 + _rsvd) _freqhops.freqhop.set_raw("\x00") elif self.MODEL == "AR-63": _mem.set_raw("\xFF" * 13 + _rsvd) else: _mem.set_raw("\xFF" * (_mem.size() // 8)) return if self.MODEL == "RB17A": _mem.set_raw("\x00" * 14 + "\xFF\xFF") elif self._reserved: _mem.set_raw("\x00" * 13 + _rsvd) elif self.MODEL == "AR-63": _mem.set_raw("\x00" * 13 + _rsvd) else: _mem.set_raw("\x00" * 13 + "\x30\x8F\xF8") _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq.fill_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.wide = mem.mode == "FM" self._set_tone(mem, _mem) if self.MODEL == "RT29_UHF" or self.MODEL == "RT29_VHF": # set the power level if mem.power == self.POWER_LEVELS[2]: _mem.txpower = self.TXPOWER_LOW elif mem.power == self.POWER_LEVELS[1]: _mem.txpower = self.TXPOWER_MED elif mem.power == self.POWER_LEVELS[0]: _mem.txpower = self.TXPOWER_HIGH else: LOG.error('%s: set_mem: unhandled power level: %s' % (mem.name, mem.power)) else: _mem.highpower = mem.power == self.POWER_LEVELS[0] if self._skipflags: if mem.skip != "S": _skp |= bitpos else: _skp &= ~bitpos LOG.debug("_skp %s" % _skp) for setting in mem.extra: if setting.get_name() == "scramble_type": setattr(_mem, setting.get_name(), int(setting.value) - 1) if self.MODEL == "RT21" or self.MODEL == "RT21V": setattr(_mem, "scramble_type2", int(setting.value) - 1) elif setting.get_name() == "freqhop": setattr(_freqhops, setting.get_name(), setting.value) elif setting.get_name() == "hop": setattr(_mem, setting.get_name(), not int(setting.value)) else: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) if self.MODEL == "RT21" or self.MODEL == "RB17A" or \ self.MODEL == "RT29_UHF" or self.MODEL == "RT29_VHF" or \ self.MODEL == "RT21V": _keys = self._memobj.keys rs = RadioSettingValueList(TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[_settings.tot]) rset = RadioSetting("tot", "Time-out timer", rs) basic.append(rset) rs = RadioSettingValueList(TOTALERT_LIST, TOTALERT_LIST[_settings.totalert]) rset = RadioSetting("totalert", "TOT Pre-alert", rs) basic.append(rset) rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) basic.append(rset) rs = RadioSettingValueList(VOICE_LIST, VOICE_LIST[_settings.voice]) rset = RadioSetting("voice", "Voice Annumciation", rs) basic.append(rset) if self.MODEL == "RB17A": rs = RadioSettingValueList(ALARM_LIST, ALARM_LIST[_settings.alarm]) rset = RadioSetting("alarm", "Alarm Type", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.save) rset = RadioSetting("save", "Battery Saver", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.use_scramble) rset = RadioSetting("use_scramble", "Scramble", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.use_vox) rset = RadioSetting("use_vox", "VOX", rs) basic.append(rset) rs = RadioSettingValueList(VOX_LIST, VOX_LIST[_settings.vox]) rset = RadioSetting("vox", "VOX Gain", rs) basic.append(rset) if self.MODEL == "RT29_UHF" or self.MODEL == "RT29_VHF": rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) def apply_pf1_listvalue(setting, obj): LOG.debug("Setting value: " + str( setting.value) + " from list") val = str(setting.value) index = PF1_CHOICES.index(val) val = PF1_VALUES[index] obj.set_value(val) if self.MODEL == "RT21" or self.MODEL == "RT21V": if _keys.pf1 in PF1_VALUES: idx = PF1_VALUES.index(_keys.pf1) else: idx = LIST_DTMF_SPECIAL_VALUES.index(0x04) rs = RadioSettingValueList(PF1_CHOICES, PF1_CHOICES[idx]) rset = RadioSetting("keys.pf1", "PF1 Key Function", rs) rset.set_apply_callback(apply_pf1_listvalue, _keys.pf1) basic.append(rset) def apply_pf1_17a_listvalue(setting, obj): LOG.debug("Setting value: " + str( setting.value) + " from list") val = str(setting.value) index = PF1_17A_CHOICES.index(val) val = PF1_17A_VALUES[index] obj.set_value(val) if self.MODEL == "RB17A": if _keys.pf1 in PF1_17A_VALUES: idx = PF1_17A_VALUES.index(_keys.pf1) else: idx = LIST_DTMF_SPECIAL_VALUES.index(0x04) rs = RadioSettingValueList(PF1_17A_CHOICES, PF1_17A_CHOICES[idx]) rset = RadioSetting("keys.pf1", "PF1 Key Function", rs) rset.set_apply_callback(apply_pf1_17a_listvalue, _keys.pf1) basic.append(rset) def apply_topkey_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = TOPKEY_CHOICES.index(val) val = TOPKEY_VALUES[index] obj.set_value(val) if self.MODEL == "RB17A": if _keys.topkey in TOPKEY_VALUES: idx = TOPKEY_VALUES.index(_keys.topkey) else: idx = TOPKEY_VALUES.index(0x0C) rs = RadioSettingValueList(TOPKEY_CHOICES, TOPKEY_CHOICES[idx]) rset = RadioSetting("keys.topkey", "Top Key Function", rs) rset.set_apply_callback(apply_topkey_listvalue, _keys.topkey) basic.append(rset) def apply_pfkey_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = PFKEY_CHOICES.index(val) val = PFKEY_VALUES[index] obj.set_value(val) if self.MODEL == "RT29_UHF" or self.MODEL == "RT29_VHF": if _keys.pf1 in PFKEY_VALUES: idx = PFKEY_VALUES.index(_keys.pf1) else: idx = PFKEY_VALUES.index(0x04) rs = RadioSettingValueList(PFKEY_CHOICES, PFKEY_CHOICES[idx]) rset = RadioSetting("keys.pf1", "PF1 Key Function", rs) rset.set_apply_callback(apply_pfkey_listvalue, _keys.pf1) basic.append(rset) if _keys.pf2 in PFKEY_VALUES: idx = PFKEY_VALUES.index(_keys.pf2) else: idx = PFKEY_VALUES.index(0x0A) rs = RadioSettingValueList(PFKEY_CHOICES, PFKEY_CHOICES[idx]) rset = RadioSetting("keys.pf2", "PF2 Key Function", rs) rset.set_apply_callback(apply_pfkey_listvalue, _keys.pf2) basic.append(rset) if self.MODEL in ["AR-63", "RB23", "RB26", "RT19", "RT40B", "RT76", "RT86", "RT619", ]: if self.MODEL == "RB26" or self.MODEL == "RB23": _settings2 = self._memobj.settings2 _settings3 = self._memobj.settings3 rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) basic.append(rset) rs = RadioSettingValueList(TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[_settings.tot]) rset = RadioSetting("tot", "Time-out timer", rs) basic.append(rset) if self.MODEL == "RT19" or self.MODEL == "RT619": rs = RadioSettingValueList(VOICE_LIST, VOICE_LIST[_settings.voice]) rset = RadioSetting("voice", "Voice Prompts", rs) basic.append(rset) rs = RadioSettingValueList(BOOTSEL_LIST, BOOTSEL_LIST[_settings.bootsel]) rset = RadioSetting("bootsel", "Boot Select", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 10, _settings.voicel + 1) rset = RadioSetting("voicel", "Voice Level", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.vox) rset = RadioSetting("vox", "Vox Function", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings.voxl]) rset = RadioSetting("voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) if self.MODEL == "AR-63": rs = RadioSettingValueList(VOICE_LIST, VOICE_LIST[_settings.voice]) rset = RadioSetting("voice", "Voice Prompts", rs) basic.append(rset) if self.MODEL in ["RT76", "RT86", ]: rs = RadioSettingValueList(VOICE_LIST3, VOICE_LIST3[_settings.voice]) rset = RadioSetting("voice", "Voice Annumciation", rs) basic.append(rset) if self.MODEL == "RB26" or self.MODEL == "RB23": rs = RadioSettingValueList(VOICE_LIST2, VOICE_LIST2[_settings.voice]) rset = RadioSetting("voice", "Voice Annumciation", rs) basic.append(rset) if self.MODEL == "RB26": rs = RadioSettingValueBoolean(not _settings.chnumberd) rset = RadioSetting("chnumberd", "Channel Number Enable", rs) basic.append(rset) if self.MODEL == "RT86": rs = RadioSettingValueList(SPECIAL_LIST, SPECIAL_LIST[_settings.tailmode]) rset = RadioSetting("tailmode", "QT/DQT Tail Mode", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.save) rset = RadioSetting("save", "Battery Save", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.beep) rset = RadioSetting("beep", "Beep", rs) basic.append(rset) if self.MODEL in ["RB23", "RB26", "RT86", ]: rs = RadioSettingValueBoolean(not _settings.tail) rset = RadioSetting("tail", "QT/DQT Tail", rs) basic.append(rset) if self.MODEL != "AR-63" and self.MODEL != "RT40B": rs = RadioSettingValueList(SAVE_LIST, SAVE_LIST[_settings.savem]) rset = RadioSetting("savem", "Battery Save Mode", rs) basic.append(rset) if self.MODEL != "RT19" and self.MODEL != "RT619" and \ self.MODEL != "AR-63" and \ self.MODEL != "RT40B": rs = RadioSettingValueList(GAIN_LIST, GAIN_LIST[_settings.gain]) rset = RadioSetting("gain", "MIC Gain", rs) basic.append(rset) rs = RadioSettingValueList(WARN_LIST, WARN_LIST[_settings.warn]) rset = RadioSetting("warn", "Warn Mode", rs) basic.append(rset) if self.MODEL == "RT86": rs = RadioSettingValueInteger(1, 16, _settings.chnumber + 1) rset = RadioSetting("settings.chnumber", "Channel Number", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.vox) rset = RadioSetting("vox", "Vox Function", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings.voxl]) rset = RadioSetting("voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) if self.MODEL == "RB26" or self.MODEL == "RB23": rs = RadioSettingValueBoolean(_settings3.vox) rset = RadioSetting("settings3.vox", "Vox Function", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings3.voxl]) rset = RadioSetting("settings3.voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings3.voxd]) rset = RadioSetting("settings3.voxd", "Vox Delay", rs) basic.append(rset) if self.MODEL == "RB26": rs = RadioSettingValueList(PFKEY_LIST, PFKEY_LIST[_settings.pf1]) rset = RadioSetting("pf1", "PF1 Key Set", rs) basic.append(rset) rs = RadioSettingValueList(PFKEY_LIST, PFKEY_LIST[_settings.pf2]) rset = RadioSetting("pf2", "PF2 Key Set", rs) basic.append(rset) elif self.MODEL == "RB23": def apply_pfkey_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = PFKEY23_CHOICES.index(val) val = PFKEY23_VALUES[index] obj.set_value(val) if _settings.pf1 in PFKEY23_VALUES: idx = PFKEY23_VALUES.index(_settings.pf1) else: idx = PFKEY23_VALUES.index(0x01) rs = RadioSettingValueList(PFKEY23_CHOICES, PFKEY23_CHOICES[idx]) rset = RadioSetting("settings.pf1", "PF1 Key Function", rs) rset.set_apply_callback(apply_pfkey_listvalue, _settings.pf1) basic.append(rset) if _settings.pf2 in PFKEY23_VALUES: idx = PFKEY23_VALUES.index(_settings.pf2) else: idx = PFKEY23_VALUES.index(0x03) rs = RadioSettingValueList(PFKEY23_CHOICES, PFKEY23_CHOICES[idx]) rset = RadioSetting("settings.pf2", "PF2 Key Function", rs) rset.set_apply_callback(apply_pfkey_listvalue, _settings.pf2) basic.append(rset) rs = RadioSettingValueInteger(1, 30, _settings2.chnumber + 1) rset = RadioSetting("settings2.chnumber", "Channel Number", rs) basic.append(rset) if self.MODEL == "RT76": rs = RadioSettingValueBoolean(_settings.vox) rset = RadioSetting("vox", "Vox Function", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings.voxl]) rset = RadioSetting("voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 30, _settings.chnumber + 1) rset = RadioSetting("chnumber", "Channel Number", rs) basic.append(rset) if self.MODEL == "AR-63": rs = RadioSettingValueBoolean(_settings.warn) rset = RadioSetting("warn", "Warn", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.scan) rset = RadioSetting("scan", "Scan", rs) basic.append(rset) rs = RadioSettingValueList(HOP_LIST, HOP_LIST[_settings.hop]) rset = RadioSetting("hop", "Hop Mode", rs) basic.append(rset) rs = RadioSettingValueList(TAIL_LIST, TAIL_LIST[_settings.tailmode]) rset = RadioSetting("tailmode", "DCS Tail Mode", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.vox) rset = RadioSetting("vox", "Vox Function", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings.voxl]) rset = RadioSetting("voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) if self.MODEL == "RT40B": rs = RadioSettingValueList(VOICE_LIST, VOICE_LIST[_settings.voice]) rset = RadioSetting("voice", "Voice Prompts", rs) basic.append(rset) rs = RadioSettingValueList(SAVEM_LIST, SAVEM_LIST[_settings.savem]) rset = RadioSetting("savem", "Battery Save Mode", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.pttstone) rset = RadioSetting("pttstone", "PTT Start Tone", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.pttetone) rset = RadioSetting("pttetone", "PTT End Tone", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.vox) rset = RadioSetting("vox", "Vox Function", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings.voxl]) rset = RadioSetting("voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) if self.MODEL == "RT86": rs = RadioSettingValueList(PFKEY86_LIST, PFKEY86_LIST[_settings.pf1]) rset = RadioSetting("pf1", "PF1 Key Set", rs) basic.append(rset) rs = RadioSettingValueList(PFKEY86_LIST, PFKEY86_LIST[_settings.pf2]) rset = RadioSetting("pf2", "PF2 Key Set", rs) basic.append(rset) if self.MODEL == "RB28B" or self.MODEL == "RB628B": rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) basic.append(rset) rs = RadioSettingValueList(TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[_settings.tot]) rset = RadioSetting("tot", "Time-out timer", rs) basic.append(rset) rs = RadioSettingValueList(VOICE_LIST2, VOICE_LIST2[_settings.voice]) rset = RadioSetting("voice", "Voice Annumciation", rs) basic.append(rset) rs = RadioSettingValueList(POT_LIST, POT_LIST[_settings.pwrontype]) rset = RadioSetting("pwrontype", "Power on Type", rs) basic.append(rset) rs = RadioSettingValueList(SAVE_LIST, SAVE_LIST[_settings.savem]) rset = RadioSetting("savem", "Battery Save Mode", rs) basic.append(rset) rs = RadioSettingValueList(GAIN_LIST, GAIN_LIST[_settings.gain]) rset = RadioSetting("gain", "MIC Gain", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 10, _settings.volume + 1) rset = RadioSetting("volume", "Volume", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 22, _settings.chnumber + 1) rset = RadioSetting("chnumber", "Channel Number", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.save) rset = RadioSetting("save", "Battery Save", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.beep) rset = RadioSetting("beep", "Beep", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.keylock) rset = RadioSetting("keylock", "Key Lock", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.vox) rset = RadioSetting("vox", "Vox Function", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings.voxl]) rset = RadioSetting("voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) rs = RadioSettingValueList(PFKEY28B_LIST, PFKEY28B_LIST[_settings.pfkey_lt]) rset = RadioSetting("pfkey_lt", "Key Set <", rs) basic.append(rset) rs = RadioSettingValueList(PFKEY28B_LIST, PFKEY28B_LIST[_settings.pfkey_gt]) rset = RadioSetting("pfkey_gt", "Key Set >", rs) basic.append(rset) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "channel": setattr(obj, setting, int(element.value) - 1) elif setting == "chnumber": setattr(obj, setting, int(element.value) - 1) elif setting == "chnumberd": setattr(obj, setting, not int(element.value)) elif setting == "tail": setattr(obj, setting, not int(element.value)) elif setting == "voicel": setattr(obj, setting, int(element.value) - 1) elif setting == "volume": setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): if cls.MODEL == "RT21": # The RT21 is pre-metadata, so do old-school detection match_size = False match_model = False # testing the file data size if len(filedata) in [0x0400, ]: match_size = True # testing the model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False else: # Radios that have always been post-metadata, so never do # old-school detection return False @directory.register class RB17ARadio(RT21Radio): """RETEVIS RB17A""" VENDOR = "Retevis" MODEL = "RB17A" BAUD_RATE = 9600 BLOCK_SIZE = 0x40 BLOCK_SIZE_UP = 0x10 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PROA8US" _fingerprint = [b"P3217s\xF8\xFF", ] _upper = 30 _skipflags = True _reserved = False _gmrs = True _ranges = [ (0x0000, 0x0300), ] _memsize = 0x0300 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RB17A, self._mmap) @directory.register class RT21VRadio(RT21Radio): """RETEVIS RT21V""" VENDOR = "Retevis" MODEL = "RT21V" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(137000000, 174000000)] _fingerprint = [b"P2207\x01\xF8\xFF", ] _murs = False # sold as MURS radio but supports full band TX/RX _upper = 5 _mem_params = (_upper, # number of channels ) @directory.register class RB26Radio(RT21Radio): """RETEVIS RB26""" VENDOR = "Retevis" MODEL = "RB26" BAUD_RATE = 9600 BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 DTCS_CODES = DTCS_EXTRA POWER_LEVELS = [chirp_common.PowerLevel("High", watts=3.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PHOGR" + b"\x01" + b"0" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 30 _ack_1st_block = False _skipflags = True _reserved = True _gmrs = True _ranges = [ (0x0000, 0x0320), ] _memsize = 0x0320 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RB26, self._mmap) @directory.register class RT76Radio(RT21Radio): """RETEVIS RT76""" VENDOR = "Retevis" MODEL = "RT76" BAUD_RATE = 9600 BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 DTCS_CODES = DTCS_EXTRA POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PHOGR\x14\xD4" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 30 _ack_1st_block = False _skipflags = False _reserved = True _gmrs = True _ranges = [ (0x0000, 0x01E0), ] _memsize = 0x01E0 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT76, self._mmap) @directory.register class RT29UHFRadio(RT21Radio): """RETEVIS RT29UHF""" VENDOR = "Retevis" MODEL = "RT29_UHF" BLOCK_SIZE = 0x40 BLOCK_SIZE_UP = 0x10 TXPOWER_MED = 0x00 TXPOWER_HIGH = 0x01 TXPOWER_LOW = 0x02 DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (17, 50, 55, 135, 217, 254, 305, 345, 425, 466, 534, 645, 765))) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=10.00), chirp_common.PowerLevel("Mid", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] _magic = b"PROHRAM" _fingerprint = [b"P3207" + b"\x13\xF8\xFF", ] # UHF model _upper = 16 _skipflags = True _reserved = False _ranges = [ (0x0000, 0x0300), ] _memsize = 0x0400 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT29, self._mmap) @directory.register class RT29VHFRadio(RT29UHFRadio): """RETEVIS RT29VHF""" VENDOR = "Retevis" MODEL = "RT29_VHF" TXPOWER_MED = 0x00 TXPOWER_HIGH = 0x01 TXPOWER_LOW = 0x02 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=10.00), chirp_common.PowerLevel("Mid", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] VALID_BANDS = [(136000000, 174000000)] _magic = b"PROHRAM" _fingerprint = [b"P2207" + b"\x01\xF8\xFF", ] # VHF model @directory.register class RB23Radio(RT21Radio): """RETEVIS RB23""" VENDOR = "Retevis" MODEL = "RB23" BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PHOGR" + b"\x01" + b"0" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 30 _ack_1st_block = False _skipflags = True _reserved = True _gmrs = True _ranges = [ (0x0000, 0x0320), ] _memsize = 0x0320 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RB26, self._mmap) @directory.register class RT19Radio(RT21Radio): """RETEVIS RT19""" VENDOR = "Retevis" MODEL = "RT19" BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PHOGRQ^" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 22 _mem_params = (_upper, # number of channels 0x160, # memory start _upper # number of freqhops ) _ack_1st_block = False _skipflags = False _reserved = True _frs = True _ranges = [ (0x0000, 0x0180), ] _memsize = 0x0180 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT19 % self._mem_params, self._mmap) @directory.register class RT619Radio(RT19Radio): """RETEVIS RT619""" VENDOR = "Retevis" MODEL = "RT619" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=0.50), chirp_common.PowerLevel("Low", watts=0.49)] _magic = b"PHOGRS]" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 16 _mem_params = (_upper, # number of channels 0x100, # memory start _upper # number of freqhops ) _frs = False _pmr = True _ranges = [ (0x0000, 0x0120), ] _memsize = 0x0120 @directory.register class AR63Radio(RT21Radio): """ABBREE AR-63""" VENDOR = "Abbree" MODEL = "AR-63" BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=3.00), chirp_common.PowerLevel("Low", watts=1.00)] _magic = b"PHOGR\xF5\x9A" _fingerprint = [b"P32073" + b"\x02\xFF", b"P32073" + b"\x03\xFF", ] _upper = 16 _ack_1st_block = False _skipflags = True _reserved = True _gmrs = False _ranges = [ (0x0000, 0x0140), ] _memsize = 0x0140 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT76, self._mmap) @directory.register class RT40BRadio(RT21Radio): """RETEVIS RT40B""" VENDOR = "Retevis" MODEL = "RT40B" BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 DTCS_CODES = DTCS_EXTRA POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(400000000, 480000000)] _magic = b"PHOGRH" + b"\x5C" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 22 _mem_params = (_upper, # number of channels ) _ack_1st_block = False _skipflags = True _reserved = True _gmrs = True _echo = True _ranges = [ (0x0000, 0x0160), ] _memsize = 0x0160 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT40B % self._mem_params, self._mmap) @directory.register class RB28BRadio(RT21Radio): """RETEVIS RB28B""" VENDOR = "Retevis" MODEL = "RB28B" BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 DTCS_CODES = DTCS_EXTRA POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PHOGR\x08\xB2" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 22 _ack_1st_block = False _skipflags = False _reserved = True _frs = True _ranges = [ (0x0000, 0x01F0), ] _memsize = 0x01F0 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RB28B, self._mmap) @directory.register class RB628BRadio(RB28BRadio): """RETEVIS RB628B""" VENDOR = "Retevis" MODEL = "RB628B" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=0.50), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PHOGR\x09\xB2" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 16 _frs = False _pmr = True @directory.register class RT86Radio(RT21Radio): """RETEVIS RT86""" VENDOR = "Retevis" MODEL = "RT86" BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 DTCS_CODES = DTCS_EXTRA POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(400000000, 480000000)] _magic = b"PHOGR" + b"\xCD\x91" _fingerprint = [b"P32073" + b"\x02\xFF", ] _upper = 16 _ack_1st_block = False _skipflags = True _reserved = True _ranges = [ (0x0000, 0x01A0), ] _memsize = 0x01A0 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RT86, self._mmap) chirp-20240224/chirp/drivers/kguv8e.py0000644000175000017500000012333214520142245016405 0ustar hibbyhibby# Copyright 2019 Pavel Milanes CO7WT # # Based on the work of Krystian Struzik # who figured out the crypt used and made possible the # Wuoxun KG-UV8D Plus driver, in which this work is based. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun KG-UV8E radio management module""" import struct import time import logging from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) CMD_ID = 128 CMD_END = 129 CMD_RD = 130 CMD_WR = 131 MEM_VALID = 158 AB_LIST = ["A", "B"] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] STEP_LIST = [str(x) for x in STEPS] ROGER_LIST = ["Off", "Begin", "End", "Both"] TIMEOUT_LIST = ["Off"] + [str(x) + "s" for x in range(15, 901, 15)] VOX_LIST = ["Off"] + ["%s" % x for x in range(1, 10)] BANDWIDTH_LIST = ["Narrow", "Wide"] VOICE_LIST = ["Off", "On"] LANGUAGE_LIST = ["Chinese", "English"] SCANMODE_LIST = ["TO", "CO", "SE"] PF1KEY_LIST = ["Call", "VFTX"] PF3KEY_LIST = ["Disable", "Scan", "Lamp", "Tele Alarm", "SOS-CH", "Radio"] WORKMODE_LIST = ["VFO", "Channel No.", "Ch. No.+Freq.", "Ch. No.+Name"] BACKLIGHT_LIST = ["Always On"] + [str(x) + "s" for x in range(1, 21)] + \ ["Always Off"] OFFSET_LIST = ["+", "-"] PONMSG_LIST = ["Bitmap", "Battery Volts"] SPMUTE_LIST = ["QT", "QT+DTMF", "QT*DTMF"] DTMFST_LIST = ["DT-ST", "ANI-ST", "DT-ANI", "Off"] DTMF_TIMES = ["%s" % x for x in range(50, 501, 10)] RPTSET_LIST = ["", "X-DIRRPT", "X-TWRPT"] # TODO < what is index 0? ALERTS = [1750, 2100, 1000, 1450] ALERTS_LIST = [str(x) for x in ALERTS] PTTID_LIST = ["Begin", "End", "Both"] LIST_10 = ["Off"] + ["%s" % x for x in range(1, 11)] SCANGRP_LIST = ["All"] + ["%s" % x for x in range(1, 11)] SCQT_LIST = ["Decoder", "Encoder", "All"] SMUTESET_LIST = ["Off", "Tx", "Rx", "Tx/Rx"] POWER_LIST = ["Lo", "Hi"] HOLD_TIMES = ["Off"] + ["%s" % x for x in range(100, 5001, 100)] RPTMODE_LIST = ["Radio", "Repeater"] # memory slot 0 is not used, start at 1 (so need 1000 slots, not 999) # structure elements whose name starts with x are currently unidentified _MEM_FORMAT = """ #seekto 0x0030; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } vhf1_limits; #seekto 0x0044; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } uhf_limits; #seekto 0x0054; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } vhf_limits; #seekto 0x0400; struct { u8 oem1[8]; u8 unknown[2]; u8 unknown2[10]; u8 unknown3[10]; u8 unknown4[8]; u8 model[10]; u8 version[6]; u8 date[8]; u8 unknown5[1]; u8 oem2[8]; } oem_info; #seekto 0x0480; struct { u16 lower; u16 upper; } scan_groups[10]; #seekto 0x0500; struct { u8 call_code[6]; } call_groups[20]; #seekto 0x0580; struct { char call_name[6]; } call_group_name[20]; #seekto 0x0800; struct { u8 ponmsg; char dispstr[15]; u8 x0810; u8 x0811; u8 x0812; u8 x0813; u8 x0814; u8 voice; u8 timeout; u8 toalarm; u8 channel_menu; u8 power_save; u8 autolock; u8 keylock; u8 beep; u8 stopwatch; u8 vox; u8 scan_rev; u8 backlight; u8 roger_beep; u8 x0822[6]; u8 x0823[6]; u16 pri_ch; u8 ani_sw; u8 ptt_delay; u8 ani_code[6]; u8 dtmf_st; u8 bcl_a; u8 bcl_b; u8 ptt_id; u8 prich_sw; u8 rpt_set; u8 rpt_spk; u8 rpt_ptt; u8 alert; u8 pf1_func; u8 pf3_func; u8 x0843; u8 workmode_a; u8 workmode_b; u8 dtmf_tx_time; u8 dtmf_interval; u8 main_ab; u16 work_cha; u16 work_chb; u8 x084d; u8 x084e; u8 x084f; u8 x0850; u8 x0851; u8 x0852; u8 x0853; u8 x0854; u8 rpt_mode; u8 language; u8 x0857; u8 x0858; u8 x0859; u8 x085a; u8 x085b; u8 x085c; u8 x085d; u8 x085e; u8 single_display; u8 ring_time; u8 scg_a; u8 scg_b; u8 x0863; u8 rpt_tone; u8 rpt_hold; u8 scan_det; u8 sc_qt; u8 x0868; u8 smuteset; u8 callcode; } settings; #seekto 0x0880; struct { u32 rxfreq; u32 txoffset; u16 rxtone; u16 txtone; u8 scrambler:4, unknown1:2, power:1, unknown2:1; u8 unknown3:1, shift_dir:2, unknown4:1, compander:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfoa; #seekto 0x08c0; struct { u32 rxfreq; u32 txoffset; u16 rxtone; u16 txtone; u8 scrambler:4, unknown1:2, power:1, unknown2:1; u8 unknown3:1, shift_dir:2, unknown4:1, compander:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfob; #seekto 0x0900; struct { u32 rxfreq; u32 txfreq; u16 rxtone; u16 txtone; u8 scrambler:4, unknown1:2, power:1, unknown2:1; u8 unknown3:2, scan_add:1, unknown4:1, compander:1, mute_mode:2, iswide:1; u16 padding; } memory[1000]; #seekto 0x4780; struct { u8 name[8]; u8 unknown[4]; } names[1000]; #seekto 0x7670; u8 valid[1000]; """ # Support for the Wouxun KG-UV8E radio # Serial coms are at 19200 baud # The data is passed in variable length records # Record structure: # Offset Usage # 0 start of record (\x7a) # 1 Command (\x80 Identify \x81 End/Reboot \x82 Read \x83 Write) # 2 direction (\xff PC-> Radio, \x00 Radio -> PC) # 3 length of payload (excluding header/checksum) (n) # 4 payload (n bytes) # 4+n+1 checksum - byte sum (% 256) of bytes 1 -> 4+n # # Memory Read Records: # the payload is 3 bytes, first 2 are offset (big endian), # 3rd is number of bytes to read # Memory Write Records: # the maximum payload size (from the Wouxun software) seems to be 66 bytes # (2 bytes location + 64 bytes data). @directory.register class KGUV8ERadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-UV8E""" VENDOR = "Wouxun" MODEL = "KG-UV8E" _model = b"KG-UV8D-A" _file_ident = b"kguv8e" # lowercase BAUD_RATE = 19200 POWER_LEVELS = [chirp_common.PowerLevel("L", watts=1), chirp_common.PowerLevel("H", watts=5)] _record_start = 0x7B NEEDS_COMPAT_SERIAL = False def _checksum(self, data): cs = 0 for byte in data: cs += byte return cs % 256 def _write_record(self, cmd, payload=b''): _packet = struct.pack('BBBB', self._record_start, cmd, 0xFF, len(payload)) checksum = bytes([self._checksum(_packet[1:] + payload)]) _packet += self.encrypt(payload + checksum) LOG.debug("Sent:\n%s" % util.hexprint(_packet)) self.pipe.write(_packet) def _read_record(self): # read 4 chars for the header _header = self.pipe.read(4) if len(_header) != 4: raise errors.RadioError('Radio did not respond') _length = struct.unpack('xxxB', _header)[0] _packet = self.pipe.read(_length) _rcs_xor = _packet[-1] _packet = self.decrypt(_packet) _cs = self._checksum(_header[1:]) _cs += self._checksum(_packet) _cs %= 256 _rcs = self.strxor(self.pipe.read(1)[0], _rcs_xor)[0] LOG.debug("_cs =%x", _cs) LOG.debug("_rcs=%x", _rcs) return (_rcs != _cs, _packet) def decrypt(self, data): result = b'' for i in range(len(data)-1, 0, -1): result += self.strxor(data[i], data[i - 1]) result += self.strxor(data[0], 0x57) return result[::-1] def encrypt(self, data): result = self.strxor(0x57, data[0]) for i in range(1, len(data), 1): result += self.strxor(result[i - 1], data[i]) return result def strxor(self, xora, xorb): return bytes([xora ^ xorb]) # Identify the radio # # A Gotcha: the first identify packet returns a bad checksum, subsequent # attempts return the correct checksum... (well it does on my radio!) # # The ID record returned by the radio also includes the current frequency range # as 4 bytes big-endian in 10 Hz increments # # Offset # 0:10 Model, zero padded (Use first 7 chars for 'KG-UV8D') # 11:14 UHF rx lower limit (in units of 10 Hz) # 15:18 UHF rx upper limit # 19:22 UHF tx lower limit # 23:26 UHF tx upper limit # 27:30 VHF rx lower limit # 31:34 VHF rx upper limit # 35:38 VHF tx lower limit # 39:42 VHF tx upper limit @classmethod def match_model(cls, filedata, filename): id = cls._file_ident return cls._file_ident in b'kg' + filedata[0x426:0x430].replace(b'(', b'').replace(b')', b'').lower() def _identify(self): """Do the identification dance""" for _i in range(0, 10): self._write_record(CMD_ID) _chksum_err, _resp = self._read_record() LOG.debug("Got:\n%s" % util.hexprint(_resp)) if _chksum_err: LOG.error("Checksum error: retrying ident...") time.sleep(0.100) continue LOG.debug("Model %s" % util.hexprint(_resp[0:9])) if _resp[0:9] == self._model: return if len(_resp) == 0: raise Exception("Radio not responding") else: raise Exception("Unable to identify radio") def _finish(self): self._write_record(CMD_END) def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._download() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): self._upload() # TODO: Load all memory. # It would be smarter to only load the active areas and none of # the padding/unused areas. Padding still need to be investigated. def _download(self): """Talk to a Wouxun KG-UV8E and do a download""" try: self._identify() return self._do_download(0, 32768, 64) except errors.RadioError: raise except Exception as e: LOG.exception('Unknown error during download process') raise errors.RadioError("Failed to communicate with radio: %s" % e) def _do_download(self, start, end, blocksize): # allocate & fill memory image = b"" for i in range(start, end, blocksize): req = struct.pack('>HB', i, blocksize) self._write_record(CMD_RD, req) cs_error, resp = self._read_record() if cs_error: LOG.debug(util.hexprint(resp)) raise Exception("Checksum error on read") LOG.debug("Got:\n%s" % util.hexprint(resp)) image += resp[2:] if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning from radio" self.status_fn(status) self._finish() return memmap.MemoryMapBytes(image) def _upload(self): """Talk to a Wouxun KG-UV8E and do a upload""" try: self._identify() self._do_upload(0, 32768, 64) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) return def _do_upload(self, start, end, blocksize): ptr = start for i in range(start, end, blocksize): req = struct.pack('>H', i) chunk = self.get_mmap()[ptr:ptr + blocksize] self._write_record(CMD_WR, req + chunk) # ~ LOG.debug(util.hexprint(req + chunk)) cserr, ack = self._read_record() # ~ LOG.debug(util.hexprint(ack)) j = struct.unpack('>H', ack)[0] if cserr or j != ptr: raise Exception("Radio did not ack block %i" % ptr) ptr += blocksize if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning to radio" self.status_fn(status) self._finish() def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_bands = [(134000000, 175000000), # supports 2m (220000000, 260000000), # supports 1.25m (350000000, 520000000)] # supports 70cm rf.valid_characters = chirp_common.CHARSET_ASCII rf.memory_bounds = (1, 999) # 999 memories rf.valid_tuning_steps = STEPS return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is experimental.\n' '\n' 'Please keep a copy of your memories with the original software ' 'if you treasure them, this driver is new and may contain' ' bugs.\n' '\n' ) return rp def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol tpol = False if _mem.txtone != 0xFFFF and (_mem.txtone & 0x2800) == 0x2800: tcode, tpol = _get_dcs(_mem.txtone) mem.dtcs = tcode txmode = "DTCS" elif _mem.txtone != 0xFFFF and _mem.txtone != 0x0: mem.rtone = (_mem.txtone & 0x7fff) / 10.0 txmode = "Tone" else: txmode = "" rpol = False if _mem.rxtone != 0xFFFF and (_mem.rxtone & 0x2800) == 0x2800: rcode, rpol = _get_dcs(_mem.rxtone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rxtone != 0xFFFF and _mem.rxtone != 0x0: mem.ctone = (_mem.rxtone & 0x7fff) / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.txtone, rxmode, _mem.rxtone)) def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number _valid = self._memobj.valid[mem.number] LOG.debug("%d %s", number, _valid == MEM_VALID) if _valid != MEM_VALID: mem.empty = True return mem else: mem.empty = False mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _nam.name: if char != 0: mem.name += chr(char) mem.name = mem.name.rstrip() self._get_tone(_mem, mem) mem.skip = "" if bool(_mem.scan_add) else "S" mem.power = self.POWER_LEVELS[_mem.power] mem.mode = _mem.iswide and "FM" or "NFM" return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0x8000 return val rx_mode = tx_mode = None rxtone = txtone = 0x0000 if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None txtone = int(mem.rtone * 10) + 0x8000 elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) + 0x8000 elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) + 0x8000 if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) + 0x8000 _mem.rxtone = rxtone _mem.txtone = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.txtone, rx_mode, _mem.rxtone)) def set_memory(self, mem): number = mem.number _mem = self._memobj.memory[number] _nam = self._memobj.names[number] if mem.empty: _mem.set_raw("\x00" * (_mem.size() // 8)) self._memobj.valid[number] = 0 self._memobj.names[number].set_raw("\x00" * (_nam.size() // 8)) return _mem.rxfreq = int(mem.freq / 10) if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = int(mem.offset / 10) elif mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "+": _mem.txfreq = int(mem.freq / 10) + int(mem.offset / 10) elif mem.duplex == "-": _mem.txfreq = int(mem.freq / 10) - int(mem.offset / 10) else: _mem.txfreq = int(mem.freq / 10) _mem.scan_add = int(mem.skip != "S") _mem.iswide = int(mem.mode == "FM") # set the tone self._set_tone(mem, _mem) # set the scrambler and compander to off by default _mem.scrambler = 0 _mem.compander = 0 # set the power if mem.power: _mem.power = self.POWER_LEVELS.index(mem.power) else: _mem.power = True # set to mute mode to QT (not QT+DTMF or QT*DTMF) by default _mem.mute_mode = 0 for i in range(0, len(_nam.name)): if i < len(mem.name) and mem.name[i]: _nam.name[i] = ord(mem.name[i]) else: _nam.name[i] = 0x0 self._memobj.valid[mem.number] = MEM_VALID def _get_settings(self): _settings = self._memobj.settings _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob cfg_grp = RadioSettingGroup("cfg_grp", "Configuration") vfoa_grp = RadioSettingGroup("vfoa_grp", "VFO A Settings") vfob_grp = RadioSettingGroup("vfob_grp", "VFO B Settings") key_grp = RadioSettingGroup("key_grp", "Key Settings") lmt_grp = RadioSettingGroup("lmt_grp", "Frequency Limits") uhf_lmt_grp = RadioSettingGroup("uhf_lmt_grp", "UHF") vhf_lmt_grp = RadioSettingGroup("vhf_lmt_grp", "VHF") vhf1_lmt_grp = RadioSettingGroup("vhf1_lmt_grp", "VHF1") oem_grp = RadioSettingGroup("oem_grp", "OEM Info") lmt_grp.append(vhf_lmt_grp) lmt_grp.append(vhf1_lmt_grp) lmt_grp.append(uhf_lmt_grp) group = RadioSettings(cfg_grp, vfoa_grp, vfob_grp, key_grp, lmt_grp, oem_grp) # # Configuration Settings # rs = RadioSetting("channel_menu", "Menu available in channel mode", RadioSettingValueBoolean(_settings.channel_menu)) cfg_grp.append(rs) rs = RadioSetting("ponmsg", "Poweron message", RadioSettingValueList( PONMSG_LIST, PONMSG_LIST[_settings.ponmsg])) cfg_grp.append(rs) rs = RadioSetting("voice", "Voice Guide", RadioSettingValueBoolean(_settings.voice)) cfg_grp.append(rs) rs = RadioSetting("language", "Language", RadioSettingValueList(LANGUAGE_LIST, LANGUAGE_LIST[_settings. language])) cfg_grp.append(rs) rs = RadioSetting("timeout", "Timeout Timer", RadioSettingValueList( TIMEOUT_LIST, TIMEOUT_LIST[_settings.timeout])) cfg_grp.append(rs) rs = RadioSetting("toalarm", "Timeout Alarm", RadioSettingValueInteger(0, 10, _settings.toalarm)) cfg_grp.append(rs) rs = RadioSetting("roger_beep", "Roger Beep", RadioSettingValueList(ROGER_LIST, ROGER_LIST[_settings.roger_beep])) cfg_grp.append(rs) rs = RadioSetting("power_save", "Power save", RadioSettingValueBoolean(_settings.power_save)) cfg_grp.append(rs) rs = RadioSetting("autolock", "Autolock", RadioSettingValueBoolean(_settings.autolock)) cfg_grp.append(rs) rs = RadioSetting("keylock", "Keypad Lock", RadioSettingValueBoolean(_settings.keylock)) cfg_grp.append(rs) rs = RadioSetting("beep", "Keypad Beep", RadioSettingValueBoolean(_settings.beep)) cfg_grp.append(rs) rs = RadioSetting("stopwatch", "Stopwatch", RadioSettingValueBoolean(_settings.stopwatch)) cfg_grp.append(rs) rs = RadioSetting("backlight", "Backlight", RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings. backlight])) cfg_grp.append(rs) rs = RadioSetting("dtmf_st", "DTMF Sidetone", RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[_settings. dtmf_st])) cfg_grp.append(rs) rs = RadioSetting("ani_sw", "ANI-ID Switch", RadioSettingValueBoolean(_settings.ani_sw)) cfg_grp.append(rs) rs = RadioSetting("ptt_id", "PTT-ID Delay", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_settings.ptt_id])) cfg_grp.append(rs) rs = RadioSetting("ring_time", "Ring Time", RadioSettingValueList(LIST_10, LIST_10[_settings.ring_time])) cfg_grp.append(rs) rs = RadioSetting("scan_rev", "Scan Mode", RadioSettingValueList(SCANMODE_LIST, SCANMODE_LIST[_settings. scan_rev])) cfg_grp.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueList(LIST_10, LIST_10[_settings.vox])) cfg_grp.append(rs) rs = RadioSetting("prich_sw", "Priority Channel Switch", RadioSettingValueBoolean(_settings.prich_sw)) cfg_grp.append(rs) rs = RadioSetting("pri_ch", "Priority Channel", RadioSettingValueInteger(1, 999, _settings.pri_ch)) cfg_grp.append(rs) rs = RadioSetting("rpt_mode", "Radio Mode", RadioSettingValueList(RPTMODE_LIST, RPTMODE_LIST[_settings. rpt_mode])) cfg_grp.append(rs) rs = RadioSetting("rpt_set", "Repeater Setting", RadioSettingValueList(RPTSET_LIST, RPTSET_LIST[_settings. rpt_set])) cfg_grp.append(rs) rs = RadioSetting("rpt_spk", "Repeater Mode Speaker", RadioSettingValueBoolean(_settings.rpt_spk)) cfg_grp.append(rs) rs = RadioSetting("rpt_ptt", "Repeater PTT", RadioSettingValueBoolean(_settings.rpt_ptt)) cfg_grp.append(rs) rs = RadioSetting("dtmf_tx_time", "DTMF Tx Duration", RadioSettingValueList(DTMF_TIMES, DTMF_TIMES[_settings. dtmf_tx_time])) cfg_grp.append(rs) rs = RadioSetting("dtmf_interval", "DTMF Interval", RadioSettingValueList(DTMF_TIMES, DTMF_TIMES[_settings. dtmf_interval])) cfg_grp.append(rs) rs = RadioSetting("alert", "Alert Tone", RadioSettingValueList(ALERTS_LIST, ALERTS_LIST[_settings.alert])) cfg_grp.append(rs) rs = RadioSetting("rpt_tone", "Repeater Tone", RadioSettingValueBoolean(_settings.rpt_tone)) cfg_grp.append(rs) rs = RadioSetting("rpt_hold", "Repeater Hold Time", RadioSettingValueList(HOLD_TIMES, HOLD_TIMES[_settings. rpt_hold])) cfg_grp.append(rs) rs = RadioSetting("scan_det", "Scan DET", RadioSettingValueBoolean(_settings.scan_det)) cfg_grp.append(rs) rs = RadioSetting("sc_qt", "SC-QT", RadioSettingValueList(SCQT_LIST, SCQT_LIST[_settings.sc_qt])) cfg_grp.append(rs) rs = RadioSetting("smuteset", "SubFreq Mute", RadioSettingValueList(SMUTESET_LIST, SMUTESET_LIST[_settings. smuteset])) cfg_grp.append(rs) # # VFO A Settings # rs = RadioSetting("workmode_a", "VFO A Workmode", RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[_settings.workmode_a])) vfoa_grp.append(rs) rs = RadioSetting("work_cha", "VFO A Channel", RadioSettingValueInteger(1, 999, _settings.work_cha)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.rxfreq", "VFO A Rx Frequency", RadioSettingValueInteger( 134000000, 520000000, _vfoa.rxfreq * 10, 5000)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.txoffset", "VFO A Tx Offset", RadioSettingValueInteger( 0, 520000000, _vfoa.txoffset * 10, 5000)) vfoa_grp.append(rs) # u16 rxtone; # u16 txtone; rs = RadioSetting("vfoa.power", "VFO A Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfoa.power])) vfoa_grp.append(rs) # shift_dir:2 rs = RadioSetting("vfoa.iswide", "VFO A NBFM", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfoa.iswide])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.mute_mode", "VFO A Mute", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfoa.mute_mode])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.step", "VFO A Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfoa.step])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.squelch", "VFO A Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfoa.squelch])) vfoa_grp.append(rs) rs = RadioSetting("bcl_a", "Busy Channel Lock-out A", RadioSettingValueBoolean(_settings.bcl_a)) vfoa_grp.append(rs) # # VFO B Settings # rs = RadioSetting("workmode_b", "VFO B Workmode", RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[_settings.workmode_b])) vfob_grp.append(rs) rs = RadioSetting("work_chb", "VFO B Channel", RadioSettingValueInteger(1, 999, _settings.work_chb)) vfob_grp.append(rs) rs = RadioSetting("vfob.rxfreq", "VFO B Rx Frequency", RadioSettingValueInteger( 134000000, 520000000, _vfob.rxfreq * 10, 5000)) vfob_grp.append(rs) rs = RadioSetting("vfob.txoffset", "VFO B Tx Offset", RadioSettingValueInteger( 0, 520000000, _vfob.txoffset * 10, 5000)) vfob_grp.append(rs) # u16 rxtone; # u16 txtone; rs = RadioSetting("vfob.power", "VFO B Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfob.power])) vfob_grp.append(rs) # shift_dir:2 rs = RadioSetting("vfob.iswide", "VFO B NBFM", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfob.iswide])) vfob_grp.append(rs) rs = RadioSetting("vfob.mute_mode", "VFO B Mute", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfob.mute_mode])) vfob_grp.append(rs) rs = RadioSetting("vfob.step", "VFO B Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfob.step])) vfob_grp.append(rs) rs = RadioSetting("vfob.squelch", "VFO B Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfob.squelch])) vfob_grp.append(rs) rs = RadioSetting("bcl_b", "Busy Channel Lock-out B", RadioSettingValueBoolean(_settings.bcl_b)) vfob_grp.append(rs) # # Key Settings # _msg = str(_settings.dispstr).split("\0")[0] val = RadioSettingValueString(0, 15, _msg) val.set_mutable(True) rs = RadioSetting("dispstr", "Display Message", val) key_grp.append(rs) dtmfchars = "0123456789" _codeobj = _settings.ani_code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x0A]) val = RadioSettingValueString(3, 6, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("ani_code", "ANI Code", val) def apply_ani_id(setting, obj): value = [] for j in range(0, 6): try: value.append(dtmfchars.index(str(setting.value)[j])) except IndexError: value.append(0xFF) obj.ani_code = value rs.set_apply_callback(apply_ani_id, _settings) key_grp.append(rs) rs = RadioSetting("pf1_func", "PF1 Key function", RadioSettingValueList( PF1KEY_LIST, PF1KEY_LIST[_settings.pf1_func])) key_grp.append(rs) rs = RadioSetting("pf3_func", "PF3 Key function", RadioSettingValueList( PF3KEY_LIST, PF3KEY_LIST[_settings.pf3_func])) key_grp.append(rs) # # Limits settings # rs = RadioSetting("vhf_limits.rx_start", "VHF RX Lower Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.rx_start * 10, 5000)) vhf_lmt_grp.append(rs) rs = RadioSetting("vhf_limits.rx_stop", "VHF RX Upper Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.rx_stop * 10, 5000)) vhf_lmt_grp.append(rs) rs = RadioSetting("vhf_limits.tx_start", "VHF TX Lower Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.tx_start * 10, 5000)) vhf_lmt_grp.append(rs) rs = RadioSetting("vhf_limits.tx_stop", "VHF TX Upper Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.tx_stop * 10, 5000)) vhf_lmt_grp.append(rs) rs = RadioSetting("vhf1_limits.rx_start", "VHF1 RX Lower Limit", RadioSettingValueInteger( 220000000, 265000000, self._memobj.vhf1_limits.rx_start * 10, 5000)) vhf1_lmt_grp.append(rs) rs = RadioSetting("vhf1_limits.rx_stop", "VHF1 RX Upper Limit", RadioSettingValueInteger( 220000000, 265000000, self._memobj.vhf1_limits.rx_stop * 10, 5000)) vhf1_lmt_grp.append(rs) rs = RadioSetting("vhf1_limits.tx_start", "VHF1 TX Lower Limit", RadioSettingValueInteger( 220000000, 265000000, self._memobj.vhf1_limits.tx_start * 10, 5000)) vhf1_lmt_grp.append(rs) rs = RadioSetting("vhf1_limits.tx_stop", "VHF1 TX Upper Limit", RadioSettingValueInteger( 220000000, 265000000, self._memobj.vhf1_limits.tx_stop * 10, 5000)) vhf1_lmt_grp.append(rs) rs = RadioSetting("uhf_limits.rx_start", "UHF RX Lower Limit", RadioSettingValueInteger( 350000000, 520000000, self._memobj.uhf_limits.rx_start * 10, 5000)) uhf_lmt_grp.append(rs) rs = RadioSetting("uhf_limits.rx_stop", "UHF RX Upper Limit", RadioSettingValueInteger( 350000000, 520000000, self._memobj.uhf_limits.rx_stop * 10, 5000)) uhf_lmt_grp.append(rs) rs = RadioSetting("uhf_limits.tx_start", "UHF TX Lower Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.tx_start * 10, 5000)) uhf_lmt_grp.append(rs) rs = RadioSetting("uhf_limits.tx_stop", "UHF TX Upper Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.tx_stop * 10, 5000)) uhf_lmt_grp.append(rs) # # OEM info # def _decode(lst): _str = ''.join([chr(c) for c in lst if chr(c) in chirp_common.CHARSET_ASCII]) return _str def do_nothing(setting, obj): return _str = _decode(self._memobj.oem_info.model) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.model", "Model", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.oem1) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.oem1", "OEM String 1", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.oem2) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.oem2", "OEM String 2", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.version) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.version", "Software Version", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.date) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.date", "OEM Date", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) return group def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) if self._is_freq(element): setattr(obj, setting, int(element.value)/10) else: setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _is_freq(self, element): return "rxfreq" in element.get_name() or "txoffset" in element.get_name() or "rx_start" in element.get_name() or "rx_stop" in element.get_name() or "tx_start" in element.get_name() or "tx_stop" in element.get_name() chirp-20240224/chirp/drivers/icomciv.py0000644000175000017500000010624414446523722016642 0ustar hibbyhibby# Latest update: April, 2021 Add hasattr test at line 564 import struct import logging from chirp.drivers import icf from chirp import chirp_common, util, errors, bitwise, directory from chirp.memmap import MemoryMapBytes from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean LOG = logging.getLogger(__name__) MEM_FORMAT = """ bbcd number[2]; u8 unknown:3 split:1, unknown_0:4; lbcd freq[5]; u8 unknown2:5, mode:3; u8 filter; u8 unknown_1:3, dig:1, unknown_2:4; """ # http://www.vk4adc.com/ # web/index.php/reference-information/49-general-ref-info/182-civ7400 MEM_IC7000_FORMAT = """ u8 bank; bbcd number[2]; u8 spl:4, skip:4; lbcd freq[5]; u8 mode; u8 filter; u8 duplex:4, tmode:4; bbcd rtone[3]; bbcd ctone[3]; u8 dtcs_polarity; bbcd dtcs[2]; lbcd freq_tx[5]; u8 mode_tx; u8 filter_tx; u8 duplex_tx:4, tmode_tx:4; bbcd rtone_tx[3]; bbcd ctone_tx[3]; u8 dtcs_polarity_tx; bbcd dtcs_tx[2]; char name[9]; """ MEM_IC7100_FORMAT = """ u8 bank; // 1 bank number bbcd number[2]; // 2,3 u8 splitSelect; // 4 split and select memory settings lbcd freq[5]; // 5-9 operating freq u8 mode; // 10 operating mode u8 filter; // 11 filter u8 dataMode; // 12 data mode setting (on or off) u8 duplex:4, // 13 duplex on/-/+ tmode:4; // 13 tone u8 dsql:4, // 14 digital squelch unknown1:4; // 14 zero bbcd rtone[3]; // 15-17 repeater tone freq bbcd ctone[3]; // 18-20 tone squelch setting u8 dtcsPolarity; // 21 DTCS polarity u8 unknown2:4, // 22 zero firstDtcs:4; // 22 first digit of DTCS code u8 secondDtcs:4, // 23 second digit DTCS thirdDtcs:4; // 23 third digit DTCS u8 digitalSquelch; // 24 Digital code squelch setting lbcd duplexOffset[3]; // 25-27 duplex offset freq char destCall[8]; // 28-35 destination call sign char accessRepeaterCall[8];// 36-43 access repeater call sign char linkRepeaterCall[8]; // 44-51 gateway/link repeater call sign bbcd duplexSettings[47]; // repeat of 5-51 for duplex char name[16]; // 52-60 Name of station """ MEM_IC910_FORMAT = """ u8 bank; // 1 bank number bbcd number[2]; // 2,3 lbcd freq[5]; // 4-8 operating freq u8 mode; // 9 operating mode u8 filter; // 10 filter u8 tmode:4, // 11 tone duplex:4; // 11 duplex off/-/+ bbcd rtone[3]; // 12-14 repeater tone freq bbcd ctone[3]; // 15-17 tone squelch setting lbcd duplexOffset[3]; // 18-20 duplex offset freq """ mem_duptone_format = """ bbcd number[2]; u8 unknown1; lbcd freq[5]; u8 unknown2:5, mode:3; u8 unknown1; u8 unknown2:2, duplex:2, unknown3:1, tmode:3; u8 unknown4; bbcd rtone[2]; u8 unknown5; bbcd ctone[2]; u8 dtcs_polarity; bbcd dtcs[2]; u8 unknown[11]; char name[9]; """ MEM_IC7300_FORMAT = """ bbcd number[2]; // 1,2 u8 spl:4, // 3 split and select memory settings select:4; lbcd freq[5]; // 4-8 receive freq u8 mode; // 9 operating mode u8 filter; // 10 filter 1-3 (undocumented) u8 dataMode:4, // 11 data mode setting (on or off) tmode:4; // 11 tone type char pad1; bbcd rtone[2]; // 12-14 tx tone freq char pad2; bbcd ctone[2]; // 15-17 tone rx squelch setting // This is duplicated from 4-17 above, even duplicated by number in the // manual! lbcd freq_tx[5]; // 4-8 receive freq u8 mode_tx; // 9 operating mode u8 filter_tx; // 10 filter 1-3 (undocumented) u8 dataMode_tx:4, // 11 data mode setting (on or off) tmode_tx:4; // 11 tone type char pad1_tx; bbcd rtone_tx[2]; // 12-14 tx tone freq char pad2_tx; bbcd ctone_tx[2]; // 15-17 tone rx squelch setting // End TX duplicate block char name[10]; // 18-27 Callsign """ MEM_IC7610_FORMAT = """ bbcd number[2]; // 1,2 u8 spl:4, // 3 split and select memory settings select:4; lbcd freq[5]; // 4-8 receive freq u8 mode; // 9 operating mode u8 filter; // 10 filter 1-3 (undocumented) u8 dataMode:4, // 11 data mode setting (on or off) tmode:4; // 11 tone type char pad1; bbcd rtone[2]; // 12-14 tx tone freq char pad2; bbcd ctone[2]; // 15-17 tone rx squelch setting char name[10]; // 18-27 Callsign """ SPLIT = ["", "spl"] class Frame: """Base class for an ICF frame""" _cmd = 0x00 _sub = 0x00 def __init__(self): self._data = b"" def set_command(self, cmd, sub): """Set the command number (and optional subcommand)""" self._cmd = cmd self._sub = sub def get_data(self): """Return the data payload""" return self._data def set_data(self, data): """Set the data payload""" self._data = data def send(self, src, dst, serial, willecho=True): """Send the frame over @serial, using @src and @dst addresses""" hdr = struct.pack("BBBBBB", 0xFE, 0xFE, src, dst, self._cmd, self._sub) raw = bytearray(hdr) if isinstance(self._data, MemoryMapBytes): data = self._data.get_packed() else: data = self._data raw.extend(data) raw.append(0xFD) LOG.debug("%02x -> %02x (%i):\n%s" % (src, dst, len(raw), util.hexprint(bytes(raw)))) serial.write(raw) if willecho: echo = serial.read(len(raw)) if echo != raw and echo: LOG.debug("Echo differed (%i/%i)" % (len(raw), len(echo))) LOG.debug(util.hexprint(bytes(raw))) LOG.debug(util.hexprint(bytes(echo))) def read(self, serial): """Read the frame from @serial""" data = bytearray() while not (data and data[-1] == 0xFD): char = serial.read(1) if not char: LOG.debug("Read %i bytes total" % len(data)) raise errors.RadioError("Timeout") data.extend(char) if data[0] == 0xFD: raise errors.RadioError("Radio reported error") src, dst = struct.unpack("BB", data[2:4]) LOG.debug("%02x <- %02x:\n%s" % (dst, src, util.hexprint(bytes(data)))) self._cmd = data[4] self._sub = data[5] self._data = data[6:-1] return src, dst def get_obj(self): raise errors.RadioError("Generic frame has no structure") class MemFrame(Frame): """A memory frame""" _cmd = 0x1A _sub = 0x00 _loc = 0 FORMAT = MEM_FORMAT def set_location(self, loc): """Set the memory location number""" self._loc = loc self._data = struct.pack(">H", int("%04i" % loc, 16)) def make_empty(self): """Mark as empty so the radio will erase the memory""" self._data = struct.pack(">HB", int("%04i" % self._loc, 16), 0xFF) def is_empty(self): """Return True if memory is marked as empty""" return len(self._data) < 5 def get_obj(self): """Return a bitwise parsed object""" # Make sure we're assignable self._data = MemoryMapBytes(bytes(self._data)) return bitwise.parse(self.FORMAT, self._data) def initialize(self): """Initialize to sane values""" self._data = MemoryMapBytes( bytes(b'\x00' * (self.get_obj().size() / 8))) class BankMemFrame(MemFrame): """A memory frame for radios with multiple banks""" FORMAT = MEM_IC7000_FORMAT _bnk = 0 def set_location(self, loc, bank=1): self._loc = loc self._bnk = bank self._data = struct.pack( ">BH", int("%02i" % bank, 16), int("%04i" % loc, 16)) def make_empty(self): """Mark as empty so the radio will erase the memory""" self._data = struct.pack( ">BHB", int("%02i" % self._bnk, 16), int("%04i" % self._loc, 16), 0xFF) def get_obj(self): # Make sure we're assignable self._data = MemoryMapBytes(bytes(self._data)) return bitwise.parse(self.FORMAT, self._data) class IC7100MemFrame(BankMemFrame): FORMAT = MEM_IC7100_FORMAT class IC910MemFrame(BankMemFrame): FORMAT = MEM_IC910_FORMAT class DupToneMemFrame(MemFrame): def get_obj(self): self._data = MemoryMapBytes(bytes(self._data)) return bitwise.parse(mem_duptone_format, self._data) class IC7300MemFrame(MemFrame): FORMAT = MEM_IC7300_FORMAT class IC7610MemFrame(MemFrame): FORMAT = MEM_IC7610_FORMAT class SpecialChannel(object): """Info for special (named) channels""" def __init__(self): self.name = None self.location = None self.channel = None def __repr__(self): s = "SpecialChannel(name=%r, location=%r, channel=%r)" return s % (self.name, self.location, self.channel) class BankSpecialChannel(SpecialChannel): """Info for special (named) channels for radios with multiple banks""" def __init__(self): super(BankSpecialChannel, self).__init__() self.bank = None def __repr__(self): s = "BankSpecialChannel(name=%r, location=%r, bank=%r, channel=%r)" return s % (self.name, self.location, self.bank, self.channel) class IcomCIVRadio(icf.IcomLiveRadio): """Base class for ICOM CIV-based radios""" BAUD_RATE = 19200 NEEDS_COMPAT_SERIAL = False MODEL = "CIV Radio" # RTS is interpreted as "transmit now" on some interface boxes for these WANTS_RTS = False _model = "\x00" _template = 0 # complete list of modes from CI-V documentation # each radio supports a subset # WARNING: "S-AM" and "PSK" are not valid (yet) for chirp _MODES = [ "LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", "CWR" "RTTYR", "S-AM", "PSK", None, None, None, None, None, None, None, None, None, None, None, None, None, "DV", ] # Unified modes where mode and filter are combined. See note at # _unified_modes. _UNIFIED_MODES = { 'FM': 'NFM', 'CW': 'NCW' } def mem_to_ch_bnk(self, mem): if self._adjust_bank_loc_start: mem -= 1 l, h = self._bank_index_bounds bank_no = (mem // (h - l + 1)) + l channel = mem % (h - l + 1) + l return (channel, bank_no) def _is_special(self, number): return False def _get_special_info(self, number): raise errors.RadioError("Radio does not support special channels") def _send_frame(self, frame): return frame.send(ord(self._model), 0xE0, self.pipe, willecho=self._willecho) def _recv_frame(self, frame=None): if not frame: frame = Frame() frame.read(self.pipe) return frame def _initialize(self): pass def _detect_echo(self): echo_test = b"\xfe\xfe\xe0\xe0\xfa\xfd" self.pipe.write(echo_test) resp = self.pipe.read(6) LOG.debug("Echo:\n%s" % util.hexprint(bytes(resp))) return resp == echo_test def _detect_baudrate(self): if self._baud_detected: return # Don't ever try to run this twice, even if we fail self._baud_detected = True bauds = [9600, 19200, 38400, 57600, 115200, 4800] bauds.remove(self.BAUD_RATE) bauds.insert(0, self.BAUD_RATE) self.pipe.timeout = 0.25 for baud in bauds: LOG.debug('Trying %i baud' % baud) self.pipe.baudrate = baud self._willecho = self._detect_echo() LOG.debug("Interface echo: %s" % self._willecho) try: f = self._get_template_memory() print('Chew: %i' % len(self.pipe.read(128))) LOG.info('Detected %i baud' % baud) break except errors.RadioError: pass else: LOG.warning('Unable to detect baudrate, using default of %i' % ( self.BAUD_RATE)) self.pipe.baudrate = self.BAUD_RATE # Restore the historical default of 1s timeout for this driver self.pipe.timeout = 1 def __init__(self, *args, **kwargs): icf.IcomLiveRadio.__init__(self, *args, **kwargs) self._classes = { "mem": MemFrame, } if self.pipe: self._willecho = self._detect_echo() LOG.debug("Interface echo: %s" % self._willecho) self.pipe.timeout = 1 else: self._willecho = False self._baud_detected = False # f = Frame() # f.set_command(0x19, 0x00) # self._send_frame(f) # # res = f.read(self.pipe) # if res: # LOG.debug("Result: %x->%x (%i)" % # (res[0], res[1], len(f.get_data()))) # LOG.debug(util.hexprint(f.get_data())) # # self._id = f.get_data()[0] self._rf = chirp_common.RadioFeatures() # On some radios, the filter field is used to signify normal versus # narrow modes, rather than being a distinct passband feature. As # such, mode + filter comprises a "unified mode" value that can be # mapped into a Chirp mode. self._unified_modes = False # Icom live radios with bank support present their memories to the # user starting from 1. For some reason, IC-7000 and IC-7100 were # implemented with the Chirp location starting from 0, so that the # user must mentally adjust. While adding IC-910 support, allowance # was made to provide a 1-based start, using the following setting. # This is not currently applied to the IC-7000 or IC-7100 due to the # inability to test, and also since changing it may cause issues if # location limit keys have been saved in the user's config file. self._adjust_bank_loc_start = False self._initialize() def get_features(self): return self._rf def _get_template_memory(self): f = self._classes["mem"]() f.set_location(self._template) self._send_frame(f) f.read(self.pipe) return f def get_raw_memory(self, number): self._detect_baudrate() LOG.debug("Getting %s (raw)" % number) f = self._classes["mem"]() if self._is_special(number): info = self._get_special_info(number) LOG.debug("Special info: %s" % info) ch = info.channel if self._rf.has_bank: bnk = info.bank elif self._rf.has_bank: ch, bnk = self.mem_to_ch_bnk(number) else: ch = number if self._rf.has_bank: f.set_location(ch, bnk) loc = "bank %i, channel %02i" % (bnk, ch) else: f.set_location(ch) loc = "number %i" % ch self._send_frame(f) f.read(self.pipe) if f.get_data() and f.get_data()[-1] == "\xFF": return "Memory " + loc + " empty." else: return repr(f.get_obj()) # We have a simple mapping between the memory location in the frequency # editor and (bank, channel) of the radio. The mapping doesn't # change so we use a little math to calculate what bank a location # is in. We can't change the bank a location is in so we just pass. def _get_bank(self, loc): if self._adjust_bank_loc_start: loc -= 1 l, h = self._bank_index_bounds return loc // (h - l + 1) def _set_bank(self, loc, bank): pass def get_memory(self, number): self._detect_baudrate() LOG.debug("Getting %s" % number) f = self._classes["mem"]() mem = chirp_common.Memory() if self._is_special(number): info = self._get_special_info(number) LOG.debug("Special info: %s" % info) if self._rf.has_bank: f.set_location(info.channel, info.bank) else: f.set_location(info.channel) mem.number = info.location mem.extd_number = info.name mem.immutable = ["number", "extd_number"] else: if self._rf.has_bank: ch, bnk = self.mem_to_ch_bnk(number) f.set_location(ch, bnk) LOG.debug("Bank %i, Channel %02i" % (bnk, ch)) else: f.set_location(number) mem.number = number self._send_frame(f) f = self._recv_frame(f) if len(f.get_data()) == 0: raise errors.RadioError("Radio reported error") if f.get_data() and f.get_data()[-1] == 0xFF: mem.empty = True LOG.debug("Found %i empty" % mem.number) return mem memobj = f.get_obj() LOG.debug(repr(memobj)) try: if memobj.skip == 1: mem.skip = "" else: mem.skip = "S" except AttributeError: pass mem.freq = int(memobj.freq) try: mem.mode = self._MODES[memobj.mode] # We do not know what a variety of the positions between # PSK and DV mean, so let's behave as if those values # are not set to maintain consistency between known-unknown # values and unknown-unknown ones. if mem.mode is None: raise IndexError(memobj.mode) except IndexError: LOG.error( "Bank %s location %s is set for mode %s, but no known " "mode matches that value.", int(memobj.bank), int(memobj.number), repr(memobj.mode), ) raise if self._unified_modes and memobj.filter == 2: try: # Adjust mode to its narrow variant mem.mode = self._UNIFIED_MODES[mem.mode] except KeyError: LOG.error( "Bank %s location %s is set for mode %s with filter %s, " "but no known mode matches that combination.", int(memobj.bank), int(memobj.number), repr(memobj.mode), int(memobj.filter), ) raise if self._rf.has_name: mem.name = str(memobj.name).rstrip() if self._rf.valid_tmodes: mem.tmode = self._rf.valid_tmodes[memobj.tmode] if self._rf.has_dtcs_polarity: if memobj.dtcs_polarity == 0x11: mem.dtcs_polarity = "RR" elif memobj.dtcs_polarity == 0x10: mem.dtcs_polarity = "RN" elif memobj.dtcs_polarity == 0x01: mem.dtcs_polarity = "NR" else: mem.dtcs_polarity = "NN" if self._rf.has_dtcs: mem.dtcs = bitwise.bcd_to_int(memobj.dtcs) if "Tone" in self._rf.valid_tmodes: mem.rtone = int(memobj.rtone) / 10.0 if "TSQL" in self._rf.valid_tmodes and self._rf.has_ctone: mem.ctone = int(memobj.ctone) / 10.0 if self._rf.valid_duplexes: mem.duplex = self._rf.valid_duplexes[memobj.duplex] if self._rf.can_odd_split and memobj.spl: if hasattr(memobj, "duplex"): mem.duplex = "split" mem.offset = int(memobj.freq_tx) mem.immutable = [] elif hasattr(memobj, "duplexOffset"): mem.offset = int(memobj.duplexOffset) * 100 else: mem.immutable = ["offset"] try: dig = RadioSetting("dig", "Digital", RadioSettingValueBoolean(bool(memobj.dig))) except AttributeError: pass else: dig.set_doc("Enable digital mode") if not mem.extra: mem.extra = RadioSettingGroup("extra", "Extra") mem.extra.append(dig) if not self._unified_modes: options = ["Wide", "Mid", "Narrow"] try: fil = RadioSetting( "filter", "Filter", RadioSettingValueList(options, options[memobj.filter - 1])) except AttributeError: pass else: fil.set_doc("Filter settings") if not mem.extra: mem.extra = RadioSettingGroup("extra", "Extra") mem.extra.append(fil) return mem def set_memory(self, mem): self._detect_baudrate() LOG.debug("Setting %s(%s)" % (mem.number, mem.extd_number)) f = self._get_template_memory() if self._is_special(mem.number): info = self._get_special_info(mem.number) LOG.debug("Special info: %s" % info) ch = info.channel if self._rf.has_bank: bnk = info.bank elif self._rf.has_bank: ch, bnk = self.mem_to_ch_bnk(mem.number) LOG.debug("Bank %i, Channel %02i" % (bnk, ch)) else: ch = mem.number if mem.empty: if self._rf.has_bank: f.set_location(ch, bnk) else: f.set_location(ch) LOG.debug("Making %i empty" % mem.number) f.make_empty() self._send_frame(f) # The next two lines accept the radio's status after setting the memory # and reports the results to the debug log. This is needed for the # IC-7000. No testing was done to see if it breaks memory delete on the # IC-746 or IC-7200. f = self._recv_frame() LOG.debug("Result:\n%s" % util.hexprint(bytes(f.get_data()))) return # f.set_data(MemoryMap(self.get_raw_memory(mem.number))) # f.initialize() memobj = f.get_obj() if self._rf.has_bank: memobj.bank = bnk memobj.number = ch else: memobj.number = ch if mem.skip == "S": memobj.skip = 0 else: try: memobj.skip = 1 except KeyError: pass memobj.freq = int(mem.freq) mode = mem.mode if self._unified_modes: lookup = [ k for k, v in self._UNIFIED_MODES.items() if v == mode] if lookup: mode = lookup[0] memobj.filter = 2 else: memobj.filter = 1 memobj.mode = self._MODES.index(mode) if self._rf.has_name: name_length = len(memobj.name.get_value()) memobj.name = mem.name.ljust(name_length)[:name_length] if self._rf.valid_tmodes: memobj.tmode = self._rf.valid_tmodes.index(mem.tmode) if self._rf.has_ctone: memobj.ctone = int(mem.ctone * 10) memobj.rtone = int(mem.rtone * 10) if self._rf.has_dtcs_polarity: if mem.dtcs_polarity == "RR": memobj.dtcs_polarity = 0x11 elif mem.dtcs_polarity == "RN": memobj.dtcs_polarity = 0x10 elif mem.dtcs_polarity == "NR": memobj.dtcs_polarity = 0x01 else: memobj.dtcs_polarity = 0x00 if self._rf.has_dtcs: bitwise.int_to_bcd(memobj.dtcs, mem.dtcs) if self._rf.can_odd_split and mem.duplex == "split": memobj.spl = 1 if hasattr(memobj, "duplex"): memobj.duplex = 0 memobj.freq_tx = int(mem.offset) memobj.tmode_tx = memobj.tmode memobj.ctone_tx = memobj.ctone memobj.rtone_tx = memobj.rtone if self._rf.has_dtcs: memobj.dtcs_polarity_tx = memobj.dtcs_polarity memobj.dtcs_tx = memobj.dtcs elif self._rf.valid_duplexes: memobj.duplex = self._rf.valid_duplexes.index(mem.duplex) if hasattr(memobj, "duplexOffset"): memobj.duplexOffset = int(mem.offset) // 100 for setting in mem.extra: if setting.get_name() == "filter": setattr(memobj, setting.get_name(), int(setting.value) + 1) else: setattr(memobj, setting.get_name(), setting.value) LOG.debug(repr(memobj)) self._send_frame(f) f = self._recv_frame() LOG.debug("Result:\n%s" % util.hexprint(bytes(f.get_data()))) @directory.register class Icom7200Radio(IcomCIVRadio): """Icom IC-7200""" MODEL = "IC-7200" _model = "\x76" _template = 201 _num_banks = 1 # Banks not supported def _initialize(self): self._rf.has_bank = False self._rf.has_dtcs_polarity = False self._rf.has_dtcs = False self._rf.has_ctone = False self._rf.has_offset = False self._rf.has_name = False self._rf.has_tuning_step = False self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY", "CWR", "RTTYR"] self._rf.valid_tmodes = [] self._rf.valid_duplexes = [] self._rf.valid_bands = [(30000, 60000000)] self._rf.valid_skips = [] self._rf.memory_bounds = (1, 201) @directory.register class Icom7000Radio(IcomCIVRadio): """Icom IC-7000""" MODEL = "IC-7000" _model = "\x70" _template = 102 _num_banks = 5 # Banks A-E _bank_index_bounds = (1, 99) _bank_class = icf.IcomBank def _initialize(self): self._classes["mem"] = BankMemFrame self._rf.has_bank = True self._rf.has_dtcs_polarity = True self._rf.has_dtcs = True self._rf.has_ctone = True self._rf.has_offset = True self._rf.has_name = True self._rf.has_tuning_step = False self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM"] self._rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] self._rf.valid_duplexes = ["", "-", "+", "split"] self._rf.valid_bands = [(30000, 199999999), (400000000, 470000000)] self._rf.valid_tuning_steps = [] self._rf.valid_skips = ["S", ""] self._rf.valid_name_length = 9 self._rf.valid_characters = chirp_common.CHARSET_ASCII self._rf.memory_bounds = (0, 99 * self._num_banks - 1) self._rf.can_odd_split = True @directory.register class Icom7100Radio(IcomCIVRadio): """Icom IC-7100""" MODEL = "IC-7100" _model = "\x88" _template = 102 _num_banks = 5 _bank_index_bounds = (1, 99) _bank_class = icf.IcomBank def _initialize(self): self._classes["mem"] = IC7100MemFrame self._rf.has_bank = True self._rf.has_bank_index = False self._rf.has_bank_names = False self._rf.has_dtcs_polarity = False self._rf.has_dtcs = False self._rf.has_ctone = True self._rf.has_offset = False self._rf.has_name = True self._rf.has_tuning_step = False self._rf.valid_modes = [ "LSB", "USB", "AM", "CW", "RTTY", "FM", "WFM", "CWR", "RTTYR", "DV" ] self._rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] self._rf.valid_duplexes = ["", "-", "+"] self._rf.valid_bands = [(30000, 199999999), (400000000, 470000000)] self._rf.valid_tuning_steps = [] self._rf.valid_skips = [] self._rf.valid_name_length = 16 self._rf.valid_characters = chirp_common.CHARSET_ASCII self._rf.memory_bounds = (0, 99 * self._num_banks - 1) @directory.register class Icom746Radio(IcomCIVRadio): """Icom IC-746""" MODEL = "IC-746" BAUD_RATE = 9600 _model = "\x56" _template = 102 _num_banks = 1 # Banks not supported def _initialize(self): self._classes["mem"] = DupToneMemFrame self._rf.has_bank = False self._rf.has_dtcs_polarity = False self._rf.has_dtcs = False self._rf.has_ctone = True self._rf.has_offset = False self._rf.has_name = True self._rf.has_tuning_step = False self._rf.valid_modes = ["LSB", "USB", "AM", "CW", "RTTY", "FM"] self._rf.valid_tmodes = ["", "Tone", "TSQL"] self._rf.valid_duplexes = ["", "-", "+"] self._rf.valid_bands = [(30000, 199999999)] self._rf.valid_tuning_steps = [] self._rf.valid_skips = [] self._rf.valid_name_length = 9 self._rf.valid_characters = chirp_common.CHARSET_ASCII self._rf.memory_bounds = (1, 99) @directory.register class Icom910Radio(IcomCIVRadio): """Icom IC-910""" MODEL = "IC-910" BAUD_RATE = 19200 _model = "\x60" _template = 100 _num_banks = 3 # Banks for 2m, 70cm, 23cm _bank_index_bounds = (1, 99) _bank_class = icf.IcomBank _SPECIAL_CHANNELS = { "1A": 100, "1b": 101, "2A": 102, "2b": 103, "3A": 104, "3b": 105, "C": 106, } _SPECIAL_CHANNELS_REV = {v: k for k, v in _SPECIAL_CHANNELS.items()} _SPECIAL_BANKS = { "2m": 1, "70cm": 2, "23cm": 3, } _SPECIAL_BANKS_REV = {v: k for k, v in _SPECIAL_BANKS.items()} def _get_special_names(self, band): return sorted([band + "-" + key for key in self._SPECIAL_CHANNELS.keys()]) def _is_special(self, number): return isinstance(number, str) or number >= 1000 def _get_special_info(self, number): info = BankSpecialChannel() if isinstance(number, str): info.name = number (band_name, chan_name) = number.split("-") info.bank = self._SPECIAL_BANKS[band_name] info.channel = self._SPECIAL_CHANNELS[chan_name] info.location = info.bank * 1000 + info.channel else: info.location = number (info.bank, info.channel) = divmod(number, 1000) band_name = self._SPECIAL_BANKS_REV[info.bank] chan_name = self._SPECIAL_CHANNELS_REV[info.channel] info.name = band_name + "-" + chan_name return info # The IC-910 has a bank of memories for each band. The 23cm band is only # available when the optional UX-910 unit is installed, but there is no # direct means of detecting its presence. Instead, attempt to access the # first memory in the 23cm bank. If that's successful, the unit is there, # and we can present all 3 banks to the user. Otherwise, the unit is not # installed, so we present 2 banks to the user, for 2m and 70cm. def _detect_23cm_unit(self): if not self.pipe: return True self._detect_baudrate() f = IC910MemFrame() f.set_location(1, 3) # First memory in 23cm bank self._send_frame(f) f.read(self.pipe) if f._cmd == 0xFA: # Error code lands in command field self._num_banks = 2 LOG.debug("UX-910 unit is %sinstalled" % ("not " if self._num_banks == 2 else "")) return self._num_banks == 3 def _initialize(self): self._classes["mem"] = IC910MemFrame self._has_23cm_unit = self._detect_23cm_unit() self._rf.has_bank = True self._rf.has_dtcs_polarity = False self._rf.has_dtcs = False self._rf.has_ctone = True self._rf.has_offset = True self._rf.has_name = False self._rf.has_tuning_step = False self._rf.valid_modes = ["LSB", "USB", "CW", "NCW", "FM", "NFM"] self._rf.valid_tmodes = ["", "Tone", "TSQL"] self._rf.valid_duplexes = ["", "-", "+"] self._rf.valid_bands = [(136000000, 174000000), (420000000, 480000000)] self._rf.valid_tuning_steps = [] self._rf.valid_skips = [] self._rf.valid_special_chans = (self._get_special_names("2m") + self._get_special_names("70cm")) self._rf.memory_bounds = (1, 99 * self._num_banks) if self._has_23cm_unit: self._rf.valid_bands.append((1240000000, 1320000000)) self._rf.valid_special_chans += self._get_special_names("23cm") # Combine mode and filter into unified mode self._unified_modes = True # Use Chirp locations starting with 1 self._adjust_bank_loc_start = True @directory.register class Icom7300Radio(IcomCIVRadio): # Added March, 2021 by Rick DeWitt """Icom IC-7300""" MODEL = "IC-7300" BAUD_RATE = 115200 _model = "\x94" _template = 100 # Use P1 as blank template _SPECIAL_CHANNELS = { "P1": 100, "P2": 101, } _SPECIAL_CHANNELS_REV = dict(zip(_SPECIAL_CHANNELS.values(), _SPECIAL_CHANNELS.keys())) def _is_special(self, number): return isinstance(number, str) or number > 99 def _get_special_info(self, number): info = SpecialChannel() if isinstance(number, str): info.name = number info.channel = self._SPECIAL_CHANNELS[number] info.location = info.channel else: info.location = number info.name = self._SPECIAL_CHANNELS_REV[number] info.channel = info.location return info def _initialize(self): self._classes["mem"] = IC7300MemFrame self._rf.has_name = True self._rf.has_dtcs = False self._rf.has_dtcs_polarity = False self._rf.has_bank = False self._rf.has_tuning_step = False self._rf.has_nostep_tuning = True self._rf.can_odd_split = True self._rf.memory_bounds = (1, 99) self._rf.valid_modes = [ "LSB", "USB", "AM", "CW", "RTTY", "FM", "CWR", "RTTYR", "Data+LSB", "Data+USB", "Data+AM", "N/A", "N/A", "Data+FM" ] self._rf.valid_tmodes = ["", "Tone", "TSQL"] # self._rf.valid_duplexes = ["", "-", "+", "split"] self._rf.valid_duplexes = [] # To prevent using memobj.duplex self._rf.valid_bands = [(30000, 74800000)] self._rf.valid_skips = [] self._rf.valid_name_length = 10 self._rf.valid_characters = chirp_common.CHARSET_ASCII self._rf.valid_special_chans = sorted(self._SPECIAL_CHANNELS.keys()) @directory.register class Icom7610Radio(Icom7300Radio): MODEL = "IC-7610" _model = '\x98' def _initialize(self): super()._initialize() self._classes['mem'] = IC7610MemFrame def probe_model(ser): """Probe the radio attached to @ser for its model""" f = Frame() f.set_command(0x19, 0x00) models = {} for rclass in directory.DRV_TO_RADIO.values(): if issubclass(rclass, IcomCIVRadio): models[rclass.MODEL] = rclass for rclass in models.values(): model = ord(rclass._model) f.send(model, 0xE0, ser) try: f.read(ser) except errors.RadioError: continue if len(f.get_data()) == 1: md = f.get_data()[0] if (md == model): return rclass if f.get_data(): LOG.debug("Got data, but not 1 byte:") LOG.debug(util.hexprint(bytes(f.get_data()))) raise errors.RadioError("Unknown response") raise errors.RadioError("Unsupported model") chirp-20240224/chirp/drivers/wouxun.py0000644000175000017500000017002014566340166016551 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun radios management module""" import time import logging from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettingValueFloat, RadioSettings from chirp.drivers.wouxun_common import wipe_memory, do_download, do_upload LOG = logging.getLogger(__name__) FREQ_ENCODE_TABLE = [0x7, 0xa, 0x0, 0x9, 0xb, 0x2, 0xe, 0x1, 0x3, 0xf] def encode_freq(freq): """Convert frequency (4 decimal digits) to Wouxun format (2 bytes)""" enc = 0 div = 1000 for i in range(0, 4): enc <<= 4 enc |= FREQ_ENCODE_TABLE[int((freq/div) % 10)] div /= 10 return enc def decode_freq(data): """Convert from Wouxun format (2 bytes) to frequency (4 decimal digits)""" freq = 0 shift = 12 for i in range(0, 4): freq *= 10 freq += FREQ_ENCODE_TABLE.index((data >> shift) & 0xf) shift -= 4 # LOG.debug("data %04x freq %d shift %d" % (data, freq, shift)) return freq @directory.register class KGUVD1PRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-UVD1P,UV2,UV3""" VENDOR = "Wouxun" MODEL = "KG-UVD1P" _model = b"KG669V" NEEDS_COMPAT_SERIAL = False _querymodel = (b"HiWOUXUN\x02", b"PROGUV6X\x02") CHARSET = list("0123456789") + \ [chr(x + ord("A")) for x in range(0, 26)] + list("?+-") POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] valid_freq = [(136000000, 175000000), (216000000, 520000000)] _MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; ul16 rx_tone; ul16 tx_tone; u8 _3_unknown_1:4, bcl:1, _3_unknown_2:3; u8 splitdup:1, skip:1, power_high:1, iswide:1, _2_unknown_2:4; u8 unknown; u8 _0_unknown_1:3, iswidex:1, _0_unknown_2:4; } memory[199]; #seekto 0x0842; u16 fm_presets_0[9]; #seekto 0x0882; u16 fm_presets_1[9]; #seekto 0x0970; struct { u16 vhf_rx_start; u16 vhf_rx_stop; u16 uhf_rx_start; u16 uhf_rx_stop; u16 vhf_tx_start; u16 vhf_tx_stop; u16 uhf_tx_start; u16 uhf_tx_stop; } freq_ranges; #seekto 0x0E00; struct { char welcome1[6]; char welcome2[6]; char single_band[6]; } strings; #seekto 0x0E20; struct { u8 unknown_flag_01:6, vfo_b_ch_disp:2; u8 unknown_flag_02:5, vfo_a_fr_step:3; u8 unknown_flag_03:4, vfo_a_squelch:4; u8 unknown_flag_04:7, power_save:1; u8 unknown_flag_05:8; u8 unknown_flag_06:6, roger_beep:2; u8 unknown_flag_07:2, transmit_time_out:6; u8 unknown_flag_08:4, vox:4; u8 unknown_1[4]; u8 unknown_flag_09:6, voice:2; u8 unknown_flag_10:7, beep:1; u8 unknown_flag_11:7, ani_id_enable:1; u8 unknown_2[2]; u8 unknown_flag_12:5, vfo_b_fr_step:3; u8 unknown_3[1]; u8 unknown_flag_13:3, ani_id_tx_delay:5; u8 unknown_4[1]; u8 unknown_flag_14:6, ani_id_sidetone:2; u8 unknown_flag_15:4, tx_time_out_alert:4; u8 unknown_flag_16:6, vfo_a_ch_disp:2; u8 unknown_flag_15:6, scan_mode:2; u8 unknown_flag_16:7, kbd_lock:1; u8 unknown_flag_17:6, ponmsg:2; u8 unknown_flag_18:5, pf1_function:3; u8 unknown_5[1]; u8 unknown_flag_19:7, auto_backlight:1; u8 unknown_flag_20:7, sos_ch:1; u8 unknown_6; u8 sd_available; u8 unknown_flag_21:7, auto_lock_kbd:1; u8 unknown_flag_22:4, vfo_b_squelch:4; u8 unknown_7[1]; u8 unknown_flag_23:7, stopwatch:1; u8 vfo_a_cur_chan; u8 unknown_flag_24:7, dual_band_receive:1; u8 current_vfo:1, unknown_flag_26:7; u8 unknown_8[2]; u8 mode_password[6]; u8 reset_password[6]; u8 ani_id_content[6]; u8 unknown_flag_25:7, menu_available:1; u8 unknown_9[1]; u8 priority_chan; u8 vfo_b_cur_chan; } settings; #seekto 0x1008; struct { u8 unknown[8]; u8 name[6]; u8 pad[2]; } names[199]; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This version of the Wouxun driver allows you to modify the ' 'frequency range settings of your radio. This has been tested ' 'and reports from other users indicate that it is a safe ' 'thing to do. However, modifications to this value may have ' 'unintended consequences, including damage to your device. ' 'You have been warned. Proceed at your own risk!') rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on.\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to download image from device.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on.\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to upload image to device.\n") return rp @classmethod def _get_querymodel(cls): if isinstance(cls._querymodel, str): while True: yield cls._querymodel else: i = 0 while True: yield cls._querymodel[i % len(cls._querymodel)] i += 1 def _identify(self): """Do the original Wouxun identification dance""" query = self._get_querymodel() for _i in range(0, 10): self.pipe.write(next(query)) resp = self.pipe.read(9) if len(resp) != 9: LOG.debug("Got:\n%s" % util.hexprint(resp)) LOG.info("Retrying identification...") time.sleep(1) continue if resp[2:8] != self._model: raise Exception("I can't talk to this model (%s)" % util.hexprint(resp)) return if len(resp) == 0: raise Exception("Radio not responding") else: raise Exception("Unable to identify radio") def _start_transfer(self): """Tell the radio to go into transfer mode""" self.pipe.write(b"\x02\x06") time.sleep(0.05) ack = self.pipe.read(1) if ack != b"\x06": raise Exception("Radio refused transfer mode") def _download(self): """Talk to an original Wouxun and do a download""" try: self._identify() self._start_transfer() return do_download(self, 0x0000, 0x2000, 0x0040) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def _upload(self): """Talk to an original Wouxun and do an upload""" try: self._identify() self._start_transfer() return do_upload(self, 0x0000, 0x2000, 0x0010) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def sync_in(self): self._mmap = self._download() self.process_mmap() def sync_out(self): self._upload() def process_mmap(self): if len(self._mmap.get_packed()) != 8192: LOG.info("Fixing old-style Wouxun image") # Originally, CHIRP's Wouxun image had eight bytes of # static data, followed by the first memory at offset # 0x0008. Between 0.1.11 and 0.1.12, this was fixed to 16 # bytes of (whatever) followed by the first memory at # offset 0x0010, like the radio actually stores it. So, # if we find one of those old ones, convert it to the new # format, padding 16 bytes of 0xFF in front. self._mmap = memmap.MemoryMap( ("\xFF" * 16) + self._mmap.get_packed()[8:8184]) self._memobj = bitwise.parse(self._MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_bands = self.valid_freq rf.valid_characters = "".join(self.CHARSET) rf.valid_name_length = 6 rf.valid_duplexes = ["", "+", "-", "split", "off"] rf.valid_tuning_steps = [5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.has_settings = True rf.memory_bounds = (1, 128) rf.can_odd_split = True return rf def get_settings(self): freq_ranges = RadioSettingGroup("freq_ranges", "Freq Ranges") fm_preset = RadioSettingGroup("fm_preset", "FM Presets") cfg_s = RadioSettingGroup("cfg_settings", "Configuration Settings") group = RadioSettings(cfg_s, freq_ranges, fm_preset) rs = RadioSetting("menu_available", "Menu Available", RadioSettingValueBoolean( self._memobj.settings.menu_available)) cfg_s.append(rs) rs = RadioSetting("vhf_rx_start", "1st band RX Lower Limit (MHz)", RadioSettingValueInteger( 50, 174, decode_freq( self._memobj.freq_ranges.vhf_rx_start))) freq_ranges.append(rs) rs = RadioSetting("vhf_rx_stop", "1st band RX Upper Limit (MHz)", RadioSettingValueInteger( 50, 174, decode_freq( self._memobj.freq_ranges.vhf_rx_stop))) freq_ranges.append(rs) rs = RadioSetting("uhf_rx_start", "2nd band RX Lower Limit (MHz)", RadioSettingValueInteger( 136, 520, decode_freq( self._memobj.freq_ranges.uhf_rx_start))) freq_ranges.append(rs) rs = RadioSetting("uhf_rx_stop", "2nd band RX Upper Limit (MHz)", RadioSettingValueInteger( 136, 520, decode_freq( self._memobj.freq_ranges.uhf_rx_stop))) freq_ranges.append(rs) rs = RadioSetting("vhf_tx_start", "1st band TX Lower Limit (MHz)", RadioSettingValueInteger( 50, 174, decode_freq( self._memobj.freq_ranges.vhf_tx_start))) freq_ranges.append(rs) rs = RadioSetting("vhf_tx_stop", "1st TX Upper Limit (MHz)", RadioSettingValueInteger( 50, 174, decode_freq( self._memobj.freq_ranges.vhf_tx_stop))) freq_ranges.append(rs) rs = RadioSetting("uhf_tx_start", "2nd band TX Lower Limit (MHz)", RadioSettingValueInteger( 136, 520, decode_freq( self._memobj.freq_ranges.uhf_tx_start))) freq_ranges.append(rs) rs = RadioSetting("uhf_tx_stop", "2nd band TX Upper Limit (MHz)", RadioSettingValueInteger( 136, 520, decode_freq( self._memobj.freq_ranges.uhf_tx_stop))) freq_ranges.append(rs) # tell the decoded ranges to UI freq_ranges = self._memobj.freq_ranges self.valid_freq = \ [(decode_freq(freq_ranges.vhf_rx_start) * 1000000, (decode_freq(freq_ranges.vhf_rx_stop) + 1) * 1000000), (decode_freq(freq_ranges.uhf_rx_start) * 1000000, (decode_freq(freq_ranges.uhf_rx_stop) + 1) * 1000000)] def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered # add some radio specific settings options = ["Off", "Welcome", "V bat"] rs = RadioSetting("ponmsg", "Poweron message", RadioSettingValueList( options, options[self._memobj.settings.ponmsg])) cfg_s.append(rs) rs = RadioSetting("strings.welcome1", "Power-On Message 1", RadioSettingValueString( 0, 6, _filter(self._memobj.strings.welcome1))) cfg_s.append(rs) rs = RadioSetting("strings.welcome2", "Power-On Message 2", RadioSettingValueString( 0, 6, _filter(self._memobj.strings.welcome2))) cfg_s.append(rs) rs = RadioSetting("strings.single_band", "Single Band Message", RadioSettingValueString( 0, 6, _filter(self._memobj.strings.single_band))) cfg_s.append(rs) options = ["Channel", "ch/freq", "Name", "VFO"] rs = RadioSetting("vfo_a_ch_disp", "VFO A Channel disp mode", RadioSettingValueList( options, options[self._memobj.settings.vfo_a_ch_disp])) cfg_s.append(rs) rs = RadioSetting("vfo_b_ch_disp", "VFO B Channel disp mode", RadioSettingValueList( options, options[self._memobj.settings.vfo_b_ch_disp])) cfg_s.append(rs) options = ["5.0", "6.25", "10.0", "12.5", "25.0", "50.0", "100.0"] rs = RadioSetting("vfo_a_fr_step", "VFO A Frequency Step", RadioSettingValueList( options, options[self._memobj.settings.vfo_a_fr_step])) cfg_s.append(rs) rs = RadioSetting("vfo_b_fr_step", "VFO B Frequency Step", RadioSettingValueList( options, options[self._memobj.settings.vfo_b_fr_step])) cfg_s.append(rs) rs = RadioSetting("vfo_a_squelch", "VFO A Squelch", RadioSettingValueInteger( 0, 9, self._memobj.settings.vfo_a_squelch)) cfg_s.append(rs) rs = RadioSetting("vfo_b_squelch", "VFO B Squelch", RadioSettingValueInteger( 0, 9, self._memobj.settings.vfo_b_squelch)) cfg_s.append(rs) rs = RadioSetting("vfo_a_cur_chan", "VFO A current channel", RadioSettingValueInteger( 1, 128, self._memobj.settings.vfo_a_cur_chan)) cfg_s.append(rs) rs = RadioSetting("vfo_b_cur_chan", "VFO B current channel", RadioSettingValueInteger( 1, 128, self._memobj.settings.vfo_b_cur_chan)) cfg_s.append(rs) rs = RadioSetting("priority_chan", "Priority channel", RadioSettingValueInteger( 0, 199, self._memobj.settings.priority_chan)) cfg_s.append(rs) rs = RadioSetting("power_save", "Power save", RadioSettingValueBoolean( self._memobj.settings.power_save)) cfg_s.append(rs) options = ["Off", "Scan", "Lamp", "SOS", "Radio"] rs = RadioSetting("pf1_function", "PF1 Function select", RadioSettingValueList( options, options[self._memobj.settings.pf1_function])) cfg_s.append(rs) options = ["Off", "Begin", "End", "Both"] rs = RadioSetting("roger_beep", "Roger beep select", RadioSettingValueList( options, options[self._memobj.settings.roger_beep])) cfg_s.append(rs) options = ["%s" % x for x in range(15, 615, 15)] transmit_time_out = options[self._memobj.settings.transmit_time_out] rs = RadioSetting("transmit_time_out", "TX Time-out Timer", RadioSettingValueList( options, transmit_time_out)) cfg_s.append(rs) rs = RadioSetting("tx_time_out_alert", "TX Time-out Alert", RadioSettingValueInteger( 0, 10, self._memobj.settings.tx_time_out_alert)) cfg_s.append(rs) rs = RadioSetting("vox", "Vox", RadioSettingValueInteger( 0, 10, self._memobj.settings.vox)) cfg_s.append(rs) options = ["Off", "Chinese", "English"] rs = RadioSetting("voice", "Voice", RadioSettingValueList( options, options[self._memobj.settings.voice])) cfg_s.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean( self._memobj.settings.beep)) cfg_s.append(rs) rs = RadioSetting("ani_id_enable", "ANI id enable", RadioSettingValueBoolean( self._memobj.settings.ani_id_enable)) cfg_s.append(rs) rs = RadioSetting("ani_id_tx_delay", "ANI id tx delay", RadioSettingValueInteger( 0, 30, self._memobj.settings.ani_id_tx_delay)) cfg_s.append(rs) options = ["Off", "Key", "ANI", "Key+ANI"] rs = RadioSetting("ani_id_sidetone", "ANI id sidetone", RadioSettingValueList( options, options[self._memobj.settings.ani_id_sidetone])) cfg_s.append(rs) options = ["Time", "Carrier", "Search"] rs = RadioSetting("scan_mode", "Scan mode", RadioSettingValueList( options, options[self._memobj.settings.scan_mode])) cfg_s.append(rs) rs = RadioSetting("kbd_lock", "Keyboard lock", RadioSettingValueBoolean( self._memobj.settings.kbd_lock)) cfg_s.append(rs) rs = RadioSetting("auto_lock_kbd", "Auto lock keyboard", RadioSettingValueBoolean( self._memobj.settings.auto_lock_kbd)) cfg_s.append(rs) rs = RadioSetting("auto_backlight", "Auto backlight", RadioSettingValueBoolean( self._memobj.settings.auto_backlight)) cfg_s.append(rs) options = ["CH A", "CH B"] rs = RadioSetting("sos_ch", "SOS CH", RadioSettingValueList( options, options[self._memobj.settings.sos_ch])) cfg_s.append(rs) rs = RadioSetting("stopwatch", "Stopwatch", RadioSettingValueBoolean( self._memobj.settings.stopwatch)) cfg_s.append(rs) rs = RadioSetting("dual_band_receive", "Dual band receive", RadioSettingValueBoolean( self._memobj.settings.dual_band_receive)) cfg_s.append(rs) options = ["VFO A", "VFO B"] rs = RadioSetting("current_vfo", "Current VFO", RadioSettingValueList( options, options[self._memobj.settings.current_vfo])) cfg_s.append(rs) options = ["Dual", "Single"] rs = RadioSetting("sd_available", "Single/Dual Band", RadioSettingValueList( options, options[self._memobj.settings.sd_available])) cfg_s.append(rs) _pwd = self._memobj.settings.mode_password rs = RadioSetting("mode_password", "Mode password (000000 disabled)", RadioSettingValueInteger(0, 9, _pwd[0]), RadioSettingValueInteger(0, 9, _pwd[1]), RadioSettingValueInteger(0, 9, _pwd[2]), RadioSettingValueInteger(0, 9, _pwd[3]), RadioSettingValueInteger(0, 9, _pwd[4]), RadioSettingValueInteger(0, 9, _pwd[5])) cfg_s.append(rs) _pwd = self._memobj.settings.reset_password rs = RadioSetting("reset_password", "Reset password (000000 disabled)", RadioSettingValueInteger(0, 9, _pwd[0]), RadioSettingValueInteger(0, 9, _pwd[1]), RadioSettingValueInteger(0, 9, _pwd[2]), RadioSettingValueInteger(0, 9, _pwd[3]), RadioSettingValueInteger(0, 9, _pwd[4]), RadioSettingValueInteger(0, 9, _pwd[5])) cfg_s.append(rs) dtmfchars = "0123456789 *#ABCD" _codeobj = self._memobj.settings.ani_id_content _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("settings.ani_id_content", "PTT-ID Code", val) def apply_ani_id(setting, obj): value = [] for j in range(0, 6): try: value.append(dtmfchars.index(str(setting.value)[j])) except IndexError: value.append(0xFF) obj.ani_id_content = value rs.set_apply_callback(apply_ani_id, self._memobj.settings) cfg_s.append(rs) for i in range(0, 9): if self._memobj.fm_presets_0[i] != 0xFFFF: used = True preset = self._memobj.fm_presets_0[i] / 10.0 + 76 else: used = False preset = 76 rs = RadioSetting("fm_presets_0_%1i" % i, "Team 1 Location %i" % (i + 1), RadioSettingValueBoolean(used), RadioSettingValueFloat(76, 108, preset, 0.1, 1)) fm_preset.append(rs) for i in range(0, 9): if self._memobj.fm_presets_1[i] != 0xFFFF: used = True preset = self._memobj.fm_presets_1[i] / 10.0 + 76 else: used = False preset = 76 rs = RadioSetting("fm_presets_1_%1i" % i, "Team 2 Location %i" % (i + 1), RadioSettingValueBoolean(used), RadioSettingValueFloat(76, 108, preset, 0.1, 1)) fm_preset.append(rs) return group def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "freq_ranges": self._set_freq_settings(element) elif element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _set_fm_preset(self, settings): obj = self._memobj for element in settings: try: (bank, index) = \ (int(a) for a in element.get_name().split("_")[-2:]) val = element.value if val[0].get_value(): value = int(val[1].get_value()*10-760) else: value = 0xffff LOG.debug("Setting fm_presets_%1i[%1i] = %s" % (bank, index, value)) if bank == 0: setting = self._memobj.fm_presets_0 else: setting = self._memobj.fm_presets_1 setting[index] = value except Exception: LOG.debug(element.get_name()) raise def _set_freq_settings(self, settings): for element in settings: try: setattr(self._memobj.freq_ranges, element.get_name(), encode_freq(int(element.value))) except Exception: LOG.debug(element.get_name()) raise def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol tpol = False if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2800: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" elif _mem.tx_tone != 0xFFFF: mem.rtone = _mem.tx_tone / 10.0 txmode = "Tone" else: txmode = "" rpol = False if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2800: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rx_tone != 0xFFFF: mem.ctone = _mem.rx_tone / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.tx_tone, rxmode, _mem.rx_tone)) def _is_txinh(self, _mem): return _mem.tx_freq.get_raw() == b"\xFF\xFF\xFF\xFF" def get_memory(self, number): _mem = self._memobj.memory[number - 1] _nam = self._memobj.names[number - 1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw() == (b"\xff" * 16): mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 if _mem.splitdup: mem.duplex = "split" elif self._is_txinh(_mem): mem.duplex = "off" elif int(_mem.rx_freq) < int(_mem.tx_freq): mem.duplex = "+" elif int(_mem.rx_freq) > int(_mem.tx_freq): mem.duplex = "-" if mem.duplex == "" or mem.duplex == "off": mem.offset = 0 elif mem.duplex == "split": mem.offset = int(_mem.tx_freq) * 10 else: mem.offset = abs(int(_mem.tx_freq) - int(_mem.rx_freq)) * 10 if not _mem.skip: mem.skip = "S" if not _mem.iswide: mem.mode = "NFM" self._get_tone(_mem, mem) mem.power = self.POWER_LEVELS[not _mem.power_high] for i in _nam.name: if i == 0xFF: break mem.name += self.CHARSET[i] mem.extra = RadioSettingGroup("extra", "Extra") bcl = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(bool(_mem.bcl))) bcl.set_doc("Busy Channel Lockout") mem.extra.append(bcl) options = ["NFM", "FM"] iswidex = RadioSetting("iswidex", "Mode TX(KG-UV6X)", RadioSettingValueList( options, options[_mem.iswidex])) iswidex.set_doc("Mode TX") mem.extra.append(iswidex) return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0x8000 return val rx_mode = tx_mode = None rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None tx_tone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = int(mem.rtone * 10) if rx_mode == "DTCS": rx_tone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = int(mem.ctone * 10) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.tx_tone, rx_mode, _mem.rx_tone)) def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _nam = self._memobj.names[mem.number - 1] if mem.empty: wipe_memory(_mem, "\xFF") return if _mem.get_raw() == (b"\xFF" * 16): wipe_memory(_mem, "\x00") _mem.rx_freq = int(mem.freq / 10) if mem.duplex == "split": _mem.tx_freq = int(mem.offset / 10) elif mem.duplex == "off": _mem.tx_freq.fill_raw(b"\xFF") elif mem.duplex == "+": _mem.tx_freq = int(mem.freq / 10) + int(mem.offset / 10) elif mem.duplex == "-": _mem.tx_freq = int(mem.freq / 10) - int(mem.offset / 10) else: _mem.tx_freq = int(mem.freq / 10) _mem.splitdup = mem.duplex == "split" _mem.skip = mem.skip != "S" _mem.iswide = mem.mode != "NFM" self._set_tone(mem, _mem) if mem.power: _mem.power_high = not self.POWER_LEVELS.index(mem.power) else: _mem.power_high = True _nam.name = [0xFF] * 6 for i in range(0, len(mem.name)): try: _nam.name[i] = self.CHARSET.index(mem.name[i]) except IndexError: raise Exception("Character `%s' not supported") for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) @classmethod def match_model(cls, filedata, filename): # New-style image (CHIRP 0.1.12) if len(filedata) == 8192 and \ filedata[0x60:0x64] != b"2009" and \ filedata[0x170:0x173] != b"LX-" and \ filedata[0x1f77:0x1f7d] == b"\xff\xff\xff\xff\xff\xff" and \ filedata[0x0d70:0x0d80] == \ b"\xff\xff\xff\xff\xff\xff\xff\xff" \ b"\xff\xff\xff\xff\xff\xff\xff\xff": # those areas are (seems to be) unused return True # Old-style image (CHIRP 0.1.11) if len(filedata) == 8200 and \ filedata[0:4] == b"\x01\x00\x00\x00": return True return False @directory.register class KGUV6DRadio(KGUVD1PRadio): """Wouxun KG-UV6 (D and X variants)""" MODEL = "KG-UV6" _querymodel = (b"HiWXUVD1\x02", b"HiKGUVD1\x02") _MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; ul16 rx_tone; ul16 tx_tone; u8 _3_unknown_1:4, bcl:1, _3_unknown_2:3; u8 splitdup:1, skip:1, power_high:1, iswide:1, _2_unknown_2:4; u8 pad; u8 _0_unknown_1:3, iswidex:1, _0_unknown_2:4; } memory[199]; #seekto 0x0F00; struct { char welcome1[6]; char welcome2[6]; char single_band[6]; } strings; #seekto 0x0F20; struct { u8 unknown_flag_01:6, vfo_b_ch_disp:2; u8 unknown_flag_02:5, vfo_a_fr_step:3; u8 unknown_flag_03:4, vfo_a_squelch:4; u8 unknown_flag_04:7, power_save:1; u8 unknown_flag_05:5, pf2_function:3; u8 unknown_flag_06:6, roger_beep:2; u8 unknown_flag_07:2, transmit_time_out:6; u8 unknown_flag_08:4, vox:4; u8 unknown_1[4]; u8 unknown_flag_09:6, voice:2; u8 unknown_flag_10:7, beep:1; u8 unknown_flag_11:7, ani_id_enable:1; u8 unknown_2[2]; u8 unknown_flag_12:5, vfo_b_fr_step:3; u8 unknown_3[1]; u8 unknown_flag_13:3, ani_id_tx_delay:5; u8 unknown_4[1]; u8 unknown_flag_14:6, ani_id_sidetone:2; u8 unknown_flag_15:4, tx_time_out_alert:4; u8 unknown_flag_16:6, vfo_a_ch_disp:2; u8 unknown_flag_20:6, scan_mode:2; u8 unknown_flag_31:7, kbd_lock:1; u8 unknown_flag_17:6, ponmsg:2; u8 unknown_flag_18:5, pf1_function:3; u8 unknown_5[1]; u8 unknown_flag_19:7, auto_backlight:1; u8 unknown_flag_26:7, sos_ch:1; u8 unknown_6; u8 sd_available; u8 unknown_flag_32:7, auto_lock_kbd:1; u8 unknown_flag_22:4, vfo_b_squelch:4; u8 unknown_7[1]; u8 unknown_flag_23:7, stopwatch:1; u8 vfo_a_cur_chan; u8 unknown_flag_24:7, dual_band_receive:1; u8 current_vfo:1, unknown_flag_33:7; u8 unknown_8[2]; u8 mode_password[6]; u8 reset_password[6]; u8 ani_id_content[6]; u8 unknown_flag_25:7, menu_available:1; u8 unknown_9[1]; u8 priority_chan; u8 vfo_b_cur_chan; } settings; //#seekto 0x0f60; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; ul16 rx_tone; ul16 tx_tone; u8 _3_unknown_3:4, bcl:1, _3_unknown_4:3; u8 splitdup:1, _2_unknown_3:1, power_high:1, iswide:1, _2_unknown_4:4; u8 pad[2]; } vfo_settings[2]; #seekto 0x0f82; u16 fm_presets_0[9]; #seekto 0x0ff0; struct { u16 vhf_rx_start; u16 vhf_rx_stop; u16 uhf_rx_start; u16 uhf_rx_stop; u16 vhf_tx_start; u16 vhf_tx_stop; u16 uhf_tx_start; u16 uhf_tx_stop; } freq_ranges; #seekto 0x1010; struct { u8 name[6]; u8 pad[10]; } names[199]; #seekto 0x1f60; struct { u8 unknown_flag_26:6, tx_offset_dir:2; u8 tx_offset[6]; u8 pad[9]; } vfo_offset[2]; #seekto 0x1f82; u16 fm_presets_1[9]; """ def get_features(self): rf = KGUVD1PRadio.get_features(self) rf.memory_bounds = (1, 199) rf.valid_tuning_steps = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] return rf def get_settings(self): freq_ranges = RadioSettingGroup("freq_ranges", "Freq Ranges") fm_preset = RadioSettingGroup("fm_preset", "FM Presets") cfg_s = RadioSettingGroup("cfg_settings", "Configuration Settings") group = RadioSettings(cfg_s, freq_ranges, fm_preset) rs = RadioSetting("menu_available", "Menu Available", RadioSettingValueBoolean( self._memobj.settings.menu_available)) cfg_s.append(rs) rs = RadioSetting("vhf_rx_start", "VHF RX Lower Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.vhf_rx_start))) freq_ranges.append(rs) rs = RadioSetting("vhf_rx_stop", "VHF RX Upper Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.vhf_rx_stop))) freq_ranges.append(rs) rs = RadioSetting("uhf_rx_start", "UHF RX Lower Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.uhf_rx_start))) freq_ranges.append(rs) rs = RadioSetting("uhf_rx_stop", "UHF RX Upper Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.uhf_rx_stop))) freq_ranges.append(rs) rs = RadioSetting("vhf_tx_start", "VHF TX Lower Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.vhf_tx_start))) freq_ranges.append(rs) rs = RadioSetting("vhf_tx_stop", "VHF TX Upper Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.vhf_tx_stop))) freq_ranges.append(rs) rs = RadioSetting("uhf_tx_start", "UHF TX Lower Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.uhf_tx_start))) freq_ranges.append(rs) rs = RadioSetting("uhf_tx_stop", "UHF TX Upper Limit (MHz)", RadioSettingValueInteger( 1, 1000, decode_freq( self._memobj.freq_ranges.uhf_tx_stop))) freq_ranges.append(rs) # tell the decoded ranges to UI freq_ranges = self._memobj.freq_ranges self.valid_freq = \ [(decode_freq(freq_ranges.vhf_rx_start) * 1000000, (decode_freq(freq_ranges.vhf_rx_stop) + 1) * 1000000), (decode_freq(freq_ranges.uhf_rx_start) * 1000000, (decode_freq(freq_ranges.uhf_rx_stop) + 1) * 1000000)] def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered # add some radio specific settings options = ["Off", "Welcome", "V bat", "N/A(KG-UV6X)"] rs = RadioSetting("ponmsg", "Poweron message", RadioSettingValueList( options, options[self._memobj.settings.ponmsg])) cfg_s.append(rs) rs = RadioSetting("strings.welcome1", "Power-On Message 1", RadioSettingValueString( 0, 6, _filter(self._memobj.strings.welcome1))) cfg_s.append(rs) rs = RadioSetting("strings.welcome2", "Power-On Message 2", RadioSettingValueString( 0, 6, _filter(self._memobj.strings.welcome2))) cfg_s.append(rs) rs = RadioSetting("strings.single_band", "Single Band Message", RadioSettingValueString( 0, 6, _filter(self._memobj.strings.single_band))) cfg_s.append(rs) options = ["Channel", "ch/freq", "Name", "VFO"] rs = RadioSetting("vfo_a_ch_disp", "VFO A Channel disp mode", RadioSettingValueList( options, options[self._memobj.settings.vfo_a_ch_disp])) cfg_s.append(rs) rs = RadioSetting("vfo_b_ch_disp", "VFO B Channel disp mode", RadioSettingValueList( options, options[self._memobj.settings.vfo_b_ch_disp])) cfg_s.append(rs) options = \ ["2.5", "5.0", "6.25", "10.0", "12.5", "25.0", "50.0", "100.0"] rs = RadioSetting("vfo_a_fr_step", "VFO A Frequency Step", RadioSettingValueList( options, options[self._memobj.settings.vfo_a_fr_step])) cfg_s.append(rs) rs = RadioSetting("vfo_b_fr_step", "VFO B Frequency Step", RadioSettingValueList( options, options[self._memobj.settings.vfo_b_fr_step])) cfg_s.append(rs) rs = RadioSetting("vfo_a_squelch", "VFO A Squelch", RadioSettingValueInteger( 0, 9, self._memobj.settings.vfo_a_squelch)) cfg_s.append(rs) rs = RadioSetting("vfo_b_squelch", "VFO B Squelch", RadioSettingValueInteger( 0, 9, self._memobj.settings.vfo_b_squelch)) cfg_s.append(rs) rs = RadioSetting("vfo_a_cur_chan", "VFO A current channel", RadioSettingValueInteger( 1, 199, self._memobj.settings.vfo_a_cur_chan)) cfg_s.append(rs) rs = RadioSetting("vfo_b_cur_chan", "VFO B current channel", RadioSettingValueInteger( 1, 199, self._memobj.settings.vfo_b_cur_chan)) cfg_s.append(rs) rs = RadioSetting("priority_chan", "Priority channel", RadioSettingValueInteger( 0, 199, self._memobj.settings.priority_chan)) cfg_s.append(rs) rs = RadioSetting("power_save", "Power save", RadioSettingValueBoolean( self._memobj.settings.power_save)) cfg_s.append(rs) options = ["Off", "Scan", "Lamp", "SOS", "Radio"] rs = RadioSetting("pf1_function", "PF1 Function select", RadioSettingValueList( options, options[self._memobj.settings.pf1_function])) cfg_s.append(rs) options = ["Off", "Radio", "fr/ch", "Rpt", "Stopwatch", "Lamp", "SOS"] rs = RadioSetting("pf2_function", "PF2 Function select", RadioSettingValueList( options, options[self._memobj.settings.pf2_function])) cfg_s.append(rs) options = ["Off", "Begin", "End", "Both"] rs = RadioSetting("roger_beep", "Roger beep select", RadioSettingValueList( options, options[self._memobj.settings.roger_beep])) cfg_s.append(rs) options = ["%s" % x for x in range(15, 615, 15)] transmit_time_out = options[self._memobj.settings.transmit_time_out] rs = RadioSetting("transmit_time_out", "TX Time-out Timer", RadioSettingValueList( options, transmit_time_out)) cfg_s.append(rs) rs = RadioSetting("tx_time_out_alert", "TX Time-out Alert", RadioSettingValueInteger( 0, 10, self._memobj.settings.tx_time_out_alert)) cfg_s.append(rs) rs = RadioSetting("vox", "Vox", RadioSettingValueInteger( 0, 10, self._memobj.settings.vox)) cfg_s.append(rs) options = ["Off", "Chinese", "English"] rs = RadioSetting("voice", "Voice", RadioSettingValueList( options, options[self._memobj.settings.voice])) cfg_s.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean( self._memobj.settings.beep)) cfg_s.append(rs) rs = RadioSetting("ani_id_enable", "ANI id enable", RadioSettingValueBoolean( self._memobj.settings.ani_id_enable)) cfg_s.append(rs) rs = RadioSetting("ani_id_tx_delay", "ANI id tx delay", RadioSettingValueInteger( 0, 30, self._memobj.settings.ani_id_tx_delay)) cfg_s.append(rs) options = ["Off", "Key", "ANI", "Key+ANI"] rs = RadioSetting("ani_id_sidetone", "ANI id sidetone", RadioSettingValueList( options, options[self._memobj.settings.ani_id_sidetone])) cfg_s.append(rs) options = ["Time", "Carrier", "Search"] rs = RadioSetting("scan_mode", "Scan mode", RadioSettingValueList( options, options[self._memobj.settings.scan_mode])) cfg_s.append(rs) rs = RadioSetting("kbd_lock", "Keyboard lock", RadioSettingValueBoolean( self._memobj.settings.kbd_lock)) cfg_s.append(rs) rs = RadioSetting("auto_lock_kbd", "Auto lock keyboard", RadioSettingValueBoolean( self._memobj.settings.auto_lock_kbd)) cfg_s.append(rs) rs = RadioSetting("auto_backlight", "Auto backlight", RadioSettingValueBoolean( self._memobj.settings.auto_backlight)) cfg_s.append(rs) options = ["CH A", "CH B"] rs = RadioSetting("sos_ch", "SOS CH", RadioSettingValueList( options, options[self._memobj.settings.sos_ch])) cfg_s.append(rs) rs = RadioSetting("stopwatch", "Stopwatch", RadioSettingValueBoolean( self._memobj.settings.stopwatch)) cfg_s.append(rs) rs = RadioSetting("dual_band_receive", "Dual band receive", RadioSettingValueBoolean( self._memobj.settings.dual_band_receive)) cfg_s.append(rs) options = ["VFO A", "VFO B"] rs = RadioSetting("current_vfo", "Current VFO", RadioSettingValueList( options, options[self._memobj.settings.current_vfo])) cfg_s.append(rs) options = ["Dual", "Single"] rs = RadioSetting("sd_available", "Single/Dual Band", RadioSettingValueList( options, options[self._memobj.settings.sd_available])) cfg_s.append(rs) _pwd = self._memobj.settings.mode_password rs = RadioSetting("mode_password", "Mode password (000000 disabled)", RadioSettingValueInteger(0, 9, _pwd[0]), RadioSettingValueInteger(0, 9, _pwd[1]), RadioSettingValueInteger(0, 9, _pwd[2]), RadioSettingValueInteger(0, 9, _pwd[3]), RadioSettingValueInteger(0, 9, _pwd[4]), RadioSettingValueInteger(0, 9, _pwd[5])) cfg_s.append(rs) _pwd = self._memobj.settings.reset_password rs = RadioSetting("reset_password", "Reset password (000000 disabled)", RadioSettingValueInteger(0, 9, _pwd[0]), RadioSettingValueInteger(0, 9, _pwd[1]), RadioSettingValueInteger(0, 9, _pwd[2]), RadioSettingValueInteger(0, 9, _pwd[3]), RadioSettingValueInteger(0, 9, _pwd[4]), RadioSettingValueInteger(0, 9, _pwd[5])) cfg_s.append(rs) dtmfchars = "0123456789 *#ABCD" _codeobj = self._memobj.settings.ani_id_content _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 6, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("settings.ani_id_content", "ANI Code", val) def apply_ani_id(setting, obj): value = [] for j in range(0, 6): try: value.append(dtmfchars.index(str(setting.value)[j])) except IndexError: value.append(0xFF) obj.ani_id_content = value rs.set_apply_callback(apply_ani_id, self._memobj.settings) cfg_s.append(rs) for i in range(0, 9): if self._memobj.fm_presets_0[i] != 0xFFFF: used = True preset = self._memobj.fm_presets_0[i]/10.0+76 else: used = False preset = 76 rs = RadioSetting("fm_presets_0_%1i" % i, "Team 1 Location %i" % (i+1), RadioSettingValueBoolean(used), RadioSettingValueFloat(76, 108, preset, 0.1, 1)) fm_preset.append(rs) for i in range(0, 9): if self._memobj.fm_presets_1[i] != 0xFFFF: used = True preset = self._memobj.fm_presets_1[i]/10.0+76 else: used = False preset = 76 rs = RadioSetting("fm_presets_1_%1i" % i, "Team 2 Location %i" % (i+1), RadioSettingValueBoolean(used), RadioSettingValueFloat(76, 108, preset, 0.1, 1)) fm_preset.append(rs) return group def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "freq_ranges": self._set_freq_settings(element) elif element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _set_fm_preset(self, settings): obj = self._memobj for element in settings: try: (bank, index) = \ (int(a) for a in element.get_name().split("_")[-2:]) val = element.value if val[0].get_value(): value = int(val[1].get_value()*10-760) else: value = 0xffff LOG.debug("Setting fm_presets_%1i[%1i] = %s" % (bank, index, value)) if bank == 0: setting = self._memobj.fm_presets_0 else: setting = self._memobj.fm_presets_1 setting[index] = value except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): if len(filedata) == 8192 and \ filedata[0x1f77:0x1f7d] == b"WELCOM": return True return False @directory.register class KG816Radio(KGUVD1PRadio, chirp_common.ExperimentalRadio): """Wouxun KG-816""" MODEL = "KG-816" _querymodel = b"HiWOUXUN\x02" _MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rx_freq[4]; lbcd tx_freq[4]; ul16 rx_tone; ul16 tx_tone; u8 _3_unknown_1:4, bcl:1, _3_unknown_2:3; u8 splitdup:1, skip:1, power_high:1, iswide:1, _2_unknown_2:4; u8 unknown; u8 _0_unknown_1:3, iswidex:1, _0_unknown_2:4; } memory[199]; #seekto 0x0d70; struct { u16 vhf_rx_start; u16 vhf_rx_stop; u16 uhf_rx_start; u16 uhf_rx_stop; u16 vhf_tx_start; u16 vhf_tx_stop; u16 uhf_tx_start; u16 uhf_tx_stop; } freq_ranges; #seekto 0x1010; struct { u8 name[6]; u8 pad[10]; } names[199]; """ @classmethod def get_experimental_warning(cls): return ('We have not that much information on this model ' 'up to now we only know it has the same memory ' 'organization of KGUVD1 but uses 199 memories. ' 'it has been reported to work but ' 'proceed at your own risk!') def get_features(self): rf = KGUVD1PRadio.get_features(self) rf.memory_bounds = (1, 199) # this is the only known difference return rf def get_settings(self): freq_ranges = RadioSettingGroup("freq_ranges", "Freq Ranges (read only)") group = RadioSettings(freq_ranges) rs = RadioSetting("vhf_rx_start", "vhf rx start", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.vhf_rx_start))) freq_ranges.append(rs) rs = RadioSetting("vhf_rx_stop", "vhf rx stop", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.vhf_rx_stop))) freq_ranges.append(rs) rs = RadioSetting("uhf_rx_start", "uhf rx start", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.uhf_rx_start))) freq_ranges.append(rs) rs = RadioSetting("uhf_rx_stop", "uhf rx stop", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.uhf_rx_stop))) freq_ranges.append(rs) rs = RadioSetting("vhf_tx_start", "vhf tx start", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.vhf_tx_start))) freq_ranges.append(rs) rs = RadioSetting("vhf_tx_stop", "vhf tx stop", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.vhf_tx_stop))) freq_ranges.append(rs) rs = RadioSetting("uhf_tx_start", "uhf tx start", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.uhf_tx_start))) freq_ranges.append(rs) rs = RadioSetting("uhf_tx_stop", "uhf tx stop", RadioSettingValueInteger( 66, 520, decode_freq( self._memobj.freq_ranges.uhf_tx_stop))) freq_ranges.append(rs) # tell the decoded ranges to UI self.valid_freq = \ [(decode_freq(self._memobj.freq_ranges.vhf_rx_start) * 1000000, (decode_freq(self._memobj.freq_ranges.vhf_rx_stop)+1) * 1000000)] return group @classmethod def match_model(cls, filedata, filename): if len(filedata) == 8192 and \ filedata[0x60:0x64] != b"2009" and \ filedata[0x170:0x173] != b"LX-" and \ filedata[0xF7E:0xF80] != b"\x01\xE2" and \ filedata[0x1f77:0x1f7d] == b"\xff\xff\xff\xff\xff\xff" and \ filedata[0x0d70:0x0d80] != ( b"\xff\xff\xff\xff\xff\xff\xff\xff" b"\xff\xff\xff\xff\xff\xff\xff\xff"): return True return False @directory.register class KG818Radio(KG816Radio): """Wouxun KG-818""" MODEL = "KG-818" @classmethod def match_model(cls, filedata, filename): return False chirp-20240224/chirp/drivers/kguv980p.py0000644000175000017500000027551314562640504016611 0ustar hibbyhibby# Copyright 2022 Mel Terechenok # KG-UV980P , KG-1000G, KG-1000G Plus unified driver using # KG-935G, KG-UV8H, KG-UV920P, and KG-UV9D Plus drivers as resources # # Based on the previous work of Pavel Milanes CO7WT # and Krystian Struzik # who figured out the crypt used and made possible the # Wuoxun KG-UV8D Plus driver. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun KG-UV980P radio management module""" import time import logging import struct from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettingValueFloat, RadioSettingValueMap, RadioSettings LOG = logging.getLogger(__name__) CMD_ID = 0x80 CMD_END = 0x81 CMD_RD = 0x82 CMD_WR = 0x83 DIR_TO = 0xFF DIR_FROM = 0x00 # This is used to write the configuration of the radio base on info # gleaned from the downloaded app. There are empty spaces and we honor # them because we don't know what they are (yet) although we read the # whole of memory. # Max Write Size = 64 for comm protocol config_map = ( # map address, write size, write count # (0x0, 64, 512), # 0 to 8000 - full write use only (0x4c, 12, 1), # Mode PSW -- Display name (0x60, 16, 3), # Freq Limits (0x740, 40, 1), # FM chan 1-20 (0x830, 16, 13), # General settings (0x900, 8, 1), # General settings (0x940, 64, 2), # Scan groups and names (0xa00, 64, 249), # Memory Channels 1-996 (0x4840, 48, 1), # Memory Channels 997-999 (0x4900, 64, 124), # Memory Names 1-992 (0x6800, 8, 7), # Memory Names 997-999 (0x7000, 64, 15), # mem valid 1 -960 (0x73c0, 39, 1), # mem valid 961 - 999 ) MEM_VALID = 0x00 MEM_INVALID = [0x80] TX_BLANK = 0x40 RX_BLANK = 0x80 CHARSET_NUMERIC = "0123456789" CHARSET = "0123456789" + \ ":;<=>?@" + \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + \ "[\\]^_`" + \ "abcdefghijklmnopqrstuvwxyz" + \ "{|}~\x4E" + \ " !\"#$%&'()*+,-./" SCANNAME_CHARSET = "0123456789" + \ ":;<=>?@" + \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + \ "[\\]^_`" + \ "abcdefghijklmnopqrstuvwxyz" + \ "{|}~\x4E" + \ " !\"#$%&'()*+,-./" MUTE_MODE_MAP = [('QT', 0b01), ('QT*DTMF', 0b10), ('QT+DTMF', 0b11)] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 30.0, 50.0, 100.0] STEP_LIST = [str(x) for x in STEPS] SQL_LIST = [int(i) for i in range(0, 10)] M_POWER_MAP = [('1 = 20W', 1), ('2 = 10W', 2)] ROGER_LIST = ["Off", "BOT", "EOT", "Both"] VOICE_MAP = [('Off', 0), ('Chinese', 1), ('On / English', 2)] VOICE_MAP_1000GPLUS = [('Off', 0), ('On', 2)] SC_REV_MAP = [('Timeout (TO)', 1), ('Carrier (CO)', 2), ('Stop (SE)', 3)] TOT_MAP = [('%d min' % i, int('%02d' % i, 10)) for i in range(1, 61)] TOT_MAP_1000GPLUS = [('%d min' % i, int('%02d' % i, 16)) for i in range(1, 61)] TOA_LIST = ["Off", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"] TOA_MAP = [('Off', 0)] + \ [('%ds' % i, int('%02d' % i, 16)) for i in range(1, 11)] RING_LIST = ["Off", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"] RING_MAP = [('Off', 0)] + \ [('%ds' % i, int('%02d' % i, 10)) for i in range(1, 11)] DTMF_ST_LIST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] DTMF_ST_LIST_1000GPLUS = ["Off", "DTMF", "ID", "DTMF+ID"] PTT_ID_MAP = [('BOT', 1), ('EOT', 2), ('Both', 3)] PTT_ID_MAP_1000GPLUS = [('Off', 0), ('BOT', 1), ('EOT', 2), ('Both', 3)] BACKLIGHT_LIST = ["Off", "Red", "Orange", "Green"] SPEAKER_MAP = [('SPK_1', 1), ('SPK_2', 2), ('SPK_1+2', 3)] SPEAKER_MAP_1000GPLUS = [('RADIO', 1), ('MIC', 2), ('BOTH', 3)] RPT_MODE_LIST = ["Radio", "X-DIRPT", "X-TWRPT", "RPT-RX", "T-W RPT"] RPT_MODE_MAP = [("OFF", 0), ("RPT-RX", 3), ("RPT-TX", 4)] APO_TIME_LIST = ["Off", "30", "60", "90", "120", "150"] ALERT_MAP = [('1750', 1), ('2100', 2), ('1000', 3), ('1450', 4)] FAN_MODE_LIST = ["TX", "Hi-Temp/TX", "Always"] SCAN_GROUP_LIST = ["All"] + ["%s" % x for x in range(1, 11)] WORKMODE_MAP = [('VFO', 1), ('Ch. No.', 2), ('Ch. No.+Freq.', 3), ('Ch. No.+Name', 4)] WORKMODE_MAP_1000GPLUS = [('Freq', 1), ('Ch-Num', 2), ('Ch-Freq', 3), ('Ch-Name', 4)] VFOBAND_MAP = [("150M", 0), ("450M", 1), ("20M", 2), ("50M", 3), ("350M", 4), ("850M", 5)] AB_LIST = ["A", "B"] POWER_MAP = [('Low', 0), ('Med', 1), ('Med2', 2), ('High', 3)] BANDWIDTH_MAP = [('Narrow', 1), ('Wide', 0)] SCRAMBLER_LIST = ["Off", "1", "2", "3", "4", "5", "6", "7", "8"] ANS_LIST = ["Off", "Normal", "Strong"] DTMF_TIMES = [str(x) for x in range(80, 501, 20)] DTMF_INTERVALS = [str(x) for x in range(60, 501, 20)] ROGER_TIMES = [str(x) for x in range(20, 1001, 20)] # For py3 compliance x/100 must be changed to x//100 PTT_ID_DELAY_MAP = [(str(x), x//100) for x in range(100, 1001, 100)] ROGER_INTERVALS = ROGER_TIMES TONE_MAP = [('Off', 0x0000)] + \ [('%.1f' % tone, int(tone * 10)) for tone in chirp_common.TONES] + \ [('DN%d' % tone, int(0x8000 + tone)) for tone in chirp_common.DTCS_CODES] + \ [('DI%d' % tone, int(0xC000 + tone)) for tone in chirp_common.DTCS_CODES] DUPLEX_LIST = ["Off", "Plus", "Minus"] SC_QT_MAP = [("Decoder - Rx QT/DT MEM", 1), ("Encoder- Tx QT/DT MEM", 2), ("All- RxTx QT/DT MEM", 3)] SC_QT_MAP_1000GPLUS = [("Rx", 1), ("Tx", 2), ("Tx/Rx", 3)] HOLD_TIMES = ["Off"] + ["%s" % x for x in range(100, 5001, 100)] PF1_SETTINGS = ["Off", "Stun", "Kill", "Monitor", "Inspection"] PF1_SETTINGS_1000GPLUS = ["OFF", "Reverse", "Pri-Sel", "Pri-Scan", "Squelch", "TX PWR", "Scan", "Scan CTCSS", "Scan DCS", "FM Radio", "Weather", "Ch-Add", "W-N", "TDR", "WORKMODE", "Band", "Repeater", "Lock", "Monitor"] ABR_LIST = ["Always", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s", "11s", "12s", "13s", "14s", "15s", "16s", "17s", "18s", "19s", "20s", "Off"] KEY_LIST = ["Off", "B/SW", "MENCH", "H-M-L", "VFO/MR", "SET-D", "TDR", "SQL", "SCAN", "FM-Radio", "Scan CTCSS", "Scan DCS"] KEY_LIST_1000GPLUS = ["OFF", "Reverse", "Pri-Sel", "Pri-Scan", "Squelch", "TX PWR", "Scan", "Scan CTCSS", "Scan DCS", "FM Radio", "Weather", "Ch-Add", "W-N", "TDR", "WORKMODE", "Band", "Repeater", "Lock", "Monitor"] RC_POWER_LIST = ["RC Stop", "RC Open"] ACTIVE_AREA_LIST = ["Area A - Left", "Area B - Right"] TDR_LIST = ["TDR ON", "TDR OFF"] PRI_CH_SCAN_LIST = ["Off", "ON-Stby", "On-Always"] # memory slot 0 is not used, start at 1 (so need 1000 slots, not 999) # structure elements whose name starts with x are currently unidentified _MEM_FORMAT = """ #seekto 0x004c; struct { u24 mode_psw; u8 xunk04F; u8 display_name[8]; } oem; #seekto 0x0060; struct { bbcd limit_144M_ChA_rx_start[2]; bbcd limit_144M_ChA_rx_stop[2]; bbcd limit_70cm_rx_start[2]; bbcd limit_70cm_rx_stop[2]; bbcd limit_10m_rx_start[2]; bbcd limit_10m_rx_stop[2]; bbcd limit_6m_rx_start[2]; bbcd limit_6m_rx_stop[2]; bbcd limit_350M_rx_start[2]; bbcd limit_350M_rx_stop[2]; bbcd limit_850M_rx_start[2]; bbcd limit_850M_rx_stop[2]; bbcd limit_144M_tx_start[2]; bbcd limit_144M_tx_stop[2]; bbcd limit_70cm_tx_start[2]; bbcd limit_70cm_tx_stop[2]; bbcd limit_10m_tx_start[2]; bbcd limit_10m_tx_stop[2]; bbcd limit_6m_tx_start[2]; bbcd limit_6m_tx_stop[2]; bbcd limit_144M_ChB_rx_start[2]; bbcd limit_144M_ChB_rx_stop[2]; } bandlimits; #seekto 0x0740; struct { u16 FM_radio1; u16 FM_radio2; u16 FM_radio3; u16 FM_radio4; u16 FM_radio5; u16 FM_radio6; u16 FM_radio7; u16 FM_radio8; u16 FM_radio9; u16 FM_radio10; u16 FM_radio11; u16 FM_radio12; u16 FM_radio13; u16 FM_radio14; u16 FM_radio15; u16 FM_radio16; u16 FM_radio17; u16 FM_radio18; u16 FM_radio19; u16 FM_radio20; u16 FM_radio21; u16 FM_radio22; u8 x76c_pad[196]; u32 vfofreq1; // 0x0830 u32 vfoofst1; u16 txtone1; u16 rxtone1; u8 xunk83C_1:3, mute1:2, xunk83C_2:3; u8 xunk83d_1:1, xunk83d_2:1, xunk83d_3:1, power1:2, am_mode1:1, xunk83d_7:1, narrow1:1; u8 xunk83e:6, shft_dir1:2; u8 xunk83F:3, compander1:1, scrambler1:4; u32 vfofreq2; u32 vfoofst2; u16 txtone2; u16 rxtone2; u8 xunk84C_1:3, mute2:2, xunk84C_2:3; u8 xunk84d_1:1, xunk84d_2:1, xunk84d_3:1, power2:2, am_mode2:1, xunk84d_7:1, narrow2:1; u8 xunk84e:6, shft_dir2:2; u8 xunk84F:3, compander2:1, scrambler2:4; u32 vfofreq3; u32 vfoofst3; u16 txtone3; u16 rxtone3; u8 xunk85C_1:3, mute3:2, xunk85C_2:3; u8 xunk85d_1:1, xunk85d_2:1, xunk85d_3:1, power3:2, am_mode3:1, xunk85d_7:1, narrow3:1; u8 xunk85e:6, shft_dir3:2; u8 xunk85F:3, compander3:1, scrambler3:4; u32 vfofreq4; u32 vfoofst4; u16 txtone4; u16 rxtone4; u8 xunk86C_1:3, mute4:2, xunk86C_2:3; u8 xunk86d_1:1, xunk86d_2:1, xunk86d_3:1, power4:2, am_mode4:1, xunk86d_7:1, narrow4:1; u8 xunk86e:6, shft_dir4:2; u8 xunk86F:3, compander4:1, scrambler4:4; u32 vfofreq5; u32 vfoofst5; u16 txtone5; u16 rxtone5; u8 xunk87C_1:3, mute5:2, xunk87C_2:3; u8 xunk87d_1:1, xunk87d_2:1, xunk87d_3:1, power5:2, am_mode5:1, xunk87d_7:1, narrow5:1; u8 xunk87e:6, shft_dir5:2; u8 xunk87F:3, compander5:1, scrambler5:4; u32 vfofreq6; u32 vfoofst6; u16 txtone6; u16 rxtone6; u8 xunk88C_1:3, mute6:2, xunk88C_2:3; u8 xunk88d_1:1, xunk88d_2:1, xunk88d_3:1, power6:2, am_mode6:1, xunk88d_7:1, narrow6:1; u8 xunk88e:6, shft_dir6:2; u8 xunk8F:3, compander6:1, scrambler6:4; u32 vfofreq7; u32 vfoofst7; u16 txtone7; u16 rxtone7; u8 xunk89C_1:3, mute7:2, xunk89C_2:3; u8 xunk89d_1:1, xunk89d_2:1, xunk89d_3:1, power7:2, am_mode7:1, xunk89d_7:1, narrow7:1; u8 xunk89e:6, shft_dir7:2; u8 xunk89F:3, compander7:1, scrambler7:4; u8 x8a0; u16 vfochan_a; u8 x8a3; u16 vfochan_b; u16 pri_ch; u8 x8a8; u8 x8a9; u8 scan_a_act; u8 scan_b_act; u8 m_pwr; u8 hold_time_rpt; u8 spk_cont; u8 x8af; u8 rc_power; u8 voice; u8 tot; u8 toa; u8 roger; u8 sc_rev; u8 dtmfsf; u8 ptt_id; u8 ring; u8 ani_sw; u8 rc_sw; u8 alert; u8 bcl_a; u8 prich_sw; u8 x8bE; u8 ptt_id_dly; u8 menu; u8 x8c1; u8 beep; u8 key_lock; u8 x8c4; u8 tx_led; u8 wt_led; u8 rx_led; u8 act_area; u8 vfomode_a; u8 vfomode_b; u8 vfosquelch_a; u8 vfosquelch_b; u8 vfostep_a; u8 vfostep_b; u8 tdr_off; u8 rpt_spk; //x8d0 u8 rpt_ptt; u8 autolock; u8 apo_time; u8 low_v; u8 fan; u8 rpt_set_model; u8 pf1_set; u8 auto_am; u8 dtmf_time; u8 dtmf_int; u8 bcl_b; u8 rpt_tone; u8 sc_qt; u8 vfoband_a; u8 x8dF; u24 ani_edit; u8 x8e3; u24 mcc_edit; u8 x8e7; u24 scc_edit; u8 x8eB; u24 ctrl_edit; u8 x8eF; u8 KeyA; u8 KeyB; u8 KeyC; u8 ABR; u8 x8f4; u8 x8f5; u8 KeyD; // KG-1000G Plus ONLY u8 x8f7; u8 x8f8; u8 x8f9; u8 x8fA; u8 x8fB; u8 x8fC; u8 x8fD; u8 x8fE; u8 x8fF; u16 FM_radio_cur_freq; u8 x902; u8 scan_det; u8 x904; u8 thr_vol_tx; u16 thr_vol_lvl; u8 x908; u8 x909; u8 x90A; u8 x90B; u8 x90C; u8 x90D; u8 x90E; u8 x90F; u8 x910pad[48]; u16 scanlower1; // x940 u16 scanupper1; u16 scanlower2; u16 scanupper2; u16 scanlower3; u16 scanupper3; u16 scanlower4; u16 scanupper4; u16 scanlower5; u16 scanupper5; u16 scanlower6; u16 scanupper6; u16 scanlower7; u16 scanupper7; u16 scanlower8; u16 scanupper8; u16 scanlower9; u16 scanupper9; u16 scanlower10; u16 scanupper10; u8 scanname0[8]; // x968 u8 scanname1[8]; u8 scanname2[8]; u8 scanname3[8]; u8 scanname4[8]; u8 scanname5[8]; u8 scanname6[8]; u8 scanname7[8]; u8 scanname8[8]; u8 scanname9[8]; u8 scanname10[8]; } settings; #seekto 0x09f0; struct { u32 rxfreq; u32 txfreq; u16 txtone; u16 rxtone; u8 unknown1:3, mute_mode:2, unknown2:3; u8 named:1, scan_add:1, extra_power_bit:1, power:2, am_mode:1, unknownbit2:1, isnarrow:1; u8 unknown3:6, Unknown4_shft_dir:2; u8 unknown5:3, compander:1, scrambler:4; } memory[1000]; #seekto 0x48f8; struct { u8 name[8]; } names[1000]; #seekto 0x6fff; u8 valid[1000]; """ def _freq_decode(in_freq, bytes=4): out_freq = 0 for i in range(bytes*2): out_freq += (in_freq & 0xF) * (10 ** i) in_freq = in_freq >> 4 if bytes == 4: return out_freq * 10 elif bytes == 2: return out_freq * 100000 def _freq_encode(in_freq, bytes=4): if bytes == 4: return int('%08d' % (in_freq / 10), 16) elif bytes == 2: return int('%04d' % (in_freq / 100000), 16) def _oem_str_decode(in_str): out_str = '' stopchar = False for c in in_str: if c != 0x50 and stopchar is False: if chr(c+48) in chirp_common.CHARSET_ASCII: out_str += chr(c+48) else: out_str += '' stopchar = True return out_str def _oem_str_encode(in_str): out_str = '' LOG.debug("OEM Input String = %s", in_str) for c in in_str: try: out_str += chr(int(ord(c))-48) except ValueError: pass while len(out_str) < 8: out_str += chr(0x50) LOG.debug("OEM Output String = %s", out_str) return out_str # OEM String Encode for KG-1000G Plus def _oem_str_decode_1000GPLUS(in_str): LOG.debug("decode OEM Input String = %s", in_str) out_str = '' for c in in_str: # 1000G+ character mapping starts with P = 32 and O = 127 if 127 >= c >= 80: out_str += chr(c - 48) elif 32 <= c < 80: out_str += chr(c+48) else: out_str += '' LOG.debug("decode OEM Output String = %s", out_str) return out_str # OEM String Encode for KG-1000G Plus def _oem_str_encode_1000GPLUS(in_str): out_str = '' LOG.debug("encode OEM Input String = %s", in_str) for c in in_str: if 32 <= ord(c) < 80: out_str += chr(int(ord(c)) + 48) elif 127 >= ord(c) >= 80: out_str += chr(int(ord(c)) - 48) while len(out_str) < 8: out_str += chr(0x50) LOG.debug("encode OEM Output String = %s", out_str) return out_str def _str_decode(in_str): out_str = '' stopchar = False for c in in_str: if c != 0x00 and stopchar is False: if chr(c) in chirp_common.CHARSET_ASCII: out_str += chr(c) else: out_str += '' stopchar = True return out_str def _str_encode(in_str): out_str = '' for c in in_str: try: out_str += chr(ord(c)) except ValueError: pass while len(out_str) < 8: out_str += chr(0x00) if out_str == " " or out_str == "": out_str = "\x00\x00\x00\x00\x00\x00\x00\x00" return out_str def _chnum_decode(in_ch): return int(('%04x' % in_ch)[0:3]) def _chnum_encode(in_ch): return int('%03d0' % in_ch, 16) # Support for the Wouxun KG-UV980P radio # Serial coms are at 19200 baud # The data is passed in variable length records # Record structure: # Offset Usage # 0 start of record (\x7c) # 1 Command (\x80 Identify \x81 End/Reboot \x82 Read \x83 Write) # 2 direction (\xff PC-> Radio, \x00 Radio -> PC) # 3 length of payload (excluding header/checksum) (n) # 4 payload (n bytes) # 4+n+1 checksum - only lower 4 bits of byte sum (% 256) of bytes 1 -> 4+n # # Memory Read Records: # the payload is 3 bytes, first 2 are offset (big endian), # 3rd is number of bytes to read # Memory Write Records: # the maximum payload size (from the Wouxun software) seems to be 66 bytes # (2 bytes location + 64 bytes data). @directory.register class KG980PRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-UV980P""" VENDOR = "Wouxun" MODEL = "KG-UV980P" _model = b"KG-UV950R2" _file_ident = b"980P" BAUD_RATE = 19200 NEEDS_COMPAT_SERIAL = False # Start Byte for Communication messages _record_start = 0xDA # _cs_size = 0x0F for 4-bit checksum, 0xFF for 8-Bit checksum _cs_size = 0x0F # _valxor = value needed to encrypt/decrypt the bytes to/from the radio _valxor = 0x57 POWER_LEVELS = [chirp_common.PowerLevel("L", watts=1.0), chirp_common.PowerLevel("M", watts=20.0), chirp_common.PowerLevel("H", watts=50.0)] def _checksum(self, data): cs = 0 for byte in data: cs += byte return ((cs % 256) & self._cs_size) def _write_record(self, cmd, payload=b''): _packet = struct.pack('BBBB', self._record_start, cmd, 0xFF, len(payload)) checksum = bytes([self._checksum(_packet[1:] + payload)]) _packet += self.encrypt(payload + checksum) LOG.debug("Sent:\n%s" % util.hexprint(_packet)) self.pipe.write(_packet) def _read_record(self): # read 4 chars for the header _header = self.pipe.read(4) if len(_header) != 4: raise errors.RadioError('Radio did not respond') _length = struct.unpack('xxxB', _header)[0] _packet = self.pipe.read(_length) _rcs_xor = _packet[-1] _packet = self.decrypt(_packet) _cs = self._checksum(_header[1:]) _cs += self._checksum(_packet) _cs %= 256 _cs = _cs & self._cs_size _rcs = self.strxor(self.pipe.read(1)[0], _rcs_xor)[0] return (_rcs != _cs, _packet) def decrypt(self, data): result = b'' for i in range(len(data)-1, 0, -1): result += self.strxor(data[i], data[i - 1]) result += self.strxor(data[0], self._valxor) return result[::-1] def encrypt(self, data): result = self.strxor(self._valxor, data[0]) for i in range(1, len(data), 1): result += self.strxor(result[i - 1], data[i]) return result def strxor(self, xora, xorb): return bytes([xora ^ xorb]) # Identify the radio # # A Gotcha: the first identify packet returns a bad checksum, subsequent # attempts return the correct checksum... (well it does on my radio!) # # The ID record returned by the radio also includes the # current frequency range # as 4 bytes big-endian in 10 Hz increments # # Offset # 0:10 Model, zero padded def _identify(self): """Do the identification dance""" for _i in range(0, 3): LOG.debug("ID try #"+str(_i)) self._write_record(CMD_ID) _chksum_err, _resp = self._read_record() if len(_resp) == 0: raise errors.RadioError("Radio not responding") else: LOG.debug("Got:\n%s" % util.hexprint(_resp)) LOG.debug("Model received is %s" % _resp[0:10]) LOG.debug("Model expected is %s" % self._model) if _chksum_err: LOG.error("Checksum error: retrying ident...") time.sleep(0.100) continue else: LOG.debug("checksum passed") if _resp[0:8] == self._model[0:8]: LOG.debug("Passed identify") break else: LOG.debug("FAILED to identify") raise errors.RadioError("Failed Identification") def _finish(self): self._write_record(CMD_END) def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._download() except errors.RadioError: raise except Exception: raise errors.RadioError("Failed to communicate with radio: %s") self.process_mmap() def sync_out(self): self._upload() # TODO: Load all memory. # It would be smarter to only load the active areas and none of # the padding/unused areas. Padding still need to be investigated. def _download(self): """Talk to a Wouxun KG-UV980P and do a download""" try: self._identify() return self._do_download(0, 32768, 64) except errors.RadioError: raise except Exception: LOG.exception('Unknown error during download process') raise errors.RadioError("Failed to communicate with radio: %s") def _do_download(self, start, end, size): # allocate & fill memory LOG.debug("Start Download") image = b"" for i in range(start, end, size): req = struct.pack("BBB", int(i / 256), int(i % 256), int(size)) self._write_record(CMD_RD, req) cs_error, resp = self._read_record() if cs_error: LOG.debug(util.hexprint(resp)) raise errors.RadioError("Checksum error on read") image += resp[2:] if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning from radio" self.status_fn(status) self._finish() LOG.debug("Download Completed") return memmap.MemoryMapBytes(image) def _upload(self): """Talk to a Wouxun KG-UV980P and do a upload""" try: self._identify() LOG.debug("Done with Upload Identify") self._do_upload() LOG.debug("Done with Mem and Settings Upload") self._finish() except errors.RadioError: raise except Exception: raise errors.RadioError("Failed to communicate with radio: %s") return def _do_upload(self): LOG.debug("Start of _do_upload") cfg_map = config_map endwrite = 0x73E7 for start, blocksize, count in cfg_map: end = start + (blocksize * count) LOG.debug("start = " + str(start)) LOG.debug("end = " + str(end)) LOG.debug("blksize = " + str(blocksize)) for addr in range(start, end, blocksize): ptr = addr req = struct.pack('>H', addr) chunk = self.get_mmap()[ptr:ptr + blocksize] self._write_record(CMD_WR, req + chunk) LOG.debug(util.hexprint(req + chunk)) cserr, ack = self._read_record() LOG.debug(util.hexprint(ack)) j = struct.unpack('>H', ack)[0] if cserr or j != ptr: raise errors.RadioError("Radio did not ack block %i" % ptr) ptr += blocksize if self.status_fn: status = chirp_common.Status() status.cur = ptr status.max = endwrite status.msg = "Cloning to radio" self.status_fn(status) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM", "AM", "NAM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_bands = [(26000000, 299999990), # supports VHF (300000000, 999999990)] # supports UHF rf.valid_characters = chirp_common.CHARSET_ASCII rf.memory_bounds = (1, 999) # 999 memories rf.valid_tuning_steps = STEPS return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is experimental and may contain bugs. \n' 'USE AT YOUR OWN RISK - ' 'SAVE A COPY OF DOWNLOAD FROM YOUR RADIO BEFORE MAKING CHANGES\n' 'Modification of Freq Limit Interfaces is done ' 'AT YOUR OWN RISK and may affect performance or certification' ) return rp def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _get_tone(self, _mem, mem): # - corrected the Polarity decoding to match 980P implementation # use 0x4000 bit mask for R # - 0x4000 appears to be the bit mask for Inverted DCS tones # - n DCS Tone will be 0x8xxx values - i DCS Tones will # be 0xCxxx values. # - Chirp Uses N for n DCS Tones and R for i DCS Tones # - 980P encodes DCS tone # in decimal - NOT OCTAL def _get_dcs(val): code = int("%03d" % (val & 0x07FF)) pol = (val & 0x4000) and "R" or "N" return code, pol # - Modified the function below to bitwise AND with 0x4000 # to check for 980P DCS Tone decoding # 0x8000 appears to be the bit mask for DCS tones tpol = False # Beta 1.1 - Fix the txtone compare to 0x8000 - was rxtone. if _mem.txtone != 0xFFFF and (_mem.txtone & 0x8000) == 0x8000: tcode, tpol = _get_dcs(_mem.txtone) mem.dtcs = tcode txmode = "DTCS" elif _mem.txtone != 0xFFFF and _mem.txtone != 0x0: mem.rtone = (_mem.txtone & 0x7fff) / 10.0 txmode = "Tone" else: txmode = "" # - Modified the function below to bitwise AND with 0x4000 # to check for 980P DCS Tone decoding rpol = False if _mem.rxtone != 0xFFFF and (_mem.rxtone & 0x8000) == 0x8000: rcode, rpol = _get_dcs(_mem.rxtone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rxtone != 0xFFFF and _mem.rxtone != 0x0: mem.ctone = (_mem.rxtone & 0x7fff) / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") def get_memory(self, number): _mem = self._memobj.memory[number] mem = chirp_common.Memory() mem.number = number _valid = self._memobj.valid[mem.number] _nam = self._memobj.names[number] # Handle deleted channel quirks due to radio firmware # not always clearing the valid channel indicators # _valid == 0x80 indicates channel was deleted thru radio menu and # only part of the channel structure data is cleared by firmware # _valid == 0x00 indicates the channel is Valid # all other values the firmware uses for _valid: look for valid # Rx and Tx freq values to determine validity if (_valid in MEM_INVALID or ((_valid != MEM_VALID) & ((_mem.rxfreq == 0xFFFFFFFF) or _mem.rxfreq == 0x00000000))): mem.empty = True if _valid == 0x80: LOG.debug("Ch %s was deleted by using radio menu" % number) LOG.debug("Current Memory: \n%s" % _mem) LOG.debug("Clearing Ch %s memory" % number) _mem.set_raw(b"\xFF" * (_mem.size() // 8)) _nam.set_raw(b"\xFF" * (_nam.size() // 8)) self._memobj.valid[mem.number] = 0xFF return mem elif (_valid != MEM_VALID) & ((_mem.rxfreq != 0xFFFFFFFF) and (_mem.rxfreq != 0x00000000)): mem.empty = False self._memobj.valid[mem.number] = MEM_VALID else: mem.empty = False mem.freq = int(_mem.rxfreq) * 10 _rxfreq = _freq_decode(_mem.rxfreq) _txfreq = _freq_decode(_mem.txfreq) mem.freq = _rxfreq if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_rxfreq) == int(_txfreq): mem.duplex = "" mem.offset = 0 elif abs(_rxfreq - _txfreq) > 70000000: mem.duplex = "split" mem.offset = _txfreq else: mem.duplex = _rxfreq > _txfreq and "-" or "+" mem.offset = abs(_rxfreq - _txfreq) if _mem.named: mem.name = _str_decode(self._memobj.names[number].name) # Remove trailing whitespaces from the name mem.name = mem.name.rstrip() else: mem.name = '' self._get_tone(_mem, mem) mem.skip = "" if bool(_mem.scan_add) else "S" pwr_index = _mem.power if _mem.power == 3: pwr_index = 2 if _mem.power: mem.power = self.POWER_LEVELS[pwr_index] else: mem.power = self.POWER_LEVELS[0] if _mem.am_mode: if _mem.isnarrow: mem.mode = "NAM" else: mem.mode = "AM" else: mem.mode = _mem.isnarrow and "NFM" or "FM" mem.extra = RadioSettingGroup("Extra", "extra") # Scrambler >8 is invalid default to off if _mem.scrambler > 8: _mem.scrambler = 0 return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): # Change to 0x8000 to # set the bit for DCS- code is a decimal version # of the code # - NOT OCTAL val = code | 0x8000 if pol == "R": # Change to 0x4000 to set the bit for # i/R polarity val += 0x4000 return val rx_mode = tx_mode = None rxtone = txtone = 0x0000 if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None txtone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) _mem.rxtone = rxtone _mem.txtone = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.txtone, rx_mode, _mem.rxtone)) def set_memory(self, mem): # _mem = Stored Memory value # mem = New value from user entry number = mem.number _mem = self._memobj.memory[number] _nam = self._memobj.names[number] if mem.empty: self._memobj.valid[number] = 0xFF _mem.set_raw(b"\xFF" * (_mem.size() // 8)) self._memobj.names[number].set_raw(b"\xFF" * (_nam.size() // 8)) else: if len(mem.name) > 0: _mem.named = True name_encoded = _str_encode(mem.name) for i in range(0, 8): _nam.name[i] = ord(name_encoded[i]) else: _mem.named = False _mem.rxfreq = _freq_encode(mem.freq) if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = _freq_encode(mem.offset) elif mem.duplex == "+": _mem.txfreq = _freq_encode(mem.freq + mem.offset) elif mem.duplex == "-": _mem.txfreq = _freq_encode(mem.freq - mem.offset) else: _mem.txfreq = _freq_encode(mem.freq) _mem.scan_add = int(mem.skip != "S") if mem.mode == "AM": _mem.am_mode = True _mem.isnarrow = False elif mem.mode == "NAM": _mem.am_mode = True _mem.isnarrow = True else: _mem.am_mode = False if mem.mode == "NFM": _mem.isnarrow = True else: _mem.isnarrow = False # set the tone self._set_tone(mem, _mem) # set the scrambler and compander to off by default # This changes them in the channel memory _mem.scrambler = 0 _mem.compander = 0 # set the power # Updated to resolve "Illegal set on attribute power" Warning if str(mem.power) == "None": _mem.power = 0 # Default to Low power else: index = self.POWER_LEVELS.index(mem.power) if index == 2: _mem.power = 0b11 # Force H to value of binary 3 else: _mem.power = index # Not sure what this bit does yet but it causes # the radio to display # MED power when the CPS shows Low Power. # Forcing it to 0 to keep them # consistent _mem.extra_power_bit = 0 # Set other unknowns to 0 to match default CPS values _mem.unknown1 = 0 _mem.unknown2 = 0 _mem.unknownbit2 = 0 _mem.unknown3 = 0 _mem.Unknown4_shft_dir = 0 _mem.unknown5 = 0 # set to mute mode to QT (not QT+DTMF or QT*DTMF) by default # This changes them in the channel memory _mem.mute_mode = 1 self._memobj.valid[number] = MEM_VALID def _get_settings(self): _settings = self._memobj.settings _oem = self._memobj.oem cfg_grp = RadioSettingGroup("cfg_grp", "Config Settings") cfg1_grp = RadioSettingGroup("cfg1_grp", "Config Settings 1") cfg2_grp = RadioSettingGroup("cfg2_grp", "Config Settings 2") if self.MODEL == "KG-1000G Plus": vfoaname = "Area A Settings" else: vfoaname = "VFO A Settings" vfoa_grp = RadioSettingGroup("vfoa_grp", vfoaname) vfo150_grp = RadioSettingGroup("vfo150_grp", "150M Settings") vfo450_grp = RadioSettingGroup("vfo450_grp", "450M Settings") vfo20_grp = RadioSettingGroup("vfo20_grp", "20M Settings") vfo50_grp = RadioSettingGroup("vfo50_grp", "50M Settings") vfo350_grp = RadioSettingGroup("vfo350_grp", "350M Settings") vfo850_grp = RadioSettingGroup("vfo850_grp", "850M Settings") if self.MODEL == "KG-1000G Plus": vfobname = "Area B Settings" else: vfobname = "VFO B Settings" vfob_grp = RadioSettingGroup("vfob_grp", vfobname) fmradio_grp = RadioSettingGroup("fmradio_grp", "FM Broadcast Memory") lmt_grp = RadioSettingGroup("lmt_grp", "Frequency Limits") lmwrn_grp = RadioSettingGroup("lmwrn_grp", "USE AT YOUR OWN RISK") rxlim_grp = RadioSettingGroup("rxlim_grp", "Rx Limits") txlim_grp = RadioSettingGroup("txlim_grp", "Tx Limits") oem_grp = RadioSettingGroup("oem_grp", "OEM Info") scan_grp = RadioSettingGroup("scan_grp", "Scan Group") scanname_grp = RadioSettingGroup("scanname_grp", "Scan Names") remote_grp = RadioSettingGroup("remote_grp", "Remote Settings") extra_grp = RadioSettingGroup("extra_grp", "Extra Settings") if self.MODEL == "KG-1000G Plus": vfoname = "Freq Mode Settings" else: vfoname = "VFO Settings" vfo_grp = RadioSettingGroup("vfo_grp", vfoname) extra_grp.append(oem_grp) cfg_grp.append(cfg1_grp) cfg_grp.append(cfg2_grp) lmt_grp.append(lmwrn_grp) lmt_grp.append(rxlim_grp) extra_grp.append(lmt_grp) vfo_grp.append(vfoa_grp) vfo_grp.append(vfob_grp) vfoa_grp.append(vfo150_grp) vfoa_grp.append(vfo450_grp) if self.MODEL == "KG-UV980P": vfoa_grp.append(vfo20_grp) lmt_grp.append(txlim_grp) vfoa_grp.append(vfo50_grp) vfoa_grp.append(vfo350_grp) vfoa_grp.append(vfo850_grp) scan_grp.append(scanname_grp) group = RadioSettings(cfg_grp, vfo_grp, fmradio_grp, remote_grp, scan_grp, extra_grp) # Configuration Settings if self.MODEL == "KG-1000G Plus": voicemap = VOICE_MAP_1000GPLUS pttidmap = PTT_ID_MAP_1000GPLUS pttidlabel = "DTMF ID" dtmflist = DTMF_ST_LIST_1000GPLUS dtmflabel = "Sidetone" spkmap = SPEAKER_MAP_1000GPLUS key_l = KEY_LIST_1000GPLUS scqt = SC_QT_MAP_1000GPLUS pf1set = PF1_SETTINGS_1000GPLUS wmmap = WORKMODE_MAP_1000GPLUS totmap = TOT_MAP_1000GPLUS lowvlabel = "Voltage Alert" fanlabel = "Fan Setting" alerttonelabel = "Alert Tone(Hz)" tonescanlabel = "Tone Save" pttdelaylabel = "DTMF ID Delay (ms)" scandetlabel = "Tone Scan" txvoltlabel = "Tx Voltage Limit" holdtimrptlabel = "Repeater Hold Time (ms)" thrvollvllabel = "Tx Voltage Min" modepswlabel = "Freq Mode Password" narrow1label = "150M W/N" mute1label = "150M SP Mute" scram1label = "150M Descrambler" narrow2label = "450M W/N" mute2label = "450M SP Mute" scram2label = "450M Descrambler" narrow3label = "20M W/N" mute3label = "20M SP Mute" scram3label = "20M Descrambler" narrow4label = "50M W/N" mute4label = "50M SP Mute" scram4label = "50M Descrambler" narrow5label = "350M W/N" mute5label = "350M SP Mute" scram5label = "350M Descrambler" narrow6label = "850M W/N" mute6label = "850M SP Mute" scram6label = "850M Descrambler" narrow7label = "W/N" mute7label = "SP Mute" scram7label = "Descrambler" else: # 980P or 1000G radios voicemap = VOICE_MAP pttidmap = PTT_ID_MAP pttidlabel = "Caller ID Tx Mode (PTT_ID)" dtmflist = DTMF_ST_LIST dtmflabel = "DTMF Sidetone" spkmap = SPEAKER_MAP key_l = KEY_LIST scqt = SC_QT_MAP pf1set = PF1_SETTINGS wmmap = WORKMODE_MAP totmap = TOT_MAP lowvlabel = "Low Voltage Shutoff" fanlabel = "Fan Mode" alerttonelabel = "Alert Pulse (Hz)" tonescanlabel = "CTCSS/DCS Scan" pttdelaylabel = "Caller ID Tx Delay PTT-ID-DLY (ms)" scandetlabel = "Scan DET" txvoltlabel = "Threshold Voltage Tx" holdtimrptlabel = "Hold Time of Repeat (ms)" thrvollvllabel = "Threshold Voltage Level" modepswlabel = "MODE PSW" narrow1label = "150M Bandwidth" mute1label = "150M Mute Mode" scram1label = "150M Scrambler" narrow2label = "450M Bandwidth" mute2label = "450M Mute Mode" scram2label = "450M Scrambler" narrow3label = "20M Bandwidth" mute3label = "20M Mute Mode" scram3label = "20M Scrambler" narrow4label = "50M Bandwidth" mute4label = "50M Mute Mode" scram4label = "50M Scrambler" narrow5label = "350M Bandwidth" mute5label = "350M Mute Mode" scram5label = "350M Scrambler" narrow6label = "850M Bandwidth" mute6label = "850M Mute Mode" scram6label = "850M Scrambler" narrow7label = "Bandwidth" mute7label = "Mute Mode" scram7label = "Scrambler" rs = RadioSetting("roger", "Roger Beep", RadioSettingValueList(ROGER_LIST, ROGER_LIST[_settings. roger])) cfg1_grp.append(rs) rs = RadioSetting("beep", "Keypad Beep", RadioSettingValueBoolean(_settings.beep)) cfg1_grp.append(rs) rs = RadioSetting("voice", "Voice Guide", RadioSettingValueMap(voicemap, _settings.voice)) cfg1_grp.append(rs) rs = RadioSetting("bcl_a", "Busy Channel Lock-out A", RadioSettingValueBoolean(_settings.bcl_a)) cfg1_grp.append(rs) rs = RadioSetting("bcl_b", "Busy Channel Lock-out B", RadioSettingValueBoolean(_settings.bcl_b)) cfg1_grp.append(rs) rs = RadioSetting("sc_rev", "Scan Mode", RadioSettingValueMap(SC_REV_MAP, _settings.sc_rev)) cfg1_grp.append(rs) rs = RadioSetting("tot", "Timeout Timer (TOT)", RadioSettingValueMap( totmap, _settings.tot)) cfg1_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("toa", "Timeout Alarm (TOA)", RadioSettingValueList( TOA_LIST, TOA_LIST[_settings.toa])) else: rs = RadioSetting("toa", "Overtime Alarm (TOA)", RadioSettingValueMap( TOA_MAP, _settings.toa)) cfg1_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("ani_sw", "Caller ID Tx - ANI-SW", RadioSettingValueBoolean(_settings.ani_sw)) cfg1_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("ring", "Ring Time (Sec)", RadioSettingValueList( RING_LIST, RING_LIST[_settings.ring])) else: rs = RadioSetting("ring", "Ring Time (Sec)", RadioSettingValueMap( RING_MAP, _settings.ring)) cfg1_grp.append(rs) rs = RadioSetting("dtmfsf", dtmflabel, RadioSettingValueList( dtmflist, dtmflist[_settings.dtmfsf])) cfg1_grp.append(rs) rs = RadioSetting("ptt_id", pttidlabel, RadioSettingValueMap(pttidmap, _settings.ptt_id)) cfg1_grp.append(rs) rs = RadioSetting("wt_led", "Standby / WT LED", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.wt_led])) cfg1_grp.append(rs) rs = RadioSetting("tx_led", "TX LED", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.tx_led])) cfg1_grp.append(rs) rs = RadioSetting("rx_led", "Rx LED", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.rx_led])) cfg1_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("prich_sw", "Priority Scan", RadioSettingValueList( PRI_CH_SCAN_LIST, PRI_CH_SCAN_LIST[_settings.prich_sw])) cfg1_grp.append(rs) else: rs = RadioSetting("prich_sw", "Priority Channel Scan", RadioSettingValueBoolean(_settings.prich_sw)) cfg1_grp.append(rs) rs = RadioSetting("spk_cont", "Speaker Control", RadioSettingValueMap( spkmap, _settings.spk_cont)) cfg1_grp.append(rs) rs = RadioSetting("autolock", "Autolock", RadioSettingValueBoolean(_settings.autolock)) cfg1_grp.append(rs) rs = RadioSetting("low_v", lowvlabel, RadioSettingValueBoolean(_settings.low_v)) cfg1_grp.append(rs) rs = RadioSetting("fan", fanlabel, RadioSettingValueList( FAN_MODE_LIST, FAN_MODE_LIST[_settings.fan])) cfg1_grp.append(rs) rs = RadioSetting("apo_time", "Auto Power-Off (Min)", RadioSettingValueList( APO_TIME_LIST, APO_TIME_LIST[_settings.apo_time])) cfg1_grp.append(rs) rs = RadioSetting("alert", alerttonelabel, RadioSettingValueMap(ALERT_MAP, _settings.alert)) cfg1_grp.append(rs) rs = RadioSetting("m_pwr", "Medium Power Level (W)", RadioSettingValueMap(M_POWER_MAP, _settings.m_pwr)) cfg1_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("rpt_set_model", "Model (RPT-SET)", RadioSettingValueList( RPT_MODE_LIST, RPT_MODE_LIST[_settings.rpt_set_model])) else: rs = RadioSetting("rpt_set_model", "Repeater Mode", RadioSettingValueMap( RPT_MODE_MAP, _settings.rpt_set_model)) cfg2_grp.append(rs) rs = RadioSetting("rpt_spk", "Repeater Speaker Switch (RPT-SPK)", RadioSettingValueBoolean(_settings.rpt_spk)) cfg2_grp.append(rs) rs = RadioSetting("rpt_ptt", "Repeater PTT (RPT-PTT)", RadioSettingValueBoolean(_settings.rpt_ptt)) cfg2_grp.append(rs) rs = RadioSetting("dtmf_time", "DTMF Tx Duration (ms)", RadioSettingValueList( DTMF_TIMES, DTMF_TIMES[_settings.dtmf_time])) cfg2_grp.append(rs) rs = RadioSetting("dtmf_int", "DTMF Interval (ms)", RadioSettingValueList( DTMF_INTERVALS, DTMF_INTERVALS[_settings.dtmf_int])) cfg2_grp.append(rs) rs = RadioSetting("sc_qt", tonescanlabel, RadioSettingValueMap( scqt, _settings.sc_qt)) cfg2_grp.append(rs) rs = RadioSetting("pri_ch", "Priority Channel", RadioSettingValueInteger( 1, 999, _chnum_decode(_settings.pri_ch))) cfg2_grp.append(rs) rs = RadioSetting("ptt_id_dly", pttdelaylabel, RadioSettingValueMap(PTT_ID_DELAY_MAP, _settings.ptt_id_dly)) cfg2_grp.append(rs) rs = RadioSetting("rc_sw", "Remote Control RC-SW", RadioSettingValueBoolean(_settings.rc_sw)) cfg2_grp.append(rs) rs = RadioSetting("scan_det", scandetlabel, RadioSettingValueBoolean(_settings.scan_det)) cfg2_grp.append(rs) rs = RadioSetting("menu", "Menu Available", RadioSettingValueBoolean(_settings.menu)) cfg2_grp.append(rs) rs = RadioSetting("thr_vol_tx", txvoltlabel, RadioSettingValueBoolean(_settings.thr_vol_tx)) cfg2_grp.append(rs) rs = RadioSetting("hold_time_rpt", holdtimrptlabel, RadioSettingValueList( HOLD_TIMES, HOLD_TIMES[_settings.hold_time_rpt])) cfg2_grp.append(rs) rs = RadioSetting("auto_am", "Auto AM", RadioSettingValueBoolean(_settings.auto_am)) cfg2_grp.append(rs) rs = RadioSetting("rpt_tone", "Repeat Tone", RadioSettingValueBoolean(_settings.rpt_tone)) cfg2_grp.append(rs) rs = RadioSetting("pf1_set", "PF1 setting", RadioSettingValueList( pf1set, pf1set[_settings.pf1_set])) cfg2_grp.append(rs) rs = RadioSetting("settings.thr_vol_lvl", thrvollvllabel, RadioSettingValueFloat( 9.5, 10.5, _settings.thr_vol_lvl / 100.0, 0.1, 1)) cfg2_grp.append(rs) dtmfchars = "0123456789" _code = '' test = int(_oem.mode_psw) _codeobj = '0x{0:0{1}X}'.format(test, 6) LOG.debug("codeobj = %s" % _codeobj) _psw = str(_codeobj) for i in range(2, 8): LOG.debug("psw[i] = %s" % _psw[i]) if _psw[i] in dtmfchars: _code += _psw[i] val_psw = RadioSettingValueString(6, 6, _code, False) val_psw.set_charset(dtmfchars) rs = RadioSetting("oem.mode_psw", modepswlabel, val_psw) def apply_psw_id(setting, obj): val2 = hex(int(str(val_psw), 16)) if (int(val2, 16) != 0): while len(val2) < 8: val2 += '0' psw = int(str(val2), 16) obj.mode_psw = psw rs.set_apply_callback(apply_psw_id, _oem) cfg2_grp.append(rs) rs = RadioSetting("ABR", "Backlight On Time (ABR)", RadioSettingValueList( ABR_LIST, ABR_LIST[_settings.ABR])) cfg2_grp.append(rs) rs = RadioSetting("KeyA", "Key A", RadioSettingValueList( key_l, key_l[_settings.KeyA])) cfg2_grp.append(rs) rs = RadioSetting("KeyB", "Key B", RadioSettingValueList( key_l, key_l[_settings.KeyB])) cfg2_grp.append(rs) rs = RadioSetting("KeyC", "Key C", RadioSettingValueList( key_l, key_l[_settings.KeyC])) cfg2_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("KeyD", "Key D", RadioSettingValueList( KEY_LIST_1000GPLUS, KEY_LIST_1000GPLUS[_settings.KeyD])) cfg2_grp.append(rs) rs = RadioSetting("key_lock", "Key Lock Active", RadioSettingValueBoolean(_settings.key_lock)) cfg2_grp.append(rs) rs = RadioSetting("act_area", "Active Area (BAND)", RadioSettingValueList( ACTIVE_AREA_LIST, ACTIVE_AREA_LIST[_settings.act_area])) cfg2_grp.append(rs) rs = RadioSetting("tdr_off", "TDR", RadioSettingValueList( TDR_LIST, TDR_LIST[_settings.tdr_off])) cfg2_grp.append(rs) # Freq Limits settings # Convert Integer back to correct limit HEX value: s = self._memobj _temp = int(s.bandlimits.limit_144M_ChA_rx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_144M_ChA_rx_start", "144M Area A Rx Lower Limit (MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_144M_ChA_rx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_144M_ChA_rx_stop", "144M Area A Rx Upper Limit (+ .9975 MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_144M_ChB_rx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_144M_ChB_rx_start", "144M Area B Rx Lower Limit (MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_144M_ChB_rx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_144M_ChB_rx_stop", "144M Area B Rx Upper Limit (+ .9975 MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_70cm_rx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_70cm_rx_start", "450M Rx Lower Limit (MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_70cm_rx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_70cm_rx_stop", "450M Rx Upper Limit (+ .9975 MHz)", val) rxlim_grp.append(rs) if self.MODEL == "KG-UV980P": _temp = int(s.bandlimits.limit_10m_rx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_10m_rx_start", "20M Rx Lower Limit (MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_10m_rx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_10m_rx_stop", "20M Rx Upper Limit (+ .9975 MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_6m_rx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_6m_rx_start", "50M Rx Lower Limit (MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_6m_rx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_6m_rx_stop", "50M Rx Upper Limit (+ .9975 MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_350M_rx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_350M_rx_start", "350M Rx Lower Limit (MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_350M_rx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_350M_rx_stop", "350M Rx Upper Limit (+ .9975 MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_850M_rx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_850M_rx_start", "850M Rx Lower Limit (MHz)", val) rxlim_grp.append(rs) _temp = int(s.bandlimits.limit_850M_rx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_850M_rx_stop", "850M Rx Upper Limit (+ .9975 MHz)", val) rxlim_grp.append(rs) if self.MODEL == "KG-UV980P": _temp = int(s.bandlimits.limit_144M_tx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_144M_tx_start", "144M Tx Lower Limit (MHz)", val) txlim_grp.append(rs) _temp = int(s.bandlimits.limit_144M_tx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_144M_tx_stop", "144M Tx Upper Limit (+ .9975 MHz)", val) txlim_grp.append(rs) _temp = int(s.bandlimits.limit_70cm_tx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_70cm_tx_start", "450M Tx Lower Limit (MHz)", val) txlim_grp.append(rs) _temp = int(s.bandlimits.limit_70cm_tx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_70cm_tx_stop", "450M tx Upper Limit (+ .9975 MHz)", val) txlim_grp.append(rs) if self.MODEL == "KG-UV980P": _temp = int(s.bandlimits.limit_10m_tx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_10m_tx_start", "20M tx Lower Limit (MHz)", val) txlim_grp.append(rs) _temp = int(s.bandlimits.limit_10m_tx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_10m_tx_stop", "20M tx Upper Limit (+ .9975 MHz)", val) txlim_grp.append(rs) _temp = int(s.bandlimits.limit_6m_tx_start) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_6m_tx_start", "50M tx Lower Limit (MHz)", val) txlim_grp.append(rs) _temp = int(s.bandlimits.limit_6m_tx_stop) // 10 val = RadioSettingValueInteger(0, 999, _temp) rs = RadioSetting("bandlimits.limit_6m_tx_stop", "50M tx Upper Limit (+ .9975 MHz)", val) txlim_grp.append(rs) # VFO Settings rs = RadioSetting("vfomode_a", "Working Mode", RadioSettingValueMap(wmmap, _settings.vfomode_a)) vfoa_grp.append(rs) rs = RadioSetting("vfoband_a", "Current Band", RadioSettingValueMap(VFOBAND_MAP, _settings.vfoband_a)) vfoa_grp.append(rs) rs = RadioSetting("vfochan_a", "Active/Work Channel", RadioSettingValueInteger(1, 999, _chnum_decode( _settings.vfochan_a))) vfoa_grp.append(rs) rs = RadioSetting("vfosquelch_a", "Squelch", RadioSettingValueInteger(0, 9, _settings.vfosquelch_a)) vfoa_grp.append(rs) rs = RadioSetting("vfostep_a", "Step", RadioSettingValueList( STEP_LIST, STEP_LIST[_settings.vfostep_a])) vfoa_grp.append(rs) # ##################### rs = RadioSetting("vfofreq1", "150M Freq", RadioSettingValueFloat( 0, 999.999999, (_freq_decode (_settings.vfofreq1) / 1000000.0), 0.000001, 6)) vfo150_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("vfoofst1", "150M Offset", RadioSettingValueFloat( 0, 999.999999, (_freq_decode (_settings.vfoofst1) / 1000000.0), 0.000001, 6)) vfo150_grp.append(rs) rs = RadioSetting("rxtone1", "150M Rx tone", RadioSettingValueMap( TONE_MAP, _settings.rxtone1)) vfo150_grp.append(rs) rs = RadioSetting("txtone1", "150M Tx tone", RadioSettingValueMap( TONE_MAP, _settings.txtone1)) vfo150_grp.append(rs) rs = RadioSetting("power1", "150M Power", RadioSettingValueMap( POWER_MAP, _settings.power1)) vfo150_grp.append(rs) rs = RadioSetting("narrow1", narrow1label, RadioSettingValueMap( BANDWIDTH_MAP, _settings.narrow1)) vfo150_grp.append(rs) rs = RadioSetting("mute1", mute1label, RadioSettingValueMap( MUTE_MODE_MAP, _settings.mute1)) vfo150_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("shft_dir1", "150M Repeater", RadioSettingValueBoolean( _settings.shft_dir1)) else: rs = RadioSetting("shft_dir1", "150M Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_settings.shft_dir1])) vfo150_grp.append(rs) rs = RadioSetting("compander1", "150M Compander", RadioSettingValueBoolean( _settings.compander1)) vfo150_grp.append(rs) rs = RadioSetting("scrambler1", scram1label, RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[_settings.scrambler1])) vfo150_grp.append(rs) rs = RadioSetting("am_mode1", "150M AM Mode", RadioSettingValueBoolean( _settings.am_mode1)) vfo150_grp.append(rs) # ########################### rs = RadioSetting("vfofreq2", "450M Freq", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfofreq2) / 1000000.0), 0.000001, 6)) vfo450_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("vfoofst2", "450M Offset", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfoofst2) / 1000000.0), 0.000001, 6)) vfo450_grp.append(rs) rs = RadioSetting("rxtone2", "450M Rx tone", RadioSettingValueMap( TONE_MAP, _settings.rxtone2)) vfo450_grp.append(rs) rs = RadioSetting("txtone2", "450M Tx tone", RadioSettingValueMap( TONE_MAP, _settings.txtone2)) vfo450_grp.append(rs) rs = RadioSetting("power2", "450M Power", RadioSettingValueMap( POWER_MAP, _settings.power2)) vfo450_grp.append(rs) rs = RadioSetting("narrow2", narrow2label, RadioSettingValueMap( BANDWIDTH_MAP, _settings.narrow2)) vfo450_grp.append(rs) rs = RadioSetting("mute2", mute2label, RadioSettingValueMap( MUTE_MODE_MAP, _settings.mute2)) vfo450_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("shft_dir2", "450M Repeater", RadioSettingValueBoolean( _settings.shft_dir2)) else: rs = RadioSetting("shft_dir2", "450M Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_settings.shft_dir2])) vfo450_grp.append(rs) rs = RadioSetting("compander2", "450M Compander", RadioSettingValueBoolean( _settings.compander2)) vfo450_grp.append(rs) rs = RadioSetting("scrambler2", scram2label, RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[_settings.scrambler2])) vfo450_grp.append(rs) rs = RadioSetting("am_mode2", "450M AM Mode", RadioSettingValueBoolean( _settings.am_mode2)) vfo450_grp.append(rs) # ########################### if self.MODEL == "KG-UV980P": rs = RadioSetting("vfofreq3", "20M Freq", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfofreq3) / 1000000.0), 0.000001, 6)) vfo20_grp.append(rs) if self.MODEL == "KG-UV980P": rs = RadioSetting("vfoofst3", "20M Offset", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfoofst3) / 1000000.0), 0.000001, 6)) vfo20_grp.append(rs) rs = RadioSetting("rxtone3", "20M Rx tone", RadioSettingValueMap( TONE_MAP, _settings.rxtone3)) vfo20_grp.append(rs) rs = RadioSetting("txtone3", "20M Tx tone", RadioSettingValueMap( TONE_MAP, _settings.txtone3)) vfo20_grp.append(rs) rs = RadioSetting("power3", "20M Power", RadioSettingValueMap( POWER_MAP, _settings.power3)) vfo20_grp.append(rs) rs = RadioSetting("narrow3", narrow3label, RadioSettingValueMap( BANDWIDTH_MAP, _settings.narrow3)) vfo20_grp.append(rs) rs = RadioSetting("mute3", mute3label, RadioSettingValueMap( MUTE_MODE_MAP, _settings.mute3)) vfo20_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("shft_dir3", "20M Repeater", RadioSettingValueBoolean( _settings.shft_dir3)) else: rs = RadioSetting("shft_dir3", "20M Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_settings.shft_dir3])) vfo20_grp.append(rs) rs = RadioSetting("compander3", "20M Compander", RadioSettingValueBoolean( _settings.compander3)) vfo20_grp.append(rs) rs = RadioSetting("scrambler3", scram3label, RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[_settings.scrambler3])) vfo20_grp.append(rs) rs = RadioSetting("am_mode3", "20M AM Mode", RadioSettingValueBoolean( _settings.am_mode3)) vfo20_grp.append(rs) # ########################### rs = RadioSetting("vfofreq4", "50M Freq", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfofreq4) / 1000000.0), 0.000001, 6)) vfo50_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("vfoofst4", "50M Offset", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfoofst4) / 1000000.0), 0.000001, 6)) vfo50_grp.append(rs) rs = RadioSetting("rxtone4", "50M Rx tone", RadioSettingValueMap( TONE_MAP, _settings.rxtone4)) vfo50_grp.append(rs) rs = RadioSetting("txtone4", "50M Tx tone", RadioSettingValueMap( TONE_MAP, _settings.txtone4)) vfo50_grp.append(rs) rs = RadioSetting("power4", "50M Power", RadioSettingValueMap( POWER_MAP, _settings.power4)) vfo50_grp.append(rs) rs = RadioSetting("narrow4", narrow4label, RadioSettingValueMap( BANDWIDTH_MAP, _settings.narrow4)) vfo50_grp.append(rs) rs = RadioSetting("mute4", mute4label, RadioSettingValueMap( MUTE_MODE_MAP, _settings.mute4)) vfo50_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("shft_dir4", "50M Repeater", RadioSettingValueBoolean( _settings.shft_dir4)) else: rs = RadioSetting("shft_dir4", "50M Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_settings.shft_dir4])) vfo50_grp.append(rs) rs = RadioSetting("compander4", "50M Compander", RadioSettingValueBoolean( _settings.compander4)) vfo50_grp.append(rs) rs = RadioSetting("scrambler4", scram4label, RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[_settings.scrambler4])) vfo50_grp.append(rs) rs = RadioSetting("am_mode4", "50M AM Mode", RadioSettingValueBoolean( _settings.am_mode4)) vfo50_grp.append(rs) # ########################### rs = RadioSetting("vfofreq5", "350M Freq", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfofreq5) / 1000000.0), 0.000001, 6)) vfo350_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("vfoofst5", "350M Offset", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfoofst5) / 1000000.0), 0.000001, 6)) vfo350_grp.append(rs) rs = RadioSetting("rxtone5", "350M Rx tone", RadioSettingValueMap( TONE_MAP, _settings.rxtone5)) vfo350_grp.append(rs) rs = RadioSetting("txtone5", "350M Tx tone", RadioSettingValueMap( TONE_MAP, _settings.txtone5)) vfo350_grp.append(rs) rs = RadioSetting("power5", "350M Power", RadioSettingValueMap( POWER_MAP, _settings.power5)) vfo350_grp.append(rs) rs = RadioSetting("narrow5", narrow5label, RadioSettingValueMap( BANDWIDTH_MAP, _settings.narrow5)) vfo350_grp.append(rs) rs = RadioSetting("mute5", mute5label, RadioSettingValueMap( MUTE_MODE_MAP, _settings.mute5)) vfo350_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("shft_dir5", "350M Repeater", RadioSettingValueBoolean( _settings.shft_dir5)) else: rs = RadioSetting("shft_dir5", "350M Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_settings.shft_dir5])) vfo350_grp.append(rs) rs = RadioSetting("compander5", "350M Compander", RadioSettingValueBoolean( _settings.compander5)) vfo350_grp.append(rs) rs = RadioSetting("scrambler5", scram5label, RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[_settings.scrambler5])) vfo350_grp.append(rs) rs = RadioSetting("am_mode5", "350M AM Mode", RadioSettingValueBoolean( _settings.am_mode5)) vfo350_grp.append(rs) # ############################ rs = RadioSetting("vfofreq6", "850M Freq", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfofreq6) / 1000000.0), 0.000001, 6)) vfo850_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("vfoofst6", "850M Offset", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfoofst6) / 1000000.0), 0.000001, 6)) vfo850_grp.append(rs) rs = RadioSetting("rxtone6", "850M Rx tone", RadioSettingValueMap( TONE_MAP, _settings.rxtone6)) vfo850_grp.append(rs) rs = RadioSetting("txtone6", "850M Tx tone", RadioSettingValueMap( TONE_MAP, _settings.txtone6)) vfo850_grp.append(rs) rs = RadioSetting("power6", "850M Power", RadioSettingValueMap( POWER_MAP, _settings.power6)) vfo850_grp.append(rs) rs = RadioSetting("narrow6", narrow6label, RadioSettingValueMap( BANDWIDTH_MAP, _settings.narrow6)) vfo850_grp.append(rs) rs = RadioSetting("mute6", mute6label, RadioSettingValueMap( MUTE_MODE_MAP, _settings.mute6)) vfo850_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("shft_dir6", "850M Repeater", RadioSettingValueBoolean( _settings.shft_dir6)) else: rs = RadioSetting("shft_dir6", "850M Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_settings.shft_dir6])) vfo850_grp.append(rs) rs = RadioSetting("compander6", "850M Compander", RadioSettingValueBoolean( _settings.compander6)) vfo850_grp.append(rs) rs = RadioSetting("scrambler6", scram6label, RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[_settings.scrambler6])) vfo850_grp.append(rs) rs = RadioSetting("am_mode6", "850M AM Mode", RadioSettingValueBoolean( _settings.am_mode6)) vfo850_grp.append(rs) # ########################### rs = RadioSetting("vfomode_b", "Working Mode", RadioSettingValueMap(wmmap, _settings.vfomode_b)) vfob_grp.append(rs) rs = RadioSetting("vfochan_b", "Active/Work Channel", RadioSettingValueInteger(1, 999, _chnum_decode( _settings.vfochan_b))) vfob_grp.append(rs) rs = RadioSetting("vfofreq7", "Freq", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfofreq7) / 1000000.0), 0.000001, 6)) vfob_grp.append(rs) if self.MODEL != "KG-1000G Plus": rs = RadioSetting("vfoofst7", "Offset", RadioSettingValueFloat( 0, 999.999999, (_freq_decode( _settings.vfoofst7) / 1000000.0), 0.000001, 6)) vfob_grp.append(rs) rs = RadioSetting("rxtone7", "Rx tone", RadioSettingValueMap( TONE_MAP, _settings.rxtone7)) vfob_grp.append(rs) rs = RadioSetting("txtone7", "Tx tone", RadioSettingValueMap( TONE_MAP, _settings.txtone7)) vfob_grp.append(rs) rs = RadioSetting("power7", "Power", RadioSettingValueMap( POWER_MAP, _settings.power7)) vfob_grp.append(rs) rs = RadioSetting("narrow7", narrow7label, RadioSettingValueMap( BANDWIDTH_MAP, _settings.narrow7)) vfob_grp.append(rs) rs = RadioSetting("mute7", mute7label, RadioSettingValueMap( MUTE_MODE_MAP, _settings.mute7)) vfob_grp.append(rs) if self.MODEL == "KG-1000G Plus": rs = RadioSetting("shft_dir7", "Repeater", RadioSettingValueBoolean( _settings.shft_dir7)) else: rs = RadioSetting("shft_dir7", "Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_settings.shft_dir7])) vfob_grp.append(rs) rs = RadioSetting("compander7", "Compander", RadioSettingValueBoolean( _settings.compander7)) vfob_grp.append(rs) rs = RadioSetting("scrambler7", scram7label, RadioSettingValueList( SCRAMBLER_LIST, SCRAMBLER_LIST[_settings.scrambler7])) vfob_grp.append(rs) rs = RadioSetting("vfosquelch_b", "Squelch", RadioSettingValueInteger(0, 9, _settings.vfosquelch_b)) vfob_grp.append(rs) rs = RadioSetting("vfostep_b", "Step", RadioSettingValueList( STEP_LIST, STEP_LIST[_settings.vfostep_b])) vfob_grp.append(rs) # Scan Group Settings def _decode(lst): LOG.debug("lst %s", lst) _str = ''.join([chr(c) for c in lst if chr(c) in SCANNAME_CHARSET]) return _str rs = RadioSetting("scan_a_act", "Scan A Active Group", RadioSettingValueList( SCAN_GROUP_LIST, SCAN_GROUP_LIST[_settings.scan_a_act])) scan_grp.append(rs) rs = RadioSetting("scan_b_act", "Scan B Active Group", RadioSettingValueList( SCAN_GROUP_LIST, SCAN_GROUP_LIST[_settings.scan_b_act])) scan_grp.append(rs) for i in range(1, 11): x = str(i) _str = _decode(getattr(_settings, 'scanname%s' % x)) LOG.debug("ScanName %s", i) LOG.debug("is %s", _str) # CPS treats PPPPPP as a blank name as it is the factory reset # value" # The Radio treats PPPPPPP as a blank name and can display 8 # chars" # Force Chirp to blank out the scan name if value is PPPPPPP # to match the radio" # Blank out the name if first 6 are spaces or null and the # 7th is a P to handle # firmware peculiarities in handling all 8 characters. if _str[0:7] == "PPPPPPP": _str = "" if self.MODEL != "KG-1000G Plus": if _str[0:7] == "\x00\x00\x00\x00\x00\x00P": _str = "" elif _str[0:7] == "\x20\x20\x20\x20\x20\x20P": _str = "" else: if _str[0:6] == "\x00\x00\x00\x00\x00\x00": _str = "" elif _str[0:6] == "\x20\x20\x20\x20\x20\x20": _str = "" elif (len(_str) == 2) & (_str[0:2] == "PP"): _str = "" rs = RadioSetting("scanname" + x, "Scan Name " + x, RadioSettingValueString(0, 8, _str)) scanname_grp.append(rs) val = getattr(_settings, 'scanlower%i' % i) rs = RadioSetting("scanlower%i" % i, "Scan Lower %i" % i, RadioSettingValueInteger(1, 999, val)) scan_grp.append(rs) val = getattr(_settings, 'scanupper%i' % i) rs = RadioSetting("scanupper%i" % i, "Scan Upper %i" % i, RadioSettingValueInteger(1, 999, val)) scan_grp.append(rs) # remote settings rs = RadioSetting("rc_power", "RC Power", RadioSettingValueList( RC_POWER_LIST, RC_POWER_LIST[_settings.rc_power])) remote_grp.append(rs) def decode_remote_vals(self, setting): # parse the id value and replace all C with empty # C indicates the end of the id value code = ('%06X' % int(setting)).replace('C', '') return int(code), code def apply_remote_id(setting, obj, val): val = str(val) value = int(val.ljust(3, '0').ljust(6, 'C'), 16) setattr(obj, setting.get_name(), value) val_ani, code_val = decode_remote_vals(self, _settings.ani_edit) LOG.debug("ani = %s" % val_ani) val_ani = RadioSettingValueString(3, 6, code_val, False) val_ani.set_charset(dtmfchars) rs = RadioSetting("settings.ani_edit", "ANI Edit", val_ani) def apply_ani_id(setting, obj): LOG.debug("val= %s" % val_ani) if str(val_ani)[0] == "0": raise errors.RadioError("ANI EDIT must start with \ Non-Zero Digit") val = str(val_ani) value = int(val.ljust(3, '0').ljust(6, 'C'), 16) obj.ani_edit = value rs.set_apply_callback(apply_ani_id, _settings) remote_grp.append(rs) val_mcc, code_val = decode_remote_vals(self, _settings.mcc_edit) LOG.debug("mcc = %s" % val_mcc) val_mcc = RadioSettingValueString(3, 6, code_val, False) val_mcc.set_charset(dtmfchars) rs = RadioSetting("mcc_edit", "MCC Edit", val_mcc) rs.set_apply_callback(apply_remote_id, _settings, val_mcc) remote_grp.append(rs) val_scc, code_val = decode_remote_vals(self, _settings.scc_edit) LOG.debug("scc = %s" % val_scc) val_scc = RadioSettingValueString(3, 6, code_val, False) val_scc.set_charset(dtmfchars) rs = RadioSetting("scc_edit", "SCC Edit", val_scc) rs.set_apply_callback(apply_remote_id, _settings, val_scc) remote_grp.append(rs) val_ctrl, code_val = decode_remote_vals(self, _settings.ctrl_edit) LOG.debug("ctrl = %s" % val_ctrl) val_ctrl = RadioSettingValueString(3, 6, code_val, False) val_ctrl.set_charset(dtmfchars) rs = RadioSetting("ctrl_edit", "CTRL Edit", val_ctrl) rs.set_apply_callback(apply_remote_id, _settings, val_ctrl) remote_grp.append(rs) # OEM Settings if self.MODEL != "KG-1000G Plus": _oem_name = _oem_str_decode(self._memobj.oem.display_name) else: displayname = self._memobj.oem.display_name _oem_name = _oem_str_decode_1000GPLUS(displayname) rs = RadioSetting("oem.display_name", "Area Message", RadioSettingValueString(1, 8, _oem_name)) oem_grp.append(rs) # FM RADIO PRESETS # memory stores raw integer value like 7600 # radio will divide 7600 by 100 and interpret correctly at 76.0 MHz for i in range(1, 21): # chan = str(i) fmname = "FM_radio%i" % i fmlabel = "FM Preset %i" % i fmvalue = getattr(_settings, fmname) # some CPS versions store values with .01 MHz in error # eg 99.5 MHz is stored as 0x26df = 9951 dec = 99.51 MHz # even though the radio properly displays 99.5 # this will drop the 0.01 MHz for Chirp Displayed values fmvalue = fmvalue // 10 / 10 rs = RadioSetting(fmname, fmlabel, RadioSettingValueFloat(76.0, 108.0, fmvalue, 0.1, 1)) fmradio_grp.append(rs) return group def get_settings(self): try: return self._get_settings() except Exception: LOG.exception("Failed to parse settings: %s") return None def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) if self._is_freq(element): # rescale freq values to match radio # expected values value = _freq_encode( element[0].get_value()*1000000.0) setattr(obj, setting, value) elif self._is_fmradio_or_voltage(element): # rescale FM Radio values to match radio # expected values setattr(obj, setting, int(element.values()[0]._current * 100.0)) elif self._is_limit(element): setattr(obj, setting, int(element[0].get_value()) * 10) # Special VFO A Settings # elif self._is_chan(element): value = _chnum_encode(element[0].get_value()) setattr(obj, setting, value) continue elif self._is_display_name(element): string = element[0].get_value() if self.MODEL != "KG-1000G Plus": nameenc = _oem_str_encode(string) else: nameenc = _oem_str_encode_1000GPLUS(string) for i in range(0, 8): LOG.debug("nameenc %s" % (nameenc[i])) self._memobj.oem.display_name[i] = \ ord(nameenc[i]) elif self._is_scan_name(element): string = element[0].get_value() LOG.debug("string %s" % (string)) value = _str_encode(string) LOG.debug("scaname %s" % (value)) setattr(obj, setting, value.encode()) else: setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _is_freq(self, element): return ("rxfreq" in element.get_name() or "txoffset" in element.get_name() or "vfofreq" in element.get_name() or "vfoofst" in element.get_name()) def _is_limit(self, element): return "limit" in element.get_name() def _is_fmradio_or_voltage(self, element): return ("FM_radio" in element.get_name() or "thr_vol_lvl" in element.get_name()) def _is_chan(self, element): return ("vfochan" in element.get_name() or "pri_ch" in element.get_name()) def _is_display_name(self, element): return "display_name" in element.get_name() def _is_scan_name(self, element): return "scanname" in element.get_name() @directory.register class KG1000GRadio(KG980PRadio): # """Wouxun KG-1000G""" VENDOR = "Wouxun" MODEL = "KG-1000G" @directory.register class KG1000GPlusRadio(KG980PRadio): # """Wouxun KG-1000G Plus""" VENDOR = "Wouxun" MODEL = "KG-1000G Plus" chirp-20240224/chirp/drivers/icv80.py0000644000175000017500000003640314561124165016135 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import icf from chirp import chirp_common, bitwise, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean, \ RadioSettings LOG = logging.getLogger(__name__) ICV80_MEM_FORMAT = """ struct { ul16 freq; ul16 offset; char name[5]; u8 unknown0:2, rtone:6; u8 unknown1:2, ctone:6; u8 unknown2:1, dtcs:7; u8 unknown3:5, tuning_step:3; u8 unknown4:2, mode:1, reverse_duplex:1, duplex:2, mult:2; u8 unknown6:2, dtcs_polarity:2, unknown8:2, tmode:2; u8 unknown9:5, tx_inhibit:1, power:2; } memory[207]; u8 skip[32]; u8 unused[32]; #seekto 0x0e50; struct { u8 unknown1:6, beep:2; u8 unknown2:3, tot:5; u8 unknown3; u8 unknown4:6, auto_pwr_off:2; u8 unknown5:6, lockout:2; u8 unknown6:7, squelch_delay:1; u8 unknown7_0; u8 unknown7_1:6, mem_display1:2; u8 unknown8:6, mem_display2:2; // CS stores the display value here as well u8 unknown9:7, dial_func:1; u8 unknown10:7, lcd:1; u8 unknown11:5, pwr_save:3; u8 unknown12:7, sel_speed:1; u8 unknown13:6, mic_mode:2; u8 unknown14:6, battery_save:2; u8 unknown15; u8 unknown16:6, resume:2; u8 unknown17:5, func_mode:3; u8 unknown18:6, backlight:2; u8 unknown19; u8 unknown:4, vox_gain:4; u8 unknown20:6, mic_gain:2; u8 unknown21:5, vox_delay:3; u8 unknown22:4, vox_tot:4; u8 unknown23[2]; u8 unknown24:6, edge:2; u8 unknown25; u8 unknown26:7, auto_low_pwr:1; u8 unknown27[3]; } settings; """ SPECIAL_CHANNELS = { "1A": 200, "1B": 201, "2A": 202, "2B": 203, "3A": 204, "3B": 205, "C": 206, } TMODES = ["", "Tone", "TSQL", "DTCS"] MODES = ["FM", "NFM"] SKIPS = ["", "S"] DUPLEXES = ["", "-", "+"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] TUNING_STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0] POWER_LEVELS = [ chirp_common.PowerLevel("High", watts=5.5), chirp_common.PowerLevel("Low", watts=0.5), chirp_common.PowerLevel("Mid", watts=2.5) ] @directory.register class ICV80Radio(icf.IcomCloneModeRadio, chirp_common.ExperimentalRadio): """Icom IC-V80""" VENDOR = "Icom" MODEL = "IC-V80" _model = "\x32\x54\x00\x01" _memsize = 0x0E80 _endframe = "Icom Inc\x2e7C" _can_hispeed = True _ranges = [(0x0000, 0x0CE0, 32), (0x0CE0, 0x0D40, 16), (0x0D40, 0x0E00, 32), (0x0E00, 0x0E20, 16), (0x0E20, 0x0E60, 32), (0x0E60, 0x0E70, 16), (0x0E70, 0x0E72, 2), (0x0E72, 0x0E77, 5), (0x0E77, 0x0E78, 1), (0x0E78, 0x0E80, 8), ] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is currently under development, " "and not all the features or functions may work as" "expected. You should proceed with caution.") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.valid_modes = MODES rf.valid_tmodes = TMODES rf.valid_duplexes = DUPLEXES rf.valid_tuning_steps = TUNING_STEPS rf.valid_power_levels = POWER_LEVELS rf.valid_skips = SKIPS rf.valid_name_length = 5 rf.valid_special_chans = sorted(SPECIAL_CHANNELS.keys()) rf.valid_bands = [(136000000, 174000000)] rf.has_ctone = True rf.has_offset = True rf.has_bank = False rf.has_settings = True return rf def process_mmap(self): self._memobj = bitwise.parse(ICV80_MEM_FORMAT, self._mmap) def get_settings(self): _settings = self._memobj.settings setmode = RadioSettingGroup("setmode", "Set Mode") display = RadioSettingGroup("display", "Display") sounds = RadioSettingGroup("sounds", "Sounds") scan = RadioSettingGroup("scan", "Scan") settings = RadioSettings(setmode, display, sounds, scan) # TOT opts = ["Off"] + ["%d min" % t for t in range(1, 31)] setmode.append( RadioSetting( "tot", "Time out Timer", RadioSettingValueList(opts, opts[_settings.tot]))) # Lockout opts = ["Off", "Rpt", "Busy"] setmode.append( RadioSetting( "lockout", "Lockout", RadioSettingValueList(opts, opts[_settings.lockout]))) # Auto Power Off opts = ["Off", "30 min", "1 hr", "2 hrs"] setmode.append( RadioSetting( "auto_pwr_off", "Auto Power Off", RadioSettingValueList(opts, opts[_settings.auto_pwr_off]))) # Power Save opts = ["Off", "1:2", "1:8", "1:16", "Auto"] setmode.append( RadioSetting( "pwr_save", "Power Save", RadioSettingValueList(opts, opts[_settings.pwr_save]))) # Battery Save opts = ["Off", "Ni-MH", "Li-Ion"] setmode.append( RadioSetting( "battery_save", "Battery Save", RadioSettingValueList(opts, opts[_settings.battery_save]))) # Auto Low Power opts = ["Off", "On"] setmode.append( RadioSetting( "auto_low_pwr", "Auto Low Power", RadioSettingValueList(opts, opts[_settings.auto_low_pwr]))) # Squelch Delay opts = ["Short", "Long"] setmode.append( RadioSetting( "squelch_delay", "Squelch Delay", RadioSettingValueList(opts, opts[_settings.squelch_delay]))) # MIC Simple Mode opts = ["Simple", "Normal 1", "Normal 2"] setmode.append( RadioSetting( "mic_mode", "Mic Simple Mode", RadioSettingValueList(opts, opts[_settings.mic_mode]))) # MIC Gain opts = ["1", "2", "3", "4"] setmode.append( RadioSetting( "mic_gain", "Mic Gain", RadioSettingValueList(opts, opts[_settings.mic_gain]))) # VOX Gain opts = ["Off"] + ["%d" % t for t in range(1, 11)] setmode.append( RadioSetting( "vox_gain", "VOX Gain", RadioSettingValueList(opts, opts[_settings.vox_gain]))) # VOX Delay opts = ["0.5 sec", "1.0 sec", "1.5 sec", "2.0 sec", "2.5 sec", "3.0 sec"] setmode.append( RadioSetting( "vox_delay", "VOX Delay", RadioSettingValueList(opts, opts[_settings.vox_delay]))) # VOX Time out Timer opts = ["Off", "1 min", "2 min", "3 min", "4 min", "5 min", "10 min", "15 min"] setmode.append( RadioSetting( "vox_tot", "VOX Time-Out Timer", RadioSettingValueList(opts, opts[_settings.vox_tot]))) # Select Speed opts = ["Manual", "Auto"] setmode.append( RadioSetting( "sel_speed", "Select Speed", RadioSettingValueList(opts, opts[_settings.sel_speed]))) # Dial Function opts = ["Audio Volume", "Tuning Dial"] setmode.append( RadioSetting( "dial_func", "Dial Function", RadioSettingValueList(opts, opts[_settings.dial_func]))) # Function Mode opts = ["0 sec", "1 sec", "2 sec", "3 sec", "Manual"] setmode.append( RadioSetting( "func_mode", "Function Mode", RadioSettingValueList(opts, opts[_settings.func_mode]))) # Backlight opts = ["Off", "On", "Auto"] display.append( RadioSetting( "backlight", "Backlight", RadioSettingValueList(opts, opts[_settings.backlight]))) # LCD Contrast opts = ["Low", "Auto"] display.append( RadioSetting( "lcd", "LCD Contrast", RadioSettingValueList(opts, opts[_settings.lcd]))) # Memory Display opts = ["Frequency", "Channel", "Name"] display.append( RadioSetting( "mem_display1", "Memory Display", RadioSettingValueList(opts, opts[_settings.mem_display1]))) # Beep opts = ["Off", "1", "2", "3"] sounds.append( RadioSetting( "beep", "Beep", RadioSettingValueList(opts, opts[_settings.beep]))) # Edge opts = ["All", "P1", "P2", "P3"] scan.append( RadioSetting( "edge", "Edge", RadioSettingValueList(opts, opts[_settings.edge]))) # Resume opts = ["T-5", "T-10", "T-15", "P-2"] scan.append( RadioSetting( "resume", "Resume", RadioSettingValueList(opts, opts[_settings.resume]))) return settings def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: setting = element.get_name() LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(_settings, setting, element.value) # This appears to need to be mirrored? if element.get_name() == 'mem_display1': _settings.mem_display2 = _settings.mem_display1 except Exception: LOG.debug(element.get_name()) raise def _get_memory(self, number, extd_number=None): bit = 1 << (number % 8) byte = number // 8 _mem = self._memobj.memory[number] _unused = self._memobj.unused[byte] _skip = self._memobj.skip[byte] mem = chirp_common.Memory(number) if extd_number is not None: mem.extd_number = extd_number mem.immutable = ["name", "number", "extd_number", "skip"] if extd_number == "C": _unused = False if (_unused & bit): mem.empty = True return mem if int(_mem.mult): mult = 6250 else: mult = 5000 mem.freq = int(_mem.freq) * mult mem.offset = int(_mem.offset) * mult if mem.extd_number == "": mem.name = str(_mem.name).rstrip() mem.skip = (_skip & bit) and "S" or "" mem.duplex = DUPLEXES[_mem.duplex] mem.power = POWER_LEVELS[_mem.power] mem.tuning_step = TUNING_STEPS[_mem.tuning_step] mem.mode = MODES[_mem.mode] mem.tmode = TMODES[_mem.tmode] mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] # Reverse duplex mem.extra = RadioSettingGroup("extra", "Extra") rev = RadioSetting("reverse_duplex", "Reverse duplex", RadioSettingValueBoolean(bool(_mem.reverse_duplex))) rev.set_doc("Reverse duplex") mem.extra.append(rev) # Tx inhibit tx_inhibit = RadioSetting("tx_inhibit", "TX inhibit", RadioSettingValueBoolean( bool(not _mem.tx_inhibit))) tx_inhibit.set_doc("TX inhibit") mem.extra.append(tx_inhibit) return mem def get_memory(self, number): extd_number = None if isinstance(number, str): try: extd_number = number number = SPECIAL_CHANNELS[number] except KeyError: raise errors.InvalidMemoryLocation( "Unknown channel %s" % number) return self._get_memory(number, extd_number) def _fill_memory(self, mem): number = mem.number _mem = self._memobj.memory[number] # zero-fill _mem.freq = 146010000 // 5000 _mem.offset = 600000 // 5000 _mem.name = str("").ljust(5) _mem.duplex = 0x0 _mem.reverse_duplex = 0x0 _mem.tx_inhibit = 0x1 _mem.power = 0x0 _mem.tuning_step = 0x0 _mem.mode = 0x0 _mem.tmode = 0x0 _mem.rtone = 0x8 _mem.ctone = 0x8 _mem.dtcs = 0x0 _mem.dtcs_polarity = 0x0 for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def set_memory(self, mem): bit = 1 << (mem.number % 8) byte = mem.number // 8 _mem = self._memobj.memory[mem.number] _unused = self._memobj.unused[byte] _skip = (mem.extd_number == "") and self._memobj.skip[byte] or None assert (_mem) if mem.empty: self._fill_memory(mem) _unused |= bit if _skip is not None: _skip |= bit return _mem.set_raw(b'\x00' * 16) if chirp_common.required_step(mem.freq) == 12.5: mult = 6250 else: mult = 5000 _mem.mult = 0 if mult == 5000 else 3 _mem.freq = mem.freq // mult _mem.offset = int(mem.offset) // mult _mem.name = str(mem.name).ljust(5) _mem.duplex = DUPLEXES.index(mem.duplex) power = mem.power or POWER_LEVELS[0] _mem.power = POWER_LEVELS.index(power) _mem.tuning_step = TUNING_STEPS.index(mem.tuning_step) _mem.mode = MODES.index(mem.mode) _mem.tmode = TMODES.index(mem.tmode) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.dtcs_polarity = DTCS_POLARITY.index(mem.dtcs_polarity) # Set used _unused &= ~bit # Set skip if _skip is not None: if mem.skip == "S": _skip |= bit else: _skip &= ~bit if mem.extra: _mem.tx_inhibit = not mem.extra['tx_inhibit'].value _mem.reverse_duplex = mem.extra['reverse_duplex'].value def get_raw_memory(self, number): return repr(self._memobj.memory[number]) chirp-20240224/chirp/drivers/ic2720.py0000644000175000017500000001253114430171343016101 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, directory, bitwise MEM_FORMAT = """ struct { u32 freq; u32 offset; u8 unknown1:2, rtone:6; u8 unknown2:2, ctone:6; u8 unknown3:1, dtcs:7; u8 unknown4:2, unknown5:2, tuning_step:4; u8 unknown6:2, tmode:2, duplex:2, unknown7:2; u8 power:2, is_fm:1, unknown8:1, dtcs_polarity:2, unknown9:2; u8 unknown[2]; } memory[200]; #seekto 0x0E20; u8 skips[25]; #seekto 0x0EB0; u8 used[25]; #seekto 0x0E40; struct { u8 bank_even:4, bank_odd:4; } banks[100]; """ TMODES = ["", "Tone", "TSQL", "DTCS"] POWER = ["High", "Low", "Med"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] STEPS = [5.0, 10.0, 12.5, 15, 20, 25, 30, 50] MODES = ["FM", "AM"] DUPLEX = ["", "", "-", "+"] POWER_LEVELS_VHF = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=15)] POWER_LEVELS_UHF = [chirp_common.PowerLevel("High", watts=35), chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=15)] @directory.register class IC2720Radio(icf.IcomCloneModeRadio): """Icom IC-2720""" VENDOR = "Icom" MODEL = "IC-2720H" _model = "\x24\x92\x00\x01" _memsize = 5152 _endframe = "Icom Inc\x2eA0" _ranges = [(0x0000, 0x1400, 32)] def _get_bank(self, loc): _bank = self._memobj.banks[loc / 2] if loc % 2: bank = _bank.bank_odd else: bank = _bank.bank_even if bank == 0x0A: return None else: return bank def _set_bank(self, loc, index): _bank = self._memobj.banks[loc / 2] if index is None: index = 0x0A if loc % 2: _bank.bank_odd = index else: _bank.bank_even = index def get_features(self): rf = chirp_common.RadioFeatures() rf.has_name = False rf.memory_bounds = (0, 199) rf.valid_modes = list(MODES) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(set(DUPLEX)) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(118000000, 999990000)] rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS_VHF return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): bitpos = (1 << (number % 8)) bytepos = (number / 8) _mem = self._memobj.memory[number] _skp = self._memobj.skips[bytepos] _usd = self._memobj.used[bytepos] mem = chirp_common.Memory() mem.number = number if _usd & bitpos: mem.empty = True return mem mem.freq = int(_mem.freq) mem.offset = int(_mem.offset) mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.tmode = TMODES[_mem.tmode] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.tuning_step = STEPS[_mem.tuning_step] mem.mode = _mem.is_fm and "FM" or "AM" mem.duplex = DUPLEX[_mem.duplex] mem.skip = (_skp & bitpos) and "S" or "" if int(mem.freq / 100000000) == 1: mem.power = POWER_LEVELS_VHF[_mem.power] else: mem.power = POWER_LEVELS_UHF[_mem.power] return mem def set_memory(self, mem): bitpos = (1 << (mem.number % 8)) bytepos = (mem.number / 8) _mem = self._memobj.memory[mem.number] _skp = self._memobj.skips[bytepos] _usd = self._memobj.used[bytepos] if mem.empty: _usd |= bitpos self._set_bank(mem.number, None) return _usd &= ~bitpos _mem.freq = mem.freq _mem.offset = mem.offset _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tmode = TMODES.index(mem.tmode) _mem.dtcs_polarity = DTCS_POLARITY.index(mem.dtcs_polarity) _mem.tuning_step = STEPS.index(mem.tuning_step) _mem.is_fm = mem.mode == "FM" _mem.duplex = DUPLEX.index(mem.duplex) if mem.skip == "S": _skp |= bitpos else: _skp &= ~bitpos if mem.power: _mem.power = POWER_LEVELS_VHF.index(mem.power) else: _mem.power = 0 chirp-20240224/chirp/drivers/ict8.py0000644000175000017500000001022514522657251016051 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, directory from chirp import bitwise mem_format = """ struct memory { bbcd freq[3]; bbcd offset[3]; u8 rtone; u8 ctone; }; struct flags { u8 empty:1, skip:1, tmode:2, duplex:2, unknown2:2; }; struct memory memory[100]; #seekto 0x0400; struct { char name[4]; } names[100]; #seekto 0x0600; struct flags flags[100]; """ DUPLEX = ["", "", "-", "+"] TMODES = ["", "", "Tone", "TSQL"] def _get_freq(bcd_array): lastnibble = bcd_array[2].get_bits(0x0F) return (int(bcd_array) - lastnibble) * 1000 + lastnibble * 500 def _set_freq(bcd_array, freq): bitwise.int_to_bcd(bcd_array, freq / 1000) bcd_array[2].set_raw(bcd_array[2].get_bits(0xF0) + freq % 10000 // 500) @directory.register class ICT8ARadio(icf.IcomCloneModeRadio): """Icom IC-T8A""" VENDOR = "Icom" MODEL = "IC-T8A" _model = "\x19\x03\x00\x01" _memsize = 0x07B0 _endframe = "Icom Inc\x2e" _ranges = [(0x0000, 0x07B0, 16)] def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_tmodes = TMODES rf.valid_duplexes = DUPLEX rf.valid_bands = [(50000000, 54000000), (118000000, 174000000), (400000000, 470000000)] rf.valid_skips = ["", "S"] rf.valid_modes = ["FM"] rf.memory_bounds = (0, 99) rf.valid_name_length = 4 rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC rf.has_dtcs = False rf.has_dtcs_polarity = False rf.valid_tuning_steps = [5, 10, 12.5, 15, 20, 25, 30, 50, 100] rf.has_tuning_step = False rf.has_mode = False rf.has_bank = False return rf def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): return (str(self._memobj.memory[number]) + str(self._memobj.names[number]) + str(self._memobj.flags[number])) def get_memory(self, number): _mem = self._memobj.memory[number] _flg = self._memobj.flags[number] _name = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number if _flg.empty: mem.empty = True return mem mem.freq = _get_freq(_mem.freq) mem.offset = _get_freq(_mem.offset) mem.rtone = chirp_common.TONES[_mem.rtone - 1] mem.ctone = chirp_common.TONES[_mem.ctone - 1] mem.duplex = DUPLEX[_flg.duplex] mem.tmode = TMODES[_flg.tmode] mem.skip = _flg.skip and "S" or "" if _name.name.get_raw(asbytes=False) != "\xFF\xFF\xFF\xFF": mem.name = str(_name.name).rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _flg = self._memobj.flags[mem.number] _name = self._memobj.names[mem.number] if mem.empty: _flg.empty = True return _mem.set_raw("\x00" * 8) _flg.set_raw("\x00") _set_freq(_mem.freq, mem.freq) _set_freq(_mem.offset, mem.offset) _mem.rtone = chirp_common.TONES.index(mem.rtone) + 1 _mem.ctone = chirp_common.TONES.index(mem.ctone) + 1 _flg.duplex = DUPLEX.index(mem.duplex) _flg.tmode = TMODES.index(mem.tmode) _flg.skip = mem.skip == "S" if mem.name: _name.name = mem.name.ljust(4) else: _name.name = "\xFF\xFF\xFF\xFF" chirp-20240224/chirp/drivers/ft7100.py0000644000175000017500000011514314522657251016130 0ustar hibbyhibby# Copyright 2011 Dan Smith # # FT-2900-specific modifications by Richard Cochran, # Initial work on settings by Chris Fosnight, # FT-7100-specific modifications by Bruno Maire, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging from chirp import util, memmap, chirp_common, bitwise, directory, errors from chirp.drivers.yaesu_clone import YaesuCloneModeRadio from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueString, RadioSettings, \ RadioSettingValueInteger, RadioSettingValueBoolean LOG = logging.getLogger(__name__) ACK = b"\x06" NB_OF_BLOCKS = 248 BLOCK_LEN = 32 def _send(pipe, data): time.sleep(0.035) # Same delay as "FT7100 Programmer" from RT Systems # pipe.write(data) --> It seems, that the single bytes are sent too fast # so send character per character with a delay for ch in data: pipe.write(bytes([ch])) time.sleep(0.0012) # 0.0011 is to short. No ACK after a few packets echo = pipe.read(len(data)) if data == b"": raise Exception("Failed to read echo." " Maybe serial hardware not connected." " Maybe radio not powered or not in receiving mode.") if data != echo: LOG.debug("expecting echo\n%s\n", util.hexprint(data)) LOG.debug("got echo\n%s\n", util.hexprint(echo)) raise Exception("Got false echo. Expected: %r, got: %r.", data, echo) def _send_ack(pipe): time.sleep(0.01) # Wait for radio input buffer ready # time.sleep(0.0003) is the absolute working minimum. # This delay is not critical for the transfer as there are not many ACKs. _send(pipe, ACK) def _wait_for_ack(pipe): echo = pipe.read(1) if echo == b"": raise Exception("Failed to read ACK. No response from radio.") if echo != ACK: raise Exception("Failed to read ACK. Expected: %r, got: %r.", ACK, echo) def _download(radio): LOG.debug("in _download\n") data = b"" for _i in range(0, 60): chunk = radio.pipe.read(BLOCK_LEN) data += chunk LOG.debug("Header:\n%s", util.hexprint(data)) if data == radio.IDBLOCK: break if len(data) > len(radio.IDBLOCK): break if data == b"": raise Exception("Got no data from radio.") if data != radio.IDBLOCK: raise Exception("Got false header. Expected: %r, got: %r." % ( radio.IDBLOCK, data)) _send_ack(radio.pipe) # read 16 Byte block # and ignore it because it is constant. This might be a bug. # It was built in at the very beginning and discovered very late that the # data might be necessary later to write to the radio. # Now the data is hardcoded in _upload(radio) data = radio.pipe.read(16) _send_ack(radio.pipe) LOG.debug('Magic 16-byte chunk:\n%s' % util.hexprint(data)) # initialize data, the big var that holds all memory data = b"" for block_nr in range(NB_OF_BLOCKS): chunk = radio.pipe.read(BLOCK_LEN) if len(chunk) != BLOCK_LEN: LOG.debug("Block %i ", block_nr) LOG.debug("Got: %i:\n%s", len(chunk), util.hexprint(chunk)) LOG.debug("len chunk is %i\n", len(chunk)) raise Exception("Failed to get full data block") else: data += chunk _send_ack(radio.pipe) if radio.status_fn: status = chirp_common.Status() status.max = NB_OF_BLOCKS * BLOCK_LEN status.cur = len(data) status.msg = "Cloning from radio" radio.status_fn(status) LOG.debug("Total: %i", len(data)) _send_ack(radio.pipe) # for debugging purposes, dump the channels, in hex. for _i in range(0, (NB_OF_BLOCKS * BLOCK_LEN) // 26): _start_data = 4 + 26 * _i chunk = data[_start_data:_start_data + 26] LOG.debug("channel %i:\n%s", _i-21, util.hexprint(chunk)) return memmap.MemoryMapBytes(data) def _upload(radio): data = radio.pipe.read(256) # Clear buffer _send(radio.pipe, radio.IDBLOCK) _wait_for_ack(radio.pipe) # write 16 Byte block # If there should be a problem, see remarks in _download(radio) _send(radio.pipe, b"\xEE\x77\x01\x00\x0E\x07\x0E\x07" b"\x00\x00\x00\x00\x00\x02\x00\x00") _wait_for_ack(radio.pipe) for block_nr in range(NB_OF_BLOCKS): data = radio.get_mmap()[block_nr * BLOCK_LEN: (block_nr + 1) * BLOCK_LEN] LOG.debug("Writing block_nr %i:\n%s", block_nr, util.hexprint(data)) _send(radio.pipe, data) _wait_for_ack(radio.pipe) if radio.status_fn: status = chirp_common.Status() status.max = NB_OF_BLOCKS * BLOCK_LEN status.cur = block_nr * BLOCK_LEN status.msg = "Cloning to radio" radio.status_fn(status) block_nr += 1 MEM_FORMAT = """ struct mem { u8 is_used:1, is_masked:1, is_skip:1, unknown11:3, show_name:1, is_split:1; u8 unknown2; ul32 freq_rx_Hz; ul32 freq_tx_Hz; ul16 offset_10khz; u8 unknown_dependent_of_band_144_b0000_430_b0101:4, tuning_step_index_1_2:4; u8 unknown51:2, is_offset_minus:1, is_offset_plus:1, unknown52:1, tone_mode_index:3; u8 tone_index; u8 dtcs_index; u8 is_mode_am:1, unknown71:2, is_packet96:1, unknown72:2, power_index:2; u8 unknown81:2, tuning_step_index_2_2:4, unknown82:2; char name[6]; u8 unknown9; u8 unknownA; }; // Settings are often present multiple times. // The memories which is written to are mapped here struct { #seekto 0x41; u8 current_band; #seekto 0xa1; u8 apo; #seekto 0xa2; u8 ars_vhf; #seekto 0xe2; u8 ars_uhf; #seekto 0xa3; u8 arts_vhf; #seekto 0xa3; u8 arts_uhf; #seekto 0xa4; u8 beep; #seekto 0xa5; u8 cwid; #seekto 0x80; char cwidw[6]; #seekto 0xa7; u8 dim; #seekto 0xaa; u8 dcsnr_vhf; #seekto 0xea; u8 dcsnr_uhf; #seekto 0xab; u8 disp; #seekto 0xac; u8 dtmfd; #seekto 0xad; u8 dtmfs; #seekto 0xae; u8 dtmfw; #seekto 0xb0; u8 lockt; #seekto 0xb1; u8 mic; #seekto 0xb2; u8 mute; #seekto 0xb4; u8 button[4]; #seekto 0xb8; u8 rf_sql_vhf; #seekto 0xf8; u8 rf_sql_uhf; #seekto 0xb9; u8 scan_vhf; #seekto 0xf9; u8 scan_uhf; #seekto 0xbc; u8 speaker_cnt; #seekto 0xff; u8 tot; #seekto 0xc0; u8 txnar_vhf; #seekto 0x100; u8 txnar_uhf; #seekto 0xc1; u8 vfotr; #seekto 0xc2; u8 am; } overlay; // All known memories #seekto 0x20; u8 nb_mem_used_vhf; #seekto 0x22; u8 nb_mem_used_vhf_and_limits; #seekto 0x24; u8 nb_mem_used_uhf; #seekto 0x26; u8 nb_mem_used_uhf_and_limits; #seekto 0x41; u8 current_band; #seekto 0x42; u8 current_nb_mem_used_vhf_maybe_not; #seekto 0x4c; u8 priority_channel_maybe_1; // not_implemented u8 priority_channel_maybe_2; // not_implemented u8 priority_channel; // not_implemented #seekto 0x87; u8 opt_01_apo_1_4; #seekto 0xa1; u8 opt_01_apo_2_4; #seekto 0xc5; u8 opt_01_apo_3_4; #seekto 0xe1; u8 opt_01_apo_4_4; #seekto 0x88; u8 opt_02_ars_vhf_1_2; #seekto 0xa2; u8 opt_02_ars_vhf_2_2; #seekto 0xc6; u8 opt_02_ars_uhf_1_2; #seekto 0xe2; u8 opt_02_ars_uhf_2_2; #seekto 0x89; u8 opt_03_arts_mode_vhf_1_2; #seekto 0xa3; u8 opt_03_arts_mode_vhf_2_2; #seekto 0xc7; u8 opt_03_arts_mode_uhf_1_2; #seekto 0xa3; u8 opt_03_arts_mode_vhf_2_2; #seekto 0x8a; u8 opt_04_beep_1_2; #seekto 0xa4; u8 opt_04_beep_2_2; #seekto 0x8b; u8 opt_05_cwid_on_1_4; #seekto 0xa5; u8 opt_05_cwid_on_2_4; #seekto 0xc9; u8 opt_05_cwid_on_3_4; #seekto 0xe5; u8 opt_05_cwid_on_4_4; #seekto 0x80; char opt_06_cwidw[6]; #seekto 0x8d; u8 opt_07_dim_1_4; #seekto 0xa7; u8 opt_07_dim_2_4; #seekto 0xcb; u8 opt_07_dim_3_4; #seekto 0xe7; u8 opt_07_dim_4_4; #seekto 0x90; u8 opt_10_dcsnr_vhf_1_2; #seekto 0xaa; u8 opt_10_dcsnr_vhf_2_2; #seekto 0xce; u8 opt_10_dcsnr_uhf_1_2; #seekto 0xea; u8 opt_10_dcsnr_uhf_2_2; #seekto 0x91; u8 opt_11_disp_1_4; #seekto 0xab; u8 opt_11_disp_2_4; #seekto 0xcf; u8 opt_11_disp_3_4; #seekto 0xeb; u8 opt_11_disp_4_4; #seekto 0x92; u8 opt_12_dtmf_delay_1_4; #seekto 0xac; u8 opt_12_dtmf_delay_2_4; #seekto 0xd0; u8 opt_12_dtmf_delay_3_4; #seekto 0xec; u8 opt_12_dtmf_delay_4_4; #seekto 0x93; u8 opt_13_dtmf_speed_1_4; #seekto 0xad; u8 opt_13_dtmf_speed_2_4; #seekto 0xd1; u8 opt_13_dtmf_speed_3_4; #seekto 0xed; u8 opt_13_dtmf_speed_4_4; #seekto 0x94; u8 opt_14_dtmfw_index_1_4; #seekto 0xae; u8 opt_14_dtmfw_index_2_4; #seekto 0xd2; u8 opt_14_dtmfw_index_3_4; #seekto 0xee; u8 opt_14_dtmfw_index_4_4; #seekto 0x96; u8 opt_16_lockt_1_4; #seekto 0xb0; u8 opt_16_lockt_2_4; #seekto 0xd4; u8 opt_16_lockt_3_4; #seekto 0xf0; u8 opt_16_lockt_4_4; #seekto 0x97; u8 opt_17_mic_MH48_1_4; #seekto 0xb1; u8 opt_17_mic_MH48_2_4; #seekto 0xd5; u8 opt_17_mic_MH48_3_4; #seekto 0xf1; u8 opt_17_mic_MH48_4_4; #seekto 0x98; u8 opt_18_mute_1_4; #seekto 0xb2; u8 opt_18_mute_2_4; #seekto 0xd6; u8 opt_18_mute_3_4; #seekto 0xf2; u8 opt_18_mute_4_4; #seekto 0x9a; u8 opt_20_pg_p_1_4[4]; #seekto 0xb4; u8 opt_20_pg_p_2_4[4]; #seekto 0xd8; u8 opt_20_pg_p_3_4[4]; #seekto 0xf4; u8 opt_20_pg_p_4_4[4]; #seekto 0x9e; u8 opt_24_rf_sql_vhf_1_2; #seekto 0xb8; u8 opt_24_rf_sql_vhf_2_2; #seekto 0xdc; u8 opt_24_rf_sql_uhf_1_2; #seekto 0xf8; u8 opt_24_rf_sql_uhf_2_2; #seekto 0x9f; u8 opt_25_scan_resume_vhf_1_2; #seekto 0xb9; u8 opt_25_scan_resume_vhf_2_2; #seekto 0xdd; u8 opt_25_scan_resume_uhf_1_2; #seekto 0xf9; u8 opt_25_scan_resume_uhf_2_2; #seekto 0xbc; u8 opt_28_speaker_cnt_1_2; #seekto 0xfc; u8 opt_28_speaker_cnt_2_2; #seekto 0xbf; u8 opt_31_tot_1_2; #seekto 0xff; u8 opt_31_tot_2_2; #seekto 0xc0; u8 opt_32_tx_nar_vhf; #seekto 0x100; u8 opt_32_tx_nar_uhf; #seekto 0xc1; u8 opt_33_vfo_tr; #seekto 0xc2; u8 opt_34_am_1_2; #seekto 0x102; u8 opt_34_am_2_2; #seekto 260; struct { struct mem mem_struct; char fill_ff[2]; } unknown00; struct { struct mem mem_struct; char fill_00[6]; } current_vfo_vhf_uhf[2]; struct { struct mem mem_struct; char fill_ff[6]; } current_mem_vhf_uhf[2]; struct { struct mem mem_struct; char fill_ff[6]; } home_vhf_uhf[2]; struct { struct mem mem_struct; char fill_010003000000[6]; } vhome; struct { struct mem mem_struct; char fill_010001000000[6]; } unknown01; struct { char name[32]; } Vertex_Standard_AH003M_Backup_DT; struct mem memory[260]; struct { char name[24]; } Vertex_Standard_AH003M; struct { u8 dtmf[16]; } dtmf_mem[16]; """ MODES_VHF = ["FM", "AM"] MODES_UHF = ["FM"] # AM can be set but is ignored by the radio DUPLEX = ["", "-", "+", "split"] TONE_MODES_RADIO = ["", "Tone", "TSQL", "CTCSS Bell", "DTCS"] TONE_MODES = ["", "Tone", "TSQL", "DTCS"] POWER_LEVELS = [ chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Low2", watts=10), chirp_common.PowerLevel("Low3", watts=20), chirp_common.PowerLevel("High", watts=35), ] TUNING_STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0] SKIP_VALUES = ["", "S"] CHARSET = r"!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^ _" DTMF_CHARSET = "0123456789*# " SPECIAL_CHANS = ['VFO-VHF', 'VFO-UHF', 'Home-VHF', 'Home-UHF', 'VFO', 'Home'] SCAN_LIMITS = ["L1", "U1", "L2", "U2", "L3", "U3", "L4", "U4", "L5", "U5"] def do_download(radio): """This is your download function""" return _download(radio) @directory.register class FT7100Radio(YaesuCloneModeRadio): """Yaesu FT-7100M""" MODEL = "FT-7100M" VARIANT = "" IDBLOCK = b"Vartex Standard AH003M M-Map V04" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False # Return information about this radio's features, including # how many memories it has, what bands it supports, etc def get_features(self): LOG.debug("get_features") rf = chirp_common.RadioFeatures() rf.has_bank = False rf.memory_bounds = (0, 240) # This radio supports 120 + 10 + 120 + 10 = 260 memories # These are zero based for chirpc rf.valid_bands = [ (108000000, 180000000), # Supports 2-meters tx (320000000, 999990000), # Supports 70-centimeters tx ] rf.can_odd_split = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = False rf.has_dtcs_polarity = False rf.has_bank = False rf.has_bank_names = False rf.has_settings = True rf.has_sub_devices = True rf.valid_tuning_steps = TUNING_STEPS rf.valid_modes = MODES_VHF rf.valid_tmodes = TONE_MODES rf.valid_power_levels = POWER_LEVELS rf.valid_duplexes = DUPLEX rf.valid_skips = SKIP_VALUES rf.valid_name_length = 6 rf.valid_characters = CHARSET rf.valid_special_chans = SPECIAL_CHANS return rf def sync_in(self): start = time.time() try: self._mmap = _download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Downloaded in %.2f sec", (time.time() - start)) self.process_mmap() def sync_out(self): self.pipe.timeout = 1 start = time.time() try: _upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) LOG.info("Uploaded in %.2f sec", (time.time() - start)) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): LOG.debug("get_memory Number: %r", number) # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Get a low-level memory object mapped to the image if isinstance(number, int) and number < 0: number = SPECIAL_CHANS[number + 10] if isinstance(number, str): mem.number = -10 + SPECIAL_CHANS.index(number) mem.extd_number = number band = 0 if self._memobj.overlay.current_band != 0: band = 1 if number == 'VFO-VHF': _mem = self._memobj.current_vfo_vhf_uhf[0].mem_struct elif number == 'VFO-UHF': _mem = self._memobj.current_vfo_vhf_uhf[1].mem_struct elif number == 'Home-VHF': _mem = self._memobj.home_vhf_uhf[0].mem_struct elif number == 'Home-UHF': _mem = self._memobj.home_vhf_uhf[1].mem_struct elif number == 'VFO': _mem = self._memobj.current_vfo_vhf_uhf[band].mem_struct elif number == 'Home': _mem = self._memobj.home_vhf_uhf[band].mem_struct _mem.is_used = True else: mem.number = number # Set the memory number _mem = self._memobj.memory[number] upper_channel = self._memobj.nb_mem_used_vhf upper_limit = self._memobj.nb_mem_used_vhf_and_limits if number >= upper_channel and number < upper_limit: i = number - upper_channel mem.extd_number = SCAN_LIMITS[i] if number >= 260-10: i = number - (260-10) mem.extd_number = SCAN_LIMITS[i] # Convert your low-level frequency to Hertz mem.freq = int(_mem.freq_rx_Hz) mem.name = str(_mem.name).rstrip() # Set the alpha tag mem.rtone = chirp_common.TONES[_mem.tone_index] mem.ctone = chirp_common.TONES[_mem.tone_index] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs_index] mem.rx_dtcs = chirp_common.DTCS_CODES[_mem.dtcs_index] tmode_radio = TONE_MODES_RADIO[_mem.tone_mode_index] # CTCSS Bell is TSQL plus a flag in the extra setting is_ctcss_bell = tmode_radio == "CTCSS Bell" if is_ctcss_bell: mem.tmode = "TSQL" else: mem.tmode = tmode_radio mem.duplex = "" if _mem.is_offset_plus: mem.duplex = "+" elif _mem.is_offset_minus: mem.duplex = "-" elif _mem.is_split: mem.duplex = "split" if _mem.is_split: mem.offset = int(_mem.freq_tx_Hz) else: mem.offset = int(_mem.offset_10khz)*10000 # 10 kHz to Hz if _mem.is_mode_am: mem.mode = "AM" else: mem.mode = "FM" mem.power = POWER_LEVELS[_mem.power_index] mem.tuning_step = TUNING_STEPS[_mem.tuning_step_index_1_2] if _mem.is_skip: mem.skip = "S" else: mem.skip = "" # mem.comment = "" mem.empty = not _mem.is_used mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("show_name", "Show Name", RadioSettingValueBoolean(_mem.show_name)) mem.extra.append(rs) rs = RadioSetting("is_masked", "Is Masked", RadioSettingValueBoolean(_mem.is_masked)) mem.extra.append(rs) rs = RadioSetting("is_packet96", "Packet 9600", RadioSettingValueBoolean(_mem.is_packet96)) mem.extra.append(rs) rs = RadioSetting("is_ctcss_bell", "CTCSS Bell", RadioSettingValueBoolean(is_ctcss_bell)) mem.extra.append(rs) return mem def set_memory(self, mem): LOG.debug("set_memory Number: %r", mem.number) if mem.number < 0: number = SPECIAL_CHANS[mem.number+10] if number == 'VFO-VHF': _mem = self._memobj.current_vfo_vhf_uhf[0].mem_struct elif number == 'VFO-UHF': _mem = self._memobj.current_vfo_vhf_uhf[1].mem_struct elif number == 'Home-VHF': _mem = self._memobj.home_vhf_uhf[0].mem_struct elif number == 'Home-UHF': _mem = self._memobj.home_vhf_uhf[1].mem_struct else: raise errors.RadioError("Unexpected Memory Number: %r", mem.number) else: _mem = self._memobj.memory[mem.number] _mem.name = mem.name.ljust(6) _mem.tone_index = chirp_common.TONES.index(mem.rtone) _mem.dtcs_index = chirp_common.DTCS_CODES.index(mem.dtcs) if mem.tmode == "TSQL": _mem.tone_index = chirp_common.TONES.index(mem.ctone) if mem.tmode == "DTSC-R": _mem.dtcs_index = chirp_common.DTCS_CODES.index(mem.rx_dtcs) _mem.is_offset_plus = 0 _mem.is_offset_minus = 0 _mem.is_split = 0 _mem.freq_rx_Hz = mem.freq _mem.freq_tx_Hz = mem.freq if mem.duplex == "+": _mem.is_offset_plus = 1 _mem.freq_tx_Hz = mem.freq + mem.offset _mem.offset_10khz = int(mem.offset/10000) elif mem.duplex == "-": _mem.is_offset_minus = 1 _mem.freq_tx_Hz = mem.freq - mem.offset _mem.offset_10khz = int(mem.offset/10000) elif mem.duplex == "split": _mem.is_split = 1 _mem.freq_tx_Hz = mem.offset # No change to _mem.offset_10khz _mem.is_mode_am = mem.mode == "AM" if mem.power: _mem.power_index = POWER_LEVELS.index(mem.power) _mem.tuning_step_index_1_2 = TUNING_STEPS.index(mem.tuning_step) _mem.is_skip = mem.skip == "S" _mem.is_used = not mem.empty # if name not empty: show name _mem.show_name = mem.name.strip() != "" # In testmode there is no setting in mem.extra # This is why the following line is not located in the else part of # the if structure below _mem.tone_mode_index = TONE_MODES_RADIO.index(mem.tmode) for setting in mem.extra: if setting.get_name() == "is_ctcss_bell": if mem.tmode == "TSQL" and setting.value: _mem.tone_mode_index = TONE_MODES_RADIO.index("CTCSS Bell") else: setattr(_mem, setting.get_name(), setting.value) LOG.debug("encoded mem\n%s\n", (util.hexprint(_mem.get_raw(asbytes=False)[0:25]))) LOG.debug(repr(_mem)) def get_settings(self): common = RadioSettingGroup("common", "Common Settings") band = RadioSettingGroup("band", "Band dependent Settings") arts = RadioSettingGroup("arts", "Auto Range Transponder System (ARTS)") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") mic_button = RadioSettingGroup("mic_button", "Microphone Buttons") setmode = RadioSettings(common, band, arts, dtmf, mic_button) _overlay = self._memobj.overlay # numbers and names of settings refer to the way they're # presented in the set menu, as well as the list starting on # page 49 of the manual # 1 Automatic Power Off opts = [ "Off", "30 Min", "1 Hour", "1.5 Hours", "2 Hours", "2.5 Hours", "3 Hours", "3.5 Hours", "4 Hours", "4.5 Hours", "5 Hours", "5.5 Hours", "6 Hours", "6.5 Hours", "7 Hours", "7.5 Hours", "8 Hours", "8.5 Hours", "9 Hours", "9.5 Hours", "10 Hours", "10.5 Hours", "11 Hours", "11.5 Hours", "12 Hours", ] common.append( RadioSetting( "apo", "Automatic Power Off", RadioSettingValueList(opts, opts[_overlay.apo]))) # 2 Automatic Repeater Shift function opts = ["Off", "On"] band.append( RadioSetting( "ars_vhf", "Automatic Repeater Shift VHF", RadioSettingValueList(opts, opts[_overlay.ars_vhf]))) band.append( RadioSetting( "ars_uhf", "Automatic Repeater Shift UHF", RadioSettingValueList(opts, opts[_overlay.ars_uhf]))) # 3 Selects the ARTS mode. # -> Only useful to set it on the radio directly # 4 Enables/disables the key/button beeper. opts = ["Off", "On"] common.append( RadioSetting( "beep", "Key/Button Beep", RadioSettingValueList(opts, opts[_overlay.beep]))) # 5 Enables/disables the CW IDer during ARTS operation. opts = ["Off", "On"] arts.append( RadioSetting( "cwid", "Enables/Disables the CW ID", RadioSettingValueList(opts, opts[_overlay.cwid]))) # 6 Callsign during ARTS operation. cwidw = _overlay.cwidw.get_raw(asbytes=False) cwidw = cwidw.rstrip('\x00') val = RadioSettingValueString(0, 6, cwidw) val.set_charset(CHARSET) rs = RadioSetting("cwidw", "CW Identifier Callsign", val) def apply_cwid(setting): value_string = setting.value.get_value() _overlay.cwidw.set_value(value_string) rs.set_apply_callback(apply_cwid) arts.append(rs) # 7 Front panel display's illumination level. opts = ["0: Off", "1: Max", "2", "3", "4", "5", "6", "7: Min"] common.append( RadioSetting( "dim", "Display Illumination", RadioSettingValueList(opts, opts[_overlay.dim]))) # 8 Setting the DCS code number. # Note: This Menu item can be set independently for each band, # and independently in each memory. # 9 Activates the DCS Code Search # -> Only useful if set on radio itself # 10 Selects 'Normal' or 'Inverted' DCS coding. opts = ["TRX Normal", "RX Reversed", "TX Reversed", "TRX Reversed"] band.append( RadioSetting( "dcsnr_vhf", "DCS coding VHF", RadioSettingValueList(opts, opts[_overlay.dcsnr_vhf]))) band.append( RadioSetting( "dcsnr_uhf", "DCS coding UHF", RadioSettingValueList(opts, opts[_overlay.dcsnr_uhf]))) # 11 Selects the 'sub' band display format opts = ["Frequency", "Off / Sub Band disabled", "DC Input Voltage", "CW ID"] common.append( RadioSetting( "disp", "Sub Band Display Format", RadioSettingValueList(opts, opts[_overlay.disp]))) # 12 Setting the DTMF Autodialer delay time opts = ["50 ms", "250 ms", "450 ms", "750 ms", "1 s"] dtmf.append( RadioSetting( "dtmfd", "Autodialer delay time", RadioSettingValueList(opts, opts[_overlay.dtmfd]))) # 13 Setting the DTMF Autodialer sending speed opts = ["50 ms", "75 ms", "100 ms"] dtmf.append( RadioSetting( "dtmfs", "Autodialer sending speed", RadioSettingValueList(opts, opts[_overlay.dtmfs]))) # 14 Current DTMF Autodialer memory rs = RadioSetting("dtmfw", "Current Autodialer memory", RadioSettingValueInteger(1, 16, _overlay.dtmfw + 1)) def apply_dtmfw(setting): _overlay.dtmfw = setting.value.get_value() - 1 rs.set_apply_callback(apply_dtmfw) dtmf.append(rs) # DTMF Memory for i in range(16): dtmf_string = "" for j in range(16): dtmf_char = '' dtmf_int = int(self._memobj.dtmf_mem[i].dtmf[j]) if dtmf_int < 10: dtmf_char = str(dtmf_int) elif dtmf_int == 14: dtmf_char = '*' elif dtmf_int == 15: dtmf_char = '#' elif dtmf_int == 255: break dtmf_string += dtmf_char radio_setting_value_string = RadioSettingValueString(0, 16, dtmf_string) radio_setting_value_string.set_charset(DTMF_CHARSET) rs = RadioSetting("dtmf_%02i" % i, "DTMF Mem " + str(i+1), radio_setting_value_string) def apply_dtmf(setting, index): radio_setting_value_string = setting.value.get_value().rstrip() j = 0 for dtmf_char in radio_setting_value_string: dtmf_int = 255 if dtmf_char in "0123456789": dtmf_int = int(dtmf_char) elif dtmf_char == '*': dtmf_int = 14 elif dtmf_char == '#': dtmf_int = 15 if dtmf_int < 255: self._memobj.dtmf_mem[index].dtmf[j] = dtmf_int j += 1 if j < 16: self._memobj.dtmf_mem[index].dtmf[j] = 255 rs.set_apply_callback(apply_dtmf, i) dtmf.append(rs) # 16 Enables/disables the PTT switch lock opts = ["Off", "Band A", "Band B", "Both"] common.append( RadioSetting( "lockt", "PTT switch lock", RadioSettingValueList(opts, opts[_overlay.lockt]))) # 17 Selects the Microphone type to be used opts = ["MH-42", "MH-48"] common.append( RadioSetting( "mic", "Microphone type", RadioSettingValueList(opts, opts[_overlay.mic]))) # 18 Reduces the audio level on the sub receiver when the # main receiver is active opts = ["Off", "On"] common.append( RadioSetting( "mute", "Mute Sub Receiver", RadioSettingValueList(opts, opts[_overlay.mute]))) # 20 - 23 Programming the microphones button assignment buttons = [ "ACC / P1", "P / P2", "P1 / P3", "P2 / P4", ] opts_button = ["Low", "Tone", "MHz", "Rev", "Home", "Band", "VFO / Memory", "Sql Off", "1750 Hz Tone Call", "Repeater", "Priority"] for i, button in enumerate(buttons): rs = RadioSetting( "button" + str(i), button, RadioSettingValueList(opts_button, opts_button[_overlay.button[i]])) def apply_button(setting, index): value_string = setting.value.get_value() value_int = opts_button.index(value_string) _overlay.button[index] = value_int rs.set_apply_callback(apply_button, i) mic_button.append(rs) # 24 Adjusts the RF SQL threshold level opts = ["Off", "S-1", "S-5", "S-9", "S-FULL"] band.append( RadioSetting( "rf_sql_vhf", "RF Sql VHF", RadioSettingValueList(opts, opts[_overlay.rf_sql_vhf]))) band.append( RadioSetting( "rf_sql_uhf", "RF Sql UHF", RadioSettingValueList(opts, opts[_overlay.rf_sql_uhf]))) # 25 Selects the Scan-Resume mode opts = ["Busy", "Time"] band.append( RadioSetting( "scan_vhf", "Scan-Resume VHF", RadioSettingValueList(opts, opts[_overlay.scan_vhf]))) band.append( RadioSetting( "scan_uhf", "Scan-Resume UHF", RadioSettingValueList(opts, opts[_overlay.scan_uhf]))) # 28 Defining the audio path to the external speaker opts = ["Off", "Band A", "Band B", "Both"] common.append( RadioSetting( "speaker_cnt", "External Speaker", RadioSettingValueList(opts, opts[_overlay.speaker_cnt]))) # 31 Sets the Time-Out Timer opts = ["Off", "Band A", "Band B", "Both"] common.append( RadioSetting( "tot", "TX Time-Out [Min.] (0 = Off)", RadioSettingValueInteger(0, 30, _overlay.tot))) # 32 Reducing the MIC Gain (and Deviation) opts = ["Off", "On"] band.append( RadioSetting( "txnar_vhf", "TX Narrowband VHF", RadioSettingValueList(opts, opts[_overlay.txnar_vhf]))) band.append( RadioSetting( "txnar_uhf", "TX Narrowband UHF", RadioSettingValueList(opts, opts[_overlay.txnar_uhf]))) # 33 Enables/disables the VFO Tracking feature opts = ["Off", "On"] common.append( RadioSetting( "vfotr", "VFO Tracking", RadioSettingValueList(opts, opts[_overlay.vfotr]))) # 34 Selects the receiving mode on the VHF band opts = ["Inhibit (only FM)", "AM", "Auto"] common.append( RadioSetting( "am", "AM Mode", RadioSettingValueList(opts, opts[_overlay.am]))) # Current Band opts = ["VHF", "UHF"] common.append( RadioSetting( "current_band", "Current Band", RadioSettingValueList(opts, opts[_overlay.current_band]))) # Show number of VHF and UHF channels val = RadioSettingValueString(0, 7, str(int(self._memobj.nb_mem_used_vhf))) val.set_mutable(False) rs = RadioSetting("num_chan_vhf", "Number of VHF channels", val) common.append(rs) val = RadioSettingValueString(0, 7, str(int(self._memobj.nb_mem_used_uhf))) val.set_mutable(False) rs = RadioSetting("num_chan_uhf", "Number of UHF channels", val) common.append(rs) return setmode def set_settings(self, uisettings): _overlay = self._memobj.overlay for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: name = element.get_name() value = element.value if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: setattr(_overlay, name, value) LOG.debug("Setting %s: %s", name, value) except Exception: LOG.debug(element.get_name()) raise def _get_upper_vhf_limit(self): if self._memobj is None: # test with tox has no _memobj upper_vhf_limit = 120 else: upper_vhf_limit = int(self._memobj.nb_mem_used_vhf) return upper_vhf_limit def _get_upper_uhf_limit(self): if self._memobj is None: # test with tox has no _memobj upper_uhf_limit = 120 else: upper_uhf_limit = int(self._memobj.nb_mem_used_uhf) return upper_uhf_limit @classmethod def match_model(cls, filedata, filename): return filedata[0x1ec0:0x1ec0+len(cls.IDBLOCK)] == cls.IDBLOCK @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn Radio off.\n" "2. Connect data cable.\n" "3. While holding \"TONE\" and \"REV\" buttons, turn radio on.\n" "4. After clicking OK, press \"TONE\" to send image.\n") rp.pre_upload = _( "1. Turn Radio off.\n" "2. Connect data cable.\n" "3. While holding \"TONE\" and \"REV\" buttons, turn radio on.\n" "4. Press \"REV\" to receive image.\n" "5. Make sure display says \"CLONE RX\" and green led is" " blinking\n" "6. Click OK to start transfer.\n") return rp def get_sub_devices(self): if not self.VARIANT: return [FT7100RadioVHF(self._mmap), FT7100RadioUHF(self._mmap)] else: return [] class FT7100RadioVHF(FT7100Radio): VARIANT = "VHF Band" def get_features(self): LOG.debug("VHF get_features") upper_vhf_limit = self._get_upper_vhf_limit() rf = FT7100Radio.get_features(self) rf.memory_bounds = (1, upper_vhf_limit) # Normally this band supports 120 + 10 memories. 1 based for chirpw rf.valid_bands = [(108000000, 180000000)] # Supports 2-meters tx rf.valid_modes = MODES_VHF rf.valid_special_chans = ['VFO', 'Home'] rf.has_sub_devices = False return rf def get_memory(self, number): LOG.debug("get_memory VHF Number: %s", number) if isinstance(number, int): if number >= 0: mem = FT7100Radio.get_memory(self, number + 0 - 1) else: mem = FT7100Radio.get_memory(self, number) mem.number = number else: mem = FT7100Radio.get_memory(self, number + '-VHF') mem.extd_number = number mem.immutable = ["number", "extd_number", "skip"] return mem def set_memory(self, mem): LOG.debug("set_memory VHF Number: %s", mem.number) # We modify memory, so dupe() it to avoid changing our caller's # version mem = mem.dupe() if isinstance(mem.number, int): if mem.number >= 0: mem.number += -1 else: mem.number += '-VHF' super(FT7100RadioVHF, self).set_memory(mem) return class FT7100RadioUHF(FT7100Radio): VARIANT = "UHF Band" def get_features(self): LOG.debug("UHF get_features") upper_uhf_limit = self._get_upper_uhf_limit() rf = FT7100Radio.get_features(self) rf.memory_bounds = (1, upper_uhf_limit) # Normally this band supports 120 + 10 memories. 1 based for chirpw rf.valid_bands = [(320000000, 999990000)] # Supports 70-centimeters tx rf.valid_modes = MODES_UHF rf.valid_special_chans = ['VFO', 'Home'] rf.has_sub_devices = False return rf def get_memory(self, number): LOG.debug("get_memory UHF Number: %s", number) upper_vhf_limit = self._get_upper_vhf_limit() if isinstance(number, int): if number >= 0: mem = FT7100Radio.get_memory(self, number + 10 + upper_vhf_limit - 1) else: mem = FT7100Radio.get_memory(self, number) mem.number = number else: mem = FT7100Radio.get_memory(self, number + '-UHF') mem.extd_number = number mem.immutable = ["number", "extd_number", "skip"] return mem def set_memory(self, mem): LOG.debug("set_memory UHF Number: %s", mem.number) # We modify memory, so dupe() it to avoid changing our caller's # version mem = mem.dupe() upper_vhf_limit = self._get_upper_vhf_limit() if isinstance(mem.number, int): if mem.number >= 0: mem.number += upper_vhf_limit - 1 + 10 else: mem.number += '-UHF' super(FT7100RadioUHF, self).set_memory(mem) return chirp-20240224/chirp/drivers/tk760g.py0000644000175000017500000014763414563632215016241 0ustar hibbyhibby# Copyright 2016 Pavel Milanes, CO7WT, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import struct import time from chirp import chirp_common, directory, memmap, errors, util, bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettings LOG = logging.getLogger(__name__) # #### IMPORTANT DATA ########################################## # This radios have a span of # 0x00000 - 0x08000 => Radio Memory / Settings data # 0x08000 - 0x10000 => FIRMWARE... hum... # ############################################################## MEM_FORMAT = """ #seekto 0x0000; struct { u8 unknown0[14]; // x00-x0d unknown u8 banks; // x0e how many banks are programmed u8 channels; // x0f how many total channels are programmed // -- ul16 tot; // x10 TOT value: range(15, 600, 15); x04b0 = off u8 tot_rekey; // x12 TOT Re-key value range(0, 60); off= 0 u8 unknown1; // x13 unknown u8 tot_reset; // x14 TOT Re-key value range(0, 60); off= 0 u8 unknown2; // x15 unknowns u8 tot_alert; // x16 TOT pre alert: range(0,10); 0 = off u8 unknown3[7]; // x17-x1d unknown u8 sql_level; // x1e SQ reference level u8 battery_save; // Only for portable: FF = off, x32 = on // -- u8 unknown4[10]; // x20 u8 unknown5:3, // x2d c2t:1, // 1 bit clear to transpond: 1-off // This is relative to DTMF / 2-Tone settings unknown6:4; u8 unknown7[5]; // x2b-x2f // -- u8 unknown8[16]; // x30 ? u8 unknown9[16]; // x40 ? u8 unknown10[16]; // x50 ? u8 unknown11[16]; // x60 ? // -- u8 add[16]; // x70-x7f 128 bits corresponding add/skip values // -- u8 unknown12:4, // x80 off_hook_decode:1, // 1 bit off hook decode enabled: 1-off off_hook_horn_alert:1, // 1 bit off hook horn alert: 1-off unknown13:2; u8 unknown14; // x81 u8 unknown15:3, // x82 self_prog:1, // 1 bit Self programming enabled: 1-on clone:1, // 1 bit clone enabled: 1-on firmware_prog:1, // 1 bit firmware programming enabled: 1-on unknown16:1, panel_test:1; // 1 bit panel test enabled u8 unknown17; // x83 u8 unknown18:5, // x84 warn_tone:1, // 1 bit warning tone, enabled: 1-on control_tone:1, // 1 bit control tone (key tone), enabled: 1-on poweron_tone:1; // 1 bit power on tone, enabled: 1-on u8 unknown19[5]; // x85-x89 u8 min_vol; // minimum volume possible: range(0,32); 0 = off u8 tone_vol; // minimum tone volume possible: // xff = continuous, range(0, 31) u8 unknown20[4]; // x8c-x8f // -- u8 unknown21[4]; // x90-x93 char poweronmesg[8]; // x94-x9b power on mesg 8 bytes, off is "\xFF" * 8 u8 unknown22[4]; // x9c-x9f // -- u8 unknown23[7]; // xa0-xa6 char ident[8]; // xa7-xae radio identification string u8 unknown24; // xaf // -- u8 unknown26[11]; // xaf-xba char lastsoftversion[5]; // software version employed to program the radio } settings; #seekto 0xd0; struct { u8 unknown[4]; char radio[6]; char data[6]; } passwords; #seekto 0x0110; struct { u8 kA; // Portable > Closed circle u8 kDA; // Portable > Triangle to Left u8 kGROUP_DOWN; // Portable > Triangle to Right u8 kGROUP_UP; // Portable > Side 1 u8 kSCN; // Portable > Open Circle u8 kMON; // Portable > Side 2 u8 kFOOT; u8 kCH_UP; u8 kCH_DOWN; u8 kVOL_UP; u8 kVOL_DOWN; u8 unknown30[5]; // -- u8 unknown31[4]; u8 kP_KNOB; // Just portable: channel knob u8 unknown32[11]; } keys; #seekto 0x0140; struct { lbcd tf01_rx[4]; lbcd tf01_tx[4]; u8 tf01_u_rx; u8 tf01_u_tx; lbcd tf02_rx[4]; lbcd tf02_tx[4]; u8 tf02_u_rx; u8 tf02_u_tx; lbcd tf03_rx[4]; lbcd tf03_tx[4]; u8 tf03_u_rx; u8 tf03_u_tx; lbcd tf04_rx[4]; lbcd tf04_tx[4]; u8 tf04_u_rx; u8 tf04_u_tx; lbcd tf05_rx[4]; lbcd tf05_tx[4]; u8 tf05_u_rx; u8 tf05_u_tx; lbcd tf06_rx[4]; lbcd tf06_tx[4]; u8 tf06_u_rx; u8 tf06_u_tx; lbcd tf07_rx[4]; lbcd tf07_tx[4]; u8 tf07_u_rx; u8 tf07_u_tx; lbcd tf08_rx[4]; lbcd tf08_tx[4]; u8 tf08_u_rx; u8 tf08_u_tx; lbcd tf09_rx[4]; lbcd tf09_tx[4]; u8 tf09_u_rx; u8 tf09_u_tx; lbcd tf10_rx[4]; lbcd tf10_tx[4]; u8 tf10_u_rx; u8 tf10_u_tx; lbcd tf11_rx[4]; lbcd tf11_tx[4]; u8 tf11_u_rx; u8 tf11_u_tx; lbcd tf12_rx[4]; lbcd tf12_tx[4]; u8 tf12_u_rx; u8 tf12_u_tx; lbcd tf13_rx[4]; lbcd tf13_tx[4]; u8 tf13_u_rx; u8 tf13_u_tx; lbcd tf14_rx[4]; lbcd tf14_tx[4]; u8 tf14_u_rx; u8 tf14_u_tx; lbcd tf15_rx[4]; lbcd tf15_tx[4]; u8 tf15_u_rx; u8 tf15_u_tx; lbcd tf16_rx[4]; lbcd tf16_tx[4]; u8 tf16_u_rx; u8 tf16_u_tx; } test_freq; #seekto 0x200; struct { char line1[32]; char line2[32]; } message; #seekto 0x2000; struct { u8 bnumb; // mem number u8 bank; // to which bank it belongs char name[8]; // name 8 chars u8 unknown20[2]; // unknown yet lbcd rxfreq[4]; // rx freq // -- lbcd txfreq[4]; // tx freq u8 rx_unkw; // unknown yet u8 tx_unkw; // unknown yet ul16 rx_tone; // rx tone ul16 tx_tone; // tx tone u8 unknown23[5]; // unknown yet u8 signaling; // xFF = off, x30 DTMF, x31 2-Tone // See the zone on x7000 // -- u8 ptt_id:2, // ??? BOT = 0, EOT = 1, Both = 2, NONE = 3 beat_shift:1, // 1 = off unknown26:2, // ??? power:1, // power: 0 low / 1 high compander:1, // 1 = off wide:1; // wide 1 / 0 narrow u8 unknown27:6, // ??? busy_lock:1, // 1 = off unknown28:1; // ??? u8 unknown29[14]; // unknown yet } memory[128]; #seekto 0x5900; struct { char model[8]; u8 unknown50[4]; char type[2]; u8 unknown51[2]; // -- char serial[8]; u8 unknown52[8]; } id; #seekto 0x6000; struct { u8 code[8]; u8 unknown60[7]; u8 count; } bot[128]; #seekto 0x6800; struct { u8 code[8]; u8 unknown61[7]; u8 count; } eot[128]; #seekto 0x7000; struct { lbcd dt2_id[5]; // DTMF lbcd ID (000-9999999999) // 2-Tone = "11 f1 ff ff ff" ??? // None = "00 f0 ff ff ff" } dtmf; """ MEM_SIZE = 0x8000 # 32,768 bytes BLOCK_SIZE = 256 BLOCKS = MEM_SIZE // BLOCK_SIZE MEM_BLOCKS = list(range(0, BLOCKS)) # define and empty block of data, as it will be used a lot in this code EMPTY_BLOCK = b"\xFF" * 256 RO_BLOCKS = list(range(0x10, 0x1F)) + list(range(0x59, 0x5f)) ACK_CMD = b"\x06" POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1), chirp_common.PowerLevel("High", watts=5)] MODES = ["NFM", "FM"] # 12.5 / 25 kHz VALID_CHARS = chirp_common.CHARSET_UPPER_NUMERIC + r"_-*()/\-+=)" SKIP_VALUES = ["", "S"] TONES = chirp_common.TONES # TONES.remove(254.1) DTCS_CODES = chirp_common.DTCS_CODES TOT = ["off"] + ["%s" % x for x in range(15, 615, 15)] TOT_PRE = ["off"] + ["%s" % x for x in range(1, 11)] TOT_REKEY = ["off"] + ["%s" % x for x in range(1, 61)] TOT_RESET = ["off"] + ["%s" % x for x in range(1, 16)] VOL = ["off"] + ["%s" % x for x in range(1, 32)] TVOL = ["%s" % x for x in range(0, 33)] TVOL[32] = "Continuous" SQL = ["off"] + ["%s" % x for x in range(1, 10)] # BOT = 0, EOT = 1, Both = 2, NONE = 3 # PTTID = ["BOT", "EOT", "Both", "none"] # For debugging purposes debug = False KEYS = { 0x33: "Display character", 0x35: "Home Channel", # Possible portable only, check it 0x37: "CH down", 0x38: "CH up", 0x39: "Key lock", 0x3a: "Lamp", # Portable only 0x3b: "Public address", 0x3c: "Reverse", # Just in updated firmwares (768G) 0x3d: "Horn alert", 0x3e: "Selectable QT", # Just in updated firmwares (768G) 0x3f: "2-tone encode", 0x40: "Monitor A: open mommentary", 0x41: "Monitor B: Open Toggle", 0x42: "Monitor C: Carrier mommentary", 0x43: "Monitor D: Carrier toggle", 0x44: "Operator selectable tone", 0x45: "Redial", 0x46: "RF Power Low", # portable only ? 0x47: "Scan", 0x48: "Scan del/add", 0x4a: "GROUP down", 0x4b: "GROUP up", # 0x4e: "Tone off (Experimental)", # undocumented !!!! 0x4f: "None", 0x50: "VOL down", 0x51: "VOL up", 0x52: "Talk around", 0x5d: "AUX", 0xa1: "Channel Up/Down" # Knob for portables only } def _raw_recv(radio, amount): """Raw read from the radio device""" try: data = radio.pipe.read(amount) except: raise errors.RadioError("Error reading data from radio") # DEBUG if debug is True: LOG.debug("<== (%d) bytes:\n\n%s" % (len(data), util.hexprint(data))) return data def _raw_send(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) except: raise errors.RadioError("Error sending data to radio") # DEBUG if debug is True: LOG.debug("==> (%d) bytes:\n\n%s" % (len(data), util.hexprint(data))) def _close_radio(radio): """Get the radio out of program mode""" _raw_send(radio, b"E") def _checksum(data): """the radio block checksum algorithm""" cs = 0 for byte in data: cs += byte return cs % 256 def _make_frame(cmd, addr): """Pack the info in the format it likes""" return struct.pack(">BH", ord(cmd), addr) def _handshake(radio, msg=""): """Make a full handshake""" # send ACK _raw_send(radio, ACK_CMD) # receive ACK ack = _raw_recv(radio, 1) # check ACK if ack != ACK_CMD: _close_radio(radio) mesg = "Handshake failed " + msg # DEBUG LOG.debug(mesg) raise Exception(mesg) def _check_write_ack(r, ack, addr): """Process the ack from the write process this is half handshake needed in tx data block""" # all ok if ack == ACK_CMD: return True # Explicit BAD checksum if ack == b"\x15": _close_radio(r) raise errors.RadioError( "Bad checksum in block %02x write" % addr) # everything else _close_radio(r) raise errors.RadioError( "Problem with the ack to block %02x write, ack %03i" % (addr, int(ack))) def _recv(radio): """Receive a single block from the radio""" cmd = _raw_recv(radio, 1) # when the RX block has two bytes and the first is \x5A # then the block is all \xFF if not cmd: raise errors.RadioError('No response from radio') elif cmd == b'Z': # Empty "zero" block ff = _raw_recv(radio, 1) _handshake(radio, "after zero block") return b'\xff' * 256 elif cmd != b'W': LOG.error('Got non-W command:') rxdata = _raw_recv(radio, BLOCK_SIZE + 1) LOG.error(util.hexprint(rxdata)) raise errors.RadioError('Received unexpected response from radio') else: rxdata = _raw_recv(radio, BLOCK_SIZE + 1) rcs = rxdata[-1] data = rxdata[:-1] ccs = _checksum(data) if rcs != ccs: _close_radio(radio) raise errors.RadioError( "Block Checksum Error! real %02x, calculated %02x" % (rcs, ccs)) _handshake(radio, "after checksum") return data def _open_radio(radio, status): """Open the radio into program mode and check if it's the correct model""" # linux min is 0.13, win min is 0.25; set to bigger to be safe radio.pipe.timeout = 1 radio.pipe.parity = "E" # DEBUG LOG.debug("Entering program mode.") # max tries tries = 10 # UI status.cur = 0 status.max = tries status.msg = "Entering program mode..." _raw_send(radio, b"PROGRAM") ack = _raw_recv(radio, 1) if ack != ACK_CMD: _close_radio(radio) LOG.debug("Radio did not accept PROGRAM command") raise errors.RadioError("The radio did not start program mode") # DEBUG LOG.debug("Received ACK to the PROGRAM command, send ID query.") _raw_send(radio, b"\x02") rid = _raw_recv(radio, 8) if not (radio.TYPE in rid): # bad response, properly close the radio before exception _close_radio(radio) # DEBUG LOG.debug("Incorrect model ID:") LOG.debug(util.hexprint(rid)) raise errors.RadioError( "Incorrect model ID, got %s, it not contains %s" % (rid.strip(b"\xff"), radio.TYPE)) # DEBUG LOG.debug("Full ident string is:") LOG.debug(util.hexprint(rid)) _handshake(radio) status.msg = "Radio ident success!" radio.status_fn(status) # a pause time.sleep(1) def do_download(radio): """ The download function """ # UI progress status = chirp_common.Status() data = b"" count = 0 # open the radio _open_radio(radio, status) # reset UI data status.cur = 0 status.max = MEM_SIZE // 256 status.msg = "Cloning from radio..." radio.status_fn(status) # DEBUG LOG.debug("Starting the download from radio") for addr in MEM_BLOCKS: # send request, but before flush the rx buffer radio.pipe.flush() _raw_send(radio, _make_frame("R", addr)) time.sleep(0.1) # now we get the data data += _recv(radio) # UI Update status.cur = count radio.status_fn(status) count += 1 _close_radio(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): """ The upload function """ # UI progress status = chirp_common.Status() data = b"" count = 0 # open the radio _open_radio(radio, status) # update UI status.cur = 0 status.max = MEM_SIZE // 256 status.msg = "Cloning to radio..." radio.status_fn(status) # DEBUG LOG.debug("Starting the upload to the radio") count = 0 raddr = 0 for addr in MEM_BLOCKS: # this is the data block to write data = radio.get_mmap()[raddr:raddr+BLOCK_SIZE] # The blocks from x59-x5F are NOT programmable # The blocks from x11-x1F are written only if not empty if addr in RO_BLOCKS: # checking if in the range of optional blocks if addr >= 0x10 and addr <= 0x1F: # block is empty ? if data == EMPTY_BLOCK: # no write of this block # but we have to continue updating the counters count += 1 raddr = count * 256 continue else: count += 1 raddr = count * 256 continue if data == EMPTY_BLOCK: frame = _make_frame(b"Z", addr) + b"\xFF" else: cs = _checksum(data) frame = _make_frame(b"W", addr) + data + bytes([cs]) _raw_send(radio, frame) # get the ACK ack = _raw_recv(radio, 1) _check_write_ack(radio, ack, addr) # DEBUG LOG.debug("Sending block %02x" % addr) # UI Update status.cur = count radio.status_fn(status) count += 1 raddr = count * 256 _close_radio(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0xA7:0xAE] if rid in cls.VARIANTS: # correct model return True else: return False class Kenwood60GBankModel(chirp_common.BankModel): """Testing the bank model on Kenwood""" channelAlwaysHasBank = True def get_num_mappings(self): return self._radio._num_banks def get_mappings(self): banks = [] for i in range(0, self._radio._num_banks): bindex = i + 1 bank = self._radio._bclass(self, i, "%03i" % bindex) bank.index = i banks.append(bank) return banks def add_memory_to_mapping(self, memory, bank): self._radio._set_bank(memory.number, bank.index) def remove_memory_from_mapping(self, memory, bank): if self._radio._get_bank(memory.number) != bank.index: raise Exception("Memory %i not in bank %s. Cannot remove." % (memory.number, bank)) # We can't "Remove" it for good # the Kenwood paradigm doesn't allow it # instead we move it to bank 0 self._radio._set_bank(memory.number, 0) def get_mapping_memories(self, bank): memories = [] for i in range(0, self._radio._upper): if self._radio._get_bank(i) == bank.index: memories.append(self._radio.get_memory(i)) return memories def get_memory_mappings(self, memory): index = self._radio._get_bank(memory.number) return [self.get_mappings()[index]] class memBank(chirp_common.Bank): """A bank model for Kenwood""" # Integral index of the bank (not to be confused with per-memory # bank indexes index = 0 class Kenwood_Serie_60G(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Kenwood Series 60G Radios base class""" VENDOR = "Kenwood" BAUD_RATE = 9600 _memsize = MEM_SIZE NAME_LENGTH = 8 _range = [136000000, 162000000] _upper = 128 _chs_progs = 0 _num_banks = 128 _bclass = memBank _kind = "" VARIANT = "" MODEL = "" NEEDS_COMPAT_SERIAL = False @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ 'This driver is experimental: Use at your own risk! ' rp.pre_download = _( "Follow these instructions to download your radio:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio (unlock it if password protected)\n" "4 - Click OK to start\n") rp.pre_upload = _( "Follow these instructions to upload your radio:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio (unlock it if password protected)\n" "4 - Click OK to start\n") return rp def get_features(self): """Return information about this radio's features""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = True rf.has_tuning_step = False rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = MODES rf.valid_duplexes = ["", "-", "+", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_characters = VALID_CHARS rf.valid_skips = SKIP_VALUES rf.valid_dtcs_codes = DTCS_CODES rf.valid_bands = [self._range] rf.valid_name_length = 8 rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [1.0, 2.5, 5.0, 6.25, 12.5] return rf def _fill(self, offset, data): """Fill an specified area of the memmap with the passed data""" self._mmap[offset] = data def _prep_data(self): """Prepare the areas in the memmap to do a consistent write it has to make an update on the x300 area with banks and channel info; other in the x1000 with banks and channel counts and a last one in x7000 with flag data""" rchs = 0 data = dict() # sorting the data for ch in range(0, self._upper): mem = self._memobj.memory[ch] bnumb = int(mem.bnumb) bank = int(mem.bank) if bnumb != 255 and (bank != 255 and bank != 0): try: data[bank].append(ch) except: data[bank] = list() data[bank].append(ch) data[bank].sort() # counting the real channels rchs = rchs + 1 # updating the channel/bank count self._memobj.settings.channels = rchs self._chs_progs = rchs self._memobj.settings.banks = len(data) # building the data for the memmap fdata = b"" for k, v in data.items(): # possible bad data if k == 0: k = 1 raise errors.InvalidValueError( "Invalid bank value '%s', bad data in the image? " "Trying to fix this, review your bank data!" % k) c = 1 for i in v: fdata += bytes([k, c, k - 1, i]) c = c + 1 # fill to match a full 256 bytes block fdata += (len(fdata) % 256) * b"\xFF" # updating the data in the memmap [x300] self._fill(0x300, fdata) # update the info in x1000; it has 2 bytes with # x00 = bank , x01 = bank's channel count # the rest of the 14 bytes are \xff bdata = b"" for i in range(1, len(data) + 1): line = bytes([i, len(data[i])]) line += b"\xff" * 14 bdata += line # fill to match a full 256 bytes block bdata += (256 - (len(bdata)) % 256) * b"\xFF" # fill to match the whole area bdata += (16 - len(bdata) // 256) * EMPTY_BLOCK # updating the data in the memmap [x1000] self._fill(0x1000, bdata) # DTMF id for each channel, 5 bytes lbcd at x7000 # ############## TODO ################### fldata = b"\x00\xf0\xff\xff\xff" * self._chs_progs + \ b"\xff" * (5 * (self._upper - self._chs_progs)) # write it # updating the data in the memmap [x7000] self._fill(0x7000, fldata) def _set_variant(self): """Select and set the correct variables for the class according to the correct variant of the radio""" rid = self._mmap[0xA7:0xAE] # identify the radio variant and set the environment to its values try: self._upper, low, high, self._kind = self.VARIANTS[rid] # Frequency ranges: some model/variants are able to work the near # ham bands, even if they are outside the OEM ranges. # By experimentation we found that 4% at the edges is in most # cases safe and will cover the near ham bands in full self._range = [int(low * 1000000 * 0.96), int(high * 1000000 * 1.04)] # setting the bank data in the features, 8 & 16 CH don't have banks if self._upper < 32: rf = chirp_common.RadioFeatures() rf.has_bank = False # put the VARIANT in the class, clean the model / CHs / Type # in the same layout as the KPG program self._VARIANT = self.MODEL + " [" + str(self._upper) + "CH]: " # In the OEM string we show the real OEM ranges self._VARIANT += self._kind + ", %d - %d MHz" % (low, high) except KeyError: LOG.debug("Wrong Kenwood radio, ID or unknown variant") LOG.debug(util.hexprint(rid)) raise errors.RadioError( "Wrong Kenwood radio, ID or unknown variant, see LOG output.") def sync_in(self): """Do a download of the radio eeprom""" self._mmap = do_download(self) self.process_mmap() def sync_out(self): """Do an upload to the radio eeprom""" # chirp signature on the eprom ;-) sign = b"Chirp" self._fill(0xbb, sign) try: self._prep_data() do_upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): """Process the memory object""" # how many channels are programmed self._chs_progs = ord(self._mmap[15]) # load the memobj self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # to set the vars on the class to the correct ones self._set_variant() def get_raw_memory(self, number): """Return a raw representation of the memory object, which is very helpful for development""" return repr(self._memobj.memory[number - 1]) def _decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" val = int(val) if val == 65535: return '', None, None elif val >= 0x2800: code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return 'DTCS', code, pol else: a = val / 10.0 return 'Tone', a, None def _encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval.set_raw("\xff\xff") elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': val = int("%i" % value, 8) + 0x2800 if pol == "R": val += 0xA000 memval.set_value(val) else: raise Exception("Internal error: invalid mode `%s'" % mode) def _get_scan(self, chan): """Get the channel scan status from the 16 bytes array on the eeprom then from the bits on the byte, return '' or 'S' as needed""" result = "S" byte = int(chan/8) bit = chan % 8 res = self._memobj.settings.add[byte] & (pow(2, bit)) if res > 0: result = "" return result def _set_scan(self, chan, value): """Set the channel scan status from UI to the mem_map""" byte = int(chan/8) bit = chan % 8 # get the actual value to see if I need to change anything actual = self._get_scan(chan) if actual != value: # I have to flip the value rbyte = self._memobj.settings.add[byte] rbyte = rbyte ^ pow(2, bit) self._memobj.settings.add[byte] = rbyte def get_memory(self, number): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[number - 1] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Memory number mem.number = number # A "blank" rxfreq is the indication of an empty memory if _mem.rxfreq[0].get_raw(asbytes=False) == '\xFF': mem.empty = True return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if _mem.get_raw(asbytes=False)[16] == "\xFF": # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX feq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 # name TAG of the channel mem.name = str(_mem.name).rstrip(' \xff') # power mem.power = POWER_LEVELS[_mem.power] # wide/marrow mem.mode = MODES[_mem.wide] # skip mem.skip = self._get_scan(number - 1) # tone data rxtone = txtone = None txtone = self._decode_tone(_mem.tx_tone) rxtone = self._decode_tone(_mem.rx_tone) chirp_common.split_tone_decode(mem, txtone, rxtone) # Extra # bank and number in the channel mem.extra = RadioSettingGroup("extra", "Extra") # validate bank b = int(_mem.bank) if b > 127 or b == 0: _mem.bank = b = 1 bank = RadioSetting("bank", "Bank", RadioSettingValueInteger(1, 128, b)) mem.extra.append(bank) # validate bnumb if int(_mem.bnumb) > 127: _mem.bank = mem.number bnumb = RadioSetting("bnumb", "Bank index", RadioSettingValueInteger(0, 127, _mem.bnumb)) mem.extra.append(bnumb) bs = RadioSetting("beat_shift", "Beat shift", RadioSettingValueBoolean( not bool(_mem.beat_shift))) mem.extra.append(bs) cp = RadioSetting("compander", "Compander", RadioSettingValueBoolean( not bool(_mem.compander))) mem.extra.append(cp) bl = RadioSetting("busy_lock", "Busy Channel lock", RadioSettingValueBoolean( not bool(_mem.busy_lock))) mem.extra.append(bl) return mem def set_memory(self, mem): """Set the memory data in the eeprom img from the UI not ready yet, so it will return as is""" # get the eprom representation of this channel _mem = self._memobj.memory[mem.number - 1] # if empty memory if mem.empty: _mem.set_raw("\xFF" * 48) return # frequency _mem.rxfreq = mem.freq / 10 # this are a mystery yet, but so falr there is no impact # whit this default values for new channels if int(_mem.rx_unkw) == 0xff: _mem.rx_unkw = 0x35 _mem.tx_unkw = 0x32 # duplex if mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 elif mem.duplex == "off": for byte in _mem.txfreq: byte.set_raw("\xFF") else: _mem.txfreq = mem.freq / 10 # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.tx_tone, txmode, txtone, txpol) self._encode_tone(_mem.rx_tone, rxmode, rxtone, rxpol) # name TAG of the channel _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _mem.name[i] = mem.name[i] except IndexError: _mem.name[i] = "\x20" # power # default power is low if mem.power is None: mem.power = POWER_LEVELS[0] _mem.power = POWER_LEVELS.index(mem.power) # wide/marrow _mem.wide = MODES.index(mem.mode) # scan add property self._set_scan(mem.number - 1, mem.skip) # bank and number in the channel if int(_mem.bnumb) == 0xff: _mem.bnumb = mem.number - 1 _mem.bank = 1 # extra settings for setting in mem.extra: if setting != "bank" or setting != "bnumb": setattr(_mem, setting.get_name(), not bool(setting.value)) # all data get sync after channel mod self._prep_data() return mem @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == MEM_SIZE: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" sett = self._memobj.settings mess = self._memobj.message keys = self._memobj.keys idm = self._memobj.id passwd = self._memobj.passwords # basic features of the radio basic = RadioSettingGroup("basic", "Basic Settings") # dealer settings dealer = RadioSettingGroup("dealer", "Dealer Settings") # buttons fkeys = RadioSettingGroup("keys", "Front keys config") # TODO / PLANNED # adjust feqs # freqs = RadioSettingGroup("freqs", "Adjust Frequencies") top = RadioSettings(basic, dealer, fkeys) # Basic tot = RadioSetting("settings.tot", "Time Out Timer (TOT)", RadioSettingValueList(TOT, '%i' % sett.tot)) basic.append(tot) totalert = RadioSetting("settings.tot_alert", "TOT pre alert", RadioSettingValueList( TOT_PRE, current_index=sett.tot_alert)) basic.append(totalert) totrekey = RadioSetting("settings.tot_rekey", "TOT re-key time", RadioSettingValueList( TOT_REKEY, current_index=sett.tot_rekey)) basic.append(totrekey) totreset = RadioSetting("settings.tot_reset", "TOT reset time", RadioSettingValueList( TOT_RESET, current_index=sett.tot_reset)) basic.append(totreset) # this feature is for mobile only if self.TYPE[0] == "M": minvol = RadioSetting("settings.min_vol", "Minimum volume", RadioSettingValueList( VOL, current_index=sett.min_vol)) basic.append(minvol) tv = int(sett.tone_vol) if tv == 255: tv = 32 tvol = RadioSetting("settings.tone_vol", "Minimum tone volume", RadioSettingValueList(TVOL, TVOL[tv])) basic.append(tvol) sql = RadioSetting("settings.sql_level", "SQL Ref Level", RadioSettingValueList( SQL, current_index=sett.sql_level)) basic.append(sql) # c2t = RadioSetting("settings.c2t", "Clear to Transpond", # RadioSettingValueBoolean(not sett.c2t)) # basic.append(c2t) ptone = RadioSetting("settings.poweron_tone", "Power On tone", RadioSettingValueBoolean(sett.poweron_tone)) basic.append(ptone) ctone = RadioSetting("settings.control_tone", "Control (key) tone", RadioSettingValueBoolean(sett.control_tone)) basic.append(ctone) wtone = RadioSetting("settings.warn_tone", "Warning tone", RadioSettingValueBoolean(sett.warn_tone)) basic.append(wtone) # Save Battery only for portables? if self.TYPE[0] == "P": bs = int(sett.battery_save) == 0x32 and True or False bsave = RadioSetting("settings.battery_save", "Battery Saver", RadioSettingValueBoolean(bs)) basic.append(bsave) ponm = str(sett.poweronmesg).strip("\xff") pom = RadioSetting("settings.poweronmesg", "Power on message", RadioSettingValueString(0, 8, ponm, False)) basic.append(pom) # dealer valid_chars = ",-/:[]" + chirp_common.CHARSET_ALPHANUMERIC mstr = "".join([c for c in self._VARIANT if c in valid_chars]) val = RadioSettingValueString(0, 35, mstr) val.set_mutable(False) mod = RadioSetting("not.mod", "Radio Version", val) dealer.append(mod) sn = str(idm.serial).strip(" \xff") val = RadioSettingValueString(0, 8, sn) val.set_mutable(False) serial = RadioSetting("not.serial", "Serial number", val) dealer.append(serial) svp = str(sett.lastsoftversion).strip(" \xff") val = RadioSettingValueString(0, 5, svp) val.set_mutable(False) sver = RadioSetting("not.softver", "Software Version", val) dealer.append(sver) l1 = str(mess.line1).strip(" \xff") line1 = RadioSetting("message.line1", "Comment 1", RadioSettingValueString(0, 32, l1)) dealer.append(line1) l2 = str(mess.line2).strip(" \xff") line2 = RadioSetting("message.line2", "Comment 2", RadioSettingValueString(0, 32, l2)) dealer.append(line2) sprog = RadioSetting("settings.self_prog", "Self program", RadioSettingValueBoolean(sett.self_prog)) dealer.append(sprog) clone = RadioSetting("settings.clone", "Allow clone", RadioSettingValueBoolean(sett.clone)) dealer.append(clone) panel = RadioSetting("settings.panel_test", "Panel Test", RadioSettingValueBoolean(sett.panel_test)) dealer.append(panel) fmw = RadioSetting("settings.firmware_prog", "Firmware program", RadioSettingValueBoolean(sett.firmware_prog)) dealer.append(fmw) # front keys # The Mobile only parameters are wrapped here if self.TYPE[0] == "M": vu = RadioSetting("keys.kVOL_UP", "VOL UP", RadioSettingValueList(KEYS.values(), KEYS[int(keys.kVOL_UP)])) fkeys.append(vu) vd = RadioSetting("keys.kVOL_DOWN", "VOL DOWN", RadioSettingValueList(KEYS.values(), KEYS[int(keys.kVOL_DOWN)])) fkeys.append(vd) chu = RadioSetting("keys.kCH_UP", "CH UP", RadioSettingValueList(KEYS.values(), KEYS[int(keys.kCH_UP)])) fkeys.append(chu) chd = RadioSetting("keys.kCH_DOWN", "CH DOWN", RadioSettingValueList(KEYS.values(), KEYS[int(keys.kCH_DOWN)])) fkeys.append(chd) foot = RadioSetting("keys.kFOOT", "Foot switch", RadioSettingValueList(KEYS.values(), KEYS[int(keys.kFOOT)])) fkeys.append(foot) # this is the common buttons for all # 260G model don't have the front keys if b"P2600" not in self.TYPE: scn_name = "SCN" if self.TYPE[0] == b"P": scn_name = "Open Circle" scn = RadioSetting("keys.kSCN", scn_name, RadioSettingValueList(KEYS.values(), KEYS[int(keys.kSCN)])) fkeys.append(scn) a_name = "A" if self.TYPE[0] == b"P": a_name = "Closed circle" a = RadioSetting("keys.kA", a_name, RadioSettingValueList(KEYS.values(), KEYS[int(keys.kA)])) fkeys.append(a) da_name = "D/A" if self.TYPE[0] == b"P": da_name = "< key" da = RadioSetting("keys.kDA", da_name, RadioSettingValueList(KEYS.values(), KEYS[int(keys.kDA)])) fkeys.append(da) gu_name = "Triangle up" if self.TYPE[0] == b"P": gu_name = "Side 1" gu = RadioSetting("keys.kGROUP_UP", gu_name, RadioSettingValueList(KEYS.values(), KEYS[int(keys.kGROUP_UP)])) fkeys.append(gu) # Side keys on portables gd_name = "Triangle Down" if self.TYPE[0] == b"P": gd_name = "> key" gd = RadioSetting("keys.kGROUP_DOWN", gd_name, RadioSettingValueList(KEYS.values(), KEYS[int(keys.kGROUP_DOWN)])) fkeys.append(gd) mon_name = "MON" if self.TYPE[0] == b"P": mon_name = "Side 2" mon = RadioSetting("keys.kMON", mon_name, RadioSettingValueList(KEYS.values(), KEYS[int(keys.kMON)])) fkeys.append(mon) return top def set_settings(self, settings): """Translate the settings in the UI into bit in the mem_struct I don't understand well the method used in many drivers so, I used mine, ugly but works ok""" mobj = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue # Let's roll the ball if "." in element.get_name(): inter, setting = element.get_name().split(".") # you must ignore the settings with "not" # this are READ ONLY attributes if inter == "not": continue obj = getattr(mobj, inter) value = element.value # integers case + special case if setting in ["tot", "tot_alert", "min_vol", "tone_vol", "sql_level", "tot_rekey", "tot_reset"]: # catching the "off" values as zero try: value = int(value) except: value = 0 # tot case step 15 if setting == "tot": value = value * 15 # off is special if value == 0: value = 0x4b0 # Caso tone_vol if setting == "tone_vol": # off is special if value == 32: value = 0xff # Bool types + inverted if setting in ["c2t", "poweron_tone", "control_tone", "warn_tone", "battery_save", "self_prog", "clone", "panel_test"]: value = bool(value) # this cases are inverted if setting == "c2t": value = not value # case battery save is special if setting == "battery_save": if bool(value) is True: value = 0x32 else: value = 0xff # String cases if setting in ["poweronmesg", "line1", "line2"]: # some vars value = str(value) just = 8 # lines with 32 if "line" in setting: just = 32 # empty case if len(value) == 0: value = "\xff" * just else: value = value.ljust(just) # case keys, with special config if inter == "keys": value = list(KEYS.keys())[list(KEYS.values()).index( str(value))] # Apply al configs done setattr(obj, setting, value) def get_bank_model(self): """Pass the bank model to the UI part""" rf = self.get_features() if rf.has_bank is True: return Kenwood60GBankModel(self) else: return None def _get_bank(self, loc): """Get the bank data for a specific channel""" mem = self._memobj.memory[loc - 1] bank = int(mem.bank) - 1 if bank > self._num_banks or bank < 1: # all channels must belong to a bank, even with just 1 bank return 0 else: return bank def _set_bank(self, loc, bank): """Set the bank data for a specific channel""" try: b = int(bank) if b > 127: b = 0 mem = self._memobj.memory[loc - 1] mem.bank = b + 1 except: msg = "You can't have a channel without a bank, click another bank" raise errors.InvalidDataError(msg) # This kenwwood family is known as "60-G Series" # all this radios ending in G are compatible: # # Portables VHF TK-260G/270G/272G/278G # Portables UHF TK-360G/370G/372G/378G/388G # # Mobiles VHF TK-760G/762G/768G # Mobiles VHF TK-860G/862G/868G # # WARNING !!!! Radios With Password in the data section ############### # # When a radio has a data password (aka to program it) the last byte (#8) # in the id code change from \xf1 to \xb1; so we remove this last byte # from the identification procedures and variants. # # This effectively render the data password USELESS even if set. # Translation: Chirps will read and write password protected radios # with no problem. @directory.register class TK868G_Radios(Kenwood_Serie_60G): """Kenwood TK-868G Radio M/C""" MODEL = "TK-868G" TYPE = b"M8680" VARIANTS = { b"M8680\x18\xff": (8, 400, 490, "M"), b"M8680;\xff": (128, 350, 390, "C1"), b"M86808\xff": (128, 400, 430, "C2"), b"M86806\xff": (128, 450, 490, "C3"), } @directory.register class TK862G_Radios(Kenwood_Serie_60G): """Kenwood TK-862G Radio K/E/(N)E""" MODEL = "TK-862G" TYPE = b"M8620" VARIANTS = { b"M8620\x06\xff": (8, 450, 490, "K"), b"M8620\x07\xff": (8, 485, 512, "K2"), b"M8620&\xff": (8, 440, 470, "E"), b"M8620V\xff": (8, 440, 470, "(N)E"), } @directory.register class TK860G_Radios(Kenwood_Serie_60G): """Kenwood TK-860G Radio K""" MODEL = "TK-860G" TYPE = b"M8600" VARIANTS = { b"M8600\x08\xff": (128, 400, 430, "K"), b"M8600\x06\xff": (128, 450, 490, "K1"), b"M8600\x07\xff": (128, 485, 512, "K2"), b"M8600\x18\xff": (128, 400, 430, "M"), b"M8600\x16\xff": (128, 450, 490, "M1"), b"M8600\x17\xff": (128, 485, 520, "M2"), } @directory.register class TK768G_Radios(Kenwood_Serie_60G): """Kenwood TK-768G Radios [M/C]""" MODEL = "TK-768G" TYPE = b"M7680" # Note that 8 CH don't have banks VARIANTS = { b"M7680\x15\xff": (8, 136, 162, "M2"), b"M7680\x14\xff": (8, 148, 174, "M"), b"M76805\xff": (128, 136, 162, "C2"), b"M76804\xff": (128, 148, 174, "C"), } @directory.register class TK762G_Radios(Kenwood_Serie_60G): """Kenwood TK-762G Radios [K/E/NE]""" MODEL = "TK-762G" TYPE = b"M7620" # Note that 8 CH don't have banks VARIANTS = { b"M7620\x05\xff": (8, 136, 162, "K2"), b"M7620\x04\xff": (8, 148, 172, "K"), b"M7620$\xff": (8, 148, 172, "E"), b"M7620T\xff": (8, 148, 172, "NE"), } @directory.register class TK760G_Radios(Kenwood_Serie_60G): """Kenwood TK-760G Radios [K/M/(N)E]""" MODEL = "TK-760G" TYPE = b"M7600" VARIANTS = { b"M7600\x05\xff": (128, 136, 162, "K2"), b"M7600\x04\xff": (128, 148, 174, "K"), b"M7600\x14\xff": (128, 148, 174, "M"), b"M7600T\xff": (128, 148, 174, "NE") } @directory.register class TK388G_Radios(Kenwood_Serie_60G): """Kenwood TK-388 Radio [K/E/M/NE]""" MODEL = "TK-388G" TYPE = b"P3880" VARIANTS = { b"P3880\x1b\xff": (128, 350, 370, "M") } @directory.register class TK378G_Radios(Kenwood_Serie_60G): """Kenwood TK-378 Radio [K/E/M/NE]""" MODEL = "TK-378G" TYPE = b"P3780" VARIANTS = { b"P3780\x16\xff": (16, 450, 470, "M"), b"P3780\x17\xff": (16, 400, 420, "M1"), b"P3780\x36\xff": (128, 490, 512, "C"), b"P3780\x39\xff": (128, 403, 430, "C1") } @directory.register class TK372G_Radios(Kenwood_Serie_60G): """Kenwood TK-372 Radio [K/E/M/NE]""" MODEL = "TK-372G" TYPE = b"P3720" VARIANTS = { b"P3720\x06\xff": (32, 450, 470, "K"), b"P3720\x07\xff": (32, 470, 490, "K1"), b"P3720\x08\xff": (32, 490, 512, "K2"), b"P3720\x09\xff": (32, 403, 430, "K3") } @directory.register class TK370G_Radios(Kenwood_Serie_60G): """Kenwood TK-370 Radio [K/E/M/NE]""" MODEL = "TK-370G" TYPE = b"P3700" VARIANTS = { b"P3700\x06\xff": (128, 450, 470, "K"), b"P3700\x07\xff": (128, 470, 490, "K1"), b"P3700\x08\xff": (128, 490, 512, "K2"), b"P3700\x09\xff": (128, 403, 430, "K3"), b"P3700\x16\xff": (128, 450, 470, "M"), b"P3700\x17\xff": (128, 470, 490, "M1"), b"P3700\x18\xff": (128, 490, 520, "M2"), b"P3700\x19\xff": (128, 403, 430, "M3"), b"P3700&\xff": (128, 440, 470, "E"), b"P3700V\xff": (128, 440, 470, "NE") } @directory.register class TK360G_Radios(Kenwood_Serie_60G): """Kenwood TK-360 Radio [K/E/M/NE]""" MODEL = "TK-360G" TYPE = b"P3600" VARIANTS = { b"P3600\x06\xff": (8, 450, 470, "K"), b"P3600\x07\xff": (8, 470, 490, "K1"), b"P3600\x08\xff": (8, 490, 512, "K2"), b"P3600\x09\xff": (8, 403, 430, "K3"), b"P3600&\xff": (8, 440, 470, "E"), b"P3600)\xff": (8, 406, 430, "E1"), b"P3600\x16\xff": (8, 450, 470, "M"), b"P3600\x17\xff": (8, 470, 490, "M1"), b"P3600\x19\xff": (8, 403, 430, "M2"), b"P3600V\xff": (8, 440, 470, "NE"), b"P3600Y\xff": (8, 403, 430, "NE1") } @directory.register class TK278G_Radios(Kenwood_Serie_60G): """Kenwood TK-278G Radio C/C1/M/M1""" MODEL = "TK-278G" TYPE = b"P2780" # Note that 16 CH don't have banks VARIANTS = { b"P27805\xff": (128, 136, 150, "C1"), b"P27804\xff": (128, 150, 174, "C"), b"P2780\x15\xff": (16, 136, 150, "M1"), b"P2780\x14\xff": (16, 150, 174, "M") } @directory.register class TK272G_Radios(Kenwood_Serie_60G): """Kenwood TK-272G Radio K/K1""" MODEL = "TK-272G" TYPE = b"P2720" VARIANTS = { b"P2720\x05\xfb": (32, 136, 150, "K1"), b"P2720\x04\xfb": (32, 150, 174, "K") } @directory.register class TK270G_Radios(Kenwood_Serie_60G): """Kenwood TK-270G Radio K/K1/M/E/NE/NT""" MODEL = "TK-270G" TYPE = b"P2700" VARIANTS = { b"P2700T\xff": (128, 146, 174, "NE/NT"), b"P2700$\xff": (128, 146, 174, "E"), b"P2700\x14\xff": (128, 150, 174, "M"), b"P2700\x05\xff": (128, 136, 150, "K1"), b"P2700\x04\xff": (128, 150, 174, "K") } @directory.register class TK260G_Radios(Kenwood_Serie_60G): """Kenwood TK-260G Radio K/K1/M/E/NE/NT""" MODEL = "TK-260G" _hasbanks = False TYPE = b"P2600" VARIANTS = { b"P2600U\xff": (8, 136, 150, "N1"), b"P2600T\xff": (8, 146, 174, "N"), b"P2600$\xff": (8, 150, 174, "E"), b"P2600\x14\xff": (8, 150, 174, "M"), b"P2600\x05\xff": (8, 136, 150, "K1"), b"P2600\x04\xff": (8, 150, 174, "K") } chirp-20240224/chirp/drivers/retevis_rb17p.py0000644000175000017500000004673514565075506017721 0ustar hibbyhibby# Copyright 2022 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { char name[10]; // 10-character Alpha Tag } names[128]; #seekto 0x0810; struct { u8 unknown01:5, dualwatch:1, workmode:2; u8 scanmode:2, unknown02:3, autokeylock:1, unknown03:2; u8 unknown04:1, beep:1, unknown05:1, voice:1, unknown06:1, noaa:1, batterysave:2; u8 squelchlevel; u8 unknown07:5, timeouttimer:2, unknown08:1; u8 alarmtype:1, voxdelay:3, voxlevel:4; u8 unknown10:2, backlight:2, unknown11:4; u8 unknown12[3]; u8 unknown13:3, rogerbeep:1, unknown14:1, sidekey:3; } settings; #seekto 0x1000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unknown1:4, compander:1, unknown2:1, highpower:1, unknown3:1; u8 unknown4:3, wide:1, scan:1, unknown5:1, bcl:2; u8 unknown6[2]; } memory[128]; """ CMD_ACK = b"\x06" ALARMTYPE_LIST = ["Local & Remote", "Local"] BACKLIGHT_LIST = ["5 seconds", "10 seconds", "30 seconds", "Always"] BATTERYSAVE_LIST = ["Off", "1:4", "1:8"] SCANMODE_LIST = ["Time Operated", "Carrier Operated", "Search"] SIDEKEY_LIST = ["Off", "Scan", "VOX", "2nd PTT", "NOAA", "Monitor"] TIMEOUTTIMER_LIST = ["60 seconds", "120 seconds", "180 seconds"] VOXDELAY_LIST = ["0.3", "0.5", "1", "1.5", "2", "2.5"] VOXLEVEL_LIST = ["Off", "1", "2", "3", "4", "5", "6", "7", "8", "9"] WORKMODE_LIST = ["Frequencies", "Channel Numbers", "Names"] BCL = ["Off", "Carrier", "QT/DCS"] GMRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] GMRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] GMRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] GMRS_FREQS = GMRS_FREQS1 + GMRS_FREQS2 + GMRS_FREQS3 * 2 def _enter_programming_mode(radio): serial = radio.pipe try: serial.write(b"\x02") time.sleep(0.01) serial.write(radio._magic) ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if not ack: raise errors.RadioError("No response from radio") elif ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") try: serial.write(b"M" + b"\x02") ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") if not ident.startswith(radio._fingerprint): LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] except: raise errors.RadioError("Failed to read block at %04x" % block_addr) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr, block_size in radio._ranges: for addr in range(start_addr, end_addr, block_size): status.cur = addr + block_size radio.status_fn(status) _write_block(radio, addr, block_size) class RB17P_Base(chirp_common.CloneModeRadio): """Base class for Retevis RB17P""" VENDOR = "Retevis" MODEL = "RB17P Base" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x40 VALID_BANDS = [(400000000, 470000000)] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PGA588" _fingerprint = b"\xFF" * 8 _upper = 128 _gmrs = True _ranges = [(0x0000, 0x1800, 0x40), ] _memsize = 0x1800 _valid_chars = chirp_common.CHARSET_ALPHANUMERIC + \ "`~!@#$%^&*()-=_+[]\\{}|;':\",./<>?" def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.valid_modes = ["NFM", "FM"] # 12.5 kHz, 25 kHz. rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_power_levels = self.POWER_LEVELS rf.can_odd_split = True rf.has_rx_dtcs = True rf.has_ctone = True rf.has_cross = True rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.has_tuning_step = False rf.has_bank = False rf.has_name = True rf.valid_name_length = 10 rf.valid_characters = self._valid_chars rf.memory_bounds = (1, 128) rf.valid_bands = self.VALID_BANDS rf.valid_tuning_steps = chirp_common.TUNING_STEPS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): self._mmap = do_download(self) self.process_mmap() def sync_out(self): do_upload(self) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _decode_tone(self, val): val = int(val) if val == 16665: return '', None, None elif val >= 12000: return 'DTCS', val - 12000, 'R' elif val >= 8000: return 'DTCS', val - 8000, 'N' else: return 'Tone', val / 10.0, None def _encode_tone(self, memval, mode, value, pol): if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_memory(self, number): _mem = self._memobj.memory[number - 1] _nam = self._memobj.names[number - 1] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _nam.name: if str(char) == "\xFF": char = " " # may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() mem.mode = _mem.wide and "FM" or "NFM" mem.skip = not _mem.scan and "S" or "" txtone = self._decode_tone(_mem.txtone) rxtone = self._decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) mem.power = self.POWER_LEVELS[1 - _mem.highpower] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueList(BCL, BCL[_mem.bcl])) mem.extra.append(rs) rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(_mem.compander)) mem.extra.append(rs) immutable = [] if self._gmrs: if mem.freq in GMRS_FREQS: if mem.freq in GMRS_FREQS1: # Non-repeater GMRS channels (limit duplex) mem.duplex == '' mem.offset = 0 immutable = ["duplex", "offset"] elif mem.freq in GMRS_FREQS2: # Non-repeater FRS channels (limit duplex, power) mem.duplex == '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable = ["duplex", "offset", "mode", "power"] elif mem.freq in GMRS_FREQS3: # GMRS repeater channels, always either simplex or +5 MHz if mem.duplex != '+': mem.duplex = '' mem.offset = 0 else: mem.offset = 5000000 else: # Not a GMRS channel, so restrict duplex since it will be # forced to off. mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] mem.immutable = immutable return mem def check_set_memory_immutable_policy(self, existing, new): existing.immutable = [] super().check_set_memory_immutable_policy(existing, new) def set_memory(self, mem): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] _nam = self._memobj.names[mem.number - 1] if mem.empty: _mem.set_raw(b"\xFF" * (_mem.size() // 8)) _nam.set_raw(b"\xFF" * (_nam.size() // 8)) return _mem.set_raw(b"\x00" * (_mem.size() // 8)) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" txtone, rxtone = chirp_common.split_tone_encode(mem) self._encode_tone(_mem.txtone, *txtone) self._encode_tone(_mem.rxtone, *rxtone) if self.MODEL != "T18" and self.MODEL != "RB18": _mem.highpower = mem.power == self.POWER_LEVELS[0] _mem.wide = mem.mode == "FM" _mem.scan = mem.skip == "" for setting in mem.extra: setattr(_mem, setting.get_name(), int(setting.value)) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) # Menu 01 - Work Mode rs = RadioSetting("workmode", "Work Mode", RadioSettingValueList( WORKMODE_LIST, WORKMODE_LIST[(_settings.workmode) - 1])) basic.append(rs) # Menu 04 - Squelch rs = RadioSetting("squelchlevel", "Squelch level", RadioSettingValueInteger( 0, 9, _settings.squelchlevel)) basic.append(rs) # Menu 05 - Battery Save rs = RadioSetting("batterysave", "Battery Save", RadioSettingValueList( BATTERYSAVE_LIST, BATTERYSAVE_LIST[_settings.batterysave])) basic.append(rs) # Menu 06 - Dual Watch rs = RadioSetting("dualwatch", "Dual Watch", RadioSettingValueBoolean(_settings.dualwatch)) basic.append(rs) # Menu 07 - Backlight Duration[s] rs = RadioSetting("backlight", "Backlight Duration", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.backlight])) basic.append(rs) # Menu 09 - Beep Tone rs = RadioSetting("beep", "Key Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) # Menu 10 - Voice Annunciation rs = RadioSetting("voice", "Voice prompts", RadioSettingValueBoolean(_settings.voice)) basic.append(rs) # Menu 11 - Time out Timer[s] rs = RadioSetting("timeouttimer", "Timeout timer", RadioSettingValueList( TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[ (_settings.timeouttimer) - 1])) basic.append(rs) # Menu 12 - Roger Tone rs = RadioSetting("rogerbeep", "Roger beep", RadioSettingValueBoolean(_settings.rogerbeep)) basic.append(rs) # Menu 13 - SideKey rs = RadioSetting("sidekey", "Side Key", RadioSettingValueList( SIDEKEY_LIST, SIDEKEY_LIST[_settings.sidekey])) basic.append(rs) # Menu 14 - Auto Key Lock rs = RadioSetting("autokeylock", "Auto Key Lock", RadioSettingValueBoolean(_settings.autokeylock)) basic.append(rs) # Menu 17 - NOAA rs = RadioSetting("noaa", "NOAA", RadioSettingValueBoolean(_settings.noaa)) basic.append(rs) # Scan Mode rs = RadioSetting("scanmode", "Scan mode", RadioSettingValueList( SCANMODE_LIST, SCANMODE_LIST[_settings.scanmode])) basic.append(rs) # Alarm Type rs = RadioSetting("alarmtype", "Alarm Type", RadioSettingValueList( ALARMTYPE_LIST, ALARMTYPE_LIST[_settings.alarmtype])) basic.append(rs) # VOX Level rs = RadioSetting("voxlevel", "Vox level", RadioSettingValueList( VOXLEVEL_LIST, VOXLEVEL_LIST[_settings.voxlevel])) basic.append(rs) # VOX Delay rs = RadioSetting("voxdelay", "Vox delay", RadioSettingValueList( VOXDELAY_LIST, VOXDELAY_LIST[_settings.voxdelay])) basic.append(rs) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "timeouttimer": setattr(obj, setting, int(element.value) + 1) elif setting == "workmode": setattr(obj, setting, int(element.value) + 1) else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # Radios that have always been post-metadata, so never do # old-school detection return False @directory.register class RB17PRadio(RB17P_Base): """Retevis RB17P""" VENDOR = "Retevis" MODEL = "RB17P" _gmrs = True _ranges = [(0x0010, 0x0510, 0x40), (0x0810, 0x0830, 0x30), (0x1000, 0x1800, 0x40) ] def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if mem.freq not in GMRS_FREQS: if mem.duplex != "off": msgs.append(chirp_common.ValidationWarning(_msg_duplex)) elif mem.duplex and mem.offset != 5000000: msgs.append(chirp_common.ValidationWarning(_msg_offset)) return msgs chirp-20240224/chirp/drivers/ic2300.py0000644000175000017500000003356714466370044016117 0ustar hibbyhibby# Copyright 2017 Windsor Schmidt # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, directory, bitwise from chirp.drivers import icf from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean, RadioSettings # The Icom IC-2300H is a 65W, 144 MHz mobile transceiver based on the IC-2200H. # Unlike the IC-2200H, this model does not accept Icom's UT-118 D-STAR board. # # A simple USB interface based on a typical FT232RL breakout board was used # during development of this module. A schematic diagram is as follows: # # # 3.5mm plug from IC-2300H # sleeve / ring / tip # --.______________ # | | | \ # |______|___|___/ FT232RL breakout # --' | | .------------------. # | +--------| RXD | # | | D1 | | # | +--|>|---| TXD | USB/PC # | | R1 | |--------> # | +--[_]---| VCC (5V) | # | | | # +------------| GND | # `------------------' # # D1: 1N4148 Schottky diode # R1: 10K ohm resistor MEM_FORMAT = """ #seekto 0x0000; // channel memories struct { ul16 frequency; ul16 offset; char name[6]; u8 repeater_tone; u8 ctcss_tone; u8 dtcs_code; u8 tuning_step:4, tone_mode:4; u8 unknown1:3, mode_narrow:1, power:2, unknown2:2; u8 dtcs_polarity:2, duplex:2, unknown3:1, reverse_duplex:1, tx_inhibit:1, display_style:1; } memory[200]; #seekto 0x1340; // channel memory flags struct { u8 unknown5:2, empty:1, skip:1, bank:4; } flags[200]; #seekto 0x1660; // power-on and regular set menu items struct { u8 key_beep; u8 tx_timeout; u8 auto_repeater; u8 auto_power_off; u8 repeater_lockout; u8 squelch_delay; u8 squelch_type; u8 dtmf_speed; u8 display_type; u8 unknown6; u8 tone_burst; u8 voltage_display; u8 unknown7; u8 display_brightness; u8 display_color; u8 auto_dimmer; u8 display_contrast; u8 scan_pause_timer; u8 mic_gain; u8 scan_resume_timer; u8 weather_alert; u8 bank_link_enable; u8 bank_link[10]; } settings; """ TUNING_STEPS = [5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0] TONE_MODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+"] DTCSP = ["NN", "NR", "RN", "RR"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=65), chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("MidLow", watts=10), chirp_common.PowerLevel("Mid", watts=25)] def _wipe_memory(mem, char): mem.set_raw(char * (mem.size() // 8)) @directory.register class IC2300Radio(icf.IcomCloneModeRadio): """Icom IC-2300""" VENDOR = "Icom" MODEL = "IC-2300H" _model = "\x32\x51\x00\x01" _memsize = 6304 _endframe = "Icom Inc.C5\xfd" _can_hispeed = True _ranges = [(0x0000, 0x18a0, 32)] # upload entire memory for now def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.valid_modes = ["FM", "NFM"] rf.valid_tmodes = list(TONE_MODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(TUNING_STEPS) rf.valid_bands = [(136000000, 174000000)] # USA tx range: 144-148 MHz rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS rf.has_settings = True return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def _get_bank(self, loc): _flag = self._memobj.flags[loc] if _flag.bank == 0x0a: return None else: return _flag.bank def _set_bank(self, loc, bank): _flag = self._memobj.flags[loc] if bank is None: _flag.bank = 0x0a else: _flag.bank = bank def get_memory(self, number): _mem = self._memobj.memory[number] _flag = self._memobj.flags[number] mem = chirp_common.Memory() mem.number = number if _flag.empty: mem.empty = True return mem mult = int(TUNING_STEPS[_mem.tuning_step] * 1000) mem.freq = (_mem.frequency * mult) mem.offset = (_mem.offset * mult) mem.name = str(_mem.name).rstrip() mem.rtone = chirp_common.TONES[_mem.repeater_tone] mem.ctone = chirp_common.TONES[_mem.ctcss_tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs_code] mem.tuning_step = TUNING_STEPS[_mem.tuning_step] mem.tmode = TONE_MODES[_mem.tone_mode] mem.mode = "NFM" if _mem.mode_narrow else "FM" mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.duplex = DUPLEX[_mem.duplex] mem.skip = "S" if _flag.skip else "" mem.power = POWER_LEVELS[_mem.power] # Reverse duplex mem.extra = RadioSettingGroup("extra", "Extra") rev = RadioSetting("reverse_duplex", "Reverse duplex", RadioSettingValueBoolean(bool(_mem.reverse_duplex))) rev.set_doc("Reverse duplex") mem.extra.append(rev) # Tx inhibit tx_inhibit = RadioSetting("tx_inhibit", "TX inhibit", RadioSettingValueBoolean( bool(_mem.tx_inhibit))) tx_inhibit.set_doc("TX inhibit") mem.extra.append(tx_inhibit) # Memory display style opt = ["Frequency", "Label"] dsp = RadioSetting("display_style", "Display style", RadioSettingValueList(opt, opt[_mem.display_style])) dsp.set_doc("Memory display style") mem.extra.append(dsp) return mem def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def set_memory(self, mem): number = mem.number _mem = self._memobj.memory[number] _flag = self._memobj.flags[number] was_empty = int(_flag.empty) _flag.empty = mem.empty if mem.empty: _wipe_memory(_mem, "\xff") return if was_empty: _wipe_memory(_mem, "\x00") mult = mem.tuning_step * 1000 _mem.frequency = (mem.freq / mult) _mem.offset = mem.offset / mult _mem.name = mem.name.ljust(6) _mem.repeater_tone = chirp_common.TONES.index(mem.rtone) _mem.ctcss_tone = chirp_common.TONES.index(mem.ctone) _mem.dtcs_code = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tuning_step = TUNING_STEPS.index(mem.tuning_step) _mem.tone_mode = TONE_MODES.index(mem.tmode) _mem.mode_narrow = mem.mode.startswith("N") _mem.dtcs_polarity = DTCSP.index(mem.dtcs_polarity) _mem.duplex = DUPLEX.index(mem.duplex) if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = POWER_LEVELS[0] _flag.skip = mem.skip != "" for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") front_panel = RadioSettingGroup("front_panel", "Front Panel Settings") top = RadioSettings(basic, front_panel) # Transmit timeout opt = ['Disabled', '1 minute'] + \ [s + ' minutes' for s in map(str, range(2, 31))] rs = RadioSetting("tx_timeout", "Transmit timeout (min)", RadioSettingValueList(opt, opt[ _settings.tx_timeout ])) basic.append(rs) # Auto Repeater (USA model only) opt = ["Disabled", "Duplex Only", "Duplex and tone"] rs = RadioSetting("auto_repeater", "Auto repeater", RadioSettingValueList(opt, opt[ _settings.auto_repeater ])) basic.append(rs) # Auto Power Off opt = ["Disabled", "30 minutes", "60 minutes", "120 minutes"] rs = RadioSetting("auto_power_off", "Auto power off", RadioSettingValueList(opt, opt[ _settings.auto_power_off ])) basic.append(rs) # Squelch Delay opt = ["Short", "Long"] rs = RadioSetting("squelch_delay", "Squelch delay", RadioSettingValueList(opt, opt[ _settings.squelch_delay ])) basic.append(rs) # Squelch Type opt = ["Noise squelch", "S-meter squelch", "Squelch attenuator"] rs = RadioSetting("squelch_type", "Squelch type", RadioSettingValueList(opt, opt[ _settings.squelch_type ])) basic.append(rs) # Repeater Lockout opt = ["Disabled", "Repeater lockout", "Busy lockout"] rs = RadioSetting("repeater_lockout", "Repeater lockout", RadioSettingValueList(opt, opt[ _settings.repeater_lockout ])) basic.append(rs) # DTMF Speed opt = ["100ms interval, 5.0 cps", "200ms interval, 2.5 cps", "300ms interval, 1.6 cps", "500ms interval, 1.0 cps"] rs = RadioSetting("dtmf_speed", "DTMF speed", RadioSettingValueList(opt, opt[ _settings.dtmf_speed ])) basic.append(rs) # Scan pause timer opt = [s + ' seconds' for s in map(str, range(2, 22, 2))] + ['Hold'] rs = RadioSetting("scan_pause_timer", "Scan pause timer", RadioSettingValueList( opt, opt[_settings.scan_pause_timer])) basic.append(rs) # Scan Resume Timer opt = ['Immediate'] + \ [s + ' seconds' for s in map(str, range(1, 6))] + ['Hold'] rs = RadioSetting("scan_resume_timer", "Scan resume timer", RadioSettingValueList( opt, opt[_settings.scan_resume_timer])) basic.append(rs) # Weather Alert (USA model only) rs = RadioSetting("weather_alert", "Weather alert", RadioSettingValueBoolean(_settings.weather_alert)) basic.append(rs) # Tone Burst rs = RadioSetting("tone_burst", "Tone burst", RadioSettingValueBoolean(_settings.tone_burst)) basic.append(rs) # Memory Display Type opt = ["Frequency", "Channel", "Name"] rs = RadioSetting("display_type", "Memory display", RadioSettingValueList(opt, opt[_settings.display_type])) front_panel.append(rs) # Display backlight brightness; opt = ["1 (dimmest)", "2", "3", "4 (brightest)"] rs = RadioSetting("display_brightness", "Backlight brightness", RadioSettingValueList( opt, opt[_settings.display_brightness])) front_panel.append(rs) # Display backlight color opt = ["Amber", "Yellow", "Green"] rs = RadioSetting("display_color", "Backlight color", RadioSettingValueList(opt, opt[_settings.display_color])) front_panel.append(rs) # Display contrast opt = ["1 (lightest)", "2", "3", "4 (darkest)"] rs = RadioSetting("display_contrast", "Display contrast", RadioSettingValueList( opt, opt[_settings.display_contrast])) front_panel.append(rs) # Auto dimmer opt = ["Disabled", "Backlight off", "1 (dimmest)", "2", "3"] rs = RadioSetting("auto_dimmer", "Auto dimmer", RadioSettingValueList(opt, opt[_settings.auto_dimmer])) front_panel.append(rs) # Microphone gain opt = ["Low", "High"] rs = RadioSetting("mic_gain", "Microphone gain", RadioSettingValueList(opt, opt[_settings.mic_gain])) front_panel.append(rs) # Key press beep rs = RadioSetting("key_beep", "Key press beep", RadioSettingValueBoolean(_settings.key_beep)) front_panel.append(rs) # Voltage Display; rs = RadioSetting("voltage_display", "Voltage display", RadioSettingValueBoolean(_settings.voltage_display)) front_panel.append(rs) # TODO: Add Bank Links settings to GUI return top def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue setting = element.get_name() setattr(_settings, setting, element.value) chirp-20240224/chirp/drivers/ft70.py0000644000175000017500000013102514461675424015770 0ustar hibbyhibby# Copyright 2010 Dan Smith # Copyright 2017 Nicolas Pike # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, bitwise from chirp import errors from chirp import memmap from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings, \ RadioSettingValueString, RadioSettingValueList, \ InvalidValueError from chirp import util import string LOG = logging.getLogger(__name__) # Testing # 37 PAG.ABK Turn the pager answer back Function ON/OFF # 38 PAG.CDR Specify a personal code (receive) # 39 PAG.CDT Specify a personal code (transmit) # 47 RX.MOD Select the receive mode. Auto FM AM MEM_SETTINGS_FORMAT = """ // FT-70DE New Model #5329 // // Communications Mode ? AMS,FM DN,DW TX vs RX? // Mode not currently correctly stored in memories ? - ALL show as FM in memories // SKIP test/where stored // Check storage of steps // Pager settings ? // Triple check/ understand _memsize and _block_lengths // Bank name label name size display 6 store 16? padded with 0xFF same for MYCALL and message // CHIRP mode DIG not supported - is there a CHIRP Fusion mode? Auto? // Check character set // Supported Modes ? // Supported Bands ? // rf.has_dtcs_polarity = False - think radio supports DTCS polarity // rf.memory_bounds = (1, 900) - should this be 0? as zero displays as blank // RPT offsets (stored per band) not included. // 59 Display radio firmware version info and Radio ID? // Front Panel settings power etc? // Banks and VFO? // Features Required // Default AMS and Memory name (in mem extras) to enabled. // Bugs // MYCALL and Opening Message errors if not 10 characters // Values greater than one sometimes stored as whole bytes, these need to be refactored into bit fields // to prevent accidental overwriting of adjacent values // Bank Name length not checked on gui input - but first 6 characters are saved correctly. // Extended characters entered as bank names on radio are corrupted in Chirp // Missing // 50 SCV.WTH Set the VFO scan frequency range. BAND / ALL - NOT FOUND // 49 SCM.WTH Set the memory scan frequency range. ALL / BAND - NOT FOUND // Radio Questions // Temp unit C/F not saved by radio, always goes back to C ? // 44 RF SQL Adjusts the RF Squelch threshold level. OFF / S1 - S9? Default is OFF - Based on RF strength - for AM? How // is this different from F, Monitor, Dial Squelch? // Password setting on radio allows letters (DTMF), but letters cannot be entered at the radio's password prompt? // 49 SCM.WTH Set the memory scan frequency range. ALL / BAND Defaults to ALL Not Band as stated in the manual. #seekto 0x049a; struct { u8 unknown0:4, squelch:4; // Squelch F, Monitor, Dial Adjust the Squelch level } squelch_settings; #seekto 0x04ba; struct { u8 unknown:3, scan_resume:5; // 52 SCN.RSM Configure the scan stop mode settings. 2.0 S - 5.0 S - 10.0 S / BUSY / HOLD u8 unknown1:3, dw_resume_interval:5; // 22 DW RSM Configure the scan stop mode settings for Dual Receive. 2.0S-10.0S/BUSY/HOLD u8 unknown2; u8 unknown3:3, apo:5; // 02 APO Set the length of time until the transceiver turns off automatically. u8 unknown4:6, gm_ring:2; // 24 GM RNG Select the beep option while receiving digital GM info. OFF/IN RNG/ALWAYS u8 temp_cf; // Placeholder as not found u8 unknown5; } first_settings; #seekto 0x04ed; struct { u8 unknown1:1, unknown2:1, unknown3:1, unknown4:1, unknown5:1, unknown6:1, unknown7:1, unknown8:1; } test_bit_field; #seekto 0x04c0; struct { u8 unknown1:5, beep_level:3; // 05 BEP.LVL Beep volume setting LEVEL1 - LEVEL4 - LEVEL7 u8 unknown2:6, beep_select:2; // 04 BEEP Sets the beep sound function OFF / KEY+SC / KEY } beep_settings; #seekto 0x04ce; struct { u8 lcd_dimmer; // 14 DIMMER LCD Dimmer u8 dtmf_delay; // 18 DT DLY DTMF delay u8 unknown0[3]; u8 unknown1:4, unknown1:4; u8 lamp; // 28 LAMP Set the duration time of the backlight and keys to be lit u8 lock; // 30 LOCK Configure the lock mode setting. KEY/DIAL/K+D/PTT/K+P/D+P/ALL u8 unknown2_1; u8 mic_gain; // 31 MCGAIN Adjust the microphone gain level u8 unknown2_3; u8 dw_interval; // 21 DW INT Set the priority memory ch mon int during Dual RX 0.1S-5.0S-10.0S u8 ptt_delay; // 42 PTT.DLY Set the PTT delay time. OFF / 20 ms / 50 ms / 100 ms / 200 ms u8 rx_save; // 48 RX.SAVE Set the battery save time. OFF / 0.2 s - 60.0 s u8 scan_restart; // 53 SCN.STR Set the scanning restart time. 0.1 s - 2.0 s - 10.0 s u8 unknown2_5; u8 unknown2_6; u8 unknown4[5]; u8 tot; // 56 TOT Set the transmission timeout timer u8 unknown5[3]; // 26 u8 vfo_mode:1, // 60 VFO.MOD Set freq setting range in the VFO mode by DIAL knob. ALL / BAND unknown7:1, scan_lamp:1, // 51 SCN.LMP Set the scan lamp ON or OFF when scanning stops On/Off unknown8:1, ars:1, // 45 RPT.ARS Turn the ARS function on/off. dtmf_speed:1, // 20 DT SPD Set DTMF speed unknown8:1, dtmf_mode:1; // DTMF Mode set from front panel u8 busy_led:1, // Not Supported ? unknown8_2:1, unknown8_3:1, bclo:1, // 03 BCLO Turns the busy channel lockout function on/off. beep_edge:1, // 06 BEP.Edg Sets the beep sound ON or OFF when a band edge is encountered. unknown8_6:1, unknown8_7:1, unknown8_8:1; // 28 u8 unknown9_1:1, unknown9_2:1, unknown9_3:1, unknown9_4:1, unknown9_5:1, password:1, // Placeholder location home_rev:1, // 26 HOME/REV Select the function of the [HOME/REV] key. moni:1; // 32 Mon/T-Call Select the function of the [MONI/T-CALL] switch. u8 gm_interval:4, // 30 // 25 GM INT Set tx interval of digital GM information. OFF / NORMAL / LONG unknown10:4; u8 unknown11; u8 unknown12:1, unknown12_2:1, unknown12_3:1, unknown12_4:1, home_vfo:1, // 27 HOME->VFO Turn transfer VFO to the Home channel ON or OFF. unknown12_6:1, unknown12_7:1, dw_rt:1; // 32 // 23 DW RVT Turn "Priority Channel Revert" feature ON or OFF during Dual Rx. u8 unknown33; u8 unknown34; u8 unknown35; u8 unknown36; u8 unknown37; u8 unknown38; u8 unknown39; u8 unknown40; u8 unknown41; u8 unknown42; u8 unknown43; u8 unknown44; u8 unknown45; u8 prog_key1; // P1 Set Mode Items to the Programmable Key u8 prog_key2; // P2 Set Mode Items to the Programmable Key u8 unknown48; u8 unknown49; u8 unknown50; } scan_settings; #seekto 0x064b; struct { u8 unknown1:1, unknown2:1, unknown3:1, unknown4:1, vfo_scan_width:1, // Placeholder as not found - 50 SCV.WTH Set the VFO scan frequency range. BAND / ALL memory_scan_width:1, // Placeholder as not found - 49 SCM.WTH Set the memory scan frequency range. ALL / BAND unknown7:1, unknown8:1; } scan_settings_1; #seekto 0x06B6; struct { u8 unknown1:3, volume:5; // # VOL and Dial Adjust the volume level } scan_settings_2; #seekto 0x0690; // Memory or VFO Settings Map? struct { u8 unknown[48]; // Array cannot be 64 elements! u8 unknown1[16]; // Exception: Not implemented for chirp.bitwise.structDataElement } vfo_info_1; #seekto 0x0710; // Backup Memory or VFO Settings Map? struct { u8 unknown[48]; u8 unknown1[16]; } vfo_backup_info_1; #seekto 0x047e; struct { u8 unknown1; u8 flag; u16 unknown2; struct { char padded_string[6]; // 36 OPN.MSG Select MSG then key vm to edit it } message; } opening_message; // 36 OPN.MSG Select the Opening Message when transceiver is ON. OFF/MSG/DC #seekto 0x094a; // DTMF Memories struct { u8 memory[16]; } dtmf[10]; #seekto 0x154a; struct { u16 channel[100]; } bank_members[24]; #seekto 0x54a; struct { u16 in_use; } bank_used[24]; #seekto 0x0EFE; struct { u8 unknown[2]; u8 name[6]; u8 unknown1[10]; } bank_info[24]; #seekto 0xCF30; struct { u8 unknown0; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 unknown5; u8 unknown6; u8 digital_popup; // 15 DIG.POP Call sign display pop up time } digital_settings_more; #seekto 0xCF7C; struct { u8 unknown0:6, ams_tx_mode:2; // AMS TX Mode Short Press AMS button AMS TX Mode u8 unknown1; u8 unknown2:7, standby_beep:1; // 07 BEP.STB Standby Beep in the digital C4FM mode. On/Off u8 unknown3; u8 unknown4:6, gm_ring:2; // 24 GM RNG Select beep option while rx digital GM info. OFF/IN RNG/ALWAYS u8 unknown5; u8 rx_dg_id; // RX DG-ID Long Press Mode Key, Mode Key to select, Dial u8 tx_dg_id; // TX DG-ID Long Press Mode Key, Dial u8 unknown6:7, vw_mode:1; // 16 DIG VW Turn the VW mode selection ON or OFF u8 unknown7; } digital_settings; // ^^^ All above referenced U8's have been refactored to minimum number of bits. """ MEM_FORMAT = """ #seekto 0x2D4A; struct { // 32 Bytes per memory entry u8 display_tag:1, // 0 Display Freq, 1 Display Name unknown0:1, // Mode if AMS not selected???????? deviation:1, // 0 Full deviation (Wide), 1 Half deviation (Narrow) clock_shift:1, // 0 None, 1 CPU clock shifted unknown1:4; // 1 u8 mode:2, // FM,AM,WFM only? - check duplex:2, // Works tune_step:4; // Works - check all steps? 7 = Auto // 1 bbcd freq[3]; // Works // 3 u8 power:2, // Works unknown2:1, // 0 FM, 1 Digital - If AMS off ams:1, // 0 AMS off, 1 AMS on ? tone_mode:4; // Works // 1 u8 charsetbits[2]; // 2 char label[6]; // Works - Can only input 6 on screen // 6 char unknown7[10]; // Rest of label ??? // 10 bbcd offset[3]; // Works // 3 u8 unknown5:2, tone:6; // Works // 1 u8 unknown6:1, dcs:7; // Works // 1 u8 unknown9; u8 ams_on_dn_vw_fm:2, // AMS DN, AMS VW, AMS FM unknown8_3:1, unknown8_4:1, smeter:4; u8 unknown10:2, att:1, auto_step:1, auto_mode:1, unknown11:2, bell:1; } memory[%d]; // DN, VW, FM, AM // AMS DN, AMS VW, AMS FM #seekto 0x280A; struct { u8 nosubvfo:1, unknown:3, pskip:1, // PSkip (Select?) skip:1, // Skip memory during scan used:1, // Memory used valid:1; // Always 1? } flag[%d]; """ MEM_CALLSIGN_FORMAT = """ #seekto 0x0ced0; struct { char callsign[10]; // 63 MYCALL Set the call sign. (up to 10 characters) u16 charset; // character set ID } my_call; """ MEM_CHECKSUM_FORMAT = """ #seekto 0xFECA; u8 checksum; """ TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEX = ["", "-", "+", "split"] MODES = ["FM", "AM", "NFM"] STEPS = [0, 5, 6.25, 10, 12.5, 15, 20, 25, 50, 100] # 0 = auto RFSQUELCH = ["OFF", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8"] SKIPS = ["", "S", "P"] FT70_DTMF_CHARS = list("0123456789ABCDEF-") CHARSET = ["%i" % int(x) for x in range(0, 10)] + \ [chr(x) for x in range(ord("A"), ord("Z") + 1)] + \ [" ", ] + \ [chr(x) for x in range(ord("a"), ord("z") + 1)] + \ list(".,:;*#_-/&()@!?^ ") + list("\x00" * 100) POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00), chirp_common.PowerLevel("Mid", watts=2.00), chirp_common.PowerLevel("Low", watts=.50)] class FT70Bank(chirp_common.NamedBank): """A FT70 bank""" def get_name(self): _bank = self._model._radio._memobj.bank_info[self.index] name = "" for i in _bank.name: if i == 0xff: break name += chr(i & 0xFF) return name.rstrip() def set_name(self, name): _bank = self._model._radio._memobj.bank_info[self.index] _bank.name = [ord(x) for x in name.ljust(6, chr(0xFF))[:6]] class FT70BankModel(chirp_common.BankModel): """A FT70 bank model""" def __init__(self, radio, name='Banks'): super(FT70BankModel, self).__init__(radio, name) _banks = self._radio._memobj.bank_info self._bank_mappings = [] for index, _bank in enumerate(_banks): bank = FT70Bank(self, "%i" % index, "BANK-%i" % index) bank.index = index self._bank_mappings.append(bank) def get_num_mappings(self): return len(self._bank_mappings) def get_mappings(self): return self._bank_mappings def _channel_numbers_in_bank(self, bank): _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xFFFF: return set() _members = self._radio._memobj.bank_members[bank.index] return set([int(ch) + 1 for ch in _members.channel if ch != 0xFFFF]) def _update_bank_with_channel_numbers(self, bank, channels_in_bank): _members = self._radio._memobj.bank_members[bank.index] if len(channels_in_bank) > len(_members.channel): raise Exception("Too many entries in bank %d" % bank.index) empty = 0 for index, channel_number in enumerate(sorted(channels_in_bank)): _members.channel[index] = channel_number - 1 empty = index + 1 for index in range(empty, len(_members.channel)): _members.channel[index] = 0xFFFF def add_memory_to_mapping(self, memory, bank): channels_in_bank = self._channel_numbers_in_bank(bank) channels_in_bank.add(memory.number) self._update_bank_with_channel_numbers(bank, channels_in_bank) _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0x06 def remove_memory_from_mapping(self, memory, bank): channels_in_bank = self._channel_numbers_in_bank(bank) try: channels_in_bank.remove(memory.number) except KeyError: raise Exception("Memory %i is not in bank %s. Cannot remove" % (memory.number, bank)) self._update_bank_with_channel_numbers(bank, channels_in_bank) if not channels_in_bank: _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0xFFFF def get_mapping_memories(self, bank): memories = [] for channel in self._channel_numbers_in_bank(bank): memories.append(self._radio.get_memory(channel)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in self._channel_numbers_in_bank(bank): banks.append(bank) return banks @directory.register class FT70Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT-70DE""" BAUD_RATE = 38400 VENDOR = "Yaesu" MODEL = "FT-70D" FORMATS = [directory.register_format('FT-70D ADMS-10', '*.ft70d')] _model = b"AH51G" _adms_ext = '.ft70d' _memsize = 65227 # 65227 read from dump _block_lengths = [10, 65217] _block_size = 32 _mem_params = (900, # size of memories array 900, # size of flags array ) _has_vibrate = False _has_af_dual = True _BEEP_SELECT = ("Off", "Key+Scan", "Key") _OPENING_MESSAGE = ("Off", "DC", "Message") _MIC_GAIN = ("Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7", "Level 8", "Level 9") _AMS_TX_MODE = ("TX Auto", "TX DIGITAL", "TX FM") _VW_MODE = ("On", "Off") _DIG_POP_UP = ("Off", "2sec", "4sec", "6sec", "8sec", "10sec", "20sec", "30sec", "60sec", "Continuous") _STANDBY_BEEP = ("On", "Off") _SCAN_RESUME = ["%.1fs" % (0.5 * x) for x in range(4, 21)] + \ ["Busy", "Hold"] _SCAN_RESTART = ["%.1fs" % (0.1 * x) for x in range(1, 10)] + \ ["%.1fs" % (0.5 * x) for x in range(2, 21)] _LAMP_KEY = ["Key %d sec" % x for x in range(2, 11)] + ["Continuous", "OFF"] _LCD_DIMMER = ["Level %d" % x for x in range(1, 7)] _TOT_TIME = ["Off"] + ["%.1f min" % (0.5 * x) for x in range(1, 21)] _OFF_ON = ("Off", "On") _ON_OFF = ("On", "Off") _DTMF_MODE = ("Manual", "Auto") _DTMF_SPEED = ("50ms", "100ms") _DTMF_DELAY = ("50ms", "250ms", "450ms", "750ms", "1000ms") _TEMP_CF = ("Centigrade", "Fahrenheit") _APO_SELECT = ("Off", "0.5H", "1.0H", "1.5H", "2.0H", "2.5H", "3.0H", "3.5H", "4.0H", "4.5H", "5.0H", "5.5H", "6.0H", "6.5H", "7.0H", "7.5H", "8.0H", "8.5H", "9.0H", "9.5H", "10.0H", "10.5H", "11.0H", "11.5H", "12.0H") _MONI_TCALL = ("Monitor", "Tone-CALL") _HOME_REV = ("Home", "Reverse") _LOCK = ("KEY", "DIAL", "Key+Dial", "PTT", "Key+PTT", "Dial+PTT", "ALL") _PTT_DELAY = ("Off", "20 ms", "50 ms", "100 ms", "200 ms") _BEEP_LEVEL = ("Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7") _SET_MODE = ("Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6", "Level 7") _RX_SAVE = ("OFF", "0.2s", ".3s", ".4s", ".5s", ".6s", ".7s", ".8s", ".9s", "1.0s", "1.5s", "2.0s", "2.5s", "3.0s", "3.5s", "4.0s", "4.5s", "5.0s", "5.5s", "6.0s", "6.5s", "7.0s", "7.5s", "8.0s", "8.5s", "9.0s", "10.0s", "15s", "20s", "25s", "30s", "35s", "40s", "45s", "50s", "55s", "60s") _VFO_MODE = ("ALL", "BAND") _VFO_SCAN_MODE = ("BAND", "ALL") _MEMORY_SCAN_MODE = ("BAND", "ALL") _VOLUME = ["Level %d" % x for x in range(0, 32)] _SQUELCH = ["Level %d" % x for x in range(0, 16)] _DG_ID = ["%d" % x for x in range(0, 100)] _GM_RING = ("OFF", "IN RING", "AlWAYS") _GM_INTERVAL = ("LONG", "NORMAL", "OFF") _MYCALL_CHR_SET = list(string.ascii_uppercase) + list(string.digits) + ['-', '/'] @classmethod def match_model(cls, filedata, filename): if filename.endswith(cls._adms_ext): return True else: return super().match_model(filedata, filename) @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio on.\n" "2. Connect cable to DATA terminal.\n" "3. Unclip battery.\n" "4. Press and hold in the [AMS] key and power key while clipping" " \n in back battery the" "(\"ADMS\" will appear on the display).\n" "5. After clicking OK, press the [BAND] key.\n") rp.pre_upload = _( "1. Turn radio on.\n" "2. Connect cable to DATA terminal.\n" "3. Unclip battery.\n" "4. Press and hold in the [AMS] key and power key while clipping" " \n in back battery the" "(\"ADMS\" will appear on the display).\n" "5. Press the [MODE] key (\"-WAIT-\" will appear on the LCD)." " OK\n click Then") return rp def process_mmap(self): mem_format = MEM_SETTINGS_FORMAT + MEM_FORMAT + MEM_CALLSIGN_FORMAT + MEM_CHECKSUM_FORMAT self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.valid_modes = list(MODES) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(500000, 999900000)] rf.valid_skips = SKIPS rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 6 rf.memory_bounds = (1, 900) rf.can_odd_split = True rf.has_ctone = False rf.has_bank_names = True rf.has_settings = True return rf def get_raw_memory(self, number): return "\n".join([repr(self._memobj.memory[number - 1]), repr(self._memobj.flag[number - 1])]) def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0xFEC9)] # The whole file -2 bytes @staticmethod def _add_ff_pad(val, length): return val.ljust(length, "\xFF")[:length] @classmethod def _strip_ff_pads(cls, messages): result = [] for msg_text in messages: result.append(str(msg_text).rstrip("\xFF")) return result def get_memory(self, number): flag = self._memobj.flag[number - 1] _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number if not flag.used: mem.empty = True if not flag.valid: mem.empty = True return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = int(_mem.offset) * 1000 mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] self._get_tmode(mem, _mem) mem.duplex = DUPLEX[_mem.duplex] if mem.duplex == "split": mem.offset = chirp_common.fix_rounded_step(mem.offset) mem.mode = self._decode_mode(_mem) mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] mem.tuning_step = STEPS[_mem.tune_step] mem.power = self._decode_power_level(_mem) mem.skip = flag.pskip and "P" or flag.skip and "S" or "" mem.name = self._decode_label(_mem) return mem def _decode_label(self, mem): return str(mem.label).rstrip("\xFF") def _encode_label(self, mem): return self._add_ff_pad(mem.name.rstrip(), 6) def _encode_charsetbits(self, mem): # We only speak English here in chirpville return [0x00, 0x00] def _decode_power_level(self, mem): # 3 High 2 Mid 1 Low return POWER_LEVELS[3 - mem.power] def _encode_power_level(self, mem): return 3 - POWER_LEVELS.index(mem.power) def _decode_mode(self, mem): mode = MODES[mem.mode] if mode == 'FM' and int(mem.deviation): return 'NFM' else: return mode def _encode_mode(self, mem): mode = mem.mode if mode == 'NFM': # Narrow is handled by a separate flag mode = 'FM' return MODES.index(mode) def _get_tmode(self, mem, _mem): mem.tmode = TMODES[_mem.tone_mode] def _set_tmode(self, _mem, mem): _mem.tone_mode = TMODES.index(mem.tmode) def _set_mode(self, _mem, mem): _mem.deviation = mem.mode == 'NFM' _mem.mode = self._encode_mode(mem) def _debank(self, mem): bm = self.get_bank_model() for bank in bm.get_memory_mappings(mem): bm.remove_memory_from_mapping(mem, bank) def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] flag = self._memobj.flag[mem.number - 1] self._debank(mem) if not mem.empty and not flag.valid: self._wipe_memory(_mem) if mem.empty and flag.valid and not flag.used: flag.valid = False return flag.used = not mem.empty flag.valid = flag.used if mem.empty: return if mem.freq < 30000000 or \ (mem.freq > 88000000 and mem.freq < 108000000) or \ mem.freq > 580000000: flag.nosubvfo = True # Masked from VFO B else: flag.nosubvfo = False # Available in both VFOs _mem.freq = int(mem.freq / 1000) _mem.offset = int(mem.offset / 1000) _mem.tone = chirp_common.TONES.index(mem.rtone) self._set_tmode(_mem, mem) _mem.duplex = DUPLEX.index(mem.duplex) self._set_mode(_mem, mem) _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tune_step = STEPS.index(mem.tuning_step) if mem.power: _mem.power = self._encode_power_level(mem) else: _mem.power = 3 # Set 3 - High power as the default _mem.label = self._encode_label(mem) charsetbits = self._encode_charsetbits(mem) _mem.charsetbits[0], _mem.charsetbits[1] = charsetbits flag.skip = mem.skip == "S" flag.pskip = mem.skip == "P" _mem.display_tag = 1 # Always Display Memory Name (For the moment..) @classmethod def _wipe_memory(cls, mem): mem.set_raw("\x00" * (mem.size() // 8)) mem.unknown1 = 0x05 def get_bank_model(self): return FT70BankModel(self) def _get_dtmf_settings(self): menu = RadioSettingGroup("dtmf_settings", "DTMF") dtmf = self._memobj.scan_settings val = RadioSettingValueList( self._DTMF_MODE, self._DTMF_MODE[dtmf.dtmf_mode]) rs = RadioSetting("scan_settings.dtmf_mode", "DTMF Mode", val) menu.append(rs) val = RadioSettingValueList( self._DTMF_DELAY, self._DTMF_DELAY[dtmf.dtmf_delay]) rs = RadioSetting( "scan_settings.dtmf_delay", "DTMF Delay", val) menu.append(rs) val = RadioSettingValueList( self._DTMF_SPEED, self._DTMF_SPEED[dtmf.dtmf_speed]) rs = RadioSetting( "scan_settings.dtmf_speed", "DTMF Speed", val) menu.append(rs) for i in range(10): name = "dtmf_%02d" % (i + 1) if i == 9: name = "dtmf_%02d" % 0 dtmfsetting = self._memobj.dtmf[i] dtmfstr = "" for c in dtmfsetting.memory: if c == 0xFF: break if c < len(FT70_DTMF_CHARS): dtmfstr += FT70_DTMF_CHARS[c] dtmfentry = RadioSettingValueString(0, 16, dtmfstr) dtmfentry.set_charset( FT70_DTMF_CHARS + list("abcdef ")) # Allow input in lowercase, space ? validation fails otherwise rs = RadioSetting(name, name.upper(), dtmfentry) rs.set_apply_callback(self.apply_dtmf, i) menu.append(rs) return menu def _get_display_settings(self): menu = RadioSettingGroup("display_settings", "Display") scan_settings = self._memobj.scan_settings val = RadioSettingValueList( self._LAMP_KEY, self._LAMP_KEY[scan_settings.lamp]) rs = RadioSetting("scan_settings.lamp", "Lamp", val) menu.append(rs) val = RadioSettingValueList( self._LCD_DIMMER, self._LCD_DIMMER[scan_settings.lcd_dimmer]) rs = RadioSetting("scan_settings.lcd_dimmer", "LCD Dimmer", val) menu.append(rs) opening_message = self._memobj.opening_message val = RadioSettingValueList( self._OPENING_MESSAGE, self._OPENING_MESSAGE[opening_message.flag]) rs = RadioSetting("opening_message.flag", "Opening Msg Mode", val) menu.append(rs) return menu def _get_config_settings(self): menu = RadioSettingGroup("config_settings", "Config") scan_settings = self._memobj.scan_settings # 02 APO Set the length of time until the transceiver turns off automatically. first_settings = self._memobj.first_settings val = RadioSettingValueList( self._APO_SELECT, self._APO_SELECT[first_settings.apo]) rs = RadioSetting("first_settings.apo", "APO", val) menu.append(rs) # 03 BCLO Turns the busy channel lockout function on/off. val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.bclo]) rs = RadioSetting("scan_settings.bclo", "Busy Channel Lockout", val) menu.append(rs) # 04 BEEP Sets the beep sound function. beep_settings = self._memobj.beep_settings val = RadioSettingValueList( self._BEEP_SELECT, self._BEEP_SELECT[beep_settings.beep_select]) rs = RadioSetting("beep_settings.beep_select", "Beep", val) menu.append(rs) # 05 BEP.LVL Beep volume setting LEVEL1 - LEVEL4 - LEVEL7 val = RadioSettingValueList( self._BEEP_LEVEL, self._BEEP_LEVEL[beep_settings.beep_level]) rs = RadioSetting("beep_settings", "Beep Level", val) menu.append(rs) # 06 BEP.Edg Sets the beep sound ON or OFF when a band edge is encountered. val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.beep_edge]) rs = RadioSetting("scan_settings.beep_edge", "Beep Band Edge", val) menu.append(rs) # 10 Bsy.LED Turn the MODE/STATUS Indicator ON or OFF while receiving signals. val = RadioSettingValueList( self._ON_OFF, self._ON_OFF[scan_settings.busy_led]) rs = RadioSetting("scan_settings.busy_led", "Busy LED", val) menu.append(rs) # 26 HOME/REV Select the function of the [HOME/REV] key. val = RadioSettingValueList( self._HOME_REV, self._HOME_REV[scan_settings.home_rev]) rs = RadioSetting("scan_settings.home_rev", "HOME/REV", val) menu.append(rs) # 27 HOME->VFO Turn transfer VFO to the Home channel ON or OFF. val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.home_vfo]) rs = RadioSetting("scan_settings.home_vfo", "Home->VFO", val) menu.append(rs) # 30 LOCK Configure the lock mode setting. KEY / DIAL / K+D / PTT / K+P / D+P / ALL val = RadioSettingValueList( self._LOCK, self._LOCK[scan_settings.lock]) rs = RadioSetting("scan_settings.lock", "Lock Mode", val) menu.append(rs) # 32 Mon/T-Call Select the function of the [MONI/T-CALL] switch. val = RadioSettingValueList( self._MONI_TCALL, self._MONI_TCALL[scan_settings.moni]) rs = RadioSetting("scan_settings.moni", "MONI/T-CALL", val) menu.append(rs) # 42 PTT.DLY Set the PTT delay time. OFF / 20 ms / 50 ms / 100 ms / 200 ms val = RadioSettingValueList( self._PTT_DELAY, self._PTT_DELAY[scan_settings.ptt_delay]) rs = RadioSetting("scan_settings.ptt_delay", "PTT Delay", val) menu.append(rs) # 45 RPT.ARS Turn the ARS function on/off. val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.ars]) rs = RadioSetting("scan_settings.ars", "ARS", val) menu.append(rs) # 48 RX.SAVE Set the battery save time. OFF / 0.2 s - 60.0 s val = RadioSettingValueList( self._RX_SAVE, self._RX_SAVE[scan_settings.rx_save]) rs = RadioSetting("scan_settings.rx_save", "RX SAVE", val) menu.append(rs) # 60 VFO.MOD Set the frequency setting range in the VFO mode by DIAL knob. ALL / BAND val = RadioSettingValueList( self._VFO_MODE, self._VFO_MODE[scan_settings.vfo_mode]) rs = RadioSetting("scan_settings.vfo_mode", "VFO MODE", val) menu.append(rs) # 56 TOT Set the timeout timer. val = RadioSettingValueList( self._TOT_TIME, self._TOT_TIME[scan_settings.tot]) rs = RadioSetting("scan_settings.tot", "Transmit Timeout (TOT)", val) menu.append(rs) # 31 MCGAIN Adjust the microphone gain level val = RadioSettingValueList( self._MIC_GAIN, self._MIC_GAIN[scan_settings.mic_gain]) rs = RadioSetting("scan_settings.mic_gain", "Mic Gain", val) menu.append(rs) # VOLUME Adjust the volume level scan_settings_2 = self._memobj.scan_settings_2 val = RadioSettingValueList( self._VOLUME, self._VOLUME[scan_settings_2.volume]) rs = RadioSetting("scan_settings_2.volume", "Volume", val) menu.append(rs) # Squelch F key, Hold Monitor, Dial to adjust squelch level squelch_settings = self._memobj.squelch_settings val = RadioSettingValueList( self._SQUELCH, self._SQUELCH[squelch_settings.squelch]) rs = RadioSetting("squelch_settings.squelch", "Squelch", val) menu.append(rs) return menu def _get_digital_settings(self): menu = RadioSettingGroup("digital_settings", "Digital") # MYCALL mycall = self._memobj.my_call mycallstr = str(mycall.callsign).rstrip("\xFF") mycallentry = RadioSettingValueString(0, 10, mycallstr, False, charset=self._MYCALL_CHR_SET) rs = RadioSetting('mycall.callsign', 'MYCALL', mycallentry) rs.set_apply_callback(self.apply_mycall, mycall) menu.append(rs) # Short Press AMS button AMS TX Mode digital_settings = self._memobj.digital_settings val = RadioSettingValueList( self._AMS_TX_MODE, self._AMS_TX_MODE[digital_settings.ams_tx_mode]) rs = RadioSetting("digital_settings.ams_tx_mode", "AMS TX Mode", val) menu.append(rs) # 16 DIG VW Turn the VW mode selection ON or OFF. val = RadioSettingValueList( self._VW_MODE, self._VW_MODE[digital_settings.vw_mode]) rs = RadioSetting("digital_settings.vw_mode", "VW Mode", val) menu.append(rs) # TX DG-ID Long Press Mode Key, Dial val = RadioSettingValueList( self._DG_ID, self._DG_ID[digital_settings.tx_dg_id]) rs = RadioSetting("digital_settings.tx_dg_id", "TX DG-ID", val) menu.append(rs) # RX DG-ID Long Press Mode Key, Mode Key to select, Dial val = RadioSettingValueList( self._DG_ID, self._DG_ID[digital_settings.rx_dg_id]) rs = RadioSetting("digital_settings.rx_dg_id", "RX DG-ID", val) menu.append(rs) # 15 DIG.POP Call sign display pop up time # 00 OFF 00 # 0A 2s 10 # 0B 4s 11 # 0C 6s 12 # 0D 8s 13 # 0E 10s 14 # 0F 20s 15 # 10 30s 16 # 11 60s 17 # 12 CONT 18 digital_settings_more = self._memobj.digital_settings_more val = RadioSettingValueList( self._DIG_POP_UP, self._DIG_POP_UP[ 0 if digital_settings_more.digital_popup == 0 else digital_settings_more.digital_popup - 9]) rs = RadioSetting("digital_settings_more.digital_popup", "Digital Popup", val) rs.set_apply_callback(self.apply_digital_popup, digital_settings_more) menu.append(rs) # 07 BEP.STB Standby Beep in the digital C4FM mode. On/Off val = RadioSettingValueList( self._STANDBY_BEEP, self._STANDBY_BEEP[digital_settings.standby_beep]) rs = RadioSetting("digital_settings.standby_beep", "Standby Beep", val) menu.append(rs) return menu def _get_gm_settings(self): menu = RadioSettingGroup("first_settings", "Group Monitor") # 24 GM RNG Select the beep option while receiving digital GM information. OFF / IN RNG /ALWAYS first_settings = self._memobj.first_settings val = RadioSettingValueList( self._GM_RING, self._GM_RING[first_settings.gm_ring]) rs = RadioSetting("first_settings.gm_ring", "GM Ring", val) menu.append(rs) # 25 GM INT Set the transmission interval of digital GM information. OFF / NORMAL / LONG scan_settings = self._memobj.scan_settings val = RadioSettingValueList( self._GM_INTERVAL, self._GM_INTERVAL[scan_settings.gm_interval]) rs = RadioSetting("scan_settings.gm_interval", "GM Interval", val) menu.append(rs) return menu def _get_scan_settings(self): menu = RadioSettingGroup("scan_settings", "Scan") scan_settings = self._memobj.scan_settings # 23 DW RVT Turn the "Priority Channel Revert" feature ON or OFF during Dual Receive. val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.dw_rt]) rs = RadioSetting("scan_settings.dw_rt", "Dual Watch Priority Channel Revert", val) menu.append(rs) # 21 DW INT Set the priority memory channel monitoring interval during Dual Receive. 0.1S - 5.0S - 10.0S val = RadioSettingValueList( self._SCAN_RESTART, self._SCAN_RESTART[scan_settings.dw_interval]) rs = RadioSetting("scan_settings.dw_interval", "Dual Watch Interval", val) menu.append(rs) # 22 DW RSM Configure the scan stop mode settings for Dual Receive. 2.0S - 10.0 S / BUSY / HOLD first_settings = self._memobj.first_settings val = RadioSettingValueList( self._SCAN_RESUME, self._SCAN_RESUME[first_settings.dw_resume_interval]) rs = RadioSetting("first_settings.dw_resume_interval", "Dual Watch Resume Interval", val) menu.append(rs) # 51 SCN.LMP Set the scan lamp ON or OFF when scanning stops. OFF / ON val = RadioSettingValueList( self._OFF_ON, self._OFF_ON[scan_settings.scan_lamp]) rs = RadioSetting("scan_settings.scan_lamp", "Scan Lamp", val) menu.append(rs) # 53 SCN.STR Set the scanning restart time. 0.1 S - 2.0 S - 10.0 S val = RadioSettingValueList( self._SCAN_RESTART, self._SCAN_RESTART[scan_settings.scan_restart]) rs = RadioSetting("scan_settings.scan_restart", "Scan Restart", val) menu.append(rs) # Scan Width Section # 50 SCV.WTH Set the VFO scan frequency range. BAND / ALL - NOT FOUND! # Scan Resume Section # 52 SCN.RSM Configure the scan stop mode settings. 2.0 S - 5.0 S - 10.0 S / BUSY / HOLD first_settings = self._memobj.first_settings val = RadioSettingValueList( self._SCAN_RESUME, self._SCAN_RESUME[first_settings.scan_resume]) rs = RadioSetting("first_settings.scan_resume", "Scan Resume", val) menu.append(rs) return menu def _get_settings(self): top = RadioSettings( self._get_config_settings(), self._get_digital_settings(), self._get_display_settings(), self._get_dtmf_settings(), self._get_gm_settings(), self._get_scan_settings() ) return top def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None @classmethod def apply_ff_padded_string(cls, setting, obj): setattr(obj, "padded_string", cls._add_ff_pad(setting.value.get_value().rstrip(), 6)) def set_settings(self, settings): _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: if element.has_apply_callback(): LOG.debug("Using apply callback") try: element.run_apply_callback() except NotImplementedError as e: LOG.error(e) continue # Find the object containing setting. obj = _mem bits = element.get_name().split(".") setting = bits[-1] for name in bits[:-1]: if name.endswith("]"): name, index = name.split("[") index = int(index[:-1]) obj = getattr(obj, name)[index] else: obj = getattr(obj, name) try: old_val = getattr(obj, setting) LOG.debug("Setting %s(%r) <= %s" % ( element.get_name(), old_val, element.value)) setattr(obj, setting, element.value) except AttributeError as e: LOG.error("Setting %s is not in the memory map: %s" % (element.get_name(), e)) except Exception: LOG.debug(element.get_name()) raise def apply_volume(cls, setting, vfo): val = setting.value.get_value() cls._memobj.vfo_info[(vfo * 2)].volume = val cls._memobj.vfo_info[(vfo * 2) + 1].volume = val def apply_dtmf(cls, setting, i): rawval = setting.value.get_value().upper().rstrip() val = [FT70_DTMF_CHARS.index(x) for x in rawval] for x in range(len(val), 16): val.append(0xFF) cls._memobj.dtmf[i].memory = val def apply_digital_popup(cls, setting, obj): rawval = setting.value.get_value() val = 0 if cls._DIG_POP_UP.index(rawval) == 0 else cls._DIG_POP_UP.index(rawval) + 9 obj.digital_popup = val def apply_mycall(cls, setting, obj): cs = setting.value.get_value() if cs[0] in ('-', '/'): raise InvalidValueError("First character of call sign can't be - or /: {0:s}".format(cs)) else: obj.callsign = cls._add_ff_pad(cs.rstrip(), 10) def load_mmap(self, filename): if filename.lower().endswith(self._adms_ext): with open(filename, 'rb') as f: self._adms_header = f.read(0xED) if b'=ADMS10, Version=1.0.1.0' not in self._adms_header: raise errors.ImageDetectFailed( 'Unsupported version found in ADMS file') LOG.debug('ADMS Header:\n%s', util.hexprint(self._adms_header)) self._mmap = memmap.MemoryMapBytes(self._model + f.read()) LOG.info('Loaded ADMS file') self.process_mmap() else: chirp_common.CloneModeRadio.load_mmap(self, filename) def save_mmap(self, filename): if filename.lower().endswith(self._adms_ext): if not hasattr(self, '_adms_header'): raise Exception('Unable to save .img to %s' % self._adms_ext) with open(filename, 'wb') as f: f.write(self._adms_header) f.write(self._mmap.get_packed()[5:]) LOG.info('Wrote file') else: chirp_common.CloneModeRadio.save_mmap(self, filename) chirp-20240224/chirp/drivers/retevis_rt26.py0000644000175000017500000007245314566340166017555 0ustar hibbyhibby# Copyright 2017 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging import re from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 unknown1:1, pttid:2, // PTT ID skip:1, // Scan Add wide:1, // Bandwidth bcl:1, // Busy Lock epilogue:1, // Epilogue (STE) highpower:1; // Power Level u8 unknown2[3]; } memory[16]; #seekto 0x0120; struct { u8 hivoltnotx:1, // TX Inhibit when voltage too high lovoltnotx:1, // TX Inhibit when voltage too low unknown1:1, fmradio:1, // Broadcast FM Radio unknown2:1, tone:1, // Tone voice:2; // Voice u8 unknown3:1, save:3, // Battery Save squelch:4; // Squelch u8 tot; // Time Out Timer u8 voxi:1, // VOX Inhibit on Receive voxd:2, // VOX Delay vox:1, // VOX voxg:4; // VOX Gain u8 unknown4; u8 unknown5:4, scanspeed:4; // Scan Speed u8 unknown6:3, scandelay:5; // Scan Delay u8 k1longp:4, // Key 1 Long Press k1shortp:4; // Key 1 Short Press u8 k2longp:4, // Key 2 Long Press k2shortp:4; // Key 2 Short Press u8 unknown7:4, ssave:4; // Super Battery Save } settings; #seekto 0x0140; struct { u8 unknown1:4, dtmfspd:4; // DTMF Speed u8 digdelay:4, // 1st Digit Delay digtime:4; // 1st Digit Time u8 stuntype:1, // Stun Type sidetone:1, // DTMF Sidetone starhash:2, // * and # Time decodetone:1, // Decode Tone txdecode:1, // TX Decode unknown2:2; u8 unknown3; u8 unknown4:4, groupcode:4; // Group Code u8 unknown5:1, resettone:1, // Reset Tone resettime:6; // Reset Time u8 codespace:4, // Code Space Time decodeto:4; // Decode Tome Out u8 unknown6; u8 idcode[3]; // ID Code u8 unknown7[2]; u8 code1_len; // PTT ID length(begging of TX) u8 code2_len; // PTT ID length(end of TX) u8 unknown8; u8 code3_len; // Stun Code length u8 code3[5]; // Stun Code u8 unknown9[10]; u8 code1[8]; // PTT ID(beginning of TX) u8 code2[8]; // PTT ID(end of TX) } dtmf; #seekto 0x0170; struct { char fp[8]; } fingerprint; """ CMD_ACK = b"\x06" NUMERIC_CHARSET = list("0123456789") DTMF_CHARSET = NUMERIC_CHARSET + list("ABCD*#") RT26_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5.00), chirp_common.PowerLevel("High", watts=10.00)] RT26_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_SHORT_PRESS = ["Off", "Monitor On/Off", "", "Scan", "Alarm", "Power High/Low"] LIST_LONG_PRESS = ["Off", "Monitor On/Off", "Monitor(momentary)", "Scan", "Alarm", "Power High/Low"] LIST_VOXDELAY = ["0.5", "1.0", "2.0", "3.0"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_TIMEOUTTIMER = ["Off"] + ["%s" % x for x in range(15, 615, 15)] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SSAVE = ["Off"] + ["%s" % x for x in range(1, 10)] LIST_SCANSPEED = ["%s" % x for x in range(100, 550, 50)] LIST_SCANDELAY = ["%s" % x for x in range(3, 31)] LIST_DIGTIME = ["%s" % x for x in range(0, 1100, 100)] LIST_DIGDELAY = ["%s" % x for x in range(100, 1100, 100)] LIST_STARHASH = ["100", "500", "1000", "0"] LIST_CODESPACE = ["None"] + ["%s" % x for x in range(600, 2100, 100)] LIST_GROUPCODE = ["Off", "A", "B", "C", "D", "#", "*"] LIST_RESETTIME = ["Off"] + ["%s" % x for x in range(1, 61)] LIST_DECODETO = ["%s" % x for x in range(500, 1000, 50)] + \ ["%s" % x for x in range(1000, 1600, 100)] LIST_STUNTYPE = ["TX/RX Inhibit", "TX Inhibit"] # Retevis RT26 fingerprints RT26_UHF_fp = b"PDK80" + b"\xF3\x00\x00" # RT26 UHF model MODELS = [RT26_UHF_fp, ] def _model_from_data(data): return data[0x0170:0x0178] def _model_from_image(radio): return _model_from_data(radio.get_mmap()) def _get_radio_model(radio): block = _rt26_read_block(radio, 0x0170, 0x10) version = block[0:8] return version def _rt26_enter_programming_mode(radio): serial = radio.pipe magic = [b"PROGRAMa", b"PROGRAMb"] for i in range(0, 2): try: LOG.debug("sending " + magic[i].decode()) serial.write(magic[i]) ack = serial.read(1) except: _rt26_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if not ack: _rt26_exit_programming_mode(radio) raise errors.RadioError("No response from radio") elif ack != CMD_ACK: LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ack)) _rt26_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") try: LOG.debug("sending " + util.hexprint("\x02")) serial.write(b"\x02") ident = serial.read(16) except: _rt26_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if not ident.startswith(b"PDK80"): LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ident)) _rt26_exit_programming_mode(radio) LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") try: LOG.debug("sending " + util.hexprint("MDK8ECUMHS1X7BN/")) serial.write(b"MXT8KCUMHS1X7BN/") ack = serial.read(1) except: _rt26_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != b"\xB2": LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ack)) _rt26_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") try: LOG.debug("sending " + util.hexprint(CMD_ACK)) serial.write(CMD_ACK) ack = serial.read(1) except: _rt26_exit_programming_mode(radio) raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: LOG.debug("Incorrect response, got this:\n\n" + util.hexprint(ack)) _rt26_exit_programming_mode(radio) raise errors.RadioError("Radio refused to enter programming mode") # DEBUG LOG.info("Positive ident, this is a %s %s" % (radio.VENDOR, radio.MODEL)) def _rt26_exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _rt26_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: _rt26_exit_programming_mode(radio) raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] serial.write(CMD_ACK) ack = serial.read(1) except: _rt26_exit_programming_mode(radio) raise errors.RadioError("Failed to read block at %04x" % block_addr) if ack != CMD_ACK: _rt26_exit_programming_mode(radio) raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _rt26_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: _rt26_exit_programming_mode(radio) raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _rt26_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio._block_size): status.cur = addr + radio._block_size radio.status_fn(status) block = _rt26_read_block(radio, addr, radio._block_size) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _rt26_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _rt26_enter_programming_mode(radio) status.cur = 0 status.max = 0x0190 for start_addr, end_addr, block_size in radio._ranges: for addr in range(start_addr, end_addr, block_size): status.cur = addr + block_size radio.status_fn(status) _rt26_write_block(radio, addr, block_size) _rt26_exit_programming_mode(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0x0170:0x0176] return rid.startswith(b"PDK80") @directory.register class RT26Radio(chirp_common.CloneModeRadio): """Retevis RT26""" VENDOR = "Retevis" MODEL = "RT26" BAUD_RATE = 4800 NEEDS_COMPAT_SERIAL = False _ranges = [ (0x0000, 0x0190, 0x10), ] _memsize = 0x0400 _block_size = 0x10 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = RT26_POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["NFM", "FM"] # 12.5 kHz, 25 kHz. rf.valid_dtcs_codes = RT26_DTCS rf.memory_bounds = (1, 16) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] rf.valid_bands = [(400000000, 520000000)] return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): self._mmap = do_download(self) self.process_mmap() def sync_out(self): do_upload(self) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" if val.get_raw(asbytes=False) == "\xFF\xFF": return '', None, None val = int(val) if val >= 12000: a = val - 12000 return 'DTCS', a, 'R' elif val >= 8000: a = val - 8000 return 'DTCS', a, 'N' else: a = val / 10.0 return 'Tone', a, None def encode_tone(self, memval, mode, value, pol): """Parse the tone data to encode from UI to mem""" if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def _my_band(self): model_tag = _model_from_image(self) return model_tag def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = _mem.wide and "FM" or "NFM" rxtone = txtone = None txtone = self.decode_tone(_mem.txtone) rxtone = self.decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) mem.power = RT26_POWER_LEVELS[_mem.highpower] if _mem.skip: mem.skip = "S" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(not _mem.bcl)) mem.extra.append(rs) rs = RadioSetting("epilogue", "Epilogue(STE)", RadioSettingValueBoolean(_mem.epilogue)) mem.extra.append(rs) val = 3 - _mem.pttid rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList( LIST_PTTID, LIST_PTTID[val])) mem.extra.append(rs) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) return _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq.fill_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.wide = mem.mode == "FM" ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_mem.txtone, txmode, txtone, txpol) self.encode_tone(_mem.rxtone, rxmode, rxtone, rxpol) _mem.highpower = mem.power == RT26_POWER_LEVELS[1] _mem.skip = mem.skip == "S" for setting in mem.extra: if setting.get_name() == "bcl": setattr(_mem, setting.get_name(), not int(setting.value)) elif setting.get_name() == "pttid": setattr(_mem, setting.get_name(), 3 - int(setting.value)) else: setattr(_mem, setting.get_name(), int(setting.value)) def _bbcd2dtmf(self, bcdarr, strlen=16): # doing bbcd, but with support for ABCD*# LOG.debug(bcdarr.get_value()) string = ''.join("%02X" % b for b in bcdarr) LOG.debug("@_bbcd2dtmf, received: %s" % string) string = string.replace('E', '#').replace('F', '*') if strlen <= 16: string = string[:strlen] return string def _dtmf2bbcd(self, value, strlen): dtmfstr = value.get_value() dtmfstr = dtmfstr.replace('#', 'E').replace('*', 'F') dtmfstr = str.ljust(dtmfstr.strip(), strlen, "F") bcdarr = list(bytearray.fromhex(dtmfstr)) LOG.debug("@_dtmf2bbcd, sending: %s" % bcdarr) return bcdarr def _bbcd2num(self, bcdarr, strlen=6): # doing bbcd LOG.debug(bcdarr.get_value()) string = ''.join("%02X" % b for b in bcdarr) LOG.debug("@_bbcd2num, received: %s" % string) if strlen <= 6: string = string[:strlen] return string def _num2bbcd(self, value): numstr = value.get_value() numstr = str.ljust(numstr.strip(), 6, "F") bcdarr = list(bytearray.fromhex(numstr)) LOG.debug("@_num2bbcd, sending: %s" % bcdarr) return bcdarr def get_settings(self): _settings = self._memobj.settings _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") top = RadioSettings(basic, dtmf) if _settings.k1shortp > 5: val = 4 else: val = _settings.k1shortp rs = RadioSetting("k1shortp", "Key 1 Short Press", RadioSettingValueList( LIST_SHORT_PRESS, LIST_SHORT_PRESS[val])) basic.append(rs) if _settings.k1longp > 5: val = 5 else: val = _settings.k1longp rs = RadioSetting("k1longp", "Key 1 Long Press", RadioSettingValueList( LIST_LONG_PRESS, LIST_LONG_PRESS[val])) basic.append(rs) if _settings.k2shortp > 5: val = 1 else: val = _settings.k2shortp rs = RadioSetting("k2shortp", "Key 2 Short Press", RadioSettingValueList( LIST_SHORT_PRESS, LIST_SHORT_PRESS[val])) basic.append(rs) if _settings.k2longp > 5: val = 3 else: val = _settings.k2longp rs = RadioSetting("k2longp", "Key 2 Long Press", RadioSettingValueList( LIST_LONG_PRESS, LIST_LONG_PRESS[val])) basic.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueBoolean(not _settings.vox)) basic.append(rs) if _settings.voxg > 8: val = 4 else: val = _settings.voxg + 1 rs = RadioSetting("voxg", "VOX Gain", RadioSettingValueInteger(1, 9, val)) basic.append(rs) rs = RadioSetting("voxd", "VOX Delay Time", RadioSettingValueList( LIST_VOXDELAY, LIST_VOXDELAY[_settings.voxd])) basic.append(rs) rs = RadioSetting("voxi", "VOX Inhibit on Receive", RadioSettingValueBoolean(_settings.voxi)) basic.append(rs) if _settings.squelch > 9: val = 5 else: val = _settings.squelch rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, val)) basic.append(rs) if _settings.voice == 3: val = 1 else: val = _settings.voice rs = RadioSetting("voice", "Voice Prompts", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("tone", "Tone", RadioSettingValueBoolean(_settings.tone)) basic.append(rs) rs = RadioSetting("lovoltnotx", "TX Inhibit (when battery < 6 volts)", RadioSettingValueBoolean(_settings.lovoltnotx)) basic.append(rs) rs = RadioSetting("hivoltnotx", "TX Inhibit (when battery > 9 volts)", RadioSettingValueBoolean(_settings.hivoltnotx)) basic.append(rs) if _settings.tot > 0x28: val = 6 else: val = _settings.tot rs = RadioSetting("tot", "Time-out Timer[s]", RadioSettingValueList( LIST_TIMEOUTTIMER, LIST_TIMEOUTTIMER[val])) basic.append(rs) if _settings.save < 3: val = 0 else: val = _settings.save - 3 rs = RadioSetting("save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) rs = RadioSetting("ssave", "Super Battery Saver[s]", RadioSettingValueList( LIST_SSAVE, LIST_SSAVE[_settings.ssave])) basic.append(rs) rs = RadioSetting("fmradio", "Broadcast FM", RadioSettingValueBoolean(_settings.fmradio)) basic.append(rs) if _settings.scanspeed > 8: val = 4 else: val = _settings.scanspeed rs = RadioSetting("scanspeed", "Scan Speed[ms]", RadioSettingValueList( LIST_SCANSPEED, LIST_SCANSPEED[val])) basic.append(rs) if _settings.scandelay > 27: val = 12 else: val = _settings.scandelay rs = RadioSetting("scandelay", "Scan Droupout Delay Time[s]", RadioSettingValueList( LIST_SCANDELAY, LIST_SCANDELAY[val])) basic.append(rs) if _mem.dtmf.dtmfspd > 11: val = 2 else: val = _mem.dtmf.dtmfspd + 4 rs = RadioSetting("dtmf.dtmfspd", "DTMF Speed[digit/s]", RadioSettingValueInteger(4, 15, val)) dtmf.append(rs) if _mem.dtmf.digtime > 10: val = 0 else: val = _mem.dtmf.digtime rs = RadioSetting("dtmf.digtime", "1st Digit Time[ms]", RadioSettingValueList( LIST_DIGTIME, LIST_DIGTIME[val])) dtmf.append(rs) if _mem.dtmf.digdelay > 9: val = 0 else: val = _mem.dtmf.digdelay rs = RadioSetting("dtmf.digdelay", "1st Digit Delay[ms]", RadioSettingValueList( LIST_DIGDELAY, LIST_DIGDELAY[val])) dtmf.append(rs) rs = RadioSetting("dtmf.starhash", "* and # Time[ms]", RadioSettingValueList( LIST_STARHASH, LIST_STARHASH[_mem.dtmf.starhash])) dtmf.append(rs) rs = RadioSetting("dtmf.codespace", "Code Space Time[ms]", RadioSettingValueList( LIST_CODESPACE, LIST_CODESPACE[_mem.dtmf.codespace])) dtmf.append(rs) rs = RadioSetting("dtmf.sidetone", "DTMF Sidetone", RadioSettingValueBoolean(_mem.dtmf.sidetone)) dtmf.append(rs) # setup pttid entries for i in range(0, 2): objname = "code" + str(i + 1) names = ["PTT ID(BOT)", "PTT ID(EOT)"] strname = str(names[i]) dtmfsetting = getattr(_mem.dtmf, objname) dtmflen = getattr(_mem.dtmf, objname + "_len") dtmfstr = self._bbcd2dtmf(dtmfsetting, dtmflen) code = RadioSettingValueString(0, 16, dtmfstr) code.set_charset(DTMF_CHARSET + list(" ")) rs = RadioSetting("dtmf." + objname, strname, code) dtmf.append(rs) def _filter(name): filtered = "" for char in str(name): if char in NUMERIC_CHARSET: filtered += char else: filtered += " " return filtered # setup id code entry codesetting = getattr(_mem.dtmf, "idcode") codestr = self._bbcd2num(codesetting, 6) code = RadioSettingValueString(0, 6, _filter(codestr)) code.set_charset(NUMERIC_CHARSET + list(" ")) rs = RadioSetting("dtmf.idcode", "ID Code", code) dtmf.append(rs) if _mem.dtmf.groupcode > 6: val = 0 else: val = _mem.dtmf.groupcode rs = RadioSetting("dtmf.groupcode", "Group Code", RadioSettingValueList( LIST_GROUPCODE, LIST_GROUPCODE[val])) dtmf.append(rs) if _mem.dtmf.resettime > 60: val = 0 else: val = _mem.dtmf.resettime rs = RadioSetting("dtmf.resettime", "Auto Reset Time[s]", RadioSettingValueList( LIST_RESETTIME, LIST_RESETTIME[_mem.dtmf.resettime])) dtmf.append(rs) rs = RadioSetting("dtmf.txdecode", "TX Decode", RadioSettingValueBoolean(_mem.dtmf.txdecode)) dtmf.append(rs) rs = RadioSetting("dtmf.decodeto", "Decode Time Out[ms]", RadioSettingValueList( LIST_DECODETO, LIST_DECODETO[_mem.dtmf.decodeto])) dtmf.append(rs) rs = RadioSetting("dtmf.decodetone", "Decode Tone", RadioSettingValueBoolean(_mem.dtmf.decodetone)) dtmf.append(rs) rs = RadioSetting("dtmf.resettone", "Reset Tone", RadioSettingValueBoolean(_mem.dtmf.resettone)) dtmf.append(rs) rs = RadioSetting("dtmf.stuntype", "Stun Type", RadioSettingValueList( LIST_STUNTYPE, LIST_STUNTYPE[_mem.dtmf.stuntype])) dtmf.append(rs) # setup stun entry objname = "code3" strname = "Stun Code" dtmfsetting = getattr(_mem.dtmf, objname) dtmflen = getattr(_mem.dtmf, objname + "_len") dtmfstr = self._bbcd2dtmf(dtmfsetting, dtmflen) code = RadioSettingValueString(0, 10, dtmfstr) code.set_charset(DTMF_CHARSET + list(" ")) rs = RadioSetting("dtmf." + objname, strname, code) dtmf.append(rs) return top def set_settings(self, settings): _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if setting == "vox": setattr(obj, setting, not int(element.value)) elif setting == "voxg": setattr(obj, setting, int(element.value) - 1) elif setting == "save": setattr(obj, setting, int(element.value) + 3) elif setting == "dtmfspd": setattr(obj, setting, int(element.value) - 4) elif re.match(r'code\d', setting): # set dtmf length field and then get bcd dtmf if setting == "code3": strlen = 10 else: strlen = 16 codelen = len(str(element.value).strip()) setattr(_mem.dtmf, setting + "_len", codelen) dtmfstr = self._dtmf2bbcd(element.value, strlen) setattr(_mem.dtmf, setting, dtmfstr) elif setting == "idcode": numstr = self._num2bbcd(element.value) setattr(_mem.dtmf, setting, numstr) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) in [0x0400, ]: match_size = True # testing the model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/wouxun_common.py0000644000175000017500000000512514446523722020122 0ustar hibbyhibby# # Copyright 2012 Filippi Marco # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """vcommon function for Wouxun (or similar) radios""" import struct import logging from chirp import util, chirp_common, memmap LOG = logging.getLogger(__name__) def wipe_memory(_mem, byte): """Cleanup a memory""" _mem.set_raw(byte * (_mem.size() // 8)) def do_download(radio, start, end, blocksize): """Initiate a download of @radio between @start and @end""" image = b"" for i in range(start, end, blocksize): cmd = struct.pack(">cHb", b"R", i, blocksize) LOG.debug(util.hexprint(cmd)) radio.pipe.write(cmd) length = len(cmd) + blocksize resp = radio.pipe.read(length) if len(resp) != (len(cmd) + blocksize): LOG.debug(util.hexprint(resp)) raise Exception("Failed to read full block (%i!=%i)" % (len(resp), len(cmd) + blocksize)) radio.pipe.write(b"\x06") radio.pipe.read(1) image += resp[4:] if radio.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning from radio" radio.status_fn(status) return memmap.MemoryMapBytes(image) def do_upload(radio, start, end, blocksize): """Initiate an upload of @radio between @start and @end""" ptr = start for i in range(start, end, blocksize): cmd = struct.pack(">cHb", b"W", i, blocksize) chunk = radio.get_mmap()[ptr:ptr+blocksize] ptr += blocksize radio.pipe.write(cmd + chunk) LOG.debug(util.hexprint(cmd + chunk)) ack = radio.pipe.read(1) if not ack == b"\x06": raise Exception("Radio did not ack block %i" % ptr) # radio.pipe.write(ack) if radio.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning to radio" radio.status_fn(status) chirp-20240224/chirp/drivers/leixen.py0000644000175000017500000011315514563632215016472 0ustar hibbyhibby# Copyright 2014 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap, errors, util from chirp import bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0184; struct { u8 unknown1:4, sql:4; // squelch level u8 unknown2; u8 obeep:1, // open beep dw_off:1, // dual watch (inverted) kbeep:1, // key beep rbeep:1, // roger beep unknown3:2, ctdcsb:1, // ct/dcs busy lock unknown4:1; u8 alarm:1, // alarm key unknown5:1, aliasen_off:1, // alias enable (inverted) save:1, // battery save unknown6:2, mrcha:1, // mr/cha vfomr:1; // vfo/mr u8 keylock_off:1, // key lock (inverted) txstop_off:1, // tx stop (inverted) scanm:1, // scan key/mode vir:1, // vox inhibit on receive keylockm:2, // key lock mode lamp:2; // backlight u8 opendis:2, // open display fmen_off:1, // fm enable (inverted) unknown7:1, fmscan_off:1, // fm scan (inverted) fmdw:1, // fm dual watch unknown8:2; u8 step:4, // step vol:4; // volume u8 apo:4, // auto power off tot:4; // time out timer u8 unknown9; u8 voxdt:4, // vox delay time voxgain:4; // vox gain u8 unknown10; u8 unknown11; u8 unknown12:3, lptime:5; // long press time u8 keyp2long:4, // p2 key long press keyp2short:4; // p2 key short press u8 keyp1long:4, // p1 key long press keyp1short:4; // p1 key short press u8 keyp3long:4, // p3 key long press keyp3short:4; // p3 key short press u8 unknown13; u8 menuen:1, // menu enable absel:1, // a/b select unknown14:2, keymshort:4; // m key short press u8 unknown15:4, dtmfst:1, // dtmf sidetone ackdecode:1, // ack decode monitor:2; // monitor u8 unknown16:3, reset:1, // reset enable unknown17:1, keypadmic_off:1, // keypad mic (inverted) unknown18:2; u8 unknown19; u8 unknown20:3, dtmftime:5; // dtmf digit time u8 unknown21:3, dtmfspace:5; // dtmf digit space time u8 unknown22:2, dtmfdelay:6; // dtmf first digit delay u8 unknown23:1, dtmfpretime:7; // dtmf pretime u8 unknown24:2, dtmfdelay2:6; // dtmf * and # digit delay u8 unknown25:3, smfont_off:1, // small font (inverted) unknown26:4; } settings; #seekto 0x01cd; struct { u8 rssi136; // squelch base level (vhf) u8 unknown0x01ce; u8 rssi400; // squelch base level (uhf) } service; #seekto 0x0900; struct { char user1[7]; // user message 1 char unknown0x0907; char unknown0x0908[8]; char unknown0x0910[8]; char system[7]; // system message char unknown0x091F; char user2[7]; // user message 2 char unknown0x0927; } messages; struct channel { bbcd rx_freq[4]; bbcd tx_freq[4]; u8 rx_tone; u8 rx_tmode_extra:6, rx_tmode:2; u8 tx_tone; u8 tx_tmode_extra:6, tx_tmode:2; u8 unknown5; u8 pttidoff:1, dtmfoff:1, %(unknownormode)s, tailcut:1, aliasop:1, talkaroundoff:1, voxoff:1, skip:1; u8 %(modeorpower)s, reverseoff:1, blckoff:1, unknown7:1, apro:3; u8 unknown8; }; struct name { char name[7]; u8 pad; }; #seekto 0x%(chanstart)x; struct channel default[%(defaults)i]; struct channel memory[199]; #seekto 0x%(namestart)x; struct name defaultname[%(defaults)i]; struct name name[199]; """ APO_LIST = ["OFF", "10M", "20M", "30M", "40M", "50M", "60M", "90M", "2H", "4H", "6H", "8H", "10H", "12H", "14H", "16H"] SQL_LIST = ["%s" % x for x in range(0, 10)] SCANM_LIST = ["CO", "TO"] TOT_LIST = ["OFF"] + ["%s seconds" % x for x in range(10, 130, 10)] _STEP_LIST = [2.5, 5., 6.25, 10., 12.5, 25.] STEP_LIST = ["{} kHz".format(x) for x in _STEP_LIST] MONITOR_LIST = ["CTC/DCS", "DTMF", "CTC/DCS and DTMF", "CTC/DCS or DTMF"] VFOMR_LIST = ["MR", "VFO"] MRCHA_LIST = ["MR CHA", "Freq. MR"] VOL_LIST = ["OFF"] + ["%s" % x for x in range(1, 16)] OPENDIS_LIST = ["All", "Lease Time", "User-defined", "Leixen"] LAMP_LIST = ["OFF", "KEY", "CONT"] KEYLOCKM_LIST = ["K+S", "PTT", "KEY", "ALL"] ABSEL_LIST = ["B Channel", "A Channel"] VOXGAIN_LIST = ["%s" % x for x in range(1, 9)] VOXDT_LIST = ["%s seconds" % x for x in range(1, 5)] DTMFTIME_LIST = ["%i milliseconds" % x for x in range(50, 210, 10)] DTMFDELAY_LIST = ["%i milliseconds" % x for x in range(0, 550, 50)] DTMFPRETIME_LIST = ["%i milliseconds" % x for x in range(100, 1100, 100)] DTMFDELAY2_LIST = ["%i milliseconds" % x for x in range(0, 450, 50)] LPTIME_LIST = ["%i milliseconds" % x for x in range(500, 2600, 100)] PFKEYLONG_LIST = ["OFF", "FM", "Monitor Momentary", "Monitor Lock", "SQ Off Momentary", "Mute", "SCAN", "TX Power", "EMG", "VFO/MR", "DTMF", "CALL", "Transmit 1750 Hz", "A/B", "Talk Around", "Reverse" ] PFKEYSHORT_LIST = ["OFF", "FM", "BandChange", "Time", "Monitor Lock", "Mute", "SCAN", "TX Power", "EMG", "VFO/MR", "DTMF", "CALL", "Transmit 1750 Hz", "A/B", "Talk Around", "Reverse" ] MODES = ["NFM", "FM"] WTFTONES = tuple(float(x) for x in range(56, 64)) TONES = tuple(sorted(WTFTONES + chirp_common.TONES)) DTCS_CODES = tuple(sorted((17, 50, 645) + chirp_common.DTCS_CODES)) TMODES = ["", "Tone", "DTCS", "DTCS"] def _image_ident_from_data(data): return data[0x168:0x178] def _image_ident_from_image(radio): return _image_ident_from_data(radio.get_mmap()) def checksum(frame): x = 0 for b in frame: x ^= b return x & 0xFF def make_frame(cmd, addr, data=b""): payload = struct.pack(">H", addr) + data header = struct.pack(">cB", cmd, len(payload)) frame = header + payload return frame + bytes([checksum(frame)]) def send(radio, frame): # LOG.debug("%04i P>R: %s" % # (len(frame), # util.hexprint(frame).replace("\n", "\n "))) try: radio.pipe.write(frame) except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def recv(radio, readdata=True): hdr = radio.pipe.read(4) # LOG.debug("%04i PBBH", hdr) length -= 2 if readdata: data = radio.pipe.read(length) # LOG.debug(" PTone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 7 rf.valid_power_levels = self._power_levels rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_skips = ["", "S"] rf.valid_tuning_steps = _STEP_LIST rf.valid_bands = [(136000000, 174000000), (400000000, 480000000)] rf.valid_tones = TONES rf.valid_dtcs_codes = DTCS_CODES rf.memory_bounds = (1, 199) return rf def sync_in(self): try: self._mmap = do_download(self) except Exception as e: finish(self) raise errors.RadioError("Failed to download from radio: %s" % e) self.process_mmap() def process_mmap(self): self._memobj = bitwise.parse( MEM_FORMAT % self._mem_formatter, self._mmap) def sync_out(self): try: do_upload(self) except errors.RadioError: finish(self) raise except Exception as e: raise errors.RadioError("Failed to upload to radio: %s" % e) def get_raw_memory(self, number): name, mem = self._get_memobjs(number) return repr(name) + repr(mem) def _get_tone(self, mem, _mem): rx_tone = tx_tone = None tx_tmode = TMODES[_mem.tx_tmode] rx_tmode = TMODES[_mem.rx_tmode] if tx_tmode == "Tone": tx_tone = TONES[_mem.tx_tone - 1] elif tx_tmode == "DTCS": tx_tone = DTCS_CODES[_mem.tx_tone - 1] if rx_tmode == "Tone": rx_tone = TONES[_mem.rx_tone - 1] elif rx_tmode == "DTCS": rx_tone = DTCS_CODES[_mem.rx_tone - 1] tx_pol = _mem.tx_tmode == 0x03 and "R" or "N" rx_pol = _mem.rx_tmode == 0x03 and "R" or "N" chirp_common.split_tone_decode(mem, (tx_tmode, tx_tone, tx_pol), (rx_tmode, rx_tone, rx_pol)) def _is_txinh(self, _mem): raw_tx = b"" for i in range(0, 4): raw_tx += _mem.tx_freq[i].get_raw() return raw_tx == b"\xFF\xFF\xFF\xFF" def _get_memobjs(self, number): _mem = self._memobj.memory[number - 1] _name = self._memobj.name[number - 1] return _mem, _name def get_memory(self, number): _mem, _name = self._get_memobjs(number) mem = chirp_common.Memory() mem.number = number if _mem.get_raw()[:4] == b"\xFF\xFF\xFF\xFF": mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 if self._is_txinh(_mem): mem.duplex = "off" mem.offset = 0 elif int(_mem.rx_freq) == int(_mem.tx_freq): mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rx_freq) * 10 - int(_mem.tx_freq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.tx_freq) * 10 else: mem.duplex = int(_mem.rx_freq) > int(_mem.tx_freq) and "-" or "+" mem.offset = abs(int(_mem.rx_freq) - int(_mem.tx_freq)) * 10 mem.name = str(_name.name).rstrip() self._get_tone(mem, _mem) mem.mode = MODES[_mem.mode] powerindex = _mem.power if _mem.power < len(self._power_levels) else -1 mem.power = self._power_levels[powerindex] mem.skip = _mem.skip and "S" or "" mem.extra = RadioSettingGroup("Extra", "extra") opts = ["On", "Off"] rs = RadioSetting("blckoff", "Busy Channel Lockout", RadioSettingValueList( opts, opts[_mem.blckoff])) mem.extra.append(rs) opts = ["Off", "On"] rs = RadioSetting("tailcut", "Squelch Tail Elimination", RadioSettingValueList( opts, opts[_mem.tailcut])) mem.extra.append(rs) apro = _mem.apro if _mem.apro < 0x5 else 0 opts = ["Off", "Compander", "Scrambler", "TX Scrambler", "RX Scrambler"] rs = RadioSetting("apro", "Audio Processing", RadioSettingValueList( opts, opts[apro])) mem.extra.append(rs) opts = ["On", "Off"] rs = RadioSetting("voxoff", "VOX", RadioSettingValueList( opts, opts[_mem.voxoff])) mem.extra.append(rs) opts = ["On", "Off"] rs = RadioSetting("pttidoff", "PTT ID", RadioSettingValueList( opts, opts[_mem.pttidoff])) mem.extra.append(rs) opts = ["On", "Off"] rs = RadioSetting("dtmfoff", "DTMF", RadioSettingValueList( opts, opts[_mem.dtmfoff])) mem.extra.append(rs) opts = ["Name", "Frequency"] aliasop = RadioSetting("aliasop", "Display", RadioSettingValueList( opts, opts[_mem.aliasop])) mem.extra.append(aliasop) opts = ["On", "Off"] rs = RadioSetting("reverseoff", "Reverse Frequency", RadioSettingValueList( opts, opts[_mem.reverseoff])) mem.extra.append(rs) opts = ["On", "Off"] rs = RadioSetting("talkaroundoff", "Talk Around", RadioSettingValueList( opts, opts[_mem.talkaroundoff])) mem.extra.append(rs) return mem def _set_tone(self, mem, _mem): ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) _mem.tx_tmode = TMODES.index(txmode) _mem.rx_tmode = TMODES.index(rxmode) if txmode == "Tone": _mem.tx_tone = TONES.index(txtone) + 1 elif txmode == "DTCS": _mem.tx_tmode = txpol == "R" and 0x03 or 0x02 _mem.tx_tone = DTCS_CODES.index(txtone) + 1 if rxmode == "Tone": _mem.rx_tone = TONES.index(rxtone) + 1 elif rxmode == "DTCS": _mem.rx_tmode = rxpol == "R" and 0x03 or 0x02 _mem.rx_tone = DTCS_CODES.index(rxtone) + 1 def set_memory(self, mem): _mem, _name = self._get_memobjs(mem.number) if mem.empty: _mem.set_raw(b"\xFF" * 16) return elif _mem.get_raw() == (b"\xFF" * 16): _mem.set_raw(b"\xFF" * 8 + b"\xFF\x00\xFF\x00\xFF\xFE\xF0\xFC") _mem.rx_freq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.tx_freq[i].set_raw(b"\xFF") elif mem.duplex == "split": _mem.tx_freq = mem.offset / 10 elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 else: _mem.tx_freq = mem.freq / 10 self._set_tone(mem, _mem) _mem.power = mem.power and self._power_levels.index(mem.power) or 0 _mem.mode = MODES.index(mem.mode) _mem.skip = mem.skip == "S" _name.name = mem.name.ljust(7) # autoset display to name if filled, else show frequency if mem.extra: # mem.extra only seems to be populated when called from edit panel aliasop = mem.extra["aliasop"] else: aliasop = None if mem.name: _mem.aliasop = False else: _mem.aliasop = True for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def _get_settings(self): _settings = self._memobj.settings _service = self._memobj.service _msg = self._memobj.messages cfg_grp = RadioSettingGroup("cfg_grp", "Basic Settings") adv_grp = RadioSettingGroup("adv_grp", "Advanced Settings") key_grp = RadioSettingGroup("key_grp", "Key Assignment") group = RadioSettings(cfg_grp, adv_grp, key_grp) # # Basic Settings # rs = RadioSetting("apo", "Auto Power Off", RadioSettingValueList( APO_LIST, APO_LIST[_settings.apo])) cfg_grp.append(rs) rs = RadioSetting("sql", "Squelch Level", RadioSettingValueList( SQL_LIST, SQL_LIST[_settings.sql])) cfg_grp.append(rs) rs = RadioSetting("scanm", "Scan Mode", RadioSettingValueList( SCANM_LIST, SCANM_LIST[_settings.scanm])) cfg_grp.append(rs) rs = RadioSetting("tot", "Time Out Timer", RadioSettingValueList( TOT_LIST, TOT_LIST[_settings.tot])) cfg_grp.append(rs) rs = RadioSetting("step", "Step", RadioSettingValueList( STEP_LIST, STEP_LIST[_settings.step])) cfg_grp.append(rs) rs = RadioSetting("monitor", "Monitor", RadioSettingValueList( MONITOR_LIST, MONITOR_LIST[_settings.monitor])) cfg_grp.append(rs) rs = RadioSetting("vfomr", "VFO/MR", RadioSettingValueList( VFOMR_LIST, VFOMR_LIST[_settings.vfomr])) cfg_grp.append(rs) rs = RadioSetting("mrcha", "MR/CHA", RadioSettingValueList( MRCHA_LIST, MRCHA_LIST[_settings.mrcha])) cfg_grp.append(rs) rs = RadioSetting("vol", "Volume", RadioSettingValueList( VOL_LIST, VOL_LIST[_settings.vol])) cfg_grp.append(rs) rs = RadioSetting("opendis", "Open Display", RadioSettingValueList( OPENDIS_LIST, OPENDIS_LIST[_settings.opendis])) cfg_grp.append(rs) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " LOG.debug("Filtered: %s" % filtered) return filtered rs = RadioSetting("messages.user1", "User-defined Message 1", RadioSettingValueString(0, 7, _filter(_msg.user1))) cfg_grp.append(rs) rs = RadioSetting("messages.user2", "User-defined Message 2", RadioSettingValueString(0, 7, _filter(_msg.user2))) cfg_grp.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.system)) val.set_mutable(False) rs = RadioSetting("messages.system", "System Message", val) cfg_grp.append(rs) rs = RadioSetting("lamp", "Backlight", RadioSettingValueList( LAMP_LIST, LAMP_LIST[_settings.lamp])) cfg_grp.append(rs) rs = RadioSetting("keylockm", "Key Lock Mode", RadioSettingValueList( KEYLOCKM_LIST, KEYLOCKM_LIST[_settings.keylockm])) cfg_grp.append(rs) rs = RadioSetting("absel", "A/B Select", RadioSettingValueList(ABSEL_LIST, ABSEL_LIST[_settings.absel])) cfg_grp.append(rs) rs = RadioSetting("obeep", "Open Beep", RadioSettingValueBoolean(_settings.obeep)) cfg_grp.append(rs) rs = RadioSetting("rbeep", "Roger Beep", RadioSettingValueBoolean(_settings.rbeep)) cfg_grp.append(rs) rs = RadioSetting("keylock_off", "Key Lock", RadioSettingValueBoolean(not _settings.keylock_off)) cfg_grp.append(rs) rs = RadioSetting("ctdcsb", "CT/DCS Busy Lock", RadioSettingValueBoolean(_settings.ctdcsb)) cfg_grp.append(rs) rs = RadioSetting("alarm", "Alarm Key", RadioSettingValueBoolean(_settings.alarm)) cfg_grp.append(rs) rs = RadioSetting("save", "Battery Save", RadioSettingValueBoolean(_settings.save)) cfg_grp.append(rs) rs = RadioSetting("kbeep", "Key Beep", RadioSettingValueBoolean(_settings.kbeep)) cfg_grp.append(rs) rs = RadioSetting("reset", "Reset Enable", RadioSettingValueBoolean(_settings.reset)) cfg_grp.append(rs) rs = RadioSetting("smfont_off", "Small Font", RadioSettingValueBoolean(not _settings.smfont_off)) cfg_grp.append(rs) rs = RadioSetting("aliasen_off", "Alias Enable", RadioSettingValueBoolean(not _settings.aliasen_off)) cfg_grp.append(rs) rs = RadioSetting("txstop_off", "TX Stop", RadioSettingValueBoolean(not _settings.txstop_off)) cfg_grp.append(rs) rs = RadioSetting("dw_off", "Dual Watch", RadioSettingValueBoolean(not _settings.dw_off)) cfg_grp.append(rs) rs = RadioSetting("fmen_off", "FM Enable", RadioSettingValueBoolean(not _settings.fmen_off)) cfg_grp.append(rs) rs = RadioSetting("fmdw", "FM Dual Watch", RadioSettingValueBoolean(_settings.fmdw)) cfg_grp.append(rs) rs = RadioSetting("fmscan_off", "FM Scan", RadioSettingValueBoolean( not _settings.fmscan_off)) cfg_grp.append(rs) rs = RadioSetting("keypadmic_off", "Keypad MIC", RadioSettingValueBoolean( not _settings.keypadmic_off)) cfg_grp.append(rs) rs = RadioSetting("voxgain", "VOX Gain", RadioSettingValueList( VOXGAIN_LIST, VOXGAIN_LIST[_settings.voxgain])) cfg_grp.append(rs) rs = RadioSetting("voxdt", "VOX Delay Time", RadioSettingValueList( VOXDT_LIST, VOXDT_LIST[_settings.voxdt])) cfg_grp.append(rs) rs = RadioSetting("vir", "VOX Inhibit on Receive", RadioSettingValueBoolean(_settings.vir)) cfg_grp.append(rs) # # Advanced Settings # val = (_settings.dtmftime) - 5 rs = RadioSetting("dtmftime", "DTMF Digit Time", RadioSettingValueList( DTMFTIME_LIST, DTMFTIME_LIST[val])) adv_grp.append(rs) val = (_settings.dtmfspace) - 5 rs = RadioSetting("dtmfspace", "DTMF Digit Space Time", RadioSettingValueList( DTMFTIME_LIST, DTMFTIME_LIST[val])) adv_grp.append(rs) val = (_settings.dtmfdelay) // 5 rs = RadioSetting("dtmfdelay", "DTMF 1st Digit Delay", RadioSettingValueList( DTMFDELAY_LIST, DTMFDELAY_LIST[val])) adv_grp.append(rs) val = (_settings.dtmfpretime) // 10 - 1 rs = RadioSetting("dtmfpretime", "DTMF Pretime", RadioSettingValueList( DTMFPRETIME_LIST, DTMFPRETIME_LIST[val])) adv_grp.append(rs) val = (_settings.dtmfdelay2) // 5 rs = RadioSetting("dtmfdelay2", "DTMF * and # Digit Delay", RadioSettingValueList( DTMFDELAY2_LIST, DTMFDELAY2_LIST[val])) adv_grp.append(rs) rs = RadioSetting("ackdecode", "ACK Decode", RadioSettingValueBoolean(_settings.ackdecode)) adv_grp.append(rs) rs = RadioSetting("dtmfst", "DTMF Sidetone", RadioSettingValueBoolean(_settings.dtmfst)) adv_grp.append(rs) rs = RadioSetting("service.rssi400", "Squelch Base Level (UHF)", RadioSettingValueInteger(0, 255, _service.rssi400)) adv_grp.append(rs) rs = RadioSetting("service.rssi136", "Squelch Base Level (VHF)", RadioSettingValueInteger(0, 255, _service.rssi136)) adv_grp.append(rs) # # Key Settings # val = (_settings.lptime) - 5 rs = RadioSetting("lptime", "Long Press Time", RadioSettingValueList( LPTIME_LIST, LPTIME_LIST[val])) key_grp.append(rs) rs = RadioSetting("keyp1long", "P1 Long Key", RadioSettingValueList( PFKEYLONG_LIST, PFKEYLONG_LIST[_settings.keyp1long])) key_grp.append(rs) rs = RadioSetting("keyp1short", "P1 Short Key", RadioSettingValueList( PFKEYSHORT_LIST, PFKEYSHORT_LIST[_settings.keyp1short])) key_grp.append(rs) rs = RadioSetting("keyp2long", "P2 Long Key", RadioSettingValueList( PFKEYLONG_LIST, PFKEYLONG_LIST[_settings.keyp2long])) key_grp.append(rs) rs = RadioSetting("keyp2short", "P2 Short Key", RadioSettingValueList( PFKEYSHORT_LIST, PFKEYSHORT_LIST[_settings.keyp2short])) key_grp.append(rs) rs = RadioSetting("keyp3long", "P3 Long Key", RadioSettingValueList( PFKEYLONG_LIST, PFKEYLONG_LIST[_settings.keyp3long])) key_grp.append(rs) rs = RadioSetting("keyp3short", "P3 Short Key", RadioSettingValueList( PFKEYSHORT_LIST, PFKEYSHORT_LIST[_settings.keyp3short])) key_grp.append(rs) val = RadioSettingValueList(PFKEYSHORT_LIST, PFKEYSHORT_LIST[_settings.keymshort]) val.set_mutable(_settings.menuen == 0) rs = RadioSetting("keymshort", "M Short Key", val) key_grp.append(rs) val = RadioSettingValueBoolean(_settings.menuen) rs = RadioSetting("menuen", "Menu Enable", val) key_grp.append(rs) return group def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "keylock_off": setattr(obj, setting, not int(element.value)) elif setting == "smfont_off": setattr(obj, setting, not int(element.value)) elif setting == "aliasen_off": setattr(obj, setting, not int(element.value)) elif setting == "txstop_off": setattr(obj, setting, not int(element.value)) elif setting == "dw_off": setattr(obj, setting, not int(element.value)) elif setting == "fmen_off": setattr(obj, setting, not int(element.value)) elif setting == "fmscan_off": setattr(obj, setting, not int(element.value)) elif setting == "keypadmic_off": setattr(obj, setting, not int(element.value)) elif setting == "dtmftime": setattr(obj, setting, int(element.value) + 5) elif setting == "dtmfspace": setattr(obj, setting, int(element.value) + 5) elif setting == "dtmfdelay": setattr(obj, setting, int(element.value) * 5) elif setting == "dtmfpretime": setattr(obj, setting, (int(element.value) + 1) * 10) elif setting == "dtmfdelay2": setattr(obj, setting, int(element.value) * 5) elif setting == "lptime": setattr(obj, setting, int(element.value) + 5) else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): if filedata[0x168:0x170].startswith(cls._file_ident) and \ filedata[0x170:0x178].startswith(cls._model_ident): return True else: return False @directory.register class JetstreamJT270MRadio(LeixenVV898Radio): """Jetstream JT270M""" VENDOR = "Jetstream" MODEL = "JT270M" ALIASES = [] _file_ident = b"JET" _model_ident = b'LX-\x89\x85\x53' class LT898UV(LeixenVV898Radio): VENDOR = "LUITON" MODEL = "LT-898UV" @classmethod def match_model(cls, filedata, filename): return False @directory.register class JetstreamJT270MHRadio(LeixenVV898Radio): """Jetstream JT270MH""" VENDOR = "Jetstream" MODEL = "JT270MH" _file_ident = b"Leixen" _model_ident = b'LX-\x89\x85\x85' _ranges = [(0x0C00, 0x2000)] _mem_formatter = {'unknownormode': 'mode:1', 'modeorpower': 'power:2', 'chanstart': 0x0C00, 'namestart': 0x1900, 'defaults': 6} _power_levels = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=10), chirp_common.PowerLevel("High", watts=25)] # Base radio has offset zero to distinguish from sub devices _offset = 0 def get_features(self): rf = super(JetstreamJT270MHRadio, self).get_features() rf.has_sub_devices = self._offset == 0 rf.memory_bounds = (1, 99) return rf def get_sub_devices(self): return [JetstreamJT270MHRadioA(self._mmap), JetstreamJT270MHRadioB(self._mmap)] def _get_memobjs(self, number): number = number * 2 - self._offset _mem = self._memobj.memory[number] _name = self._memobj.name[number] return _mem, _name class JetstreamJT270MHRadioA(JetstreamJT270MHRadio): VARIANT = 'A Band' _offset = 1 class JetstreamJT270MHRadioB(JetstreamJT270MHRadio): VARIANT = 'B Band' _offset = 2 @directory.register class LeixenVV898SRadio(LeixenVV898Radio): """Leixen VV-898S, also VV-898E which is identical""" VENDOR = "Leixen" MODEL = "VV-898S" _model_ident = b'LX-\x89\x85\x75' _mem_formatter = {'unknownormode': 'mode:1', 'modeorpower': 'power:2', 'chanstart': 0x0D00, 'namestart': 0x19B0, 'defaults': 3} _power_levels = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Med", watts=10), chirp_common.PowerLevel("High", watts=25)] @directory.register class VV898E(LeixenVV898SRadio): '''Leixen has called this radio both 898E and S historically, ident is identical''' VENDOR = "Leixen" MODEL = "VV-898E" @classmethod def match_model(cls, filedata, filename): return False @directory.register @directory.detected_by(LeixenVV898SRadio) class VV898SDualBank(JetstreamJT270MHRadio): '''Newer VV898S 1.06+ firmware that features dual memory banks''' VENDOR = "Leixen" MODEL = "VV-898S" VARIANT = "Dual Bank" @classmethod def match_model(cls, filedata, filename): return False @directory.register @directory.detected_by(VV898E) class VV898EDualBank(JetstreamJT270MHRadio): '''Newer VV898E 1.06+ firmware that features dual memory banks''' VENDOR = "Leixen" MODEL = "VV-898E" VARIANT = "Dual Bank" @classmethod def match_model(cls, filedata, filename): return False chirp-20240224/chirp/drivers/vx510.py0000644000175000017500000001445214430171343016062 0ustar hibbyhibby# Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import yaesu_clone from chirp import chirp_common, bitwise # This driver is unfinished and therefore does not register itself with Chirp. # # Downloads should work consistently but an upload has not been attempted. # # There is a stray byte at 0xC in the radio download that is not present in the # save file from the CE-21 software. This puts the first few bytes of channel 1 # in the wrong location. A quick hack to fix the subsequent channels was to # insert the #seekto dynamically, but this does nothing to fix reading of # channel 1 (memory[0]). MEM_FORMAT = """ u8 unknown1[6]; u8 prioritych; #seekto %d; struct { u8 empty:1, txinhibit:1, tot:1, low_power:1, bclo:1, btlo:1, skip:1, pwrsave:1; u8 unknown2:5, narrow:1, unknown2b:2; u24 name; u8 ctone; u8 rtone; u8 unknown3; bbcd freq_rx[3]; bbcd freq_tx[3]; } memory[32]; char imgname[10]; """ STEPS = [5.0, 6.25] CHARSET = "".join([chr(x) for x in range(ord("0"), ord("9")+1)] + [chr(x) for x in range(ord("A"), ord("Z")+1)]) + \ r"<=>*+-\/_ " TONES = list(chirp_common.TONES) TONES.remove(165.5) TONES.remove(171.3) TONES.remove(177.3) POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00), chirp_common.PowerLevel("Low", watts=1.0)] # @directory.register class VX510Radio(yaesu_clone.YaesuCloneModeRadio): """Vertex VX-510V""" BAUD_RATE = 9600 VENDOR = "Vertex Standard" MODEL = "VX-510V" _model = "" _memsize = 470 _block_lengths = [10, 460] _block_size = 8 def _checksums(self): return [] # These checksums don't pass, so the alg might be different than Yaesu. # return [yaesu_clone.YaesuChecksum(0, self._memsize - 2)] # return [yaesu_clone.YaesuChecksum(0, 10), # yaesu_clone.YaesuChecksum(12, self._memsize - 1)] def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = False rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_modes = ["FM", "NFM"] rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.memory_bounds = (1, 32) rf.valid_bands = [(13600000, 174000000)] rf.valid_skips = ["", "S"] rf.valid_power_levels = POWER_LEVELS rf.valid_name_length = 4 rf.valid_characters = CHARSET return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % 0xA, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) def get_memory(self, number): mem = chirp_common.Memory() mem.number = number _mem = self._memobj.memory[number-1] mem.empty = _mem.empty mem.freq = chirp_common.fix_rounded_step(int(_mem.freq_rx) * 1000) for i in range(0, 4): index = (_mem.name >> (i*6)) & 0x3F mem.name += CHARSET[index] freq_tx = chirp_common.fix_rounded_step(int(_mem.freq_tx) * 1000) if _mem.txinhibit: mem.duplex = "off" elif mem.freq == freq_tx: mem.duplex = "" mem.offset = 0 elif 144000000 <= mem.freq < 148000000: mem.duplex = "+" if freq_tx > mem.freq else "-" mem.offset = abs(mem.freq - freq_tx) else: mem.duplex = "split" mem.offset = freq_tx mem.mode = _mem.narrow and "NFM" or "FM" mem.power = POWER_LEVELS[_mem.low_power] rtone = int(_mem.rtone) ctone = int(_mem.ctone) tmode_tx = tmode_rx = "" if rtone & 0x80: tmode_tx = "DTCS" mem.dtcs = chirp_common.DTCS_CODES[int(rtone) - 0x80] elif rtone: tmode_tx = "Tone" mem.rtone = TONES[rtone - 1] if not ctone: # not used, but this is a better default than 88.5 mem.ctone = TONES[rtone - 1] if ctone & 0x80: tmode_rx = "DTCS" mem.rx_dtcs = chirp_common.DTCS_CODES[int(ctone) - 0x80] elif ctone: tmode_rx = "Tone" mem.ctone = TONES[ctone - 1] if tmode_tx == "Tone" and not tmode_rx: mem.tmode = "Tone" elif tmode_tx == tmode_rx and tmode_tx == "Tone" and \ mem.rtone == mem.ctone: mem.tmode = "TSQL" elif tmode_tx == tmode_rx and tmode_tx == "DTCS" and \ mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif tmode_rx or tmode_tx: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (tmode_tx, tmode_rx) mem.skip = _mem.skip and "S" or "" return mem @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize # @directory.register class VX510File(VX510Radio, chirp_common.FileBackedRadio): """Vertex CE-21 File""" VENDOR = "Vertex Standard" MODEL = "CE-21 File" _model = "" _memsize = 664 def _checksums(self): return [yaesu_clone.YaesuChecksum(0, self._memsize - 1)] def process_mmap(self): # CE-21 file is missing the 0xC byte, probably a checksum. # It's not a YaesuChecksum. self._memobj = bitwise.parse(MEM_FORMAT % 0x9, self._mmap) @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize chirp-20240224/chirp/drivers/id51plus.py0000644000175000017500000001071014430171343016636 0ustar hibbyhibby# Copyright 2015 Eric Dropps # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import logging from chirp.drivers import id31 from chirp import directory, bitwise LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { u24 freq; u16 offset; u16 rtone:6, ctone:6, unknown2:1, mode:3; u8 dtcs; u8 tune_step:4, dsql_mode:2, unknown5:2; u8 unknown4; u8 tmode:4, duplex:2, dtcs_polarity:2; char name[16]; u8 digcode; u8 urcall[7]; u8 rpt1call[7]; u8 rpt2call[7]; } memory[500]; #seekto 0x6A40; u8 used_flags[70]; #seekto 0x6A86; u8 skip_flags[69]; #seekto 0x6ACB; u8 pskp_flags[69]; #seekto 0x6B40; struct { u8 unknown:3, bank:5; u8 index; } banks[500]; #seekto 0x6FD0; struct { char name[16]; } bank_names[26]; #seekto 0xA8C0; struct { u24 freq; u16 offset; u8 unknown1[4]; u8 call[7]; char name[16]; char subname[8]; u8 unknown3[10]; } repeaters[750]; #seekto 0x1384E; struct { u8 call[7]; } rptcall[750]; #seekto 0x14FBE; struct { char name[16]; } rptgroup_names[30]; #seekto 0x1519E; struct { char call[8]; char tag[4]; } mycall[6]; #seekto 0x151E6; struct { char call[8]; } urcall[200]; #seekto 0x15826; struct { char name[16]; } urcallname[200]; """ @directory.register class ID51PLUSRadio(id31.ID31Radio): """Icom ID-51 Plus/50th Anniversary""" MODEL = "ID-51 Plus" _memsize = 0x1FB40 _model = "\x33\x90\x00\x02" _endframe = "Icom Inc\x2E\x44\x41" _bank_class = id31.ID31Bank _ranges = [(0x00000, 0x1FB40, 32)] MODES = {0: "FM", 1: "NFM", 3: "AM", 5: "DV"} @classmethod def match_model(cls, filedata, filename): """Given contents of a stored file (@filedata), return True if this radio driver handles the represented model""" # The default check for ICOM is just to check memory size # Since the ID-51 and ID-51 Plus/Anniversary have exactly # the same memory size, we need to do a more detailed check. if len(filedata) == cls._memsize: snip = bytes(filedata[0x1AF40:0x1AF60]) if snip != bytes(b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'): return True return False def _get_bank(self, loc): _bank = self._memobj.banks[loc] LOG.debug("Bank Value for location %s is %s" % (loc, _bank.bank)) if _bank.bank == 0x1F: return None else: return _bank.bank def _set_bank(self, loc, bank): _bank = self._memobj.banks[loc] if bank is None: _bank.bank = 0x1F else: _bank.bank = bank def get_features(self): rf = super(ID51PLUSRadio, self).get_features() rf.valid_bands = [(108000000, 174000000), (380000000, 479000000)] return rf def get_repeater_call_list(self): calls = [] # Unlike previous DStar radios, there is not a separate repeater # callsign list. It's only the DV Memory banks. for repeater in self._memobj.repeaters: call = id31._decode_call(repeater.call) if call == "CALLSIGN": call = "" calls.append(call.rstrip()) return calls def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) @directory.register class ID51PLUS2Radio(ID51PLUSRadio): MODEL = 'ID-51 Plus2' _model = b'\x33\x90\x00\x03' _endframe = b'Icom Inc.DA' _raw_frames = True _highbit_flip = True _icf_data = { 'MapRev': 1, 'EtcData': 0x400001, } @classmethod def match_model(cls, filedata, filename): # This model is always matched with metadata return False chirp-20240224/chirp/drivers/icp7.py0000644000175000017500000001523314466370044016047 0ustar hibbyhibby# Copyright 2017 SASANO Takayoshi (JG1UAA) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf from chirp import chirp_common, directory, bitwise # memory number: # 000 - 999 regular memory channels (supported, others not) # 1000 - 1049 scan edges # 1050 - 1249 auto write channels # 1250 call channel (C0) # 1251 call channel (C1) MEM_FORMAT = """ struct { ul32 freq; ul32 offset; ul16 train_sql:2, tmode:3, duplex:2, train_tone:9; ul16 tuning_step:4, rtone:6, ctone:6; ul16 unknown0:6, mode:3, dtcs:7; u8 unknown1:6, dtcs_polarity:2; char name[6]; } memory[1251]; #seekto 0x6b1e; struct { u8 bank; u8 index; } banks[1050]; #seekto 0x689e; u8 used[132]; #seekto 0x6922; u8 skips[132]; #seekto 0x69a6; u8 pskips[132]; #seekto 0x7352; struct { char name[6]; } bank_names[18]; """ MODES = ["FM", "WFM", "AM", "Auto"] TMODES = ["", "Tone", "TSQL", "", "DTCS"] DUPLEX = ["", "-", "+"] DTCS_POLARITY = ["NN", "NR", "RN", "RR"] TUNING_STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 200.0, 0.0] # 0.0 as "Auto" class ICP7Bank(icf.IcomBank): """ICP7 bank""" def get_name(self): _bank = self._model._radio._memobj.bank_names[self.index] return str(_bank.name).rstrip() def set_name(self, name): _bank = self._model._radio._memobj.bank_names[self.index] _bank.name = name.ljust(6)[:6] @directory.register class ICP7Radio(icf.IcomCloneModeRadio): """Icom IC-P7""" VENDOR = "Icom" MODEL = "IC-P7" _model = "\x28\x69\x00\x01" _memsize = 0x7500 _endframe = "Icom Inc\x2e\x41\x38" _ranges = [(0x0000, 0x7500, 32)] _num_banks = 18 _bank_class = ICP7Bank _can_hispeed = True def _get_bank(self, loc): _bank = self._memobj.banks[loc] if _bank.bank != 0xff: return _bank.bank else: return None def _set_bank(self, loc, bank): _bank = self._memobj.banks[loc] if bank is None: _bank.bank = 0xff else: _bank.bank = bank def _get_bank_index(self, loc): _bank = self._memobj.banks[loc] return _bank.index def _set_bank_index(self, loc, index): _bank = self._memobj.banks[loc] _bank.index = index def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 999) rf.valid_tmodes = TMODES rf.valid_duplexes = DUPLEX rf.valid_modes = MODES rf.valid_bands = [(495000, 999990000)] rf.valid_skips = ["", "S", "P"] rf.valid_tuning_steps = TUNING_STEPS rf.valid_name_length = 6 rf.has_settings = True rf.has_ctone = True rf.has_bank = True rf.has_bank_index = True rf.has_bank_names = True return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): bit = 1 << (number % 8) byte = int(number / 8) _mem = self._memobj.memory[number] _usd = self._memobj.used[byte] _skp = self._memobj.skips[byte] _psk = self._memobj.pskips[byte] mem = chirp_common.Memory() mem.number = number if _usd & bit: mem.empty = True return mem mem.freq = _mem.freq // 3 mem.offset = _mem.offset // 3 mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] mem.tuning_step = TUNING_STEPS[_mem.tuning_step] mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.mode = MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_polarity] mem.name = str(_mem.name).rstrip() if _skp & bit: mem.skip = "P" if _psk & bit else "S" else: mem.skip = "" return mem def set_memory(self, mem): bit = 1 << (mem.number % 8) byte = int(mem.number / 8) _mem = self._memobj.memory[mem.number] _usd = self._memobj.used[byte] _skp = self._memobj.skips[byte] _psk = self._memobj.pskips[byte] if mem.empty: _usd |= bit # We use default value instead of zero-fill # to avoid unexpected behavior. _mem.freq = 15000 _mem.offset = 479985000 _mem.train_sql = ~0 _mem.tmode = ~0 _mem.duplex = ~0 _mem.train_tone = ~0 _mem.tuning_step = ~0 _mem.rtone = ~0 _mem.ctone = ~0 _mem.unknown0 = 0 _mem.mode = ~0 _mem.dtcs = ~0 _mem.unknown1 = ~0 _mem.dtcs_polarity = ~0 _mem.name = " " _skp |= bit _psk |= bit else: _usd &= ~bit _mem.freq = mem.freq * 3 _mem.offset = mem.offset * 3 _mem.train_sql = 0 # Train SQL mode (0:off 1:Tone 2:MSK) _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) _mem.train_tone = 228 # Train SQL Tone (x10 Hz) _mem.tuning_step = TUNING_STEPS.index(mem.tuning_step) _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.unknown0 = 0 # unknown (always zero) _mem.mode = MODES.index(mem.mode) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.unknown1 = ~0 # unknown (always one) _mem.dtcs_polarity = DTCS_POLARITY.index(mem.dtcs_polarity) _mem.name = mem.name.ljust(6)[:6] if mem.skip == "S": _skp |= bit _psk &= ~bit elif mem.skip == "P": _skp |= bit _psk |= bit else: _skp &= ~bit _psk &= ~bit chirp-20240224/chirp/drivers/anytone_ht.py0000644000175000017500000007322214566340166017362 0ustar hibbyhibby# Copyright 2015 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp import errors from chirp import memmap from chirp import util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) mem_format = """ struct memory { bbcd freq[4]; bbcd offset[4]; u8 unknown1:4, tune_step:4; u8 unknown2:2, txdcsextra:1, txinv:1, channel_width:2, unknown3:1, tx_off:1; u8 unknown4:2, rxdcsextra:1, rxinv:1, power:2, duplex:2; u8 unknown5:4, rxtmode:2, txtmode:2; u8 unknown6:2, txtone:6; u8 unknown7:2, rxtone:6; u8 txcode; u8 rxcode; u8 unknown8[3]; char name[6]; u8 squelch:4, unknown9:2, bcl:2; u8 unknownA; u8 unknownB:7, sqlmode:1; u8 unknownC[4]; }; #seekto 0x0010; struct { u8 unknown1; u8 unknown2:5, bands1:3; char model[7]; u8 unknown3:5, bands2:3; u8 unknown4[6]; u8 unknown5[16]; char date[9]; u8 unknown6[7]; u8 unknown7[16]; u8 unknown8[16]; char dealer[16]; char stockdate[9]; u8 unknown9[7]; char selldate[9]; u8 unknownA[7]; char seller[16]; } oem_info; #seekto 0x0100; u8 used_flags[50]; #seekto 0x0120; u8 skip_flags[50]; #seekto 0x0220; struct { u8 unknown220:6, display:2; u8 unknown221:7, upvfomr:1; u8 unknown222:7, dnvfomr:1; u8 unknown223:7, fmvfomr:1; u8 upmrch; u8 dnmrch; u8 unknown226:1, fmmrch:7; u8 unknown227; u8 unknown228:7, fastscano:1; // obltr-8r only u8 unknown229:6, pause:2; u8 unknown22A:5, stop:3; u8 unknown22B:6, backlight:2; u8 unknown22C:6, color:2; u8 unknown22D:6, vdisplay:2; u8 unknown22E; u8 unknown22F:5, pf1key:3; u8 beep:1, alarmoff:1, main:1, radio:1, unknown230:1, allband:1, elimtail:1, monikey:1; u8 fastscan:1, // termn-8r only keylock:1, unknown231:2, lwenable:1, swenable:1, fmenable:1, amenable:1; u8 unknown232:3, tot:5; u8 unknown233:7, amvfomr:1; u8 unknown234:3, apo:5; u8 unknown235:5, pf2key:3; // keylock for obltr-8r u8 unknown236; u8 unknown237:4, save:4; u8 unknown238:5, tbst:3; u8 unknown239:4, voxlevel:4; u8 unknown23A:3, voxdelay:5; u8 unknown23B:5, tail:3; u8 unknown23C; u8 unknown23D:1, ammrch:7; u8 unknown23E:5, vvolume:3; u8 unknown23F:5, fmam:3; u8 unknown240:4, upmrbank:4; u8 unknown241:7, upwork:1; u8 unknown242:7, uplink:1; u8 unknown243:4, dnmrbank:4; u8 unknown244:7, dnwork:1; u8 unknown245:7, downlink:1; u8 unknown246:7, banklink1:1; u8 unknown247:7, banklink2:1; u8 unknown248:7, banklink3:1; u8 unknown249:7, banklink4:1; u8 unknown24A:7, banklink5:1; u8 unknown24B:7, banklink6:1; u8 unknown24C:7, banklink7:1; u8 unknown24D:7, banklink8:1; u8 unknown24E:7, banklink9:1; u8 unknown24F:7, banklink0:1; u8 unknown250:6, noaa:2; u8 unknown251:5, noaach:3; u8 unknown252:6, part95:2; u8 unknown253:3, gmrs:5; u8 unknown254:5, murs:3; u8 unknown255:5, amsql:3; } settings; #seekto 0x0246; struct { u8 unused:7, bank:1; } banklink[10]; #seekto 0x03E0; struct { char line1[6]; char line2[6]; } welcome_msg; #seekto 0x2000; struct memory memory[200]; """ def _echo_write(radio, data): try: radio.pipe.write(data) except Exception as e: LOG.error("Error writing to radio: %s" % e) raise errors.RadioError("Unable to write to radio") def _read(radio, length): try: data = radio.pipe.read(length) except Exception as e: LOG.error("Error reading from radio: %s" % e) raise errors.RadioError("Unable to read from radio") if len(data) != length: LOG.error("Short read from radio (%i, expected %i)" % (len(data), length)) LOG.debug(util.hexprint(data)) raise errors.RadioError("Short read from radio") return data valid_model = [b'TERMN8R', b'OBLTR8R'] def _ident(radio): radio.pipe.timeout = 1 _echo_write(radio, b"PROGRAM") response = radio.pipe.read(3) if response != b"QX\x06": LOG.debug("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Radio did not respond. Check connection.") _echo_write(radio, b"\x02") response = radio.pipe.read(16) LOG.debug(util.hexprint(response)) if radio._file_ident not in response: LOG.debug("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Unsupported model") def _finish(radio): endframe = b"\x45\x4E\x44" _echo_write(radio, endframe) result = radio.pipe.read(1) if result != b"\x06": LOG.debug("Got:\n%s" % util.hexprint(result)) raise errors.RadioError("Radio did not finish cleanly") def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def _send(radio, cmd, addr, length, data=None): frame = struct.pack(">cHb", cmd, addr, length) if data: frame += data frame += bytes([_checksum(frame[1:])]) frame += b"\x06" _echo_write(radio, frame) LOG.debug("Sent:\n%s" % util.hexprint(frame)) if data: result = radio.pipe.read(1) if result != b"\x06": LOG.debug("Ack was: %s" % repr(result)) raise errors.RadioError( "Radio did not accept block at %04x" % addr) return result = _read(radio, length + 6) LOG.debug("Got:\n%s" % util.hexprint(result)) header = result[:4] data = result[4:-2] ack = result[-1:] if ack != b"\x06": LOG.debug("Ack was: %s" % repr(ack)) raise errors.RadioError("Radio NAK'd block at %04x" % addr) _cmd, _addr, _length = struct.unpack(">cHb", header) if _addr != addr or _length != _length: LOG.debug("Expected/Received:") LOG.debug(" Length: %02x/%02x" % (length, _length)) LOG.debug(" Addr: %04x/%04x" % (addr, _addr)) raise errors.RadioError("Radio send unexpected block") cs = _checksum(result[1:-2]) if cs != result[-2]: LOG.debug("Calculated: %02x" % cs) LOG.debug("Actual: %02x" % result[-2]) raise errors.RadioError("Block at 0x%04x failed checksum" % addr) return data def _download(radio): _ident(radio) memobj = None data = b"" for start, end in radio._ranges: for addr in range(start, end, 0x10): block = _send(radio, b'R', addr, 0x10) data += block status = chirp_common.Status() status.cur = len(data) status.max = end status.msg = "Cloning from radio" radio.status_fn(status) _finish(radio) return memmap.MemoryMapBytes(data) def _upload(radio): _ident(radio) for start, end in radio._ranges: for addr in range(start, end, 0x10): if addr < 0x0100: continue block = radio._mmap[addr:addr + 0x10] _send(radio, b'W', addr, len(block), block) status = chirp_common.Status() status.cur = addr status.max = end status.msg = "Cloning to radio" radio.status_fn(status) _finish(radio) APO = ['Off', '30 Minutes', '1 Hour', '2 Hours'] BACKLIGHT = ['Off', 'On', 'Auto'] BCLO = ['Off', 'Repeater', 'Busy'] CHARSET = chirp_common.CHARSET_ASCII COLOR = ['Blue', 'Orange', 'Purple'] DISPLAY = ['Frequency', 'N/A', 'Name'] DUPLEXES = ['', '', '-', '+', 'split', 'off'] GMRS = ['GMRS %s' % x for x in range(1, 8)] + \ ['GMRS %s' % x for x in range(15, 23)] + \ ['GMRS Repeater %s' % x for x in range(15, 23)] MAIN = ['Up', 'Down'] MODES = ['FM', 'NFM'] MONI = ['Squelch Off Momentarily', 'Squelch Off'] MRBANK = ['Bank %s' % x for x in range(1, 10)] + ['Bank 0'] MURS = ['MURS %s' % x for x in range(1, 6)] NOAA = ['Weather Off', 'Weather On', 'Weather Alerts'] NOAACH = ['WX %s' % x for x in range(1, 8)] PART95 = ['Normal(Part 90)', 'GMRS(Part 95A)', 'MURS(Part 95J)'] PAUSE = ['%s Seconds (TO)' % x for x in range(5, 20, 5)] + ['2 Seconds (CO)'] PFKEYT = ['Off', 'VOLT', 'CALL', 'FHSS', 'SUB PTT', 'ALARM', 'MONI'] PFKEYO = ['Off', 'VOLT', 'CALL', 'SUB PTT', 'ALARM', 'MONI'] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5), chirp_common.PowerLevel("Mid", watts=2), chirp_common.PowerLevel("Low", watts=1)] SAVE = ['Off', '1:2', '1:3', '1:5', '1:8', 'Auto'] SQUELCH = ['%s' % x for x in range(0, 10)] STOP = ['%s Seconds' % x for x in range(0, 4)] + ['Manual'] TAIL = ['Off', '120 Degree', '180 Degree', '240 Degree'] TBST = ['Off', '1750 Hz', '2100 Hz', '1000 Hz', '1450 Hz'] TMODES = ['', 'Tone', 'DTCS', ''] TONES = [62.5] + list(chirp_common.TONES) TOT = ['Off'] + ['%s Seconds' % x for x in range(10, 280, 10)] VDISPLAY = ['Frequency/Channel', 'Battery Voltage', 'Off'] VFOMR = ["VFO", "MR"] VOXLEVEL = ['Off'] + ['%s' % x for x in range(1, 11)] VOXDELAY = ['%.1f Seconds' % (0.1 * x) for x in range(5, 31)] WORKMODE = ["Channel", "Bank"] @directory.register class AnyToneTERMN8RRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """AnyTone TERMN-8R""" VENDOR = "AnyTone" MODEL = "TERMN-8R" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _file_ident = b"TERMN8R" # May try to mirror the OEM behavior later _ranges = [ (0x0000, 0x8000), ] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("The Anytone driver is currently experimental. " "There are no known issues with it, but you should " "proceed with caution.") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_cross = True rf.valid_tuning_steps = [2.5, 5, 6.25, 10, 12.5, 20, 25, 30, 50] rf.has_tuning_step = False rf.has_rx_dtcs = True rf.valid_skips = ["", "S"] rf.valid_modes = MODES rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_tones = TONES rf.valid_dtcs_codes = chirp_common.ALL_DTCS_CODES rf.valid_bands = [(136000000, 174000000), (400000000, 520000000)] rf.valid_characters = CHARSET rf.valid_name_length = 6 rf.valid_power_levels = POWER_LEVELS rf.valid_duplexes = DUPLEXES rf.can_odd_split = True rf.memory_bounds = (0, 199) return rf def sync_in(self): self._mmap = _download(self) self.process_mmap() def sync_out(self): _upload(self) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def _get_dcs_index(self, _mem, which): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) return (int(extra) << 8) | int(base) def _set_dcs_index(self, _mem, which, index): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) base.set_value(index & 0xFF) extra.set_value(index >> 8) def get_memory(self, number): bitpos = (1 << (number % 8)) bytepos = (number / 8) _mem = self._memobj.memory[number] _skp = self._memobj.skip_flags[bytepos] _usd = self._memobj.used_flags[bytepos] mem = chirp_common.Memory() mem.number = number if _usd & bitpos: mem.empty = True return mem mem.freq = int(_mem.freq) * 100 # compensate for 6.25 and 12.5 kHz tuning steps, add 500 Hz if needed lastdigit = int(_mem.freq) % 10 if (lastdigit == 2 or lastdigit == 7): mem.freq += 50 mem.offset = int(_mem.offset) * 100 mem.name = self.filter_name(str(_mem.name).rstrip()) mem.duplex = DUPLEXES[_mem.duplex] mem.mode = MODES[_mem.channel_width] if bool(_mem.tx_off): mem.duplex = "off" mem.offset = 0 rxtone = txtone = None rxmode = TMODES[_mem.rxtmode] txmode = TMODES[_mem.txtmode] if txmode == "Tone": txtone = TONES[_mem.txtone] elif txmode == "DTCS": txtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem, 'tx')] if rxmode == "Tone": rxtone = TONES[_mem.rxtone] elif rxmode == "DTCS": rxtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index(_mem, 'rx')] rxpol = _mem.rxinv and "R" or "N" txpol = _mem.txinv and "R" or "N" chirp_common.split_tone_decode(mem, (txmode, txtone, txpol), (rxmode, rxtone, rxpol)) if _skp & bitpos: mem.skip = "S" mem.power = POWER_LEVELS[_mem.power] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueList(BCLO, BCLO[_mem.bcl])) mem.extra.append(rs) rs = RadioSetting("squelch", "Squelch", RadioSettingValueList(SQUELCH, SQUELCH[_mem.squelch])) mem.extra.append(rs) return mem def set_memory(self, mem): bitpos = (1 << (mem.number % 8)) bytepos = (mem.number / 8) _mem = self._memobj.memory[mem.number] _skp = self._memobj.skip_flags[bytepos] _usd = self._memobj.used_flags[bytepos] if mem.empty: _usd |= bitpos _skp |= bitpos _mem.set_raw("\xFF" * 32) return _usd &= ~bitpos if _mem.get_raw(asbytes=False) == ("\xFF" * 32): LOG.debug("Initializing empty memory") _mem.set_raw("\x00" * 32) _mem.squelch = 3 _mem.freq = mem.freq / 100 if mem.duplex == "off": _mem.duplex = DUPLEXES.index("") _mem.offset = 0 _mem.tx_off = True elif mem.duplex == "split": diff = mem.offset - mem.freq _mem.duplex = DUPLEXES.index("-") if diff < 0 \ else DUPLEXES.index("+") _mem.offset = abs(diff) / 100 else: _mem.offset = mem.offset / 100 _mem.duplex = DUPLEXES.index(mem.duplex) _mem.name = mem.name.ljust(6) try: _mem.channel_width = MODES.index(mem.mode) except ValueError: _mem.channel_width = 0 ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) _mem.txtmode = TMODES.index(txmode) _mem.rxtmode = TMODES.index(rxmode) if txmode == "Tone": _mem.txtone = TONES.index(txtone) elif txmode == "DTCS": self._set_dcs_index(_mem, 'tx', chirp_common.ALL_DTCS_CODES.index(txtone)) if rxmode == "Tone": _mem.sqlmode = 1 _mem.rxtone = TONES.index(rxtone) elif rxmode == "DTCS": _mem.sqlmode = 1 self._set_dcs_index(_mem, 'rx', chirp_common.ALL_DTCS_CODES.index(rxtone)) else: _mem.sqlmode = 0 _mem.txinv = txpol == "R" _mem.rxinv = rxpol == "R" if mem.skip: _skp |= bitpos else: _skp &= ~bitpos if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _msg = self._memobj.welcome_msg _oem = self._memobj.oem_info _settings = self._memobj.settings cfg_grp = RadioSettingGroup("cfg_grp", "Function Setup") oem_grp = RadioSettingGroup("oem_grp", "OEM Info") group = RadioSettings(cfg_grp, oem_grp) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered # # Function Setup # rs = RadioSetting("welcome_msg.line1", "Welcome Message 1", RadioSettingValueString( 0, 6, _filter(_msg.line1))) cfg_grp.append(rs) rs = RadioSetting("welcome_msg.line2", "Welcome Message 2", RadioSettingValueString( 0, 6, _filter(_msg.line2))) cfg_grp.append(rs) rs = RadioSetting("display", "Display Mode", RadioSettingValueList(DISPLAY, DISPLAY[_settings.display])) cfg_grp.append(rs) rs = RadioSetting("upvfomr", "Up VFO/MR", RadioSettingValueList(VFOMR, VFOMR[_settings.upvfomr])) cfg_grp.append(rs) rs = RadioSetting("dnvfomr", "Down VFO/MR", RadioSettingValueList(VFOMR, VFOMR[_settings.dnvfomr])) cfg_grp.append(rs) rs = RadioSetting("upwork", "Up Work Mode", RadioSettingValueList(WORKMODE, WORKMODE[_settings.upwork])) cfg_grp.append(rs) rs = RadioSetting("upmrbank", "Up MR Bank", RadioSettingValueList(MRBANK, MRBANK[_settings.upmrbank])) cfg_grp.append(rs) rs = RadioSetting("upmrch", "Up MR Channel", RadioSettingValueInteger(0, 200, _settings.upmrch)) cfg_grp.append(rs) rs = RadioSetting("dnwork", "Down Work Mode", RadioSettingValueList(WORKMODE, WORKMODE[_settings.dnwork])) cfg_grp.append(rs) rs = RadioSetting("dnmrbank", "Down MR Bank", RadioSettingValueList(MRBANK, MRBANK[_settings.dnmrbank])) cfg_grp.append(rs) rs = RadioSetting("dnmrch", "Down MR Channel", RadioSettingValueInteger(0, 200, _settings.dnmrch)) cfg_grp.append(rs) rs = RadioSetting("main", "Main", RadioSettingValueList(MAIN, MAIN[_settings.main])) cfg_grp.append(rs) rs = RadioSetting("pause", "Scan Pause Time", RadioSettingValueList(PAUSE, PAUSE[_settings.pause])) cfg_grp.append(rs) rs = RadioSetting("stop", "Function Keys Stop Time", RadioSettingValueList(STOP, STOP[_settings.stop])) cfg_grp.append(rs) rs = RadioSetting("backlight", "Backlight", RadioSettingValueList(BACKLIGHT, BACKLIGHT[ _settings.backlight])) cfg_grp.append(rs) rs = RadioSetting("color", "Backlight Color", RadioSettingValueList(COLOR, COLOR[_settings.color])) cfg_grp.append(rs) rs = RadioSetting("vdisplay", "Vice-Machine Display", RadioSettingValueList(VDISPLAY, VDISPLAY[_settings.vdisplay])) cfg_grp.append(rs) rs = RadioSetting("voxlevel", "Vox Level", RadioSettingValueList(VOXLEVEL, VOXLEVEL[_settings.voxlevel])) cfg_grp.append(rs) rs = RadioSetting("voxdelay", "Vox Delay", RadioSettingValueList(VOXDELAY, VOXDELAY[_settings.voxdelay])) cfg_grp.append(rs) rs = RadioSetting("tot", "Time Out Timer", RadioSettingValueList(TOT, TOT[_settings.tot])) cfg_grp.append(rs) rs = RadioSetting("tbst", "Tone Burst", RadioSettingValueList(TBST, TBST[_settings.tbst])) cfg_grp.append(rs) rs = RadioSetting("monikey", "MONI Key Function", RadioSettingValueList(MONI, MONI[_settings.monikey])) cfg_grp.append(rs) if self.MODEL == "TERMN-8R": rs = RadioSetting("pf1key", "PF1 Key Function", RadioSettingValueList(PFKEYT, PFKEYT[_settings.pf1key])) cfg_grp.append(rs) rs = RadioSetting("pf2key", "PF2 Key Function", RadioSettingValueList(PFKEYT, PFKEYT[_settings.pf2key])) cfg_grp.append(rs) if self.MODEL == "OBLTR-8R": rs = RadioSetting("pf1key", "PF1 Key Function", RadioSettingValueList(PFKEYO, PFKEYO[_settings.pf1key])) cfg_grp.append(rs) rs = RadioSetting("fmam", "PF2 Key Function", RadioSettingValueList(PFKEYO, PFKEYO[_settings.fmam])) cfg_grp.append(rs) rs = RadioSetting("apo", "Automatic Power Off", RadioSettingValueList(APO, APO[_settings.apo])) cfg_grp.append(rs) rs = RadioSetting("save", "Power Save", RadioSettingValueList(SAVE, SAVE[_settings.save])) cfg_grp.append(rs) rs = RadioSetting("tail", "Tail Eliminator Type", RadioSettingValueList(TAIL, TAIL[_settings.tail])) cfg_grp.append(rs) rs = RadioSetting("fmvfomr", "FM VFO/MR", RadioSettingValueList(VFOMR, VFOMR[_settings.fmvfomr])) cfg_grp.append(rs) rs = RadioSetting("fmmrch", "FM MR Channel", RadioSettingValueInteger(0, 100, _settings.fmmrch)) cfg_grp.append(rs) rs = RadioSetting("noaa", "NOAA", RadioSettingValueList(NOAA, NOAA[_settings.noaa])) cfg_grp.append(rs) rs = RadioSetting("noaach", "NOAA Channel", RadioSettingValueList(NOAACH, NOAACH[_settings.noaach])) cfg_grp.append(rs) rs = RadioSetting("part95", "PART95", RadioSettingValueList(PART95, PART95[_settings.part95])) cfg_grp.append(rs) rs = RadioSetting("gmrs", "GMRS", RadioSettingValueList(GMRS, GMRS[_settings.gmrs])) cfg_grp.append(rs) rs = RadioSetting("murs", "MURS", RadioSettingValueList(MURS, MURS[_settings.murs])) cfg_grp.append(rs) for i in range(0, 9): val = self._memobj.banklink[i].bank rs = RadioSetting("banklink/%i.bank" % i, "Bank Link %i" % (i + 1), RadioSettingValueBoolean(val)) cfg_grp.append(rs) val = self._memobj.banklink[9].bank rs = RadioSetting("banklink/9.bank", "Bank Link 0", RadioSettingValueBoolean(val)) cfg_grp.append(rs) rs = RadioSetting("allband", "All Band", RadioSettingValueBoolean(_settings.allband)) cfg_grp.append(rs) rs = RadioSetting("alarmoff", "Alarm Function Off", RadioSettingValueBoolean(_settings.alarmoff)) cfg_grp.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep)) cfg_grp.append(rs) rs = RadioSetting("radio", "Radio", RadioSettingValueBoolean(_settings.radio)) cfg_grp.append(rs) if self.MODEL == "TERMN-8R": rs = RadioSetting("keylock", "Keylock", RadioSettingValueBoolean(_settings.keylock)) cfg_grp.append(rs) rs = RadioSetting("fastscan", "Fast Scan", RadioSettingValueBoolean(_settings.fastscan)) cfg_grp.append(rs) if self.MODEL == "OBLTR-8R": # "pf2key" is used for OBLTR-8R "keylock" rs = RadioSetting("pf2key", "Keylock", RadioSettingValueBoolean(_settings.pf2key)) cfg_grp.append(rs) rs = RadioSetting("fastscano", "Fast Scan", RadioSettingValueBoolean(_settings.fastscano)) cfg_grp.append(rs) rs = RadioSetting("uplink", "Up Bank Link Select", RadioSettingValueBoolean(_settings.uplink)) cfg_grp.append(rs) rs = RadioSetting("downlink", "Down Bank Link Select", RadioSettingValueBoolean(_settings.downlink)) cfg_grp.append(rs) # # OEM info # val = RadioSettingValueString(0, 7, _filter(_oem.model)) val.set_mutable(False) rs = RadioSetting("oem_info.model", "Model", val) oem_grp.append(rs) val = RadioSettingValueString(0, 9, _filter(_oem.date)) val.set_mutable(False) rs = RadioSetting("oem_info.date", "Date", val) oem_grp.append(rs) val = RadioSettingValueString(0, 16, _filter(_oem.dealer)) val.set_mutable(False) rs = RadioSetting("oem_info.dealer", "Dealer Code", val) oem_grp.append(rs) val = RadioSettingValueString(0, 9, _filter(_oem.stockdate)) val.set_mutable(False) rs = RadioSetting("oem_info.stockdate", "Stock Date", val) oem_grp.append(rs) val = RadioSettingValueString(0, 9, _filter(_oem.selldate)) val.set_mutable(False) rs = RadioSetting("oem_info.selldate", "Sell Date", val) oem_grp.append(rs) return group def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): return cls._file_ident in filedata[0x10:0x20] @directory.register class AnyToneOBLTR8RRadio(AnyToneTERMN8RRadio): """AnyTone OBLTR-8R""" VENDOR = "AnyTone" MODEL = "OBLTR-8R" _file_ident = b"OBLTR8R" chirp-20240224/chirp/drivers/th_uv3r.py0000644000175000017500000001776414437323351016607 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """TYT uv3r radio management module""" import logging from chirp import chirp_common, bitwise, errors, directory from chirp.drivers.wouxun import do_download, do_upload LOG = logging.getLogger(__name__) def tyt_uv3r_prep(radio): try: radio.pipe.write(b"PROGRAMa") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio did not ACK first command") except: raise errors.RadioError("Unable to communicate with the radio") def tyt_uv3r_download(radio): tyt_uv3r_prep(radio) return do_download(radio, 0x0000, 0x0910, 0x0010) def tyt_uv3r_upload(radio): tyt_uv3r_prep(radio) return do_upload(radio, 0x0000, 0x0910, 0x0010) mem_format = """ struct memory { ul24 duplex:2, bit:1, iswide:1, bits:2, is625:1, freq:17; ul16 offset; ul16 rx_tone; ul16 tx_tone; u8 unknown; u8 name[6]; }; #seekto 0x0010; struct memory memory[128]; #seekto 0x0870; u8 emptyflags[16]; u8 skipflags[16]; """ THUV3R_DUPLEX = ["", "+", "-"] THUV3R_CHARSET = "".join([chr(ord("0") + x) for x in range(0, 10)] + [" -*+"] + [chr(ord("A") + x) for x in range(0, 26)] + ["_/"]) @directory.register class TYTUV3RRadio(chirp_common.CloneModeRadio): VENDOR = "TYT" MODEL = "TH-UV3R" BAUD_RATE = 2400 _memsize = 2320 NEEDS_COMPAT_SERIAL = False def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_tuning_step = False rf.has_cross = True rf.memory_bounds = (1, 128) rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS"] rf.valid_skips = [] rf.valid_modes = ["FM", "NFM"] rf.valid_name_length = 6 rf.valid_characters = THUV3R_CHARSET rf.valid_bands = [(136000000, 520000000)] rf.valid_tuning_steps = [5.0, 6.25, 10.0, 12.5, 25.0, 37.50, 50.0, 100.0] rf.valid_skips = ["", "S"] return rf def sync_in(self): self.pipe.timeout = 2 self._mmap = tyt_uv3r_download(self) self.process_mmap() def sync_out(self): tyt_uv3r_upload(self) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _decode_tone_value(self, value): if value == 0xFFFF: return "", "N", 0 elif value & 0x8000: # FIXME: rev pol pol = value & 0x4000 and "R" or "N" return "DTCS", pol, int("%x" % (value & 0x0FFF)) else: return "Tone", "N", int("%x" % value) / 10.0 def _decode_tone(self, mem, _mem): tx_mode, tpol, tx_tone = self._decode_tone_value(_mem.tx_tone) rx_mode, rpol, rx_tone = self._decode_tone_value(_mem.rx_tone) if rx_mode == tx_mode == "": return mem.dtcs_polarity = "%s%s" % (tpol, rpol) if rx_mode == tx_mode == "DTCS": # Break this for now until we can support this in chirp tx_tone = rx_tone if rx_mode in ["", tx_mode] and rx_tone in [0, tx_tone]: mem.tmode = rx_mode == "Tone" and "TSQL" or tx_mode if mem.tmode == "DTCS": mem.dtcs = tx_tone elif mem.tmode == "TSQL": mem.ctone = tx_tone else: mem.rtone = tx_tone return mem.cross_mode = "%s->%s" % (tx_mode, rx_mode) mem.tmode = "Cross" if tx_mode == "Tone": mem.rtone = tx_tone elif tx_mode == "DTCS": mem.dtcs = tx_tone if rx_mode == "Tone": mem.ctone = rx_tone elif rx_mode == "DTCS": mem.dtcs = rx_tone # No support for different codes yet def _encode_tone(self, mem, _mem): if mem.tmode == "": _mem.tx_tone = _mem.rx_tone = 0xFFFF return def _tone(val): return int("%i" % (val * 10), 16) def _dcs(val, pol): polmask = pol == "R" and 0xC000 or 0x8000 return int("%i" % (val), 16) | polmask rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": rx_mode = "" tx_mode = "Tone" tx_tone = _tone(mem.rtone) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = _tone(mem.ctone) elif mem.tmode == "DTCS": rx_mode = tx_mode = "DTCS" tx_tone = _dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->", 1) if tx_mode == "DTCS": tx_tone = _dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = _tone(mem.rtone) if rx_mode == "DTCS": rx_tone = _dcs(mem.dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = _tone(mem.ctone) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number bit = 1 << ((number - 1) % 8) byte = (number - 1) / 8 if self._memobj.emptyflags[byte] & bit: mem.empty = True return mem mult = _mem.is625 and 6250 or 5000 mem.freq = _mem.freq * mult mem.offset = _mem.offset * 5000 mem.duplex = THUV3R_DUPLEX[_mem.duplex] mem.mode = _mem.iswide and "FM" or "NFM" self._decode_tone(mem, _mem) mem.skip = (self._memobj.skipflags[byte] & bit) and "S" or "" for char in _mem.name: try: c = THUV3R_CHARSET[char] except: c = "" mem.name += c mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] bit = 1 << ((mem.number - 1) % 8) byte = (mem.number - 1) // 8 if mem.empty: self._memobj.emptyflags[byte] |= bit _mem.set_raw("\xFF" * 16) return self._memobj.emptyflags[byte] &= ~bit if chirp_common.is_fractional_step(mem.freq): mult = 6250 _mem.is625 = True else: mult = 5000 _mem.is625 = False _mem.freq = mem.freq / mult _mem.offset = mem.offset / 5000 _mem.duplex = THUV3R_DUPLEX.index(mem.duplex) _mem.iswide = mem.mode == "FM" self._encode_tone(mem, _mem) if mem.skip: self._memobj.skipflags[byte] |= bit else: self._memobj.skipflags[byte] &= ~bit name = [] for char in mem.name.ljust(6): try: c = THUV3R_CHARSET.index(char) except: c = THUV3R_CHARSET.index(" ") name.append(c) _mem.name = name LOG.debug(repr(_mem)) @classmethod def match_model(cls, filedata, filename): return len(filedata) == 2320 chirp-20240224/chirp/drivers/kguv8d.py0000644000175000017500000011312514520142245016403 0ustar hibbyhibby# Copyright 2014 Ron Wellsted M0RNW # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun KG-UV8D radio management module""" import time import logging from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettings import struct LOG = logging.getLogger(__name__) CMD_ID = 128 CMD_END = 129 CMD_RD = 130 CMD_WR = 131 MEM_VALID = 158 AB_LIST = ["A", "B"] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] STEP_LIST = [str(x) for x in STEPS] ROGER_LIST = ["Off", "BOT", "EOT", "Both"] TIMEOUT_LIST = ["Off"] + [str(x) + "s" for x in range(15, 901, 15)] VOX_LIST = ["Off"] + ["%s" % x for x in range(1, 10)] BANDWIDTH_LIST = ["Narrow", "Wide"] VOICE_LIST = ["Off", "On"] LANGUAGE_LIST = ["Chinese", "English"] SCANMODE_LIST = ["TO", "CO", "SE"] PF1KEY_LIST = ["Call", "VFTX"] PF3KEY_LIST = ["Scan", "Lamp", "Tele Alarm", "SOS-CH", "Radio", "Disable"] WORKMODE_LIST = ["VFO", "Channel No.", "Ch. No.+Freq.", "Ch. No.+Name"] BACKLIGHT_LIST = ["Always On"] + [str(x) + "s" for x in range(1, 21)] + \ ["Always Off"] OFFSET_LIST = ["+", "-"] PONMSG_LIST = ["Bitmap", "Battery Volts"] SPMUTE_LIST = ["QT", "QT+DTMF", "QT*DTMF"] DTMFST_LIST = ["DT-ST", "ANI-ST", "DT-ANI", "Off"] DTMF_TIMES = ["%s" % x for x in range(50, 501, 10)] RPTSET_LIST = ["X-TWRPT", "X-DIRRPT"] ALERTS = [1750, 2100, 1000, 1450] ALERTS_LIST = [str(x) for x in ALERTS] PTTID_LIST = ["BOT", "EOT", "Both"] LIST_10 = ["Off"] + ["%s" % x for x in range(1, 11)] SCANGRP_LIST = ["All"] + ["%s" % x for x in range(1, 11)] SCQT_LIST = ["All", "Decoder", "Encoder"] SMUTESET_LIST = ["Off", "Tx", "Rx", "Tx/Rx"] POWER_LIST = ["Lo", "Hi"] HOLD_TIMES = ["Off"] + ["%s" % x for x in range(100, 5001, 100)] RPTMODE_LIST = ["Radio", "Repeater"] # memory slot 0 is not used, start at 1 (so need 1000 slots, not 999) # structure elements whose name starts with x are currently unidentified _MEM_FORMAT = """ #seekto 0x0044; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } uhf_limits; #seekto 0x0054; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } vhf_limits; #seekto 0x0400; struct { u8 model[8]; u8 unknown[2]; u8 oem1[10]; u8 oem2[10]; u8 unknown2[8]; u8 version[10]; u8 unknown3[6]; u8 date[8]; } oem_info; #seekto 0x0480; struct { u16 lower; u16 upper; } scan_groups[10]; #seekto 0x0500; struct { u8 call_code[6]; } call_groups[20]; #seekto 0x0580; struct { char call_name[6]; } call_group_name[20]; #seekto 0x0800; struct { u8 ponmsg; char dispstr[15]; u8 x0810; u8 x0811; u8 x0812; u8 x0813; u8 x0814; u8 voice; u8 timeout; u8 toalarm; u8 channel_menu; u8 power_save; u8 autolock; u8 keylock; u8 beep; u8 stopwatch; u8 vox; u8 scan_rev; u8 backlight; u8 roger_beep; u8 mode_sw_pwd[6]; u8 reset_pwd[6]; u16 pri_ch; u8 ani_sw; u8 ptt_delay; u8 ani[6]; u8 dtmf_st; u8 bcl_a; u8 bcl_b; u8 ptt_id; u8 prich_sw; u8 rpt_set; u8 rpt_spk; u8 rpt_ptt; u8 alert; u8 pf1_func; u8 pf3_func; u8 workmode_b; u8 workmode_a; u8 x0845; u8 dtmf_tx_time; u8 dtmf_interval; u8 main_ab; u16 work_cha; u16 work_chb; u8 x084d; u8 x084e; u8 x084f; u8 x0850; u8 x0851; u8 x0852; u8 x0853; u8 x0854; u8 rpt_mode; u8 language; u8 x0857; u8 x0858; u8 x0859; u8 x085a; u8 x085b; u8 x085c; u8 x085d; u8 x085e; u8 single_display; u8 ring_time; u8 scg_a; u8 scg_b; u8 x0863; u8 rpt_tone; u8 rpt_hold; u8 scan_det; u8 sc_qt; u8 x0868; u8 smuteset; u8 callcode; } settings; #seekto 0x0880; struct { u32 rxfreq; u32 txoffset; u16 rxtone; u16 txtone; u8 unknown1:6, power:1, unknown2:1; u8 unknown3:1, shift_dir:2, unknown4:2, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfoa; #seekto 0x08c0; struct { u32 rxfreq; u32 txoffset; u16 rxtone; u16 txtone; u8 unknown1:6, power:1, unknown2:1; u8 unknown3:1, shift_dir:2, unknown4:2, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfob; #seekto 0x0900; struct { u32 rxfreq; u32 txfreq; u16 rxtone; u16 txtone; u8 unknown1:6, power:1, unknown2:1; u8 unknown3:2, scan_add:1, unknown4:2, mute_mode:2, iswide:1; u16 padding; } memory[1000]; #seekto 0x4780; struct { u8 name[8]; } names[1000]; #seekto 0x6700; u8 valid[1000]; """ # Support for the Wouxun KG-UV8D radio # Serial coms are at 19200 baud # The data is passed in variable length records # Record structure: # Offset Usage # 0 start of record (\x7d) # 1 Command (\x80 Identify \x81 End/Reboot \x82 Read \x83 Write) # 2 direction (\xff PC-> Radio, \x00 Radio -> PC) # 3 length of payload (excluding header/checksum) (n) # 4 payload (n bytes) # 4+n+1 checksum - byte sum (% 256) of bytes 1 -> 4+n # # Memory Read Records: # the payload is 3 bytes, first 2 are offset (big endian), # 3rd is number of bytes to read # Memory Write Records: # the maximum payload size (from the Wouxun software) seems to be 66 bytes # (2 bytes location + 64 bytes data). @directory.register class KGUV8DRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-UV8D""" VENDOR = "Wouxun" MODEL = "KG-UV8D" _model = b"KG-UV8D" _file_ident = b"KGUV8D" BAUD_RATE = 19200 POWER_LEVELS = [chirp_common.PowerLevel("L", watts=1), chirp_common.PowerLevel("H", watts=5)] NEEDS_COMPAT_SERIAL = False _record_start = 0x7D def _checksum(self, data): cs = 0 for byte in data: cs += byte return cs % 256 def _write_record(self, cmd, payload=None): # build the packet _length = 0 if payload: _length = len(payload) _packet = struct.pack('BBBB', self._record_start, cmd, 0xFF, _length) if payload: # add the chars to the packet _packet += payload # calculate and add the checksum to the packet _packet += bytes([self._checksum(_packet[1:])]) LOG.debug("Sent:\n%s" % util.hexprint(_packet)) self.pipe.write(_packet) def _read_record(self): # read 4 chars for the header _header = self.pipe.read(4) if len(_header) != 4: raise errors.RadioError('Radio did not respond') _length = struct.unpack('xxxB', _header)[0] _packet = self.pipe.read(_length) _cs = self._checksum(_header[1:]) _cs += self._checksum(_packet) _cs %= 256 _rcs = self.pipe.read(1)[0] LOG.debug("_cs =%x", _cs) LOG.debug("_rcs=%x", _rcs) return (_rcs != _cs, _packet) # Identify the radio # # A Gotcha: the first identify packet returns a bad checksum, subsequent # attempts return the correct checksum... (well it does on my radio!) # # The ID record returned by the radio also includes the current frequency range # as 4 bytes big-endian in 10 Hz increments # # Offset # 0:10 Model, zero padded (Use first 7 chars for 'KG-UV8D') # 11:14 UHF rx lower limit (in units of 10 Hz) # 15:18 UHF rx upper limit # 19:22 UHF tx lower limit # 23:26 UHF tx upper limit # 27:30 VHF rx lower limit # 31:34 VHF rx upper limit # 35:38 VHF tx lower limit # 39:42 VHF tx upper limit # @classmethod def match_model(cls, filedata, filename): return cls._file_ident in filedata[0x400:0x408] def _identify(self): """Do the identification dance""" for _i in range(0, 10): self._write_record(CMD_ID) _chksum_err, _resp = self._read_record() LOG.debug("Got:\n%s" % util.hexprint(_resp)) if _chksum_err: LOG.error("Checksum error: retrying ident...") time.sleep(0.100) continue LOG.debug("Model %s" % util.hexprint(_resp[0:7])) if _resp[0:7] == self._model: return if len(_resp) == 0: raise Exception("Radio not responding") else: raise Exception("Unable to identify radio") def _finish(self): self._write_record(CMD_END) def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._download() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): self._upload() # TODO: This is a dumb, brute force method of downloading the memory. # it would be smarter to only load the active areas and none of # the padding/unused areas. def _download(self): """Talk to a Wouxun KG-UV8D and do a download""" try: self._identify() return self._do_download(0, 32768, 64) except errors.RadioError: raise except Exception as e: LOG.exception('Unknown error during download process') raise errors.RadioError("Failed to communicate with radio: %s" % e) def _do_download(self, start, end, blocksize): # allocate & fill memory image = b"" for i in range(start, end, blocksize): req = struct.pack('>HB', i, blocksize) self._write_record(CMD_RD, req) cs_error, resp = self._read_record() if cs_error: # TODO: probably should retry a few times here LOG.debug(util.hexprint(resp)) raise Exception("Checksum error on read") LOG.debug("Got:\n%s" % util.hexprint(resp)) image += resp[2:] if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning from radio" self.status_fn(status) self._finish() return memmap.MemoryMapBytes(image) def _upload(self): """Talk to a Wouxun KG-UV8D and do a upload""" try: self._identify() self._do_upload(0, 32768, 64) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) return def _do_upload(self, start, end, blocksize): ptr = start for i in range(start, end, blocksize): req = struct.pack('>H', i) chunk = self.get_mmap()[ptr:ptr + blocksize] self._write_record(CMD_WR, req + chunk) LOG.debug(util.hexprint(req + chunk)) cserr, ack = self._read_record() LOG.debug(util.hexprint(ack)) j = struct.unpack('>H', ack)[0] if cserr or j != ptr: raise Exception("Radio did not ack block %i" % ptr) ptr += blocksize if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning to radio" self.status_fn(status) self._finish() def get_features(self): # TODO: This probably needs to be setup correctly to match the true # features of the radio rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_tuning_steps = STEPS rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_bands = [(134000000, 175000000), # supports 2m (400000000, 520000000)] # supports 70cm rf.valid_characters = chirp_common.CHARSET_ASCII rf.memory_bounds = (1, 999) # 999 memories return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is currently under development. " "There are no known issues with it, but you should " "proceed with caution.") return rp def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol tpol = False if _mem.txtone != 0xFFFF and (_mem.txtone & 0x2800) == 0x2800: tcode, tpol = _get_dcs(_mem.txtone) mem.dtcs = tcode txmode = "DTCS" elif _mem.txtone != 0xFFFF and _mem.txtone != 0x0: mem.rtone = (_mem.txtone & 0x7fff) / 10.0 txmode = "Tone" else: txmode = "" rpol = False if _mem.rxtone != 0xFFFF and (_mem.rxtone & 0x2800) == 0x2800: rcode, rpol = _get_dcs(_mem.rxtone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rxtone != 0xFFFF and _mem.rxtone != 0x0: mem.ctone = (_mem.rxtone & 0x7fff) / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.txtone, rxmode, _mem.rxtone)) def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number _valid = self._memobj.valid[mem.number] LOG.debug("%d %s", number, _valid == MEM_VALID) if _valid != MEM_VALID: mem.empty = True return mem else: mem.empty = False mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _nam.name: if char != 0: mem.name += chr(char) mem.name = mem.name.rstrip() self._get_tone(_mem, mem) mem.skip = "" if bool(_mem.scan_add) else "S" mem.power = self.POWER_LEVELS[_mem.power] mem.mode = _mem.iswide and "FM" or "NFM" return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0x8000 return val rx_mode = tx_mode = None rxtone = txtone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None txtone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) _mem.rxtone = rxtone _mem.txtone = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.txtone, rx_mode, _mem.rxtone)) def set_memory(self, mem): number = mem.number _mem = self._memobj.memory[number] _nam = self._memobj.names[number] if mem.empty: _mem.set_raw("\x00" * (_mem.size() // 8)) self._memobj.valid[number] = 0 self._memobj.names[number].set_raw("\x00" * (_nam.size() // 8)) return _mem.rxfreq = int(mem.freq / 10) if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = int(mem.offset / 10) elif mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "+": _mem.txfreq = int(mem.freq / 10) + int(mem.offset / 10) elif mem.duplex == "-": _mem.txfreq = int(mem.freq / 10) - int(mem.offset / 10) else: _mem.txfreq = int(mem.freq / 10) _mem.scan_add = int(mem.skip != "S") _mem.iswide = int(mem.mode == "FM") # set the tone self._set_tone(mem, _mem) # set the power if mem.power: _mem.power = self.POWER_LEVELS.index(mem.power) else: _mem.power = True # TODO: set the correct mute mode, for now just # set to mute mode to QT (not QT+DTMF or QT*DTMF) _mem.mute_mode = 0 for i in range(0, len(_nam.name)): if i < len(mem.name) and mem.name[i]: _nam.name[i] = ord(mem.name[i]) else: _nam.name[i] = 0x0 self._memobj.valid[mem.number] = MEM_VALID def _get_settings(self): _settings = self._memobj.settings _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob cfg_grp = RadioSettingGroup("cfg_grp", "Configuration") vfoa_grp = RadioSettingGroup("vfoa_grp", "VFO A Settings") vfob_grp = RadioSettingGroup("vfob_grp", "VFO B Settings") key_grp = RadioSettingGroup("key_grp", "Key Settings") lmt_grp = RadioSettingGroup("lmt_grp", "Frequency Limits") oem_grp = RadioSettingGroup("oem_grp", "OEM Info") group = RadioSettings(cfg_grp, vfoa_grp, vfob_grp, key_grp, lmt_grp, oem_grp) # # Configuration Settings # rs = RadioSetting("channel_menu", "Menu available in channel mode", RadioSettingValueBoolean(_settings.channel_menu)) cfg_grp.append(rs) rs = RadioSetting("ponmsg", "Poweron message", RadioSettingValueList( PONMSG_LIST, PONMSG_LIST[_settings.ponmsg])) cfg_grp.append(rs) rs = RadioSetting("voice", "Voice Guide", RadioSettingValueBoolean(_settings.voice)) cfg_grp.append(rs) rs = RadioSetting("language", "Language", RadioSettingValueList(LANGUAGE_LIST, LANGUAGE_LIST[_settings. language])) cfg_grp.append(rs) rs = RadioSetting("timeout", "Timeout Timer", RadioSettingValueInteger(15, 900, _settings.timeout * 15, 15)) cfg_grp.append(rs) rs = RadioSetting("toalarm", "Timeout Alarm", RadioSettingValueInteger(0, 10, _settings.toalarm)) cfg_grp.append(rs) rs = RadioSetting("roger_beep", "Roger Beep", RadioSettingValueBoolean(_settings.roger_beep)) cfg_grp.append(rs) rs = RadioSetting("power_save", "Power save", RadioSettingValueBoolean(_settings.power_save)) cfg_grp.append(rs) rs = RadioSetting("autolock", "Autolock", RadioSettingValueBoolean(_settings.autolock)) cfg_grp.append(rs) rs = RadioSetting("keylock", "Keypad Lock", RadioSettingValueBoolean(_settings.keylock)) cfg_grp.append(rs) rs = RadioSetting("beep", "Keypad Beep", RadioSettingValueBoolean(_settings.beep)) cfg_grp.append(rs) rs = RadioSetting("stopwatch", "Stopwatch", RadioSettingValueBoolean(_settings.stopwatch)) cfg_grp.append(rs) rs = RadioSetting("backlight", "Backlight", RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings. backlight])) cfg_grp.append(rs) rs = RadioSetting("dtmf_st", "DTMF Sidetone", RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[_settings. dtmf_st])) cfg_grp.append(rs) rs = RadioSetting("ani-id_sw", "ANI-ID Switch", RadioSettingValueBoolean(_settings.ani_sw)) cfg_grp.append(rs) rs = RadioSetting("ptt-id_delay", "PTT-ID Delay", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_settings.ptt_id])) cfg_grp.append(rs) rs = RadioSetting("ring_time", "Ring Time", RadioSettingValueList(LIST_10, LIST_10[_settings.ring_time])) cfg_grp.append(rs) rs = RadioSetting("scan_rev", "Scan Mode", RadioSettingValueList(SCANMODE_LIST, SCANMODE_LIST[_settings. scan_rev])) cfg_grp.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueList(LIST_10, LIST_10[_settings.vox])) cfg_grp.append(rs) rs = RadioSetting("prich_sw", "Priority Channel Switch", RadioSettingValueBoolean(_settings.prich_sw)) cfg_grp.append(rs) rs = RadioSetting("pri_ch", "Priority Channel", RadioSettingValueInteger(1, 999, _settings.pri_ch)) cfg_grp.append(rs) rs = RadioSetting("rpt_mode", "Radio Mode", RadioSettingValueList(RPTMODE_LIST, RPTMODE_LIST[_settings. rpt_mode])) cfg_grp.append(rs) rs = RadioSetting("rpt_set", "Repeater Setting", RadioSettingValueList(RPTSET_LIST, RPTSET_LIST[_settings. rpt_set])) cfg_grp.append(rs) rs = RadioSetting("rpt_spk", "Repeater Mode Speaker", RadioSettingValueBoolean(_settings.rpt_spk)) cfg_grp.append(rs) rs = RadioSetting("rpt_ptt", "Repeater PTT", RadioSettingValueBoolean(_settings.rpt_ptt)) cfg_grp.append(rs) rs = RadioSetting("dtmf_tx_time", "DTMF Tx Duration", RadioSettingValueList(DTMF_TIMES, DTMF_TIMES[_settings. dtmf_tx_time])) cfg_grp.append(rs) rs = RadioSetting("dtmf_interval", "DTMF Interval", RadioSettingValueList(DTMF_TIMES, DTMF_TIMES[_settings. dtmf_interval])) cfg_grp.append(rs) rs = RadioSetting("alert", "Alert Tone", RadioSettingValueList(ALERTS_LIST, ALERTS_LIST[_settings.alert])) cfg_grp.append(rs) rs = RadioSetting("rpt_tone", "Repeater Tone", RadioSettingValueBoolean(_settings.rpt_tone)) cfg_grp.append(rs) rs = RadioSetting("rpt_hold", "Repeater Hold Time", RadioSettingValueList(HOLD_TIMES, HOLD_TIMES[_settings. rpt_hold])) cfg_grp.append(rs) rs = RadioSetting("scan_det", "Scan DET", RadioSettingValueBoolean(_settings.scan_det)) cfg_grp.append(rs) rs = RadioSetting("sc_qt", "SC-QT", RadioSettingValueList(SCQT_LIST, SCQT_LIST[_settings.smuteset])) cfg_grp.append(rs) rs = RadioSetting("smuteset", "SubFreq Mute", RadioSettingValueList(SMUTESET_LIST, SMUTESET_LIST[_settings. smuteset])) cfg_grp.append(rs) _pwd = "".join(map(chr, _settings.mode_sw_pwd)) val = RadioSettingValueString(0, 6, _pwd) val.set_mutable(True) rs = RadioSetting("mode_sw_pwd", "Mode Switch Password", val) cfg_grp.append(rs) _pwd = "".join(map(chr, _settings.reset_pwd)) val = RadioSettingValueString(0, 6, _pwd) val.set_mutable(True) rs = RadioSetting("reset_pwd", "Reset Password", val) cfg_grp.append(rs) # # VFO A Settings # rs = RadioSetting("vfoa_mode", "VFO A Workmode", RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[_settings. workmode_a])) vfoa_grp.append(rs) rs = RadioSetting("vfoa_chan", "VFO A Channel", RadioSettingValueInteger(1, 999, _settings.work_cha)) vfoa_grp.append(rs) rs = RadioSetting("rxfreqa", "VFO A Rx Frequency", RadioSettingValueInteger( 134000000, 520000000, _vfoa.rxfreq * 10, 5000)) vfoa_grp.append(rs) rs = RadioSetting("txoffa", "VFO A Tx Offset", RadioSettingValueInteger( 0, 520000000, _vfoa.txoffset * 10, 5000)) vfoa_grp.append(rs) # u16 rxtone; # u16 txtone; rs = RadioSetting("vfoa_power", "VFO A Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfoa.power])) vfoa_grp.append(rs) # shift_dir:2 rs = RadioSetting("vfoa_iswide", "VFO A NBFM", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfoa.iswide])) vfoa_grp.append(rs) rs = RadioSetting("vfoa_mute_mode", "VFO A Mute", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfoa.mute_mode])) vfoa_grp.append(rs) rs = RadioSetting("vfoa_step", "VFO A Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfoa.step])) vfoa_grp.append(rs) rs = RadioSetting("vfoa_squelch", "VFO A Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfoa.squelch])) vfoa_grp.append(rs) rs = RadioSetting("bcl_a", "Busy Channel Lock-out A", RadioSettingValueBoolean(_settings.bcl_a)) vfoa_grp.append(rs) # # VFO B Settings # rs = RadioSetting("vfob_mode", "VFO B Workmode", RadioSettingValueList( WORKMODE_LIST, WORKMODE_LIST[_settings.workmode_b])) vfob_grp.append(rs) rs = RadioSetting("vfob_chan", "VFO B Channel", RadioSettingValueInteger(1, 999, _settings.work_chb)) vfob_grp.append(rs) rs = RadioSetting("rxfreqb", "VFO B Rx Frequency", RadioSettingValueInteger( 134000000, 520000000, _vfob.rxfreq * 10, 5000)) vfob_grp.append(rs) rs = RadioSetting("txoffb", "VFO B Tx Offset", RadioSettingValueInteger( 0, 520000000, _vfob.txoffset * 10, 5000)) vfob_grp.append(rs) # u16 rxtone; # u16 txtone; rs = RadioSetting("vfob_power", "VFO B Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfob.power])) vfob_grp.append(rs) # shift_dir:2 rs = RadioSetting("vfob_iswide", "VFO B NBFM", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfob.iswide])) vfob_grp.append(rs) rs = RadioSetting("vfob_mute_mode", "VFO B Mute", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfob.mute_mode])) vfob_grp.append(rs) rs = RadioSetting("vfob_step", "VFO B Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfob.step])) vfob_grp.append(rs) rs = RadioSetting("vfob_squelch", "VFO B Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfob.squelch])) vfob_grp.append(rs) rs = RadioSetting("bcl_b", "Busy Channel Lock-out B", RadioSettingValueBoolean(_settings.bcl_b)) vfob_grp.append(rs) # # Key Settings # _msg = str(_settings.dispstr).split("\0")[0] val = RadioSettingValueString(0, 15, _msg) val.set_mutable(True) rs = RadioSetting("dispstr", "Display Message", val) key_grp.append(rs) _ani = "" for i in _settings.ani: if i < 10: _ani += chr(i + 0x30) else: break val = RadioSettingValueString(0, 6, _ani) val.set_mutable(True) rs = RadioSetting("ani", "ANI code", val) key_grp.append(rs) rs = RadioSetting("pf1_func", "PF1 Key function", RadioSettingValueList( PF1KEY_LIST, PF1KEY_LIST[self._memobj.settings.pf1_func])) key_grp.append(rs) rs = RadioSetting("pf3_func", "PF3 Key function", RadioSettingValueList( PF3KEY_LIST, PF3KEY_LIST[self._memobj.settings.pf3_func])) key_grp.append(rs) # # Scan Group Settings # # settings: # u8 scg_a; # u8 scg_b; # # struct { # u16 lower; # u16 upper; # } scan_groups[10]; # # Call group settings # # # Limits settings # rs = RadioSetting("urx_start", "UHF RX Lower Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.rx_start * 10, 5000)) lmt_grp.append(rs) rs = RadioSetting("urx_stop", "UHF RX Upper Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.rx_stop * 10, 5000)) lmt_grp.append(rs) rs = RadioSetting("utx_start", "UHF TX Lower Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.tx_start * 10, 5000)) lmt_grp.append(rs) rs = RadioSetting("utx_stop", "UHF TX Upper Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.tx_stop * 10, 5000)) lmt_grp.append(rs) rs = RadioSetting("vrx_start", "VHF RX Lower Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.rx_start * 10, 5000)) lmt_grp.append(rs) rs = RadioSetting("vrx_stop", "VHF RX Upper Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.rx_stop * 10, 5000)) lmt_grp.append(rs) rs = RadioSetting("vtx_start", "VHF TX Lower Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.tx_start * 10, 5000)) lmt_grp.append(rs) rs = RadioSetting("vtx_stop", "VHF TX Upper Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.tx_stop * 10, 5000)) lmt_grp.append(rs) # # OEM info # def _decode(lst): _str = ''.join([chr(c) for c in lst if chr(c) in chirp_common.CHARSET_ASCII]) return _str _str = _decode(self._memobj.oem_info.model) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("model", "Model", val) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.oem1) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem1", "OEM String 1", val) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.oem2) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem2", "OEM String 2", val) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.version) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("version", "Software Version", val) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.date) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("date", "OEM Date", val) oem_grp.append(rs) return group def get_settings(self): try: return self._get_settings() except Exception: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None chirp-20240224/chirp/drivers/retevis_rb28.py0000644000175000017500000006046114563632215017525 0ustar hibbyhibby# Copyright 2023 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import ( bandplan_iaru_r1, bandplan_na, bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueInteger, RadioSettingValueList, ) LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0000; struct { lbcd rxfreq[4]; // RX Frequency 0-3 lbcd txfreq[4]; // TX Frequency 4-7 u8 rxtone; // PL/DPL Decode 8 u8 unused_9; // 9 u8 txtone; // PL/DPL Encode A u8 unused_b; // B u8 compander:1, // Compander C unused_1:1, // highpower:1, // Power Level wide:1, // Bandwidth unused_2:4; // u8 reserved[3]; // Reserved D-F } memory[%d]; #seekto 0x002D; struct { u8 unknown_2d_7:1, // 002D unknown_2d_6:1, // unknown_2d_5:1, // savem:1, // Battery Save Set save:1, // Battery Save beep:1, // Beep voice:1, // Voice Prompts unused_2d_0:1; // u8 squelch; // Squelch 002E u8 tot; // Time-out Timer 002F u8 channel_4[13]; // 0030-003C u8 unused_3d; // 003D u8 voxl; // Vox Level 003E u8 voxd; // Vox Delay 003F u8 channel_5[13]; // 0040-004C u8 unknown_3[3]; // 004D-004F u8 channel_6[13]; // 0050-005C u8 unknown_4[3]; // 005D-005F u8 channel_7[13]; // 0060-006C u8 volume; // Volume 006D u8 tone; // Tone 006E u8 chnumber; // Channel 006F u8 channel_8[13]; // 0070-007C u8 unknown_7d; // 007D u8 scan; // Scan 007E u8 backlight; // Back Light 007F u8 channel_9[13]; // 0080-008C u8 wxchnumber; // Weather Channel 008D u8 wxwarn; // Weather Warn 008E u8 roger; // End Tone 008F u8 channel_10[13]; // 0090-009C u8 unknown_9d; // 009D u8 keylock; // Key Lock 009E u8 unknown_9f; // 009F u8 channel_11[13]; // 00A0-00AC u8 unknown_ad; // 00AD u8 unknown_ae; // 00AE u8 unknown_af; // 00AF u8 channel_12[13]; // 00B0-00BC u8 autokeylock; // Key Lock 00BD u8 pfkey_lt; // Key Set < Long 00BE u8 pfkey_gt; // Key Set > Long 00BB } settings; #seekto 0x00AD; struct { u8 chnl_8:1, // Busy Channel Lockout 8 00AD chnl_7:1, // Busy Channel Lockout 7 chnl_6:1, // Busy Channel Lockout 6 chnl_5:1, // Busy Channel Lockout 5 chnl_4:1, // Busy Channel Lockout 4 chnl_3:1, // Busy Channel Lockout 3 chnl_2:1, // Busy Channel Lockout 2 chnl_1:1; // Busy Channel Lockout 1 u8 chnl_16:1, // Busy Channel Lockout 16 00AE chnl_15:1, // Busy Channel Lockout 15 chnl_14:1, // Busy Channel Lockout 14 chnl_13:1, // Busy Channel Lockout 13 chnl_12:1, // Busy Channel Lockout 12 chnl_11:1, // Busy Channel Lockout 11 chnl_10:1, // Busy Channel Lockout 10 chnl_9:1; // Busy Channel Lockout 09 u8 unused_af_7:1, // 00AF unused_af_6:1, // chnl_22:1, // Busy Channel Lockout 22 chnl_21:1, // Busy Channel Lockout 21 chnl_20:1, // Busy Channel Lockout 20 chnl_19:1, // Busy Channel Lockout 19 chnl_18:1, // Busy Channel Lockout 18 chnl_17:1; // Busy Channel Lockout 17 } bclo; """ CMD_ACK = b"\x06" BACKLIGHT_LIST = ["Off", "ON", "5S", "10S", "15S", "30S"] PFKEY_US_LIST = ["None", "Weather", "Warn", "Call", "Monitor"] PFKEY_EU_LIST = ["None", "Warn", "Call", "Monitor"] SAVE_LIST = ["Normal", "Super"] TIMEOUTTIMER_LIST = ["%s seconds" % x for x in range(15, 195, 15)] VOICE_LIST = ["Off", "English"] VOXD_LIST = ["0.5", "1.0", "1.5", "2.0", "2.5", "3.0"] VOXL_LIST = ["OFF"] + ["%s" % x for x in range(1, 10)] PMR_TONES = tuple( set(chirp_common.TONES) - set([69.3, 159.8, 165.5, 171.3, 177.3, 183.5, 189.9, 196.6, 199.5, 206.5, 229.1, 254.1])) PMR_DTCS_CODES = tuple( set(chirp_common.DTCS_CODES) - set([36, 53, 122, 145, 212, 225, 246, 252, 255, 266, 274, 325, 332, 356, 446, 452, 454, 455, 462, 523, 526])) def _enter_programming_mode(radio): serial = radio.pipe _magic = radio._magic try: serial.write(_magic) for i in range(1, 5): ack = serial.read(1) if ack == CMD_ACK: break except: raise errors.RadioError("Error communicating with radio") if not ack: raise errors.RadioError("No response from radio") elif ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") try: serial.write(b"\x02") ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") # check if ident is OK for fp in radio._fingerprint: if fp in ident: break else: LOG.debug("Incorrect model ID, got this:\n\n" + util.hexprint(ident)) raise errors.RadioError("Radio identification failed.") try: serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except: raise errors.RadioError("Radio refused to exit programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] if block_addr != 0 or radio._ack_1st_block: serial.write(CMD_ACK) ack = serial.read(1) except: raise errors.RadioError("Failed to read block at %04x" % block_addr) if block_addr != 0 or radio._ack_1st_block: if ack != CMD_ACK: raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE_UP): status.cur = addr + radio.BLOCK_SIZE_UP radio.status_fn(status) _write_block(radio, addr, radio.BLOCK_SIZE_UP) _exit_programming_mode(radio) @directory.register class RB28Radio(chirp_common.CloneModeRadio): """RETEVIS RB28""" VENDOR = "Retevis" MODEL = "RB28" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x20 BLOCK_SIZE_UP = 0x10 TONES = PMR_TONES DTCS_CODES = PMR_DTCS_CODES PFKEY_LIST = PFKEY_US_LIST POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.50), chirp_common.PowerLevel("Low", watts=0.50)] VALID_BANDS = [(400000000, 480000000)] _magic = b"PHOGR\x0B\x28" _fingerprint = [b"P32073" + b"\x02\xFF", b"P32073" + b"\x00\xFF", ] _upper = 22 _mem_params = (_upper, # number of channels ) _ack_1st_block = False _reserved = True _frs = True _ranges = [ (0x0000, 0x0160), ] _memsize = 0x0160 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = False rf.valid_skips = [] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = ["", "off"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_tones = self.TONES rf.valid_dtcs_codes = self.DTCS_CODES rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [2.5, 5., 6.25, 10., 12.5, 25.] rf.valid_bands = self.VALID_BANDS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def get_memory(self, number): mem = chirp_common.Memory() mem.number = number _mem = self._memobj.memory[number - 1] if self._reserved: _rsvd = _mem.reserved.get_raw(asbytes=False) mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw(asbytes=False) == "\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = _mem.wide and "FM" or "NFM" if _mem.txtone in [0, 0xFF]: txmode = "" elif _mem.txtone < 0x27: mem.rtone = PMR_TONES[_mem.txtone - 1] txmode = "Tone" elif _mem.txtone >= 0x27: tcode = PMR_DTCS_CODES[_mem.txtone - 0x27] mem.dtcs = tcode txmode = "DTCS" else: LOG.warn("Bug: tx_mode is %02x" % _mem.txtone) if _mem.rxtone in [0, 0xFF]: rxmode = "" elif _mem.rxtone < 0x27: mem.ctone = PMR_TONES[_mem.rxtone - 1] rxmode = "Tone" elif _mem.rxtone >= 0x27: rcode = PMR_DTCS_CODES[_mem.rxtone - 0x27] mem.rx_dtcs = rcode rxmode = "DTCS" else: LOG.warn("Bug: rx_mode is %02x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.power = self.POWER_LEVELS[1 - _mem.highpower] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSettingValueBoolean(_mem.compander) rset = RadioSetting("compander", "Compander", rs) mem.extra.append(rset) _obj = self._memobj.bclo key = "chnl_%i" % (mem.number) rs = RadioSettingValueBoolean(getattr(_obj, "chnl_%i" % (mem.number))) rset = RadioSetting(key, "Busy Channel Lockout", rs) mem.extra.append(rset) immutable = [] if self._frs: if mem.number >= 1 and mem.number <= 22: # 22 FRS fixed channels FRS_FREQ = bandplan_na.ALL_GMRS_FREQS[mem.number - 1] mem.freq = FRS_FREQ mem.duplex == '' mem.offset = 0 mem.mode = "NFM" immutable = ["empty", "freq", "duplex", "offset", "mode"] if mem.number >= 8 and mem.number <= 14: mem.power = self.POWER_LEVELS[1] immutable += ["power"] elif self._pmr: if mem.number >= 1 and mem.number <= 16: # 16 PMR fixed channels PMR_FREQ = bandplan_iaru_r1.PMR446_FREQS[mem.number - 1] mem.freq = PMR_FREQ mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] mem.immutable = immutable return mem def _set_tone(self, _mem, which, value, mode): if mode == "Tone": val = PMR_TONES.index(value) + 1 elif mode == "DTCS": val = PMR_DTCS_CODES.index(value) + 0x27 elif mode == "": val = 0 else: raise errors.RadioError("Internal error: tmode %s" % mode) setattr(_mem, which, val) def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if self._reserved: _rsvd = _mem.reserved.get_raw(asbytes=False) if mem.empty: if self._reserved: _mem.set_raw("\xFF" * 13 + _rsvd) else: _mem.set_raw("\xFF" * (_mem.size() // 8)) return if self._reserved: _mem.set_raw("\x00" * 13 + _rsvd) else: _mem.set_raw("\x00" * 13 + "\xFF\xFF\xFF") _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.wide = mem.mode == "FM" rxtone = txtone = 0 rxmode = txmode = "" if mem.tmode == "DTCS": rxmode = txmode = "DTCS" rxtone = txtone = mem.dtcs elif mem.tmode and mem.tmode != "Cross": rxtone = txtone = mem.tmode == "Tone" and mem.rtone or mem.ctone txmode = "Tone" rxmode = mem.tmode == "TSQL" and "Tone" or "" elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "DTCS": txtone = mem.dtcs elif txmode == "Tone": txtone = mem.rtone if rxmode == "DTCS": rxtone = mem.rx_dtcs elif rxmode == "Tone": rxtone = mem.ctone self._set_tone(_mem, "txtone", txtone, txmode) self._set_tone(_mem, "rxtone", rxtone, rxmode) _mem.highpower = mem.power == self.POWER_LEVELS[0] for setting in mem.extra: if setting.get_name().startswith("chnl_"): setattr(self._memobj.bclo, setting.get_name(), setting.value) else: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) rs = RadioSettingValueInteger(0, 9, _settings.squelch) rset = RadioSetting("squelch", "Squelch Level", rs) basic.append(rset) rs = RadioSettingValueList(TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[_settings.tot - 1]) rset = RadioSetting("tot", "Time-out timer", rs) basic.append(rset) rs = RadioSettingValueList(VOICE_LIST, VOICE_LIST[_settings.voice]) rset = RadioSetting("voice", "Voice Prompts", rs) basic.append(rset) rs = RadioSettingValueList(SAVE_LIST, SAVE_LIST[_settings.savem]) rset = RadioSetting("savem", "Battery Save Mode", rs) basic.append(rset) rs = RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.backlight]) rset = RadioSetting("backlight", "Back Light", rs) basic.append(rset) rs = RadioSettingValueInteger(0, 9, _settings.volume) rset = RadioSetting("volume", "Volume", rs) basic.append(rset) rs = RadioSettingValueInteger(0, 10, _settings.tone) rset = RadioSetting("tone", "Tone", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 22, _settings.chnumber + 1) rset = RadioSetting("chnumber", "Channel Number", rs) basic.append(rset) if self.MODEL == "RB28": rs = RadioSettingValueInteger(1, 11, _settings.wxchnumber + 1) rset = RadioSetting("wxchnumber", "Weather Channel Number", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.autokeylock) rset = RadioSetting("autokeylock", "Auto Key Lock", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.save) rset = RadioSetting("save", "Battery Save", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.roger) rset = RadioSetting("roger", "End Tone", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.beep) rset = RadioSetting("beep", "Beep", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.scan) rset = RadioSetting("scan", "Scan", rs) basic.append(rset) if self.MODEL == "RB28": rs = RadioSettingValueBoolean(_settings.wxwarn) rset = RadioSetting("wxwarn", "Weather Warn", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.keylock) rset = RadioSetting("keylock", "Key Lock", rs) basic.append(rset) rs = RadioSettingValueList(VOXL_LIST, VOXL_LIST[_settings.voxl]) rset = RadioSetting("voxl", "Vox Level", rs) basic.append(rset) rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "Vox Delay", rs) basic.append(rset) rs = RadioSettingValueList(self.PFKEY_LIST, self.PFKEY_LIST[_settings.pfkey_lt]) rset = RadioSetting("pfkey_lt", "Key Set < Long", rs) basic.append(rset) rs = RadioSettingValueList(self.PFKEY_LIST, self.PFKEY_LIST[_settings.pfkey_gt]) rset = RadioSetting("pfkey_gt", "Key Set > Long", rs) basic.append(rset) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "chnumber": setattr(obj, setting, int(element.value) - 1) elif setting == "tot": setattr(obj, setting, int(element.value) + 1) elif setting == "wxchnumber": setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # Radios that have always been post-metadata, so never do # old-school detection return False @directory.register class RB628Radio(RB28Radio): """RETEVIS RB628""" VENDOR = "Retevis" MODEL = "RB628" PFKEY_LIST = PFKEY_EU_LIST POWER_LEVELS = [chirp_common.PowerLevel("High", watts=0.50), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PHOGR\x28\x0B" _fingerprint = [b"P32073" + b"\x00\xFF", ] _upper = 16 _mem_params = (_upper, # number of channels ) _frs = False _pmr = True chirp-20240224/chirp/drivers/baofeng_common.py0000644000175000017500000007142514562116574020166 0ustar hibbyhibby# Copyright 2016: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """common functions for Baofeng (or similar) handheld radios""" import time import struct import logging from chirp import chirp_common, memmap from chirp import errors, util from chirp import bandplan_na from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, InternalError, \ RadioSettingValueList LOG = logging.getLogger(__name__) STIMEOUT = 1.5 TXPOWER_HIGH = 0x00 TXPOWER_LOW = 0x02 def _clean_buffer(radio): radio.pipe.timeout = 0.005 junk = radio.pipe.read(256) radio.pipe.timeout = STIMEOUT if junk: LOG.debug("Got %i bytes of junk before starting" % len(junk)) def _rawrecv(radio, amount): """Raw read from the radio device""" data = "" try: data = radio.pipe.read(amount) except: msg = "Generic error reading data from radio; check your cable." raise errors.RadioError(msg) if len(data) != amount: msg = "Error reading data from radio: not the amount of data we want." raise errors.RadioError(msg) return data def _rawsend(radio, data): """Raw send to the radio device""" try: radio.pipe.write(data) except: raise errors.RadioError("Error sending data to radio") def _make_frame(cmd, addr, length, data=""): """Pack the info in the header format""" frame = struct.pack(">BHB", ord(cmd), addr, length) # add the data if set if len(data) != 0: frame += data # return the data return frame def _recv(radio, addr, length): """Get data from the radio """ # read 4 bytes of header hdr = _rawrecv(radio, 4) # read data data = _rawrecv(radio, length) # DEBUG LOG.info("Response:") LOG.debug(util.hexprint(hdr + data)) c, a, l = struct.unpack(">BHB", hdr) if a != addr or l != length or c != ord("X"): LOG.error("Invalid answer for block 0x%04x:" % addr) LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (c, a, l)) raise errors.RadioError("Unknown response from the radio") return data def _read_from_data(data, data_start, data_stop): data = data[data_start:data_stop] return data def _get_data_from_image(radio, _data_start, _data_stop): image_data = _read_from_data( radio.get_mmap().get_byte_compatible(), _data_start, _data_stop) return image_data def _read_block(radio, start, size, first_command=False): msg = struct.pack(">BHB", ord("S"), start, size) radio.pipe.write(msg) if radio._ack_block and first_command is False: ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError( "Radio refused to send second block 0x%04x" % start) answer = radio.pipe.read(4) if len(answer) != 4: raise errors.RadioError("Radio refused to send block 0x%04x" % start) cmd, addr, length = struct.unpack(">BHB", answer) if cmd != ord("X") or addr != start or length != size: LOG.error("Invalid answer for block 0x%04x:" % start) LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (cmd, addr, length)) raise errors.RadioError("Unknown response from radio") chunk = radio.pipe.read(size) if not chunk: raise errors.RadioError("Radio did not send block 0x%04x" % start) elif len(chunk) != size: LOG.error("Chunk length was 0x%04i" % len(chunk)) raise errors.RadioError("Radio sent incomplete block 0x%04x" % start) radio.pipe.write(b"\x06") time.sleep(0.05) return chunk def _get_aux_data_from_radio(radio): block0 = _read_block(radio, 0x1E80, 0x40, True) block1 = _read_block(radio, 0x1EC0, 0x40, False) block2 = _read_block(radio, 0x1F00, 0x40, False) block3 = _read_block(radio, 0x1F40, 0x40, False) block4 = _read_block(radio, 0x1F80, 0x40, False) block5 = _read_block(radio, 0x1FC0, 0x40, False) version = block1[48:62] area1 = block2 + block3[0:32] area2 = block3[48:64] area3 = block4[16:64] # check for dropped byte dropped_byte = block5[15:16] == b"\xFF" # True/False return version, area1, area2, area3, dropped_byte def _get_radio_firmware_version(radio): # New radios will reply with 'alternative' (aka: bad) data if the Aux # memory area is read without first reading a block from another area # of memory. Reading any block that is outside of the Aux memory area # (which starts at 0x1EC0) prior to reading blocks in the Aux mem area # turns out to be a workaround for this problem. # read and disregard block0 block0 = _read_block(radio, 0x1E80, 0x40, True) block1 = _read_block(radio, 0x1EC0, 0x40, False) block2 = _read_block(radio, 0x1FC0, 0x40, False) # get firmware version version = block1[48:62] # firmware version # Some new radios will drop the byte at 0x1FCF when read in 0x40 byte # blocks. This results in the next 0x30 bytes being moved forward one # position (putting 0xFF in position 0x1FCF and pads the now missing byte # at the end, 0x1FFF, with 0x80). # detect dropped byte dropped_byte = (block2[15:16] == b"\xFF") # dropped byte? return version, dropped_byte def _image_ident_from_data(data, start, stop): return data[start:stop] def _get_image_firmware_version(radio): return _image_ident_from_data(radio.get_mmap(), radio._fw_ver_start, radio._fw_ver_start + 0x0E) def _do_ident(radio, magic): """Put the radio in PROGRAM mode""" # set the serial discipline radio.pipe.baudrate = 9600 radio.pipe.parity = "N" radio.pipe.timeout = STIMEOUT # flush input buffer _clean_buffer(radio) # send request to enter program mode _rawsend(radio, magic) ack = _rawrecv(radio, 1) if ack != b"\x06": if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond") _rawsend(radio, b"\x02") # Ok, get the response ident = _rawrecv(radio, radio._magic_response_length) # check if response is OK if not ident.startswith(b"\xaa") or not ident.endswith(b"\xdd"): # bad response msg = "Unexpected response, got this:" msg += util.hexprint(ident) LOG.debug(msg) raise errors.RadioError("Unexpected response from radio.") # DEBUG LOG.info("Valid response, got this:") LOG.debug(util.hexprint(ident)) _rawsend(radio, b"\x06") ack = _rawrecv(radio, 1) if ack != b"\x06": if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio refused clone") return ident def _ident_radio(radio): for magic in radio._magic: error = None try: data = _do_ident(radio, magic) return data except errors.RadioError as e: print(e) error = e time.sleep(2) if error: raise error raise errors.RadioError("Radio did not respond") def _download(radio): """Get the memory map""" # put radio in program mode ident = _ident_radio(radio) # identify radio radio_ident, has_dropped_byte = _get_radio_firmware_version(radio) LOG.info("Radio firmware version:") LOG.debug(util.hexprint(radio_ident)) LOG.info("Radio has dropped byte issue: %s" % repr(has_dropped_byte)) if radio_ident == "\xFF" * 16: ident += radio.MODEL.ljust(8) elif radio.MODEL in ("GMRS-V1", "GMRS-V2", "MURS-V1", "MURS-V2"): # check if radio_ident is OK if not radio_ident[:7] in radio._fileid: msg = "Incorrect model ID, got this:\n\n" msg += util.hexprint(radio_ident) LOG.debug(msg) raise errors.RadioError("Incorrect 'Model' selected.") # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._mem_size // radio._recv_block_size status.msg = "Cloning from radio..." radio.status_fn(status) start = 0 end = radio._mem_size blocksize = radio._recv_block_size passes = 1 if has_dropped_byte: passes = 2 end = radio._mem_size - radio._recv_block_size data = b"" for i in range(0, passes): if i == 1: start = radio._mem_size - radio._recv_block_size end = radio._mem_size blocksize = 0x10 for addr in range(start, end, blocksize): frame = _make_frame("S", addr, blocksize) # DEBUG LOG.info("Request sent:") LOG.debug(util.hexprint(frame)) # sending the read request _rawsend(radio, frame) if radio._ack_block: ack = _rawrecv(radio, 1) if ack != b"\x06": raise errors.RadioError( "Radio refused to send block 0x%04x" % addr) # now we read d = _recv(radio, addr, blocksize) _rawsend(radio, b"\x06") time.sleep(0.05) # aggregate the data data += d # UI Update status.cur = addr // blocksize status.msg = "Cloning from radio..." radio.status_fn(status) data += ident return data def _upload(radio): """Upload procedure""" # put radio in program mode _ident_radio(radio) # identify radio radio_ident, aux_r1, aux_r2, aux_r3, \ has_dropped_byte = _get_aux_data_from_radio(radio) LOG.info("Radio firmware version:") LOG.debug(util.hexprint(radio_ident)) LOG.info("Radio has dropped byte issue: %s" % repr(has_dropped_byte)) # identify image image_ident = _get_image_firmware_version(radio) LOG.info("Image firmware version:") LOG.debug(util.hexprint(image_ident)) if radio.MODEL in ("GMRS-V1", "MURS-V1"): # check if radio_ident is OK if radio_ident != image_ident: msg = "Incorrect model ID, got this:\n\n" msg += util.hexprint(radio_ident) LOG.debug(msg) raise errors.RadioError("Image not supported by radio") aux_i1 = _get_data_from_image(radio, 0x1F00, 0x1F60) aux_i2 = _get_data_from_image(radio, 0x1F70, 0x1F80) aux_i3 = _get_data_from_image(radio, 0x1F90, 0x1FC0) # check if Aux memory of image matches Aux memory of radio aux_matched = False if aux_i1 != aux_r1: # Area 1 does not match # The safest thing to do is to skip uploading Aux mem area. LOG.info("Aux memory mismatch") LOG.info("Aux area 1 from image is %s" % repr(aux_i1)) LOG.info("Aux area 1 from radio is %s" % repr(aux_r1)) elif aux_i2 != aux_r2: # Area 2 does not match # The safest thing to do is to skip uploading Aux mem area. LOG.info("Aux memory mismatch") LOG.info("Aux area 2 from image is %s" % repr(aux_i2)) LOG.info("Aux area 2 from radio is %s" % repr(aux_r2)) elif aux_i3 != aux_r3: # Area 3 does not match # The safest thing to do is to skip uploading Aux mem area. LOG.info("Aux memory mismatch") LOG.info("Aux area 3 from image is %s" % repr(aux_i3)) LOG.info("Aux area 3 from radio is %s" % repr(aux_r3)) else: # All areas matched # Uploading full Aux mem area is permitted aux_matched = True if has_dropped_byte and not aux_matched: msg = ("Image not supported by radio. You must...\n" "1. Download from radio.\n" "2. Make changes.\n" "3. Upload back to same radio.") raise errors.RadioError(msg) if has_dropped_byte or (aux_matched and radio.VENDOR != "BTECH"): _ranges = [(0x0000, 0x0DF0), (0x0E00, 0x1800), (0x1E80, 0x2000), ] else: _ranges = radio._ranges # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._mem_size // radio._send_block_size status.msg = "Cloning to radio..." radio.status_fn(status) # the fun start here for start, end in _ranges: for addr in range(start, end, radio._send_block_size): # sending the data data = radio.get_mmap()[addr:addr + radio._send_block_size] frame = _make_frame("X", addr, radio._send_block_size, data) _rawsend(radio, frame) time.sleep(0.05) # receiving the response ack = _rawrecv(radio, 1) if ack != b"\x06": msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) # UI Update status.cur = addr // radio._send_block_size status.msg = "Cloning to radio..." radio.status_fn(status) def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True def bcd_decode_freq(bytes): real_freq = 0 for byte in bytes: if byte > 9: msg = ("Found Invalid BCD Encoding") raise InternalError(msg) real_freq = (real_freq * 10) + byte return chirp_common.format_freq(real_freq * 10) class BaofengCommonHT(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Baofeng HT Style Radios""" VENDOR = "Baofeng" MODEL = "" IDENT = "" _gmrs = False _bw_shift = False _tri_band = False def sync_in(self): """Download from radio""" try: data = _download(self) except errors.RadioError: # Pass through any real errors we raise raise except: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except errors.RadioError: raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_features(self): """Get the radio's features""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_name_length = self.LENGTH_NAME if self._gmrs: rf.valid_duplexes = ["", "+", "off"] else: rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = self.SKIP_VALUES rf.valid_dtcs_codes = self.DTCS_CODES rf.memory_bounds = (0, 127) rf.valid_power_levels = self.POWER_LEVELS rf.valid_bands = self.VALID_BANDS rf.valid_tuning_steps = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] return rf def _is_txinh(self, _mem): raw_tx = b"" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw() return raw_tx == b"\xFF\xFF\xFF\xFF" def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number if _mem.get_raw()[:1] == b"\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if self._is_txinh(_mem): # TX freq not set mem.duplex = "off" mem.offset = 0 else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 for char in _nam.name: if str(char) == "\xFF": char = " " # The OEM software may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() dtcs_pol = ["N", "N"] if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 elif _mem.txtone <= 0x0258: txmode = "DTCS" if _mem.txtone > 0x69: index = _mem.txtone - 0x6A dtcs_pol[0] = "R" else: index = _mem.txtone - 1 mem.dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 elif _mem.rxtone <= 0x0258: rxmode = "DTCS" if _mem.rxtone >= 0x6A: index = _mem.rxtone - 0x6A dtcs_pol[1] = "R" else: index = _mem.rxtone - 1 mem.rx_dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) if not _mem.scan: mem.skip = "S" levels = self.POWER_LEVELS if self._tri_band: if _mem.lowpower == TXPOWER_HIGH: mem.power = levels[0] elif _mem.lowpower == TXPOWER_LOW: mem.power = levels[1] else: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.power, levels)) mem.power = levels[0] else: try: mem.power = levels[_mem.lowpower] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.power, levels)) mem.power = levels[0] mem.mode = _mem.wide and "FM" or "NFM" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(self.PTTID_LIST, self.PTTID_LIST[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("scode", "S-CODE", RadioSettingValueList(self.SCODE_LIST, self.SCODE_LIST[_mem.scode])) mem.extra.append(rs) immutable = [] if self._gmrs: if self.MODEL == "UV-9G": if mem.number >= 1 and mem.number <= 30: # 30 GMRS fixed channels GMRS_30_FIXED_FREQS = \ bandplan_na.ALL_GMRS_FREQS + \ bandplan_na.GMRS_HIRPT GMRS_FREQ = GMRS_30_FIXED_FREQS[mem.number - 1] mem.freq = GMRS_FREQ immutable = ["empty", "freq"] if mem.number <= 22: # GMRS simplex only channels mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] if mem.number >= 8 and mem.number <= 14: # GMRS 467 MHz interstitial channels # must be narrow FM and low power mem.mode = "NFM" mem.power = self.POWER_LEVELS[2] immutable += ["mode", "power"] if mem.number > 22: # GMRS repeater only channels mem.duplex = '+' mem.offset = 5000000 immutable += ["duplex", "offset"] elif mem.freq in bandplan_na.ALL_GMRS_FREQS: # 98 GMRS customizable channels if mem.freq in bandplan_na.GMRS_LOW: # GMRS 462 MHz interstitial frequencies mem.duplex = '' mem.offset = 0 immutable = ["duplex", "offset"] if mem.freq in bandplan_na.GMRS_HHONLY: # GMRS 467 MHz interstitial frequencies mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[2] immutable = ["duplex", "offset", "mode", "power"] if mem.freq in bandplan_na.GMRS_HIRPT: # GMRS 462 MHz main frequencies # GMRS 467 MHz main frequencies (repeater input) if mem.duplex == '': mem.offset = 0 if mem.duplex == '+': mem.offset = 5000000 else: # Not a GMRS frequency - disable TX mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] mem.immutable = immutable return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _nam = self._memobj.names[mem.number] if mem.empty: _mem.set_raw("\xff" * 16) _nam.set_raw("\xff" * 16) return _mem.set_raw("\x00" * 16) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": rxmode = txmode = "DTCS" _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 _mem.rxtone = self.DTCS_CODES.index(mem.dtcs) + 1 elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) elif txmode == "DTCS": _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCS": _mem.rxtone = self.DTCS_CODES.index(mem.rx_dtcs) + 1 else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 if txmode == "DTCS" and mem.dtcs_polarity[0] == "R": _mem.txtone += 0x69 if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R": _mem.rxtone += 0x69 _mem.scan = mem.skip != "S" _mem.wide = mem.mode == "FM" if self._tri_band: levels = self.POWER_LEVELS if mem.power is None: _mem.lowpower = TXPOWER_HIGH elif mem.power == levels[0]: _mem.lowpower = TXPOWER_HIGH elif mem.power == levels[1]: _mem.lowpower = TXPOWER_LOW else: _mem.lowpower = TXPOWER_HIGH else: if mem.power: _mem.lowpower = self.POWER_LEVELS.index(mem.power) else: _mem.lowpower = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) else: # there are no extra settings, load defaults _mem.bcl = 0 _mem.pttid = 0 _mem.scode = 0 def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _set_fm_preset(self, settings): for element in settings: try: val = element.value if self._memobj.fm_presets <= 108.0 * 10 - 650: value = int(val.get_value() * 10 - 650) else: value = int(val.get_value() * 10) LOG.debug("Setting fm_presets = %s" % (value)) if self._bw_shift: value = ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8) self._memobj.fm_presets = value except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/vx3.py0000644000175000017500000010165414520142245015717 0ustar hibbyhibby# Copyright 2011 Rick Farina # based on modification of Dan Smith's original work # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettings import re import logging LOG = logging.getLogger(__name__) # interesting offsets which may be checksums needed later # 0x0393 checksum1? # 0x0453 checksum1a? # 0x0409 checksum2? # 0x04C9 checksum2a? MEM_FORMAT = """ #seekto 0x7F4A; u8 checksum; #seekto 0x024A; struct { u8 unk01_1:3, att_broadcast:1, att_marine:1, unk01_2:2, att_wx:1; u8 unk02; u8 apo; u8 arts_beep; u8 unk04_1; u8 beep_level; u8 beep_mode; u8 unk04_2; u8 arts_cwid[16]; u8 unk05[10]; u8 channel_counter; u8 unk06_1[2]; u8 dtmf_delay; u8 dtmf_chan_active; u8 unk06_2[5]; u8 emergency_eai_time; u8 emergency_signal; u8 unk07[30]; u8 fw_key_timer; u8 internet_key; u8 lamp; u8 lock_mode; u8 my_key; u8 mic_gain; u8 mem_ch_step; u8 unk08[3]; u8 sql_fm; u8 sql_wfm; u8 radio_am_sql; u8 radio_fm_sql; u8 on_timer; u8 openmsg_mode; u8 openmsg[6]; u8 pager_rxtone1; u8 pager_rxtone2; u8 pager_txtone1; u8 pager_txtone2; u8 password[4]; u8 unk10; u8 priority_time; u8 ptt_delay; u8 rx_save; u8 scan_resume; u8 scan_restart; u8 sub_rx_timer; u8 unk11[7]; u8 tot; u8 wake_up; u8 unk12[2]; u8 vfo_mode:1, arts_cwid_enable:1, scan_lamp:1, fast_tone_search:1, ars:1, dtmf_speed:1, split_tone:1, dtmf_autodialer:1; u8 busy_led:1, tone_search_mute:1, unk14_1:1, bclo:1, band_edge_beep:1, unk14_2:2, txsave:1; u8 unk15_1:2, smart_search:1, emergency_eai:1, unk15_2:2, hm_rv:1, moni_tcall:1; u8 lock:1, unk16_1:1, arts:1, arts_interval:1, unk16_2:1, protect_memory:1, unk16_3:1, mem_storage:1; u8 vol_key_mode:1, unk17_1:2, wx_alert:1, temp_unit:1, unk17_2:2, password_active:1; u8 fm_broadcast_mode:1, fm_antenna:1, am_antenna:1, fm_speaker_out:1, home_vfo:1, unk18_1:2, priority_revert:1; } settings; // banks? #seekto 0x034D; u8 banks_unk1; #seekto 0x0356; struct { u32 unmask; } banks_unmask1; #seekto 0x0409; u8 banks_unk3; #seekto 0x0416; struct { u32 unmask; } banks_unmask2; #seekto 0x04CA; struct { u8 memory[16]; } dtmf[10]; #seekto 0x0B7A; struct { u8 name[6]; } bank_names[24]; #seekto 0x0E0A; struct { u16 channels[100]; } banks[24]; #seekto 0x02EE; struct { u16 in_use; } bank_used[24]; #seekto 0x03FE; struct { u8 speaker; u8 earphone; } volumes; #seekto 0x20CA; struct { u8 even_pskip:1, even_skip:1, even_valid:1, // TODO: should be "showname", i.e., show alpha name even_masked:1, odd_pskip:1, odd_skip:1, odd_valid:1, odd_masked:1; } flags[999]; #seekto 0x244A; struct { u8 unknown1a:2, txnarrow:1, clockshift:1, unknown1b:4; u8 mode:2, duplex:2, tune_step:4; bbcd freq[3]; u8 power:2, unknown2:4, tmode:2; // TODO: tmode should be 6 bits (extended tone modes) u8 name[6]; bbcd offset[3]; u8 unknown3:2, tone:6; u8 unknown4:1, dcs:7; u8 unknown5; u8 smetersquelch; u8 unknown7a:2, attenuate:1, unknown7b:1, automode:1, unknown8:1, bell:2; } memory[999]; """ # fix auto mode setting and auto step setting DUPLEX = ["", "-", "+", "split"] MODES = ["FM", "AM", "WFM", "Auto", "NFM"] # NFM handled specially in radio TMODES = ["", "Tone", "TSQL", "DTCS"] # TODO: TMODES = ["", "Tone, "TSQL", "DTCS", "Rev Tone", "User Tone", "Pager", # "Message", "D Code", "Tone/DTCS", "DTCS/Tone"] # still need to verify 9 is correct, and add auto: look at byte 1 and 20 STEPS = [5.0, 9, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] # STEPS = list(chirp_common.TUNING_STEPS) # STEPS.remove(6.25) # STEPS.remove(30.0) # STEPS.append(100.0) # STEPS.append(9.0) #this fails because 9 is out of order in the list # Empty char should be 0xFF but right now we are coding in a space CHARSET = list("0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + "+-/\x00[](){}\x00\x00_" + ("\x00" * 13) + "*" + "\x00\x00,'|\x00\x00\x00\x00" + ("\x00" * 64)) DTMFCHARSET = list("0123456789ABCD*#") POWER_LEVELS = [chirp_common.PowerLevel("High", watts=1.50), chirp_common.PowerLevel("Low", watts=0.10)] class VX3Bank(chirp_common.NamedBank): """A VX3 Bank""" def get_name(self): _bank = self._model._radio._memobj.bank_names[self.index] name = "" for i in _bank.name: if i == 0xFF: break name += CHARSET[i & 0x7F] return name.rstrip() def set_name(self, name): name = name.upper() _bank = self._model._radio._memobj.bank_names[self.index] _bank.name = [CHARSET.index(x) for x in name.ljust(6)[:6]] class VX3BankModel(chirp_common.BankModel): """A VX-3 bank model""" def get_num_mappings(self): return len(self.get_mappings()) def get_mappings(self): banks = self._radio._memobj.banks bank_mappings = [] for index, _bank in enumerate(banks): bank = VX3Bank(self, "%i" % index, "b%i" % (index + 1)) bank.index = index bank_mappings.append(bank) return bank_mappings def _get_channel_numbers_in_bank(self, bank): _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xFFFF: return set() _members = self._radio._memobj.banks[bank.index] return set([int(ch) + 1 for ch in _members.channels if ch != 0xFFFF]) def _update_bank_with_channel_numbers(self, bank, channels_in_bank): _members = self._radio._memobj.banks[bank.index] if len(channels_in_bank) > len(_members.channels): raise Exception("Too many entries in bank %d" % bank.index) empty = 0 for index, channel_number in enumerate(sorted(channels_in_bank)): _members.channels[index] = channel_number - 1 empty = index + 1 for index in range(empty, len(_members.channels)): _members.channels[index] = 0xFFFF def add_memory_to_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) channels_in_bank.add(memory.number) self._update_bank_with_channel_numbers(bank, channels_in_bank) _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = ((len(channels_in_bank) - 1) * 2) _banks_unmask1 = self._radio._memobj.banks_unmask1 _banks_unmask2 = self._radio._memobj.banks_unmask2 _banks_unmask1.unmask = 0x0017FFFF _banks_unmask2.unmask = 0x0017FFFF def remove_memory_from_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) try: channels_in_bank.remove(memory.number) except KeyError: raise Exception("Memory %i is not in bank %s. Cannot remove" % (memory.number, bank)) self._update_bank_with_channel_numbers(bank, channels_in_bank) _bank_used = self._radio._memobj.bank_used[bank.index] if channels_in_bank: _bank_used.in_use = ((len(channels_in_bank) - 1) * 2) else: _bank_used.in_use = 0xFFFF def get_mapping_memories(self, bank): memories = [] for channel in self._get_channel_numbers_in_bank(bank): memories.append(self._radio.get_memory(channel)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in self._get_channel_numbers_in_bank(bank): banks.append(bank) return banks def _wipe_memory(mem): mem.set_raw("\x00" * (mem.size() // 8)) # the following settings are set to match the defaults # on the radio, some of these fields are unknown mem.name = [0xFF for _i in range(0, 6)] mem.unknown5 = 0x0D # not sure what this is mem.unknown7a = 0b0 mem.unknown7b = 0b1 mem.automode = 0x01 # autoselect mode @directory.register class VX3Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu VX-3""" BAUD_RATE = 19200 VENDOR = "Yaesu" MODEL = "VX-3" # 41 48 30 32 38 _model = b"AH028" _memsize = 32587 _block_lengths = [10, 32577] # right now this reads in 45 seconds and writes in 41 seconds _block_size = 32 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [F/W] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. After clicking OK, press the [BAND] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [F/W] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. Press the [V/M] key (\"-WAIT-\" will appear on the LCD).\n") return rp def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x7F49)] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = True rf.has_bank_names = True rf.has_dtcs_polarity = False rf.valid_modes = list(set(MODES)) rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(500000, 999000000)] rf.valid_skips = ["", "S", "P"] rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 6 rf.memory_bounds = (1, 999) rf.can_odd_split = True rf.has_ctone = False rf.has_settings = True return rf def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): _mem = self._memobj.memory[number-1] _flag = self._memobj.flags[(number-1)/2] nibble = ((number-1) % 2) and "even" or "odd" used = _flag["%s_masked" % nibble] valid = _flag["%s_valid" % nibble] pskip = _flag["%s_pskip" % nibble] skip = _flag["%s_skip" % nibble] mem = chirp_common.Memory() mem.number = number if not used: mem.empty = True if not valid: mem.empty = True mem.power = POWER_LEVELS[0] return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = int(_mem.offset) * 1000 mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] mem.tmode = TMODES[_mem.tmode] mem.duplex = DUPLEX[_mem.duplex] if mem.duplex == "split": mem.offset = chirp_common.fix_rounded_step(mem.offset) if _mem.txnarrow and _mem.mode == MODES.index("FM"): # FM narrow mem.mode = "NFM" else: mem.mode = MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] mem.tuning_step = STEPS[_mem.tune_step] mem.skip = pskip and "P" or skip and "S" or "" mem.power = POWER_LEVELS[~_mem.power & 0x01] for i in _mem.name: if i == 0xFF: break mem.name += CHARSET[i & 0x7F] mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] _flag = self._memobj.flags[(mem.number-1)/2] nibble = ((mem.number-1) % 2) and "even" or "odd" used = _flag["%s_masked" % nibble] valid = _flag["%s_valid" % nibble] if not mem.empty and not valid: _wipe_memory(_mem) if mem.empty and valid and not used: _flag["%s_valid" % nibble] = False return _flag["%s_masked" % nibble] = not mem.empty if mem.empty: return _flag["%s_valid" % nibble] = True _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 1000 _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) if mem.mode == "NFM": _mem.mode = MODES.index("FM") _mem.txnarrow = True else: _mem.mode = MODES.index(mem.mode) _mem.txnarrow = False _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tune_step = STEPS.index(mem.tuning_step) if mem.power == POWER_LEVELS[1]: # Low _mem.power = 0x00 else: # Default to High _mem.power = 0x03 _flag["%s_pskip" % nibble] = mem.skip == "P" _flag["%s_skip" % nibble] = mem.skip == "S" for i in range(0, 6): _mem.name[i] = CHARSET.index(mem.name.ljust(6)[i]) if mem.name.strip(): _mem.name[0] |= 0x80 def validate_memory(self, mem): msgs = yaesu_clone.YaesuCloneModeRadio.validate_memory(self, mem) return msgs def get_bank_model(self): return VX3BankModel(self) def _decode_chars(self, inarr): LOG.debug("@_decode_chars, type: %s" % type(inarr)) LOG.debug(inarr) outstr = "" for i in inarr: if i == 0xFF: break outstr += CHARSET[i & 0x7F] return outstr.rstrip() def _encode_chars(self, instr, length=16): LOG.debug("@_encode_chars, type: %s" % type(instr)) LOG.debug(instr) outarr = [] instr = str(instr) for i in range(length): if i < len(instr): outarr.append(CHARSET.index(instr[i])) else: outarr.append(0xFF) return outarr def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") sound = RadioSettingGroup("sound", "Sound") dtmf = RadioSettingGroup("dtmf", "DTMF") arts = RadioSettingGroup("arts", "ARTS") eai = RadioSettingGroup("eai", "Emergency") msg = RadioSettingGroup("msg", "Messages") top = RadioSettings(basic, sound, arts, dtmf, eai, msg) basic.append(RadioSetting( "att_wx", "Attenuation WX", RadioSettingValueBoolean(_settings.att_wx))) basic.append(RadioSetting( "att_marine", "Attenuation Marine", RadioSettingValueBoolean(_settings.att_marine))) basic.append(RadioSetting( "att_broadcast", "Attenuation Broadcast", RadioSettingValueBoolean(_settings.att_broadcast))) basic.append(RadioSetting( "ars", "Auto Repeater Shift", RadioSettingValueBoolean(_settings.ars))) basic.append(RadioSetting( "home_vfo", "Home->VFO", RadioSettingValueBoolean(_settings.home_vfo))) basic.append(RadioSetting( "bclo", "Busy Channel Lockout", RadioSettingValueBoolean(_settings.bclo))) basic.append(RadioSetting( "busyled", "Busy LED", RadioSettingValueBoolean(_settings.busy_led))) basic.append(RadioSetting( "fast_tone_search", "Fast Tone search", RadioSettingValueBoolean(_settings.fast_tone_search))) basic.append(RadioSetting( "priority_revert", "Priority Revert", RadioSettingValueBoolean(_settings.priority_revert))) basic.append(RadioSetting( "protect_memory", "Protect memory", RadioSettingValueBoolean(_settings.protect_memory))) basic.append(RadioSetting( "scan_lamp", "Scan Lamp", RadioSettingValueBoolean(_settings.scan_lamp))) basic.append(RadioSetting( "split_tone", "Split tone", RadioSettingValueBoolean(_settings.split_tone))) basic.append(RadioSetting( "tone_search_mute", "Tone search mute", RadioSettingValueBoolean(_settings.tone_search_mute))) basic.append(RadioSetting( "txsave", "TX save", RadioSettingValueBoolean(_settings.txsave))) basic.append(RadioSetting( "wx_alert", "WX Alert", RadioSettingValueBoolean(_settings.wx_alert))) opts = ["Bar Int", "Bar Ext"] basic.append(RadioSetting( "am_antenna", "AM antenna", RadioSettingValueList(opts, opts[_settings.am_antenna]))) opts = ["Ext Ant", "Earphone"] basic.append(RadioSetting( "fm_antenna", "FM antenna", RadioSettingValueList(opts, opts[_settings.fm_antenna]))) opts = ["off"] + ["%0.1f" % (t / 60.0) for t in range(30, 750, 30)] basic.append(RadioSetting( "apo", "APO time (hrs)", RadioSettingValueList(opts, opts[_settings.apo]))) opts = ["+/- 5 MHz", "+/- 10 MHz", "+/- 50 MHz", "+/- 100 MHz"] basic.append(RadioSetting( "channel_counter", "Channel counter", RadioSettingValueList(opts, opts[_settings.channel_counter]))) opts = ["0.3", "0.5", "0.7", "1.0", "1.5"] basic.append(RadioSetting( "fw_key_timer", "FW key timer (s)", RadioSettingValueList(opts, opts[_settings.fw_key_timer]))) opts = ["Home", "Reverse"] basic.append(RadioSetting( "hm_rv", "HM/RV key", RadioSettingValueList(opts, opts[_settings.hm_rv]))) opts = ["%d" % t for t in range(2, 11)] + ["continuous", "off"] basic.append(RadioSetting( "lamp", "Lamp Timer (s)", RadioSettingValueList(opts, opts[_settings.lamp]))) basic.append(RadioSetting( "lock", "Lock", RadioSettingValueBoolean(_settings.lock))) opts = ["key", "ptt", "key+ptt"] basic.append(RadioSetting( "lock_mode", "Lock mode", RadioSettingValueList(opts, opts[_settings.lock_mode]))) opts = ["10", "20", "50", "100"] basic.append(RadioSetting( "mem_ch_step", "Memory Chan step", RadioSettingValueList(opts, opts[_settings.mem_ch_step]))) opts = ["lower", "next"] basic.append(RadioSetting( "mem_storage", "Memory storage mode", RadioSettingValueList(opts, opts[_settings.mem_storage]))) opts = ["%d" % t for t in range(1, 10)] basic.append(RadioSetting( "mic_gain", "Mic gain", RadioSettingValueList(opts, opts[_settings.mic_gain]))) opts = ["monitor", "tone call"] basic.append(RadioSetting( "moni_tcall", "Moni/TCall button", RadioSettingValueList(opts, opts[_settings.moni_tcall]))) opts = ["off"] + \ ["%02d:%02d" % (t / 60, t % 60) for t in range(10, 1450, 10)] basic.append(RadioSetting( "on_timer", "On Timer (hrs)", RadioSettingValueList(opts, opts[_settings.on_timer]))) opts2 = ["off"] + \ ["0.%d" % t for t in range(1, 10)] + \ ["%1.1f" % (t / 10.0) for t in range(10, 105, 5)] basic.append(RadioSetting( "priority_time", "Priority time", RadioSettingValueList(opts2, opts2[_settings.priority_time]))) opts = ["off", "20", "50", "100", "200"] basic.append(RadioSetting( "ptt_delay", "PTT delay (ms)", RadioSettingValueList(opts, opts[_settings.ptt_delay]))) basic.append(RadioSetting( "rx_save", "RX save (s)", RadioSettingValueList(opts2, opts2[_settings.rx_save]))) basic.append(RadioSetting( "scan_restart", "Scan restart (s)", RadioSettingValueList(opts2, opts2[_settings.scan_restart]))) opts = ["%1.1f" % (t / 10.0) for t in range(20, 105, 5)] + \ ["busy", "hold"] basic.append(RadioSetting( "scan_resume", "Scan resume (s)", RadioSettingValueList(opts, opts[_settings.scan_resume]))) opts = ["single", "continuous"] basic.append(RadioSetting( "smart_search", "Smart search", RadioSettingValueList(opts, opts[_settings.smart_search]))) opts = ["off"] + ["TRX %d" % t for t in range(1, 11)] + ["hold"] + \ ["TX %d" % t for t in range(1, 11)] basic.append(RadioSetting( "sub_rx_timer", "Sub RX timer", RadioSettingValueList(opts, opts[_settings.sub_rx_timer]))) opts = ["C", "F"] basic.append(RadioSetting( "temp_unit", "Temperature unit", RadioSettingValueList(opts, opts[_settings.temp_unit]))) opts = ["off"] + ["%1.1f" % (t / 10.0) for t in range(5, 105, 5)] basic.append(RadioSetting( "tot", "Time-out timer (mins)", RadioSettingValueList(opts, opts[_settings.tot]))) opts = ["all", "band"] basic.append(RadioSetting( "vfo_mode", "VFO mode", RadioSettingValueList(opts, opts[_settings.vfo_mode]))) opts = ["off"] + ["%d" % t for t in range(5, 65, 5)] + ["EAI"] basic.append(RadioSetting( "wake_up", "Wake up (s)", RadioSettingValueList(opts, opts[_settings.wake_up]))) opts = ["hold", "3 secs"] basic.append(RadioSetting( "vol_key_mode", "Volume key mode", RadioSettingValueList(opts, opts[_settings.vol_key_mode]))) # subgroup programmable keys opts = ["INTNET", "INT MR", "Set Mode (my key)"] basic.append(RadioSetting( "internet_key", "Internet key", RadioSettingValueList(opts, opts[_settings.internet_key]))) keys = ["Antenna AM", "Antenna FM", "Antenna Attenuator", "Auto Power Off", "Auto Repeater Shift", "ARTS Beep", "ARTS Interval", "Busy Channel Lockout", "Bell Ringer", "Bell Select", "Bank Name", "Band Edge Beep", "Beep Level", "Beep Select", "Beep User", "Busy LED", "Channel Counter", "Clock Shift", "CW ID", "CW Learning", "CW Pitch", "CW Training", "DC Voltage", "DCS Code", "DCS Reverse", "DTMF A/M", "DTMF Delay", "DTMF Set", "DTMF Speed", "EAI Timer", "Emergency Alarm", "Ext Menu", "FW Key", "Half Deviation", "Home/Reverse", "Home > VFO", "INT Code", "INT Conn Mode", "INT A/M", "INT Set", "INT Key", "INTNET", "Lamp", "LED Light", "Lock", "Moni/T-Call", "Mic Gain", "Memory Display", "Memory Write Mode", "Memory Channel Step", "Memory Name Write", "Memory Protect", "Memory Skip", "Message List", "Message Reg", "Message Set", "On Timer", "Open Message", "Pager Answer Back", "Pager Receive Code", "Pager Transmit Code", "Pager Frequency", "Priority Revert", "Priority Timer", "Password", "PTT Delay", "Repeater Shift Direction", "Repeater Shift", "Receive Mode", "Smart Search", "Save Rx", "Save Tx", "Scan Lamp", "Scan Resume", "Scan Restart", "Speaker Out", "Squelch Level", "Squelch Type", "Squelch S Meter", "Squelch Split Tone", "Step", "Stereo", "Sub Rx", "Temp", "Tone Frequency", "Time Out Timer", "Tone Search Mute", "Tone Search Speed", "VFO Band", "VFO Skip", "Volume Mode", "Wake Up", "Weather Alert"] rs = RadioSetting( "my_key", "My key", RadioSettingValueList(keys, keys[_settings.my_key - 16])) # TODO: fix keys list isn't exactly right order # leave disabled in settings for now # basic.append(rs) # sound tab sound.append(RadioSetting( "band_edge_beep", "Band edge beep", RadioSettingValueBoolean(_settings.band_edge_beep))) opts = ["off", "key+scan", "key"] sound.append(RadioSetting( "beep_mode", "Beep mode", RadioSettingValueList(opts, opts[_settings.beep_mode]))) _volumes = self._memobj.volumes opts = list(map(str, list(range(0, 33)))) sound.append(RadioSetting( "speaker_vol", "Speaker volume", RadioSettingValueList(opts, opts[_volumes.speaker]))) sound.append(RadioSetting( "earphone_vol", "Earphone volume", RadioSettingValueList(opts, opts[_volumes.earphone]))) opts = ["auto", "speaker"] sound.append(RadioSetting( "fm_speaker_out", "FM Speaker out", RadioSettingValueList(opts, opts[_settings.fm_speaker_out]))) opts = ["mono", "stereo"] sound.append(RadioSetting( "fm_broadcast_mode", "FM broadcast mode", RadioSettingValueList( opts, opts[_settings.fm_broadcast_mode]))) opts = list(map(str, list(range(16)))) sound.append(RadioSetting( "sql_fm", "Squelch level (FM)", RadioSettingValueList(opts, opts[_settings.sql_fm]))) opts = list(map(str, list(range(9)))) sound.append(RadioSetting( "sql_wfm", "Squelch level (WFM)", RadioSettingValueList(opts, opts[_settings.sql_wfm]))) opts = list(map(str, list(range(16)))) sound.append(RadioSetting( "radio_am_sql", "Squelch level (Broadcast Radio AM)", RadioSettingValueList(opts, opts[_settings.radio_am_sql]))) opts = list(map(str, list(range(9)))) sound.append(RadioSetting( "radio_fm_sql", "Squelch level (Broadcast Radio FM)", RadioSettingValueList(opts, opts[_settings.radio_fm_sql]))) # dtmf tab opts = ["manual", "auto"] dtmf.append(RadioSetting( "dtmf_autodialer", "DTMF autodialer mode", RadioSettingValueList(opts, opts[_settings.dtmf_autodialer]))) opts = ["50", "250", "450", "750", "1000"] dtmf.append(RadioSetting( "dtmf_delay", "DTMF delay (ms)", RadioSettingValueList(opts, opts[_settings.dtmf_delay]))) opts = ["50", "100"] dtmf.append(RadioSetting( "dtmf_speed", "DTMF speed (ms)", RadioSettingValueList(opts, opts[_settings.dtmf_speed]))) opts = list(map(str, list(range(10)))) dtmf.append(RadioSetting( "dtmf_chan_active", "DTMF active", RadioSettingValueList( opts, opts[_settings.dtmf_chan_active]))) for i in range(10): name = "dtmf" + str(i) dtmfsetting = self._memobj.dtmf[i] dtmfstr = "" for c in dtmfsetting.memory: if c < len(DTMFCHARSET): dtmfstr += DTMFCHARSET[c] LOG.debug(dtmfstr) dtmfentry = RadioSettingValueString(0, 16, dtmfstr) dtmfentry.set_charset(DTMFCHARSET + list(" ")) rs = RadioSetting(name, name.upper(), dtmfentry) dtmf.append(rs) # arts tab arts.append(RadioSetting( "arts", "ARTS", RadioSettingValueBoolean(_settings.arts))) opts = ["off", "in range", "always"] arts.append(RadioSetting( "arts_beep", "ARTS beep", RadioSettingValueList(opts, opts[_settings.arts_beep]))) opts = ["15", "25"] arts.append(RadioSetting( "arts_interval", "ARTS interval", RadioSettingValueList(opts, opts[_settings.arts_interval]))) arts.append(RadioSetting( "arts_cwid_enable", "CW ID", RadioSettingValueBoolean(_settings.arts_cwid_enable))) cwid = RadioSettingValueString( 0, 16, self._decode_chars(_settings.arts_cwid.get_value())) cwid.set_charset(CHARSET) arts.append(RadioSetting("arts_cwid", "CW ID", cwid)) # EAI tab eai.append(RadioSetting( "emergency_eai", "EAI", RadioSettingValueBoolean(_settings.emergency_eai))) opts = ["interval %dm" % t for t in range(1, 10)] + \ ["interval %dm" % t for t in range(10, 55, 5)] + \ ["continuous %dm" % t for t in range(1, 10)] + \ ["continuous %dm" % t for t in range(10, 55, 5)] eai.append(RadioSetting( "emergency_eai_time", "EAI time", RadioSettingValueList( opts, opts[_settings.emergency_eai_time]))) opts = ["beep", "strobe", "beep+strobe", "beam", "beep+beam", "cw", "beep+cw", "cwt"] eai.append(RadioSetting( "emergency_signal", "emergency signal", RadioSettingValueList( opts, opts[_settings.emergency_signal]))) # msg tab opts = ["off", "dc voltage", "message"] msg.append(RadioSetting( "openmsg_mode", "Opening message mode", RadioSettingValueList(opts, opts[_settings.openmsg_mode]))) openmsg = RadioSettingValueString( 0, 6, self._decode_chars(_settings.openmsg.get_value())) openmsg.set_charset(CHARSET) msg.append(RadioSetting("openmsg", "Opening Message", openmsg)) return top def set_settings(self, uisettings): for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() _settings = self._memobj.settings if re.match(r'dtmf\d', setting): # set dtmf fields dtmfstr = str(element.value).strip() newval = [] for i in range(0, 16): if i < len(dtmfstr): newval.append(DTMFCHARSET.index(dtmfstr[i])) else: newval.append(0xFF) LOG.debug(newval) idx = int(setting[-1:]) _settings = self._memobj.dtmf[idx] _settings.memory = newval continue if re.match('.*_vol$', setting): # volume fields voltype = re.sub('_vol$', '', setting) setattr(self._memobj.volumes, voltype, element.value) continue if setting == "my_key": # my_key is memory is off by 9 from list, beware hacks! opts = element.value.get_options() optsidx = opts.index(element.value.get_value()) idx = optsidx + 16 setattr(_settings, "my_key", idx) continue oldval = getattr(_settings, setting) newval = element.value if setting == "arts_cwid": newval = self._encode_chars(newval) if setting == "openmsg": newval = self._encode_chars(newval, 6) LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/th9000.py0000644000175000017500000007603214520142245016124 0ustar hibbyhibby# Copyright 2015 David Fannin KK6DF # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp import errors from chirp import memmap from chirp import util from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings, \ RadioSettingValueList, RadioSettingValueString, RadioSettingValueInteger LOG = logging.getLogger(__name__) # # Chirp Driver for TYT TH-9000D (models: 2M (144 MHz), 1.25M (220 MHz) # and 70 cm (440 MHz) radios) # # Version 1.0 # # - Skip channels # # Global Parameters # MMAPSIZE = 16384 TONES = [62.5] + list(chirp_common.TONES) TMODES = ['', 'Tone', 'DTCS', ''] DUPLEXES = ['', 'err', '-', '+'] # index 2 not used MODES = ['WFM', 'FM', 'NFM'] # 25k, 20k,15k bw TUNING_STEPS = [5.0, 6.25, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0] # index 0-9 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=65), chirp_common.PowerLevel("Mid", watts=25), chirp_common.PowerLevel("Low", watts=10)] CROSS_MODES = chirp_common.CROSS_MODES APO_LIST = ["Off", "30 min", "1 hr", "2 hrs"] BGCOLOR_LIST = ["Blue", "Orange", "Purple"] BGBRIGHT_LIST = ["%s" % x for x in range(1, 32)] SQUELCH_LIST = ["Off"] + ["Level %s" % x for x in range(1, 20)] TIMEOUT_LIST = ["Off"] + ["%s min" % x for x in range(1, 30)] TXPWR_LIST = ["60W", "25W"] # maximum power for Hi setting TBSTFREQ_LIST = ["1750 Hz", "2100 Hz", "1000 Hz", "1450 Hz"] BEEP_LIST = ["Off", "On"] MEM_FORMAT = """ #seekto 0x0000; struct { u8 unknown0000[16]; char idhdr[16]; u8 unknown0001[16]; } fidhdr; """ # Overall Memory Map: # # Memory Map (Range 0x0100-3FF0, step 0x10): # # Field Start End Size # (hex) (hex) (hex) # # 1 Channel Set Flag 0100 011F 20 # 2 Channel Skip Flag 0120 013F 20 # 3 Blank/Unknown 0140 01EF B0 # 4 Unknown 01F0 01FF 10 # 5 TX/RX Range 0200 020F 10 # 6 Bootup Passwd 0210 021F 10 # 7 Options, Radio 0220 023F 20 # 8 Unknown 0240 019F # 8B Startup Label 03E0 03E7 07 # 9 Channel Bank 2000 38FF 1900 # Channel 000 2000 201F 20 # Channel 001 2020 202F 20 # ... # Channel 199 38E0 38FF 20 # 10 Blank/Unknown 3900 3FFF 6FF 14592 16383 1792 # Total Map Size 16128 (2^8 = 16384) # # TH9000/220 memory map # section: 1 and 2: Channel Set/Skip Flags # # Channel Set (starts 0x100) : Channel Set bit is value 0 if a memory # location in the channel bank is active. # Channel Skip (starts 0x120): Channel Skip bit is value 0 if a memory # location in the channel bank is active. # # Both flag maps are a total 24 bytes in length, aligned on 32 byte records. # bit = 0 channel set/no skip, 1 is channel not set/skip # # to index a channel: # cbyte = channel / 8 ; # cbit = channel % 8 ; # setflag = csetflag[cbyte].c[cbit] ; # skipflag = cskipflag[cbyte].c[cbit] ; # # channel range is 0-199, range is 32 bytes (last 7 unknown) # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x0100; struct { bit c[8]; } csetflag[32]; struct { u8 unknown0100[7]; } ropt0100; #seekto 0x0120; struct { bit c[8]; } cskipflag[32]; struct { u8 unknown0120[7]; } ropt0120; """ # TH9000 memory map # section: 5 TX/RX Range # used to set the TX/RX range of the radio (e.g. 222-228 MHz for 220 meter) # possible to set range for tx/rx # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x0200; struct { bbcd txrangelow[4]; bbcd txrangehi[4]; bbcd rxrangelow[4]; bbcd rxrangehi[4]; } freqrange; """ # TH9000 memory map # section: 6 bootup_passwd # used to set bootup passwd (see boot_passwd checkbox option) # # options - bootup password # # bytes:bit type description # --------------------------------------------------------------------------- # 6 u8 bootup_passwd[6] bootup passwd, 6 chars, numeric chars # 30-39 , see boot_passwd checkbox to set # 10 u8 unknown; # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x0210; struct { u8 bootup_passwd[6]; u8 unknown2010[10]; } ropt0210; """ # TH9000/220 memory map # section: 7 Radio Options # used to set a number of radio options # # bytes:bit type description # --------------------------------------------------------------------------- # 1 u8 display_mode display mode, range 0-2, 0=freq,1=channel, # 2=name (selecting name affects vfo_mr) # 1 u8 vfo_mr; vfo_mr , 0=vfo, mr=1 # 1 u8 unknown; # 1 u8 squelch; squelch level, range 0-19, hex for menu # 1 u8 unknown[2]; # 1 u8 channel_lock; if display_mode[channel] selected, then # lock=1,no lock =0 # 1 u8 unknown; # 1 u8 bg_brightness ; background brightness, range 0-21, hex, # menu index # 1 u8 unknown; # 1 u8 bg_color ; bg color, menu index, blue 0 , orange 1, # purple 2 # 1 u8 tbst_freq ; tbst freq, menu 0=1750 Hz, 1=2100, # 2=1000, 3=1450 Hz # 1 u8 timeout_timer; timeout timer, hex, value = minutes, # 0= no timeout # 1 u8 unknown; # 1 u8 auto_power_off; auto power off, range 0-3, off,30min, 1hr, # 2hr, hex menu index # 1 u8 voice_prompt; voice prompt, value 0,1 , Beep ON = 1, # Beep Off = 2 # # description of function setup options, starting at 0x0230 # # bytes:bit type description # --------------------------------------------------------------------------- # 1 u8 // 0 # :4 unknown:6 # :1 elim_sql_tail:1 eliminate squelsh tail when no ctcss checkbox # (1=checked) # :1 sql_key_function "squelch off" 1 , "squelch momentary off" 0 , # menu index # 2 u8 unknown[2] /1-2 # 1 u8 // 3 # :4 unknown:4 # :1 inhibit_init_ops:1 //bit 5 # :1 unknownD:1 # :1 inhibit_setup_bg_chk:1 //bit 7 # :1 unknown:1 # 1 u8 tail_elim_type menu , (off=0,120=1,180=2), // 4 # 1 u8 choose_tx_power menu , (60w=0,25w=1) // 5 # 2 u8 unknown[2]; // 6-7 # 1 u8 bootup_passwd_flag checkbox 1=on, 0=off // 8 # 7 u8 unknown[7]; // 9-F # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x0220; struct { u8 display_mode; u8 vfo_mr; u8 unknown0220A; u8 squelch; u8 unknown0220B[2]; u8 channel_lock; u8 unknown0220C; u8 bg_brightness; u8 unknown0220D; u8 bg_color; u8 tbst_freq; u8 timeout_timer; u8 unknown0220E; u8 auto_power_off; u8 voice_prompt; u8 unknown0230A:6, elim_sql_tail:1, sql_key_function:1; u8 unknown0230B[2]; u8 unknown0230C:4, inhibit_init_ops:1, unknown0230D:1, inhibit_setup_bg_chk:1, unknown0230E:1; u8 tail_elim_type; u8 choose_tx_power; u8 unknown0230F[2]; u8 bootup_passwd_flag; u8 unknown0230G[7]; } settings; """ # TH9000 memory map # section: 8B Startup Label # # bytes:bit type description # --------------------------------------------------------------------------- # 7 char start_label[7] label displayed at startup (usually your call # sign) # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x03E0; struct { char startname[7]; } slabel; """ # TH9000/220 memory map # section: 9 Channel Bank # description of channel bank (200 channels , range 0-199) # Each 32 Byte (0x20 hex) record: # bytes:bit type description # --------------------------------------------------------------------------- # 4 bbcd freq[4] receive frequency in packed binary coded # decimal # 4 bbcd offset[4] transmit offset in packed binary coded decimal # (note: plus/minus direction set by 'duplex' # field) # 1 u8 # :4 unknown:4 # :4 tuning_step:4 tuning step, menu index value from 0-9 # 5,6.25,8.33,10,12.5,15,20,25,30,50 # 1 u8 # :4 unknown:4 not yet decoded, used for DCS coding? # :2 channel_width:2 channel spacing, menu index value from 0-3 # 25,20,12.5 # :1 reverse:1 reverse flag, 0=off, 1=on (reverses tx and # rx freqs) # :1 txoff:1 transmitt off flag, 0=transmit , # 1=do not transmit # 1 u8 # :1 talkaround:1 talkaround flag, 0=off, 1=on (bypasses # repeater) # :1 compander:1 compander flag, 0=off, 1=on (turns on/off # voice compander option) # :2 unknown:2 # :2 power:2 tx power setting, value range 0-2, 0=hi, # 1=med, 2=lo # :2 duplex:2 duplex settings, 0=simplex, # 2= minus(-) offset, 3= plus (+) offset # (see offset field) # # 1 u8 # :4 unknown:4 # :2 rxtmode:2 rx tone mode, value range 0-2, 0=none, # 1=CTCSS, 2=DCS (ctcss tone in field rxtone) # :2 txtmode:2 tx tone mode, value range 0-2, 0=none, # 1=CTCSS, 3=DCS (ctcss tone in field txtone) # 1 u8 # :2 unknown:2 # :6 txtone:6 tx ctcss tone, menu index # 1 u8 # :2 unknown:2 # :6 rxtone:6 rx ctcss tone, menu index # 1 u8 txcode ?, not used for ctcss # 1 u8 rxcode ?, not used for ctcss # 3 u8 unknown[3] # 7 char name[7] 7 byte char string for channel name # 1 u8 # :6 unknown:6, # :2 busychannellockout:2 busy channel lockout option , # 0=off, 1=repeater, 2=busy # (lock out tx if channel busy) # 4 u8 unknownI[4]; # 1 u8 # :7 unknown:7 # :1 scrambler:1 scrambler flag, 0=off, 1=on (turns on tyt # scrambler option) # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x2000; struct { bbcd freq[4]; bbcd offset[4]; u8 unknown2000A:4, tuning_step:4; u8 rxdcsextra:1, txdcsextra:1, rxinv:1, txinv:1, channel_width:2, reverse:1, txoff:1; u8 talkaround:1, compander:1, unknown2000C:2, power:2, duplex:2; u8 unknown2000D:4, rxtmode:2, txtmode:2; u8 unknown2000E:2, txtone:6; u8 unknown2000F:2, rxtone:6; u8 txcode; u8 rxcode; u8 unknown2000G[3]; char name[7]; u8 unknown2000H:6, busychannellockout:2; u8 unknown2000I[4]; u8 unknown2000J:7, scrambler:1; } memory[200] ; """ def _echo_write(radio, data): try: radio.pipe.write(data) radio.pipe.read(len(data)) except Exception as e: LOG.error("Error writing to radio: %s" % e) raise errors.RadioError("Unable to write to radio") def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def _read(radio, length): try: data = radio.pipe.read(length) except Exception as e: LOG.error("Error reading from radio: %s" % e) raise errors.RadioError("Unable to read from radio") if len(data) != length: LOG.error("Short read from radio (%i, expected %i)" % (len(data), length)) LOG.debug(util.hexprint(data)) raise errors.RadioError("Short read from radio") return data def _ident(radio): radio.pipe.timeout = 1 exito = False for i in range(0, 5): _echo_write(radio, b"PROGRAM") response = radio.pipe.read(3) if response == b"QX\06": exito = True break # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) _echo_write(radio, b"\x02") response = radio.pipe.read(16) LOG.debug(util.hexprint(response)) if response[1:8] != b"TH-9000": LOG.error("Looking for:\n%s" % util.hexprint("TH-9000")) LOG.error("Response was:\n%s" % util.hexprint(response)) raise errors.RadioError("Unsupported model") def _send(radio, cmd, addr, length, data=None): frame = struct.pack(">cHb", cmd, addr, length) if data: frame += data frame += bytes([_checksum(frame[1:])]) frame += b"\x06" _echo_write(radio, frame) LOG.debug("Sent:\n%s" % util.hexprint(frame)) if data: result = radio.pipe.read(1) if result != b"\x06": LOG.debug("Ack was: %s" % repr(result)) raise errors.RadioError( "Radio did not accept block at %04x" % addr) return result = _read(radio, length + 6) LOG.debug("Got:\n%s" % util.hexprint(result)) header = result[:4] data = result[4:-2] ack = result[-1:] if ack != b"\x06": LOG.debug("Ack was: %s" % repr(ack)) raise errors.RadioError("Radio NAK'd block at %04x" % addr) _cmd, _addr, _length = struct.unpack(">cHb", header) if _addr != addr or _length != _length: LOG.debug("Expected/Received:") LOG.debug(" Length: %02x/%02x" % (length, _length)) LOG.debug(" Addr: %04x/%04x" % (addr, _addr)) raise errors.RadioError("Radio send unexpected block") cs = _checksum(result[1:-2]) if cs != result[-2]: LOG.debug("Calculated: %02x" % cs) LOG.debug("Actual: %02x" % result[-2]) raise errors.RadioError("Block at 0x%04x failed checksum" % addr) return data def _finish(radio): endframe = b"\x45\x4E\x44" _echo_write(radio, endframe) result = radio.pipe.read(1) # TYT radios acknowledge the "endframe" command, Luiton radios do not. if result != b"" and result != b"\x06": LOG.error("Got:\n%s" % util.hexprint(result)) raise errors.RadioError("Radio did not finish cleanly") def do_download(radio): _ident(radio) _memobj = None data = b"" for start, end in radio._ranges: for addr in range(start, end, 0x10): block = _send(radio, b'R', addr, 0x10) data += block status = chirp_common.Status() status.cur = len(data) status.max = end status.msg = "Downloading from radio" radio.status_fn(status) _finish(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): _ident(radio) for start, end in radio._ranges: for addr in range(start, end, 0x10): if addr < 0x0100: continue block = radio._mmap[addr:addr + 0x10] _send(radio, b'W', addr, len(block), block) status = chirp_common.Status() status.cur = addr status.max = end status.msg = "Uploading to Radio" radio.status_fn(status) _finish(radio) # # The base class, extended for use with other models # class Th9000Radio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """TYT TH-9000""" VENDOR = "TYT" MODEL = "TH9000 Base" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False valid_freq = [(900000000, 999000000)] _memsize = MMAPSIZE _ranges = [(0x0000, 0x4000)] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("The TYT TH-9000 driver is an beta version." "Proceed with Caution and backup your data") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_cross = True rf.has_tuning_step = False rf.has_rx_dtcs = True rf.valid_skips = ["", "S"] rf.memory_bounds = (0, 199) rf.valid_name_length = 7 rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "-" rf.valid_modes = MODES rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ['Tone->DTCS', 'DTCS->Tone', '->Tone', '->DTCS', 'Tone->Tone'] rf.valid_power_levels = POWER_LEVELS rf.valid_tones = TONES rf.valid_dtcs_codes = chirp_common.ALL_DTCS_CODES rf.valid_bands = self.valid_freq rf.valid_tuning_steps = TUNING_STEPS return rf # Do a download of the radio from the serial port def sync_in(self): self._mmap = do_download(self) self.process_mmap() # Do an upload of the radio to the serial port def sync_out(self): do_upload(self) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # Return a raw representation of the memory object, which # is very helpful for development def get_raw_memory(self, number): return repr(self._memobj.memory[number]) # not working yet def _get_dcs_index(self, _mem, which): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) return (int(extra) << 8) | int(base) def _set_dcs_index(self, _mem, which, index): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) base.set_value(index & 0xFF) extra.set_value(index >> 8) # Extract a high-level memory object from the low-level memory map # This is called to populate a memory in the UI def get_memory(self, number): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[number] # get flag info cbyte = number // 8 cbit = 7 - (number % 8) setflag = self._memobj.csetflag[cbyte].c[cbit] skipflag = self._memobj.cskipflag[cbyte].c[cbit] mem = chirp_common.Memory() mem.number = number # Set the memory number if setflag == 1: mem.empty = True return mem mem.freq = int(_mem.freq) * 100 # compensate for 6.25 and 12.5 kHz tuning steps, add 500 Hz if needed lastdigit = int(_mem.freq) % 10 if (lastdigit == 2 or lastdigit == 7): mem.freq += 50 mem.offset = int(_mem.offset) * 100 # Set the alpha tag mem.name = self.filter_name(str(_mem.name).rstrip()) mem.duplex = DUPLEXES[_mem.duplex] mem.mode = MODES[_mem.channel_width] mem.power = POWER_LEVELS[_mem.power] rxtone = txtone = None rxmode = TMODES[_mem.rxtmode] txmode = TMODES[_mem.txtmode] # doesn't work if rxmode == "Tone": rxtone = TONES[_mem.rxtone] elif rxmode == "DTCS": rxtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index( _mem, 'rx')] if txmode == "Tone": txtone = TONES[_mem.txtone] elif txmode == "DTCS": txtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index( _mem, 'tx')] rxpol = _mem.rxinv and "R" or "N" txpol = _mem.txinv and "R" or "N" chirp_common.split_tone_decode(mem, (txmode, txtone, txpol), (rxmode, rxtone, rxpol)) mem.skip = "S" if skipflag == 1 else "" # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem # Store details about a high-level memory to the memory map # This is called when a user edits a memory in the UI def set_memory(self, mem): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number] cbyte = mem.number // 8 cbit = 7 - (mem.number % 8) if mem.empty: self._memobj.csetflag[cbyte].c[cbit] = 1 self._memobj.cskipflag[cbyte].c[cbit] = 1 return self._memobj.csetflag[cbyte].c[cbit] = 0 self._memobj.cskipflag[cbyte].c[cbit] = 1 if (mem.skip == "S") else 0 _mem.set_raw("\x00" * 32) _mem.freq = mem.freq / 100 # Convert to low-level frequency _mem.offset = mem.offset / 100 # Convert to low-level frequency _mem.name = mem.name.ljust(7)[:7] # Store the alpha tag _mem.duplex = DUPLEXES.index(mem.duplex) try: _mem.channel_width = MODES.index(mem.mode) except ValueError: _mem.channel_width = 0 ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) _mem.txtmode = TMODES.index(txmode) _mem.rxtmode = TMODES.index(rxmode) if txmode == "Tone": _mem.txtone = TONES.index(txtone) elif txmode == "DTCS": self._set_dcs_index(_mem, 'tx', chirp_common.ALL_DTCS_CODES.index(txtone)) if rxmode == "Tone": _mem.rxtone = TONES.index(rxtone) elif rxmode == "DTCS": self._set_dcs_index(_mem, 'rx', chirp_common.ALL_DTCS_CODES.index(rxtone)) _mem.txinv = txpol == "R" _mem.rxinv = rxpol == "R" if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 def _get_settings(self): _settings = self._memobj.settings _freqrange = self._memobj.freqrange _slabel = self._memobj.slabel basic = RadioSettingGroup("basic", "Global Settings") freqrange = RadioSettingGroup("freqrange", "Frequency Ranges") top = RadioSettingGroup("top", "All Settings", basic, freqrange) settings = RadioSettings(top) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += "" return filtered val = RadioSettingValueString(0, 7, _filter(_slabel.startname)) rs = RadioSetting("startname", "Startup Label", val) basic.append(rs) rs = RadioSetting("bg_color", "LCD Color", RadioSettingValueList(BGCOLOR_LIST, BGCOLOR_LIST[ _settings.bg_color])) basic.append(rs) rs = RadioSetting("bg_brightness", "LCD Brightness", RadioSettingValueList(BGBRIGHT_LIST, BGBRIGHT_LIST[ _settings.bg_brightness])) basic.append(rs) rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueList(SQUELCH_LIST, SQUELCH_LIST[ _settings.squelch])) basic.append(rs) rs = RadioSetting("timeout_timer", "Timeout Timer (TOT)", RadioSettingValueList(TIMEOUT_LIST, TIMEOUT_LIST[ _settings.timeout_timer])) basic.append(rs) rs = RadioSetting("auto_power_off", "Auto Power Off (APO)", RadioSettingValueList(APO_LIST, APO_LIST[ _settings.auto_power_off])) basic.append(rs) rs = RadioSetting("voice_prompt", "Beep Prompt", RadioSettingValueList(BEEP_LIST, BEEP_LIST[ _settings.voice_prompt])) basic.append(rs) rs = RadioSetting("tbst_freq", "Tone Burst Frequency", RadioSettingValueList(TBSTFREQ_LIST, TBSTFREQ_LIST[ _settings.tbst_freq])) basic.append(rs) rs = RadioSetting("choose_tx_power", "Max Level of TX Power", RadioSettingValueList(TXPWR_LIST, TXPWR_LIST[ _settings.choose_tx_power])) basic.append(rs) (flow, fhigh) = self.valid_freq[0] flow /= 1000 fhigh /= 1000 fmidrange = (fhigh - flow) / 2 rs = RadioSetting("txrangelow", "TX Freq, Lower Limit (kHz)", RadioSettingValueInteger( flow, flow + fmidrange, int(_freqrange.txrangelow) / 10)) freqrange.append(rs) rs = RadioSetting("txrangehi", "TX Freq, Upper Limit (kHz)", RadioSettingValueInteger( fhigh-fmidrange, fhigh, int(_freqrange.txrangehi) / 10)) freqrange.append(rs) rs = RadioSetting("rxrangelow", "RX Freq, Lower Limit (kHz)", RadioSettingValueInteger( flow, flow+fmidrange, int(_freqrange.rxrangelow) / 10)) freqrange.append(rs) rs = RadioSetting("rxrangehi", "RX Freq, Upper Limit (kHz)", RadioSettingValueInteger( fhigh-fmidrange, fhigh, int(_freqrange.rxrangehi) / 10)) freqrange.append(rs) return settings def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("failed to parse settings") traceback.print_exc() return None def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if name in ["txrangelow", "txrangehi", "rxrangelow", "rxrangehi"]: LOG.debug("setting %s = %s" % (name, int(element.value) * 10)) setattr(self._memobj.freqrange, name, int(element.value) * 10) continue if name in ["startname"]: LOG.debug("setting %s = %s" % (name, element.value)) setattr(self._memobj.slabel, name, element.value) continue obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): return False def match_orig_model(cls, filedata, filename): # This old-style file detection should only be used for the # original TYT TH9000 classes for compatibility if cls.VENDOR != 'TYT' or 'TH9000_' not in cls.MODEL: return False if MMAPSIZE == len(filedata): (flow, fhigh) = cls.valid_freq[0] flow /= 1000000 fhigh /= 1000000 txmin = filedata[0x200] * 100 + (filedata[0x201] >> 4) \ * 10 + filedata[0x201] % 16 txmax = filedata[0x204] * 100 + (filedata[0x205] >> 4) \ * 10 + filedata[0x205] % 16 rxmin = filedata[0x208] * 100 + (filedata[0x209] >> 4) \ * 10 + filedata[0x209] % 16 rxmax = filedata[0x20C] * 100 + (filedata[0x20D] >> 4) \ * 10 + filedata[0x20D] % 16 if (rxmin >= flow and rxmax <= fhigh and txmin >= flow and txmax <= fhigh): return True return False @directory.register class Th9000220Radio(Th9000Radio): """TYT TH-9000 220""" VENDOR = "TYT" MODEL = "TH9000_220" BAUD_RATE = 9600 valid_freq = [(220000000, 260000000)] @classmethod def match_model(cls, filedata, filename): return match_orig_model(cls, filedata, filename) @directory.register class Th9000144Radio(Th9000220Radio): """TYT TH-9000 144""" VENDOR = "TYT" MODEL = "TH9000_144" BAUD_RATE = 9600 valid_freq = [(136000000, 174000000)] @classmethod def match_model(cls, filedata, filename): return match_orig_model(cls, filedata, filename) @directory.register class Th9000440Radio(Th9000220Radio): """TYT TH-9000 440""" VENDOR = "TYT" MODEL = "TH9000_440" BAUD_RATE = 9600 valid_freq = [(400000000, 490000000)] @classmethod def match_model(cls, filedata, filename): return match_orig_model(cls, filedata, filename) @directory.register class Lt580VHFRadio(Th9000144Radio): """Luiton LT-580 VHF""" VENDOR = "LUITON" MODEL = "LT-580_VHF" @directory.register class Lt580UHFRadio(Th9000440Radio): """Luiton LT-580 UHF""" VENDOR = "LUITON" MODEL = "LT-580_UHF" @directory.register class RT9000DVHFRadio(Th9000Radio): """Retevis RT9000D VHF""" VENDOR = "Retevis" MODEL = "RT9000D_136-174" valid_freq = [(136000000, 174000000)] @directory.register class RT9000D220Radio(Th9000Radio): """Retevis RT9000D 220""" VENDOR = "Retevis" MODEL = "RT9000D_220-260" valid_freq = [(220000000, 260000000)] @directory.register class RT9000DUHFRadio(Th9000Radio): """Retevis RT9000D UHF""" VENDOR = "Retevis" MODEL = "RT9000D_400-490" valid_freq = [(400000000, 490000000)] @directory.register class RT9000D6688Radio(Th9000Radio): """Retevis RT9000D 66-88""" VENDOR = "Retevis" MODEL = "RT9000D_66-88" valid_freq = [(66000000, 88000000)] chirp-20240224/chirp/drivers/uv5x3.py0000644000175000017500000013231314557410440016172 0ustar hibbyhibby# Copyright 2016: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings, \ InvalidValueError LOG = logging.getLogger(__name__) # #### MAGICS ######################################################### # BTECH UV-5X3 magic string MSTRING_UV5X3 = b"\x50\x0D\x0C\x20\x16\x03\x28" # MTC UV-5R-3 magic string MSTRING_UV5R3 = b"\x50\x0D\x0C\x20\x17\x09\x19" # #### ID strings ##################################################### # BTECH UV-5X3 UV5X3_fp1 = b"UVVG302" # BFB300 original UV5X3_fp2 = b"UVVG301" # UVV300 original UV5X3_fp3 = b"UVVG306" # UVV306 original # MTC UV-5R-3 UV5R3_fp1 = b"5R31709" DTMF_CHARS = " 1234567890*#ABCD" STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] LIST_AB = ["A", "B"] LIST_ALMOD = ["Site", "Tone", "Code"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_COLOR = ["Off", "Blue", "Orange", "Purple"] LIST_DELAYPROCTIME = ["%s ms" % x for x in range(100, 4100, 100)] LIST_DTMFSPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_DTMFST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] LIST_MODE = ["Channel", "Name", "Frequency"] LIST_OFF1TO9 = ["Off"] + list("123456789") LIST_OFF1TO10 = LIST_OFF1TO9 + ["10"] LIST_OFFAB = ["Off"] + LIST_AB LIST_RESETTIME = ["%s ms" % x for x in range(100, 16100, 100)] LIST_RESUME = ["TO", "CO", "SE"] LIST_PONMSG = ["Full", "Message"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_SCODE = ["%s" % x for x in range(1, 16)] LIST_RPSTE = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SHIFTD = ["Off", "+", "-"] LIST_STEDELAY = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] LIST_STEP = [str(x) for x in STEPS] LIST_TIMEOUT = ["%s sec" % x for x in range(15, 615, 15)] LIST_TXPOWER = ["High", "Low"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_WORKMODE = ["Frequency", "Channel"] LIST_DTMF_SPECIAL_DIGITS = ["*", "#", "A", "B", "C", "D"] LIST_DTMF_SPECIAL_VALUES = [0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00] def model_match(cls, data): """Match the opened/downloaded image to the correct version""" match_rid1 = False match_rid2 = False rid1 = data[0x1EF0:0x1EF7] if rid1 in cls._fileid: match_rid1 = True if match_rid1: return True else: return False @directory.register class UV5X3(bfc.BaofengCommonHT): """BTech UV-5X3""" VENDOR = "BTECH" MODEL = "UV-5X3" NEEDS_COMPAT_SERIAL = False _fileid = [UV5X3_fp3, UV5X3_fp2, UV5X3_fp1] _magic = [MSTRING_UV5X3, ] _magic_response_length = 14 _fw_ver_start = 0x1EF0 _recv_block_size = 0x40 _mem_size = 0x2000 _ack_block = True _ranges = [(0x0000, 0x0DF0), (0x0E00, 0x1800), (0x1E00, 0x1E70), (0x1EE0, 0x1EF0), (0x1F60, 0x1F70), (0x1F80, 0x1F90), (0x1FA0, 0x1FB0), (0x1FE0, 0x2000)] _send_block_size = 0x10 MODES = ["FM", "NFM"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" LENGTH_NAME = 7 SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] VALID_BANDS = [(130000000, 180000000), (220000000, 226000000), (400000000, 521000000)] PTTID_LIST = LIST_PTTID SCODE_LIST = LIST_SCODE MEM_FORMAT = """ #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1; u8 unknown2:7, lowpower:1; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[128]; #seekto 0x0B00; struct { u8 code[16]; } pttid[15]; #seekto 0x0C80; struct { u8 inspection[8]; u8 monitor[8]; u8 alarmcode[8]; u8 stun[8]; u8 kill[8]; u8 revive[8]; u8 code[7]; u8 unknown06; u8 dtmfon; u8 dtmfoff; u8 unused00:6, aniid:2; u8 unknown07[5]; u8 masterid[5]; u8 unknown08[3]; u8 viceid[5]; u8 unknown09[3]; u8 unused01:7, mastervice:1; u8 unused02:3, mrevive:1, mkill:1, mstun:1, mmonitor:1, minspection:1; u8 unused03:3, vrevive:1, vkill:1, vstun:1, vmonitor:1, vinspection:1; u8 unused04:6, txdisable:1, rxdisable:1; u8 groupcode; u8 spacecode; u8 delayproctime; u8 resettime; } ani; #seekto 0x0E20; struct { u8 unused00:4, squelch:4; u8 unused01:5, step:3; u8 unknown00; u8 unused02:5, save:3; u8 unused03:4, vox:4; u8 unknown01; u8 unused04:4, abr:4; u8 unused05:7, tdr:1; u8 unused06:7, beep:1; u8 unused07:2, timeout:6; u8 unknown02[4]; u8 unused09:6, voice:2; u8 unknown03; u8 unused10:6, dtmfst:2; u8 unknown04; u8 unused11:6, screv:2; u8 unused12:6, pttid:2; u8 unused13:2, pttlt:6; u8 unused14:6, mdfa:2; u8 unused15:6, mdfb:2; u8 unknown05; u8 unused16:7, sync:1; u8 unknown06[4]; u8 unused17:6, wtled:2; u8 unused18:6, rxled:2; u8 unused19:6, txled:2; u8 unused20:6, almod:2; u8 unknown07; u8 unused21:6, tdrab:2; u8 unused22:7, ste:1; u8 unused23:4, rpste:4; u8 unused24:4, rptrl:4; u8 unused25:7, ponmsg:1; u8 unused26:7, roger:1; u8 unused27:7, dani:1; u8 unused28:2, dtmfg:6; u8 unknown08:7, unknown09:1; u8 unknown10[3]; u8 cht; u8 unknown11[13]; u8 displayab:1, unknown12:2, fmradio:1, alarm:1, unknown13:1, reset:1, menu:1; u8 unknown14; u8 unused29:7, workmode:1; u8 unused30:7, keylock:1; } settings; #seekto 0x0E76; struct { u8 unused0:1, mrcha:7; u8 unused1:1, mrchb:7; } wmchannel; struct vfo { u8 unknown0[8]; u8 freq[8]; u8 offset[6]; ul16 rxtone; ul16 txtone; u8 unused0:7, band:1; u8 unknown3; u8 unknown4:2, sftd:2, scode:4; u8 unknown5; u8 unknown6:1, step:3, unknown7:4; u8 txpower:1, widenarr:1, unknown8:6; }; #seekto 0x0F00; struct { struct vfo a; struct vfo b; } vfo; #seekto 0x0F4E; u16 fm_presets; #seekto 0x1000; struct { char name[7]; u8 unknown[9]; } names[128]; struct subvfo { u8 freq[8]; u8 unknown0[8]; }; #seekto 0x1E00; struct { struct subvfo vhf; struct subvfo vhf2; struct subvfo uhf; } subvfoa; #seekto 0x1E40; struct { struct subvfo vhf; struct subvfo vhf2; struct subvfo uhf; } subvfob; #seekto 0x1ED0; struct { char line1[7]; char line2[7]; } sixpoweron_msg; #seekto 0x1EF0; struct { char line1[7]; char line2[7]; } firmware_msg; struct squelch { u8 sql0; u8 sql1; u8 sql2; u8 sql3; u8 sql4; u8 sql5; u8 sql6; u8 sql7; u8 sql8; u8 sql9; }; #seekto 0x1F60; struct { struct squelch vhf; u8 unknown0[6]; u8 unknown1[16]; struct squelch vhf2; u8 unknown2[6]; u8 unknown3[16]; struct squelch uhf; } squelch; #seekto 0x1FE0; struct { char line1[7]; char line2[7]; } poweron_msg; struct limit { u8 enable; bbcd lower[2]; bbcd upper[2]; }; #seekto 0x1FF0; struct { struct limit vhf; struct limit vhf2; struct limit uhf; } limits; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") fm_preset = RadioSettingGroup("fm_preset", "FM Preset") dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") dtmfd = RadioSettingGroup("dtmfd", "DTMF Decode Settings") service = RadioSettingGroup("service", "Service Settings") top = RadioSettings(basic, advanced, other, work, fm_preset, dtmfe, dtmfd, service) # Basic settings if _mem.settings.squelch > 0x09: val = 0x00 else: val = _mem.settings.squelch rs = RadioSetting("settings.squelch", "Squelch", RadioSettingValueList( LIST_OFF1TO9, LIST_OFF1TO9[val])) basic.append(rs) if _mem.settings.save > 0x04: val = 0x00 else: val = _mem.settings.save rs = RadioSetting("settings.save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) if _mem.settings.vox > 0x0A: val = 0x00 else: val = _mem.settings.vox rs = RadioSetting("settings.vox", "Vox", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) if _mem.settings.abr > 0x0A: val = 0x00 else: val = _mem.settings.abr rs = RadioSetting("settings.abr", "Backlight Timeout", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) rs = RadioSetting("settings.tdr", "Dual Watch", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean(_mem.settings.beep)) basic.append(rs) if _mem.settings.timeout > 0x27: val = 0x03 else: val = _mem.settings.timeout rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( LIST_TIMEOUT, LIST_TIMEOUT[val])) basic.append(rs) if _mem.settings.voice > 0x02: val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) if _mem.settings.screv > 0x02: val = 0x01 else: val = _mem.settings.screv rs = RadioSetting("settings.screv", "Scan Resume", RadioSettingValueList( LIST_RESUME, LIST_RESUME[val])) basic.append(rs) rs = RadioSetting("settings.pttid", "When to send PTT ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[ _mem.settings.pttid])) basic.append(rs) if _mem.settings.pttlt > 0x1E: val = 0x05 else: val = _mem.settings.pttlt rs = RadioSetting("pttlt", "PTT ID Delay", RadioSettingValueInteger(0, 50, val)) basic.append(rs) rs = RadioSetting("settings.mdfa", "Display Mode (A)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfa])) basic.append(rs) rs = RadioSetting("settings.mdfb", "Display Mode (B)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfb])) basic.append(rs) rs = RadioSetting("settings.sync", "Sync A & B", RadioSettingValueBoolean(_mem.settings.sync)) basic.append(rs) rs = RadioSetting("settings.wtled", "Standby LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.wtled])) basic.append(rs) rs = RadioSetting("settings.rxled", "RX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.rxled])) basic.append(rs) rs = RadioSetting("settings.txled", "TX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.txled])) basic.append(rs) if _mem.settings.almod > 0x02: val = 0x00 else: val = _mem.settings.almod rs = RadioSetting("settings.almod", "Alarm Mode", RadioSettingValueList( LIST_ALMOD, LIST_ALMOD[val])) basic.append(rs) if _mem.settings.tdrab > 0x02: val = 0x00 else: val = _mem.settings.tdrab rs = RadioSetting("settings.tdrab", "Dual Watch TX Priority", RadioSettingValueList( LIST_OFFAB, LIST_OFFAB[val])) basic.append(rs) rs = RadioSetting("settings.ste", "Squelch Tail Eliminate (HT to HT)", RadioSettingValueBoolean(_mem.settings.ste)) basic.append(rs) if _mem.settings.rpste > 0x0A: val = 0x00 else: val = _mem.settings.rpste rs = RadioSetting("settings.rpste", "Squelch Tail Eliminate (repeater)", RadioSettingValueList( LIST_RPSTE, LIST_RPSTE[val])) basic.append(rs) if _mem.settings.rptrl > 0x0A: val = 0x00 else: val = _mem.settings.rptrl rs = RadioSetting("settings.rptrl", "STE Repeater Delay", RadioSettingValueList( LIST_STEDELAY, LIST_STEDELAY[val])) basic.append(rs) rs = RadioSetting("settings.ponmsg", "Power-On Message", RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[ _mem.settings.ponmsg])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger Beep", RadioSettingValueBoolean(_mem.settings.roger)) basic.append(rs) rs = RadioSetting("settings.dani", "Decode ANI", RadioSettingValueBoolean(_mem.settings.dani)) basic.append(rs) if _mem.settings.dtmfg > 0x3C: val = 0x14 else: val = _mem.settings.dtmfg rs = RadioSetting("settings.dtmfg", "DTMF Gain", RadioSettingValueInteger(0, 60, val)) basic.append(rs) # Advanced settings rs = RadioSetting("settings.reset", "RESET Menu", RadioSettingValueBoolean(_mem.settings.reset)) advanced.append(rs) rs = RadioSetting("settings.menu", "All Menus", RadioSettingValueBoolean(_mem.settings.menu)) advanced.append(rs) rs = RadioSetting("settings.fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_mem.settings.fmradio)) advanced.append(rs) rs = RadioSetting("settings.alarm", "Alarm Sound", RadioSettingValueBoolean(_mem.settings.alarm)) advanced.append(rs) # Other settings def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = _mem.firmware_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val) other.append(rs) _msg = _mem.sixpoweron_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2", val) other.append(rs) _msg = _mem.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 7, _filter(_msg.line2))) other.append(rs) if str(_mem.firmware_msg.line1) == ("UVVG302" or "5R31709"): lower = 136 upper = 174 else: lower = 130 upper = 179 if int(_mem.limits.vhf.lower) < lower: val = lower else: val = int(_mem.limits.vhf.lower) rs = RadioSetting("limits.vhf.lower", "VHF Lower Limit (MHz)", RadioSettingValueInteger(lower, upper, val)) other.append(rs) if int(_mem.limits.vhf.upper) > upper: val = upper else: val = int(_mem.limits.vhf.upper) rs = RadioSetting("limits.vhf.upper", "VHF Upper Limit (MHz)", RadioSettingValueInteger(lower, upper, val)) other.append(rs) if str(_mem.firmware_msg.line1) == "UVVG302": lower = 200 upper = 230 elif str(_mem.firmware_msg.line1) == "5R31709": lower = 200 upper = 260 else: lower = 220 upper = 225 if int(_mem.limits.vhf2.lower) < lower: val = lower else: val = int(_mem.limits.vhf2.lower) rs = RadioSetting("limits.vhf2.lower", "VHF2 Lower Limit (MHz)", RadioSettingValueInteger(lower, upper, val)) other.append(rs) if int(_mem.limits.vhf2.upper) > upper: val = upper else: val = int(_mem.limits.vhf2.upper) rs = RadioSetting("limits.vhf2.upper", "VHF2 Upper Limit (MHz)", RadioSettingValueInteger(lower, upper, val)) other.append(rs) if str(_mem.firmware_msg.line1) == "UVVG302": lower = 400 upper = 480 else: lower = 400 upper = 520 if int(_mem.limits.uhf.lower) < lower: val = lower else: val = int(_mem.limits.uhf.lower) rs = RadioSetting("limits.uhf.lower", "UHF Lower Limit (MHz)", RadioSettingValueInteger(lower, upper, val)) other.append(rs) if int(_mem.limits.uhf.upper) > upper: val = upper else: val = int(_mem.limits.uhf.upper) rs = RadioSetting("limits.uhf.upper", "UHF Upper Limit (MHz)", RadioSettingValueInteger(lower, upper, val)) other.append(rs) # Work mode settings rs = RadioSetting("settings.displayab", "Display", RadioSettingValueList( LIST_AB, LIST_AB[_mem.settings.displayab])) work.append(rs) rs = RadioSetting("settings.workmode", "VFO/MR Mode", RadioSettingValueList( LIST_WORKMODE, LIST_WORKMODE[_mem.settings.workmode])) work.append(rs) rs = RadioSetting("settings.keylock", "Keypad Lock", RadioSettingValueBoolean(_mem.settings.keylock)) work.append(rs) rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrcha)) work.append(rs) rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrchb)) work.append(rs) def my_validate(value): _vhf_lower = int(_mem.limits.vhf.lower) _vhf_upper = int(_mem.limits.vhf.upper) _vhf2_lower = int(_mem.limits.vhf2.lower) _vhf2_upper = int(_mem.limits.vhf2.upper) _uhf_lower = int(_mem.limits.uhf.lower) _uhf_upper = int(_mem.limits.uhf.upper) value = chirp_common.parse_freq(value) msg = ("Can't be less than %i.0000") if value > 99000000 and value < _vhf_lower * 1000000: raise InvalidValueError(msg % (_vhf_lower)) msg = ("Can't be between %i.9975-%i.0000") if (_vhf_upper + 1) * 1000000 <= value and \ value < _vhf2_lower * 1000000: raise InvalidValueError(msg % (_vhf_upper, _vhf2_lower)) if (_vhf2_upper + 1) * 1000000 <= value and \ value < _uhf_lower * 1000000: raise InvalidValueError(msg % (_vhf2_upper, _uhf_lower)) msg = ("Can't be greater than %i.9975") if value > 99000000 and value >= (_uhf_upper + 1) * 1000000: raise InvalidValueError(msg % (_uhf_upper)) return chirp_common.format_freq(value) def my_vhf_validate(value): _vhf_lower = int(_mem.limits.vhf.lower) _vhf_upper = int(_mem.limits.vhf.upper) value = chirp_common.parse_freq(value) msg = ("Must be between %i.0000-%i.9975") if (_vhf_upper + 1) * 1000000 <= value or \ value < _vhf_lower * 1000000: raise InvalidValueError(msg % (_vhf_lower, _vhf_upper)) return chirp_common.format_freq(value) def my_vhf2_validate(value): _vhf2_lower = int(_mem.limits.vhf2.lower) _vhf2_upper = int(_mem.limits.vhf2.upper) value = chirp_common.parse_freq(value) msg = ("Must be between %i.0000-%i.9975") if (_vhf2_upper + 1) * 1000000 <= value or \ value < _vhf2_lower * 1000000: raise InvalidValueError(msg % (_vhf2_lower, _vhf2_upper)) return chirp_common.format_freq(value) def my_uhf_validate(value): _uhf_lower = int(_mem.limits.uhf.lower) _uhf_upper = int(_mem.limits.uhf.upper) value = chirp_common.parse_freq(value) msg = ("Must be between %i.0000-%i.9975") if (_uhf_upper + 1) * 1000000 <= value or \ value < _uhf_lower * 1000000: raise InvalidValueError(msg % (_uhf_lower, _uhf_upper)) return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq( _mem.vfo.a.freq)) val1a.set_validate_callback(my_validate) rs = RadioSetting("vfo.a.freq", "VFO A Frequency", val1a) rs.set_apply_callback(apply_freq, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString(0, 10, bfc.bcd_decode_freq( _mem.vfo.b.freq)) val1b.set_validate_callback(my_validate) rs = RadioSetting("vfo.b.freq", "VFO B Frequency", val1b) rs.set_apply_callback(apply_freq, _mem.vfo.b) work.append(rs) val = bfc.bcd_decode_freq(_mem.subvfoa.vhf.freq) if int(float(val)) == 0: val = str(int(_mem.limits.vhf.lower)) + ".000000" val1a = RadioSettingValueString(0, 10, val) val1a.set_validate_callback(my_vhf_validate) rs = RadioSetting("subvfoa.vhf.freq", "VFO A VHF (Saved)", val1a) rs.set_apply_callback(apply_freq, _mem.subvfoa.vhf) work.append(rs) val = bfc.bcd_decode_freq(_mem.subvfob.vhf.freq) if int(float(val)) == 0: val = str(int(_mem.limits.vhf.lower)) + ".000000" val1b = RadioSettingValueString(0, 10, val) val1b.set_validate_callback(my_vhf_validate) rs = RadioSetting("subvfob.vhf.freq", "VFO B VHF (Saved)", val1b) rs.set_apply_callback(apply_freq, _mem.subvfob.vhf) work.append(rs) val = bfc.bcd_decode_freq(_mem.subvfoa.vhf2.freq) if int(float(val)) == 0: val = str(int(_mem.limits.vhf2.lower)) + ".000000" val1a = RadioSettingValueString(0, 10, val) val1a.set_validate_callback(my_vhf2_validate) rs = RadioSetting("subvfoa.vhf2.freq", "VFO A VHF2 (Saved)", val1a) rs.set_apply_callback(apply_freq, _mem.subvfoa.vhf2) work.append(rs) val = bfc.bcd_decode_freq(_mem.subvfob.vhf2.freq) if int(float(val)) == 0: val = str(int(_mem.limits.vhf2.lower)) + ".000000" val1b = RadioSettingValueString(0, 10, val) val1b.set_validate_callback(my_vhf2_validate) rs = RadioSetting("subvfob.vhf2.freq", "VFO B VHF2 (Saved)", val1b) rs.set_apply_callback(apply_freq, _mem.subvfob.vhf2) work.append(rs) val = bfc.bcd_decode_freq(_mem.subvfoa.uhf.freq) if int(float(val)) == 0: val = str(int(_mem.limits.uhf.lower)) + ".000000" val1a = RadioSettingValueString(0, 10, val) val1a.set_validate_callback(my_uhf_validate) rs = RadioSetting("subvfoa.uhf.freq", "VFO A UHF (Saved)", val1a) rs.set_apply_callback(apply_freq, _mem.subvfoa.uhf) work.append(rs) val = bfc.bcd_decode_freq(_mem.subvfob.uhf.freq) if int(float(val)) == 0: val = str(int(_mem.limits.uhf.lower)) + ".000000" val1b = RadioSettingValueString(0, 10, val) val1b.set_validate_callback(my_uhf_validate) rs = RadioSetting("subvfob.uhf.freq", "VFO B UHF (Saved)", val1b) rs.set_apply_callback(apply_freq, _mem.subvfob.uhf) work.append(rs) rs = RadioSetting("vfo.a.sftd", "VFO A Shift", RadioSettingValueList( LIST_SHIFTD, LIST_SHIFTD[_mem.vfo.a.sftd])) work.append(rs) rs = RadioSetting("vfo.b.sftd", "VFO B Shift", RadioSettingValueList( LIST_SHIFTD, LIST_SHIFTD[_mem.vfo.b.sftd])) work.append(rs) def convert_bytes_to_offset(bytes): real_offset = 0 for byte in bytes: real_offset = (real_offset * 10) + byte return chirp_common.format_freq(real_offset * 1000) def apply_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 1000 for i in range(5, -1, -1): obj.offset[i] = value % 10 value /= 10 val1a = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.a.offset)) rs = RadioSetting("vfo.a.offset", "VFO A Offset", val1a) rs.set_apply_callback(apply_offset, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.b.offset)) rs = RadioSetting("vfo.b.offset", "VFO B Offset", val1b) rs.set_apply_callback(apply_offset, _mem.vfo.b) work.append(rs) rs = RadioSetting("vfo.a.txpower", "VFO A Power", RadioSettingValueList( LIST_TXPOWER, LIST_TXPOWER[_mem.vfo.a.txpower])) work.append(rs) rs = RadioSetting("vfo.b.txpower", "VFO B Power", RadioSettingValueList( LIST_TXPOWER, LIST_TXPOWER[_mem.vfo.b.txpower])) work.append(rs) rs = RadioSetting("vfo.a.widenarr", "VFO A Bandwidth", RadioSettingValueList( LIST_BANDWIDTH, LIST_BANDWIDTH[_mem.vfo.a.widenarr])) work.append(rs) rs = RadioSetting("vfo.b.widenarr", "VFO B Bandwidth", RadioSettingValueList( LIST_BANDWIDTH, LIST_BANDWIDTH[_mem.vfo.b.widenarr])) work.append(rs) rs = RadioSetting("vfo.a.scode", "VFO A S-CODE", RadioSettingValueList( LIST_SCODE, LIST_SCODE[_mem.vfo.a.scode])) work.append(rs) rs = RadioSetting("vfo.b.scode", "VFO B S-CODE", RadioSettingValueList( LIST_SCODE, LIST_SCODE[_mem.vfo.b.scode])) work.append(rs) rs = RadioSetting("vfo.a.step", "VFO A Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.a.step])) work.append(rs) rs = RadioSetting("vfo.b.step", "VFO B Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.b.step])) work.append(rs) # broadcast FM settings _fm_presets = self._memobj.fm_presets if _fm_presets <= 108.0 * 10 - 650: preset = _fm_presets / 10.0 + 65 elif _fm_presets >= 65.0 * 10 and _fm_presets <= 108.0 * 10: preset = _fm_presets / 10.0 else: preset = 76.0 rs = RadioSetting("fm_presets", "FM Preset(MHz)", RadioSettingValueFloat(65, 108.0, preset, 0.1, 1)) fm_preset.append(rs) # DTMF encode settings for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 16, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) def apply_code(setting, obj): code = [] for j in range(0, 16): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.pttid[i]) dtmfe.append(rs) if _mem.ani.dtmfon > 0xC3: val = 0x03 else: val = _mem.ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if _mem.ani.dtmfoff > 0xC3: val = 0x03 else: val = _mem.ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) _codeobj = self._memobj.ani.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 7, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.code", "ANI Code", val) def apply_code(setting, obj): code = [] for j in range(0, 7): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfe.append(rs) rs = RadioSetting("ani.aniid", "When to send ANI ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[_mem.ani.aniid])) dtmfe.append(rs) # DTMF decode settings rs = RadioSetting("ani.mastervice", "Master and Vice ID", RadioSettingValueBoolean(_mem.ani.mastervice)) dtmfd.append(rs) _codeobj = _mem.ani.masterid _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.masterid", "Master Control ID", val) def apply_code(setting, obj): code = [] for j in range(0, 5): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.masterid = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) rs = RadioSetting("ani.minspection", "Master Inspection", RadioSettingValueBoolean(_mem.ani.minspection)) dtmfd.append(rs) rs = RadioSetting("ani.mmonitor", "Master Monitor", RadioSettingValueBoolean(_mem.ani.mmonitor)) dtmfd.append(rs) rs = RadioSetting("ani.mstun", "Master Stun", RadioSettingValueBoolean(_mem.ani.mstun)) dtmfd.append(rs) rs = RadioSetting("ani.mkill", "Master Kill", RadioSettingValueBoolean(_mem.ani.mkill)) dtmfd.append(rs) rs = RadioSetting("ani.mrevive", "Master Revive", RadioSettingValueBoolean(_mem.ani.mrevive)) dtmfd.append(rs) _codeobj = _mem.ani.viceid _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.viceid", "Vice Control ID", val) def apply_code(setting, obj): code = [] for j in range(0, 5): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.viceid = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) rs = RadioSetting("ani.vinspection", "Vice Inspection", RadioSettingValueBoolean(_mem.ani.vinspection)) dtmfd.append(rs) rs = RadioSetting("ani.vmonitor", "Vice Monitor", RadioSettingValueBoolean(_mem.ani.vmonitor)) dtmfd.append(rs) rs = RadioSetting("ani.vstun", "Vice Stun", RadioSettingValueBoolean(_mem.ani.vstun)) dtmfd.append(rs) rs = RadioSetting("ani.vkill", "Vice Kill", RadioSettingValueBoolean(_mem.ani.vkill)) dtmfd.append(rs) rs = RadioSetting("ani.vrevive", "Vice Revive", RadioSettingValueBoolean(_mem.ani.vrevive)) dtmfd.append(rs) _codeobj = _mem.ani.inspection _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 8, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.inspection", "Inspection Code", val) def apply_code(setting, obj): code = [] for j in range(0, 8): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.inspection = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) _codeobj = _mem.ani.monitor _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 8, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.monitor", "Monitor Code", val) def apply_code(setting, obj): code = [] for j in range(0, 8): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.monitor = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) _codeobj = _mem.ani.alarmcode _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 8, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.alarm", "Alarm Code", val) def apply_code(setting, obj): code = [] for j in range(0, 8): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.alarmcode = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) _codeobj = _mem.ani.stun _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 8, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.stun", "Stun Code", val) def apply_code(setting, obj): code = [] for j in range(0, 8): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.stun = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) _codeobj = _mem.ani.kill _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 8, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.kill", "Kill Code", val) def apply_code(setting, obj): code = [] for j in range(0, 8): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.kill = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) _codeobj = _mem.ani.revive _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 8, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.revive", "Revive Code", val) def apply_code(setting, obj): code = [] for j in range(0, 8): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.revive = code rs.set_apply_callback(apply_code, self._memobj.ani) dtmfd.append(rs) def apply_dmtf_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = LIST_DTMF_SPECIAL_DIGITS.index(val) val = LIST_DTMF_SPECIAL_VALUES[index] obj.set_value(val) if _mem.ani.groupcode in LIST_DTMF_SPECIAL_VALUES: idx = LIST_DTMF_SPECIAL_VALUES.index(_mem.ani.groupcode) else: idx = LIST_DTMF_SPECIAL_VALUES.index(0x0B) rs = RadioSetting("ani.groupcode", "Group Code", RadioSettingValueList(LIST_DTMF_SPECIAL_DIGITS, LIST_DTMF_SPECIAL_DIGITS[idx])) rs.set_apply_callback(apply_dmtf_listvalue, _mem.ani.groupcode) dtmfd.append(rs) if _mem.ani.spacecode in LIST_DTMF_SPECIAL_VALUES: idx = LIST_DTMF_SPECIAL_VALUES.index(_mem.ani.spacecode) else: idx = LIST_DTMF_SPECIAL_VALUES.index(0x0C) rs = RadioSetting("ani.spacecode", "Space Code", RadioSettingValueList(LIST_DTMF_SPECIAL_DIGITS, LIST_DTMF_SPECIAL_DIGITS[idx])) rs.set_apply_callback(apply_dmtf_listvalue, _mem.ani.spacecode) dtmfd.append(rs) if _mem.ani.resettime > 0x9F: val = 0x4F else: val = _mem.ani.resettime rs = RadioSetting("ani.resettime", "Reset Time", RadioSettingValueList(LIST_RESETTIME, LIST_RESETTIME[val])) dtmfd.append(rs) if _mem.ani.delayproctime > 0x27: val = 0x04 else: val = _mem.ani.delayproctime rs = RadioSetting("ani.delayproctime", "Delay Processing Time", RadioSettingValueList(LIST_DELAYPROCTIME, LIST_DELAYPROCTIME[val])) dtmfd.append(rs) # Service settings for band in ["vhf", "vhf2", "uhf"]: for index in range(0, 10): key = "squelch.%s.sql%i" % (band, index) if band == "vhf": _obj = self._memobj.squelch.vhf _name = "VHF" elif band == "vhf2": _obj = self._memobj.squelch.vhf2 _name = "220" elif band == "uhf": _obj = self._memobj.squelch.uhf _name = "UHF" val = RadioSettingValueInteger(0, 123, getattr(_obj, "sql%i" % ( index))) if index == 0: val.set_mutable(False) name = "%s Squelch %i" % (_name, index) rs = RadioSetting(key, name, val) service.append(rs) return top @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == 0x200E: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False @directory.register class MTCUV5R3Radio(UV5X3): VENDOR = "MTC" MODEL = "UV-5R-3" _fileid = [UV5R3_fp1, ] _magic = [MSTRING_UV5R3, ] VALID_BANDS = [(136000000, 174000000), (200000000, 260000000), (400000000, 521000000)] chirp-20240224/chirp/drivers/ic9x.py0000644000175000017500000003364514446523722016071 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import threading import logging import uuid from chirp.drivers import ic9x_ll, icf from chirp import chirp_common, errors, util, directory from chirp import bitwise LOG = logging.getLogger(__name__) IC9XA_SPECIAL = {} IC9XB_SPECIAL = {} for i in range(0, 25): idA = "%iA" % i idB = "%iB" % i Anum = 800 + i * 2 Bnum = 400 + i * 2 IC9XA_SPECIAL[idA] = Anum IC9XA_SPECIAL[idB] = Bnum IC9XB_SPECIAL[idA] = Bnum IC9XB_SPECIAL[idB] = Bnum + 1 IC9XA_SPECIAL["C0"] = IC9XB_SPECIAL["C0"] = -1 IC9XA_SPECIAL["C1"] = IC9XB_SPECIAL["C1"] = -2 IC9X_SPECIAL = { 0: {}, 1: IC9XA_SPECIAL, 2: IC9XB_SPECIAL, } CHARSET = chirp_common.CHARSET_ALPHANUMERIC + \ "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" class Lock: """Maintains the state of an ic9x This makes sure that only one RadioThread accesses the radio at one time. It also keeps track of the last successful unlock of the radio so that we know when to re-send the magic wakeup sequence. """ def __init__(self): self.lock = threading.Lock() self.id = str(uuid.uuid4()) self._last = 0 def __enter__(self): LOG.debug('%s locking', self.id) self.lock.acquire() LOG.debug('%s locked', self.id) def __exit__(self, exc_type, exc_value, exc_tb): self.lock.release() if exc_type is None: self._last = time.time() LOG.debug('%s unlocked success=%s', self.id, exc_type is None) def __repr__(self): return '' % self.id @property def stale(self): return time.time() - self._last > 4 def locked(fn): """Decorator for operations that talk to the radio. Runs them with the lock and sends the magic wakeup if the timer is expired. """ def _lock(self, *a, **k): with self._lock: LOG.debug('Locked for %s', fn.__name__) if self._lock.stale: LOG.debug('Doing wakeup') self._init() r = fn(self, *a, **k) return r return _lock class IC9xBank(icf.IcomNamedBank): """Icom 9x Bank""" def get_name(self): banks = self._model._radio._ic9x_get_banks() return banks[self.index] def set_name(self, name): banks = self._model._radio._ic9x_get_banks() banks[self.index] = name self._model._radio._ic9x_set_banks(banks) @directory.register class IC9xRadio(icf.IcomLiveRadio): """Base class for Icom IC-9x radios""" MODEL = "IC-91/92AD" NEEDS_COMPAT_SERIAL = False _model = "ic9x" # Fake model info for detect.py vfo = 0 _upper = 300 _num_banks = 26 _bank_class = IC9xBank def _get_bank(self, loc): mem = self.get_memory(loc) return mem._bank def _set_bank(self, loc, bank): mem = self.get_memory(loc) mem._bank = bank self.set_memory(mem) def _get_bank_index(self, loc): mem = self.get_memory(loc) return mem._bank_index def _set_bank_index(self, loc, index): mem = self.get_memory(loc) mem._bank_index = index self.set_memory(mem) def _init(self): """Does the magic wakeup dance""" self.pipe.baudrate = 4800 self.pipe.timeout = 1 for i in range(5): buf = (b'\xfe' * 8) * 20 + ( b'\xfe\xfe\x01\x80\x19\xfd') self.pipe.write(buf) time.sleep(0.1) resp = self.pipe.read(5) if b'\x80\x01\x19' in resp: LOG.debug('Radio responded to wakeup attempt %i' % (i + 1)) self.pipe.baudrate = 38400 while True: r = ic9x_ll.ic9x_recv(self.pipe) if not r: break LOG.debug('Got post-wakeup response: %r' % r) return time.sleep(1) LOG.warning('Made %i attempts to wake radio', i + 1) raise errors.RadioError('Radio not responding') def __init__(self, *args, **kwargs): if 'lock' in kwargs: self._lock = kwargs.pop('lock') else: self._lock = Lock() super().__init__(*args, **kwargs) self.__memcache = {} self.__bankcache = {} @locked def get_memory(self, number): if isinstance(number, str): try: number = IC9X_SPECIAL[self.vfo][number] except KeyError: raise errors.InvalidMemoryLocation( "Unknown channel %s" % number) if number < -2 or number > 999: raise errors.InvalidValueError("Number must be between 0 and 999") if number in self.__memcache: return self.__memcache[number] try: mem = ic9x_ll.get_memory(self.pipe, self.vfo, number) except errors.InvalidMemoryLocation: mem = chirp_common.Memory() mem.number = number if number < self._upper: mem.empty = True if number > self._upper or number < 0: mem.extd_number = util.get_dict_rev(IC9X_SPECIAL, [self.vfo][number]) mem.immutable = ["number", "skip", "bank", "bank_index", "extd_number"] self.__memcache[mem.number] = mem return mem @locked def get_raw_memory(self, number): mframe = ic9x_ll.get_memory_frame(self.pipe, self.vfo, number) return repr(bitwise.parse(ic9x_ll.MEMORY_FRAME_FORMAT, mframe)) def get_memories(self, lo=0, hi=None): if hi is None: hi = self._upper memories = [] for i in range(lo, hi + 1): try: LOG.debug("Getting %i" % i) mem = self.get_memory(i) if mem: memories.append(mem) LOG.debug("Done: %s" % mem) except errors.InvalidMemoryLocation: pass except errors.InvalidDataError as e: LOG.error("Error talking to radio: %s" % e) break return memories @locked def set_memory(self, _memory): # Make sure we mirror the DV-ness of the new memory we're # setting, and that we capture the Bank value of any currently # stored memory (unless the special type is provided) and # communicate that to the low-level routines with the special # subclass if isinstance(_memory, ic9x_ll.IC9xMemory) or \ isinstance(_memory, ic9x_ll.IC9xDVMemory): memory = _memory else: if isinstance(_memory, chirp_common.DVMemory): memory = ic9x_ll.IC9xDVMemory() else: memory = ic9x_ll.IC9xMemory() try: memory.clone(ic9x_ll.get_memory(self.pipe, self.vfo, _memory.number)) except errors.InvalidMemoryLocation: pass memory.clone(_memory) if memory.empty: ic9x_ll.erase_memory(self.pipe, self.vfo, memory.number) else: ic9x_ll.set_memory(self.pipe, self.vfo, memory) memory = ic9x_ll.get_memory(self.pipe, self.vfo, memory.number) self.__memcache[memory.number] = memory @locked def _ic9x_get_banks(self): if len(list(self.__bankcache.keys())) == 26: return [self.__bankcache[k] for k in sorted(self.__bankcache.keys())] banks = ic9x_ll.get_banks(self.pipe, self.vfo) i = 0 for bank in banks: self.__bankcache[i] = bank i += 1 return banks @locked def _ic9x_set_banks(self, banks): if len(banks) != len(list(self.__bankcache.keys())): raise errors.InvalidDataError("Invalid bank list length (%i:%i)" % (len(banks), len(list(self.__bankcache.keys())))) cached_names = [str(self.__bankcache[x]) for x in sorted(self.__bankcache.keys())] need_update = False for i in range(0, 26): if banks[i] != cached_names[i]: need_update = True self.__bankcache[i] = banks[i] LOG.dbeug("Updating %s: %s -> %s" % (chr(i + ord("A")), cached_names[i], banks[i])) if need_update: ic9x_ll.set_banks(self.pipe, self.vfo, banks) def get_sub_devices(self): return [IC9xRadioA(self.pipe, lock=self._lock), IC9xRadioB(self.pipe, lock=self._lock)] def get_features(self): rf = chirp_common.RadioFeatures() rf.has_sub_devices = True rf.valid_special_chans = list(IC9X_SPECIAL[self.vfo].keys()) return rf class IC9xRadioA(IC9xRadio): """IC9x Band A subdevice""" VARIANT = "Band A" vfo = 1 _upper = 849 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = True rf.has_bank_index = True rf.has_bank_names = True rf.memory_bounds = (0, self._upper) rf.valid_modes = ["FM", "WFM", "AM"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_duplexes = ["", "-", "+"] rf.valid_tuning_steps = list(chirp_common.TUNING_STEPS) rf.valid_bands = [(500000, 9990000000)] rf.valid_skips = ["", "S", "P"] rf.valid_characters = CHARSET rf.valid_name_length = 8 return rf class IC9xRadioB(IC9xRadio, chirp_common.IcomDstarSupport): """IC9x Band B subdevice""" VARIANT = "Band B" vfo = 2 _upper = 399 MYCALL_LIMIT = (1, 7) URCALL_LIMIT = (1, 61) RPTCALL_LIMIT = (1, 61) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = True rf.has_bank_index = True rf.has_bank_names = True rf.requires_call_lists = False rf.memory_bounds = (0, self._upper) rf.valid_modes = ["FM", "NFM", "AM", "DV"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_duplexes = ["", "-", "+"] rf.valid_tuning_steps = list(chirp_common.TUNING_STEPS) rf.valid_bands = [(118000000, 174000000), (350000000, 470000000)] rf.valid_skips = ["", "S", "P"] rf.valid_characters = CHARSET rf.valid_name_length = 8 return rf def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.__rcalls = [] self.__mcalls = [] self.__ucalls = [] @locked def __get_call_list(self, cache, cstype, ulimit): if cache: return cache calls = [] for i in range(ulimit - 1): call = ic9x_ll.get_call(self.pipe, cstype, i+1) calls.append(call) return calls @locked def __set_call_list(self, cache, cstype, ulimit, calls): for i in range(ulimit - 1): blank = " " * 8 try: acall = cache[i] except IndexError: acall = blank try: bcall = calls[i] except IndexError: bcall = blank if acall == bcall: continue # No change to this one ic9x_ll.set_call(self.pipe, cstype, i + 1, calls[i]) return calls def get_mycall_list(self): self.__mcalls = self.__get_call_list(self.__mcalls, ic9x_ll.IC92MyCallsignFrame, self.MYCALL_LIMIT[1]) return self.__mcalls def get_urcall_list(self): self.__ucalls = self.__get_call_list(self.__ucalls, ic9x_ll.IC92YourCallsignFrame, self.URCALL_LIMIT[1]) return self.__ucalls def get_repeater_call_list(self): self.__rcalls = self.__get_call_list(self.__rcalls, ic9x_ll.IC92RepeaterCallsignFrame, self.RPTCALL_LIMIT[1]) return self.__rcalls def set_mycall_list(self, calls): self.__mcalls = self.__set_call_list(self.__mcalls, ic9x_ll.IC92MyCallsignFrame, self.MYCALL_LIMIT[1], calls) def set_urcall_list(self, calls): self.__ucalls = self.__set_call_list(self.__ucalls, ic9x_ll.IC92YourCallsignFrame, self.URCALL_LIMIT[1], calls) def set_repeater_call_list(self, calls): self.__rcalls = self.__set_call_list(self.__rcalls, ic9x_ll.IC92RepeaterCallsignFrame, self.RPTCALL_LIMIT[1], calls) def _test(): import serial ser = IC9xRadioB(serial.Serial(port="/dev/ttyUSB1", baudrate=38400, timeout=0.1)) print(ser.get_urcall_list()) print("-- FOO --") ser.set_urcall_list(["K7TAY", "FOOBAR", "BAZ"]) if __name__ == "__main__": _test() chirp-20240224/chirp/drivers/kenwood_hmk.py0000644000175000017500000001036514563632215017512 0ustar hibbyhibby# Copyright 2008 Dan Smith # Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import csv import logging from chirp import chirp_common, errors, directory from chirp.drivers import generic_csv LOG = logging.getLogger(__name__) class OmittedHeaderError(Exception): """An internal exception to indicate that a header was omitted""" pass @directory.register class HMKRadio(generic_csv.CSVRadio): """Kenwood HMK format""" VENDOR = "Kenwood" MODEL = "HMK" FILE_EXTENSION = "hmk" DUPLEX_MAP = { " ": "", "S": "split", "+": "+", "-": "-", } SKIP_MAP = { "Off": "", "On": "S", } TMODE_MAP = { "Off": "", "T": "Tone", "CT": "TSQL", "DCS": "DTCS", "": "Cross", } ATTR_MAP = { "!!Ch": (int, "number"), "M.Name": (str, "name"), "Rx Freq.": (chirp_common.parse_freq, "freq"), "Shift/Split": (lambda v: HMKRadio.DUPLEX_MAP[v], "duplex"), "Offset": (chirp_common.parse_freq, "offset"), "T/CT/DCS": (lambda v: HMKRadio.TMODE_MAP[v], "tmode"), "TO Freq.": (float, "rtone"), "CT Freq.": (float, "ctone"), "DCS Code": (int, "dtcs"), "Mode": (str, "mode"), "Rx Step": (float, "tuning_step"), "L.Out": (lambda v: HMKRadio.SKIP_MAP[v], "skip"), } def load(self, filename=None): if filename is None and self._filename is None: raise errors.RadioError("Need a location to load from") if filename: self._filename = filename self._blank() f = open(self._filename, "r") for line in f: if line.strip() == "// Memory Channels": break reader = csv.reader(f, delimiter=chirp_common.SEPCHAR, quotechar='"') good = 0 lineno = 0 for line in reader: lineno += 1 if lineno == 1: header = line continue if len(header) > len(line): LOG.debug("Line %i has %i columns, expected %i" % (lineno, len(line), len(header))) self.errors.append("Column number mismatch on line %i" % lineno) continue # hmk stores Tx Freq. in its own field, but Chirp expects the Tx # Freq. for odd-split channels to be in the Offset field. # If channel is odd-split, copy Tx Freq. field to Offset field. if line[header.index('Shift/Split')] == "S": line[header.index('Offset')] = line[header.index('Tx Freq.')] # fix EU decimal line = [i.replace(',', '.') for i in line] try: mem = self._parse_csv_data_line(header, line) if mem.number is None: raise Exception("Invalid Location field" % lineno) except Exception as e: LOG.error("Line %i: %s" % (lineno, e)) self.errors.append("Line %i: %s" % (lineno, e)) continue self._grow(mem.number) self.memories[mem.number] = mem good += 1 if not good: for error in errors: LOG.error("kenwood_hmk: %s", error) raise errors.InvalidDataError("No channels found") @classmethod def match_model(cls, filedata, filename): """Match files ending in .hmk""" return filename.lower().endswith("." + cls.FILE_EXTENSION) chirp-20240224/chirp/drivers/kenwood_itm.py0000644000175000017500000001021514563632215017516 0ustar hibbyhibby# Copyright 2008 Dan Smith # Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import csv import logging from chirp import chirp_common, errors, directory from chirp.drivers import generic_csv LOG = logging.getLogger(__name__) class OmittedHeaderError(Exception): """An internal exception to indicate that a header was omitted""" pass @directory.register class ITMRadio(generic_csv.CSVRadio): """Kenwood ITM format""" VENDOR = "Kenwood" MODEL = "ITM" FILE_EXTENSION = "itm" ATTR_MAP = { "CH": (int, "number"), "RXF": (chirp_common.parse_freq, "freq"), "NAME": (str, "name"), } def _clean_duplex(self, headers, line, mem): try: txfreq = chirp_common.parse_freq( generic_csv.get_datum_by_header(headers, line, "TXF")) except ValueError: mem.duplex = "off" return mem if mem.freq == txfreq: mem.duplex = "" elif txfreq: mem.duplex = "split" mem.offset = txfreq return mem def _clean_number(self, headers, line, mem): zone = int(generic_csv.get_datum_by_header(headers, line, "ZN")) mem.number = zone * 100 + mem.number return mem def _clean_tmode(self, headers, line, mem): rtone = eval(generic_csv.get_datum_by_header(headers, line, "TXSIG")) ctone = eval(generic_csv.get_datum_by_header(headers, line, "RXSIG")) if rtone: mem.tmode = "Tone" if ctone: mem.tmode = "TSQL" mem.rtone = rtone or 88.5 mem.ctone = ctone or mem.rtone return mem def load(self, filename=None): if filename is None and self._filename is None: raise errors.RadioError("Need a location to load from") if filename: self._filename = filename self._blank() f = open(self._filename, "r") for line in f: if line.strip() == "// Conventional Data": break reader = csv.reader(f, delimiter=chirp_common.SEPCHAR, quotechar='"') good = 0 lineno = 0 for line in reader: lineno += 1 if lineno == 1: header = line continue if len(line) == 0: # End of channel data break if len(header) > len(line): LOG.error("Line %i has %i columns, expected %i" % (lineno, len(line), len(header))) self.errors.append("Column number mismatch on line %i" % lineno) continue # fix EU decimal line = [i.replace(',', '.') for i in line] try: mem = self._parse_csv_data_line(header, line) if mem.number is None: raise Exception("Invalid Location field" % lineno) except Exception as e: LOG.error("Line %i: %s" % (lineno, e)) self.errors.append("Line %i: %s" % (lineno, e)) continue self._grow(mem.number) self.memories[mem.number] = mem good += 1 if not good: for error in errors: LOG.error("kenwood_itm: %s", error) raise errors.InvalidDataError("No channels found") @classmethod def match_model(cls, filedata, filename): return filename.lower().endswith("." + cls.FILE_EXTENSION) chirp-20240224/chirp/drivers/radtel_t18.py0000644000175000017500000013652714547737342017176 0ustar hibbyhibby# Copyright 2021 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 speccode:1, // Retevis RB87 PTT ID compander:1, scramble:1, skip:1, highpower:1, narrow:1, unknown2:1, bcl:1; u8 unknown3[3]; } memory[%d]; #seekto 0x02B0; struct { u8 voicesw; // Voice SW + u8 voiceselect; // Voice Select u8 scan; // Scan + u8 vox; // VOX + u8 voxgain; // Vox Gain + u8 voxnotxonrx; // Rx Disable Vox + u8 hivoltnotx; // High Vol Inhibit TX + u8 lovoltnotx; // Low Vol Inhibit TX + u8 rxemergency; // RX Emergency } settings2; #seekto 0x03C0; struct { u8 codesw:1, // Retevis RB29 code switch scanmode:1, vox:1, // Retevis RB19 VOX speccode:1, voiceprompt:2, batterysaver:1, beep:1; // Retevis RB87 vox u8 squelchlevel; u8 sidekey2; // Retevis RT22S setting // Retevis RB85 sidekey 1 short // Retevis RB19 sidekey 2 long // Retevis RT47 sidekey 1 long // Retevis RB87 sidekey 1 long u8 timeouttimer; u8 voxlevel; u8 sidekey2S; u8 unused; // Selected channel u8 voxdelay; u8 sidekey1L; u8 sidekey2L; u8 unused2[3]; u8 unknown3:4, unknown4:1, unknown5:2, power10w:1; // Retevis RT85 power 10w on/off // Retevis RT75 stop TX with low voltage } settings; """ MEM_FORMAT_RB18 = """ #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 jumpcode:1, unknown1:2, skip:1, highpower:1, narrow:1, unknown2:1, bcl:1; u8 unknown3[3]; } memory[%d]; #seekto 0x0630; struct { u8 unk630:7, voice:1; u8 unk631:7, language:1; u8 unk632:7, scan:1; u8 unk633:7, vox:1; u8 unk634:5, vox_level:3; u8 unk635; u8 unk636:7, lovoltnotx:1; u8 unk637:7, hivoltnotx:1; u8 unknown2[8]; u8 unk640:5, rogerbeep:1, batterysaver:1, beep:1; u8 squelchlevel; u8 unk642; u8 timeouttimer; u8 unk644:7, tail:1; u8 channel; } settings; """ MEM_FORMAT_T20FRS = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; lbcd rxtone[2]; lbcd txtone[2]; u8 jumpcode:1, unknown1:2, skip:1, highpower:1, narrow:1, unknown2:1, bcl:1; u8 unknown3[3]; } memory[%d]; #seekto 0x02B0; struct { u8 voicesw; // Voice SW + u8 voiceselect; // Voice Select u8 scan; // Scan + u8 vox; // VOX + u8 voxgain; // Vox Gain + u8 voxnotxonrx; // Rx Disable Vox + u8 hivoltnotx; // High Vol Inhibit TX + u8 lovoltnotx; // Low Vol Inhibit TX + u8 rxemergency; // RX Emergency } settings2; #seekto 0x02C0; struct { u8 unk:6, batterysaver:1, beep:1; u8 squelchlevel; u8 sidekey2; u8 timeouttimer; } settings; """ CMD_ACK = b"\x06" VOICE_LIST = ["Off", "Chinese", "English"] VOICE_LIST2 = ["English", "Chinese"] VOICE_LIST3 = ["Off", "English", "Chinese"] VOICE_LIST4 = ["Chinese", "English"] TIMEOUTTIMER_LIST = ["Off", "30 seconds", "60 seconds", "90 seconds", "120 seconds", "150 seconds", "180 seconds", "210 seconds", "240 seconds", "270 seconds", "300 seconds"] SCANMODE_LIST = ["Carrier", "Time"] VOXLEVEL_LIST = ["Off", "1", "2", "3", "4", "5", "6", "7", "8", "9"] VOXDELAY_LIST = ["0.5 seconds", "1.0 seconds", "1.5 seconds", "2.0 seconds", "2.5 seconds", "3.0 seconds"] SIDEKEY19_LIST = ["Off", "Scan", "Emergency Alarm"] SIDEKEY2_LIST = SIDEKEY19_LIST + ["Display Battery"] SIDEKEY29_LIST = ["Off", "Scan", "VOX", "Busy Lock", "Emergency Alarm"] SIDEKEY85SHORT_LIST = ["Off", "Noise Cansellation On", "Continuous Monitor", "High/Low Power", "Emergency Alarm", "Show Battery", "Scan", "VOX", "Busy Channel Lock"] SIDEKEY85LONG_LIST = ["Off", "Noise Cansellation On", "Continuous Monitor", "Monitor Momentary", "High/Low Power", "Emergency Alarm", "Show Battery", "Scan", "VOX", "Busy Channel Lock"] SPECCODE_LIST = ["SpeCode 1", "SpeCode 2"] SIDEKEY75_LIST = ["Off", "Monitor Momentary", "Scan", "VOX", "Monitor", "Announciation"] SIDEKEY47_LIST = ["Monitor Momentary", "Channel Lock", "Scan", "VOX"] SIDEKEYV8A_LIST = ["Off", "Monitor", "High/Low Power", "Alarm"] SIDEKEY87_LIST = ["Scan", "Emergency Alarm"] FRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] FRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] FRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] FRS_FREQS = FRS_FREQS1 + FRS_FREQS2 + FRS_FREQS3 FRS16_FREQS = [462562500, 462587500, 462612500, 462637500, 462662500, 462625000, 462725000, 462687500, 462712500, 462550000, 462575000, 462600000, 462650000, 462675000, 462700000, 462725000] GMRS_FREQS = FRS_FREQS1 + FRS_FREQS2 + FRS_FREQS3 * 2 MURS_FREQS = [151820000, 151880000, 151940000, 154570000, 154600000] PMR_FREQS1 = [446006250, 446018750, 446031250, 446043750, 446056250, 446068750, 446081250, 446093750] PMR_FREQS2 = [446106250, 446118750, 446131250, 446143750, 446156250, 446168750, 446181250, 446193750] PMR_FREQS = PMR_FREQS1 + PMR_FREQS2 def _t18_enter_programming_mode(radio): serial = radio.pipe _magic = b"\x02" + radio._magic try: serial.write(_magic) if radio._echo: chew = serial.read(len(_magic)) # Chew the echo ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if not ack: raise errors.RadioError("No response from radio") elif ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") try: serial.write(b"\x02") if radio._echo: serial.read(1) # Chew the echo ident = serial.read(8) except: raise errors.RadioError("Error communicating with radio") # check if ident is OK for fp in radio._fingerprint: if ident.startswith(fp): break else: LOG.debug("Incorrect model ID, got this:\n\n" + util.hexprint(ident)) raise errors.RadioError("Radio identification failed.") try: serial.write(CMD_ACK) if radio._echo: serial.read(1) # Chew the echo ack = serial.read(1) except: raise errors.RadioError("Error communicating with radio") if radio.MODEL == "RT647": if ack != b"\xF0": raise errors.RadioError("Radio refused to enter programming mode") else: if ack != CMD_ACK: raise errors.RadioError("Radio refused to enter programming mode") def _t18_exit_programming_mode(radio): serial = radio.pipe try: serial.write(radio.CMD_EXIT) if radio._echo: chew = serial.read(1) # Chew the echo except: raise errors.RadioError("Radio refused to exit programming mode") def _t18_read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"W" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) if radio._echo: serial.read(4) # Chew the echo response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] if radio.ACK_BLOCK: serial.write(CMD_ACK) if radio._echo: serial.read(1) # Chew the echo ack = serial.read(1) except: raise errors.RadioError("Failed to read block at %04x" % block_addr) if radio.ACK_BLOCK: if ack != CMD_ACK: raise Exception("No ACK reading block %04x." % (block_addr)) return block_data def _t18_write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if radio._echo: serial.read(4 + len(data)) # Chew the echo if serial.read(1) != CMD_ACK: raise Exception("No ACK") except: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _t18_enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _t18_read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _t18_exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _t18_enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) _t18_write_block(radio, addr, radio.BLOCK_SIZE) _t18_exit_programming_mode(radio) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" if len(data) == cls._memsize: rid = data[0x03D0:0x03D8] return b"P558" in rid else: return False @directory.register class T18Radio(chirp_common.CloneModeRadio): """radtel T18""" VENDOR = "Radtel" MODEL = "T18" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x08 CMD_EXIT = b"b" ACK_BLOCK = True VALID_BANDS = [(400000000, 470000000)] _magic = b"1ROGRAM" _fingerprint = [b"SMP558" + b"\x00\x00"] _upper = 16 _mem_params = (_upper # number of channels ) _frs = _frs16 = _murs = _pmr = _gmrs = False _echo = False _ranges = [ (0x0000, 0x03F0), ] _memsize = 0x03F0 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.valid_modes = ["NFM", "FM"] # 12.5 kHz, 25 kHz. rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_duplexes = ["", "-", "+", "split", "off"] if self.MODEL != "T18" and \ self.MODEL != "RB618" and \ self.MODEL != "RT647": rf.valid_power_levels = self.POWER_LEVELS rf.can_odd_split = True rf.has_rx_dtcs = True rf.has_ctone = True rf.has_cross = True rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.has_tuning_step = False rf.has_bank = False rf.has_name = False rf.memory_bounds = (1, self._upper) rf.valid_bands = self.VALID_BANDS rf.valid_tuning_steps = chirp_common.TUNING_STEPS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) def sync_in(self): self._mmap = do_download(self) self.process_mmap() def sync_out(self): do_upload(self) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _decode_tone(self, val): val = int(val) if val == 16665: return '', None, None elif val >= 12000: return 'DTCS', val - 12000, 'R' elif val >= 8000: return 'DTCS', val - 8000, 'N' else: return 'Tone', val / 10.0, None def _encode_tone(self, memval, mode, value, pol): if mode == '': memval[0].set_raw(0xFF) memval[1].set_raw(0xFF) elif mode == 'Tone': memval.set_value(int(value * 10)) elif mode == 'DTCS': flag = 0x80 if pol == 'N' else 0xC0 memval.set_value(value) memval[1].set_bits(flag) else: raise Exception("Internal error: invalid mode `%s'" % mode) def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem if _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.mode = not _mem.narrow and "FM" or "NFM" mem.skip = _mem.skip and "S" or "" txtone = self._decode_tone(_mem.txtone) rxtone = self._decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) if self.MODEL != "T18" and self.MODEL != "RB618": mem.power = self.POWER_LEVELS[1 - _mem.highpower] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueBoolean(not _mem.bcl)) mem.extra.append(rs) if self.MODEL != "RB18" and self.MODEL != "RB618" and \ self.MODEL != "FRS-B1" and self.MODEL != "BF-V8A" and \ self.MODEL != "RB29" and self.MODEL != "RB629" and \ self.MODEL != "BF-T20FRS": if self.MODEL not in ["RB87", "RT47V"]: rs = RadioSetting("scramble", "Scramble", RadioSettingValueBoolean(not _mem.scramble)) mem.extra.append(rs) rs = RadioSetting("compander", "Compander", RadioSettingValueBoolean(not _mem.compander)) mem.extra.append(rs) if self.MODEL != "RT47V" and self.MODEL != "T8" and \ self.MODEL != "RB17" and self.MODEL != "RB617" and \ self.MODEL != "RB75" and self.MODEL != "RB19P": if self.MODEL == "RB87": rs = RadioSettingValueBoolean(not _mem.speccode) rset = RadioSetting("speccode", "PTT-ID", rs) mem.extra.append(rset) else: rs = RadioSettingValueBoolean(not _mem.speccode) rset = RadioSetting("speccode", "Spec Code", rs) mem.extra.append(rset) immutable = [] if self._frs: if mem.freq in FRS_FREQS: if mem.number >= 1 and mem.number <= 22: FRS_FREQ = FRS_FREQS[mem.number - 1] mem.freq = FRS_FREQ mem.duplex = '' mem.offset = 0 mem.mode = "NFM" if mem.number >= 8 and mem.number <= 14: mem.power = self.POWER_LEVELS[1] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] else: immutable = ["empty", "freq", "duplex", "offset", "mode"] elif self._frs16: if mem.freq in FRS16_FREQS: if mem.number >= 1 and mem.number <= 16: FRS_FREQ = FRS16_FREQS[mem.number - 1] mem.freq = FRS_FREQ mem.duplex = '' mem.offset = 0 mem.mode = "NFM" immutable = ["empty", "freq", "duplex", "offset", "mode"] elif self._murs: if mem.freq in MURS_FREQS: if mem.number >= 1 and mem.number <= 5: MURS_FREQ = MURS_FREQS[mem.number - 1] mem.freq = MURS_FREQ mem.duplex = '' mem.offset = 0 if mem.number <= 3: mem.mode = "NFM" immutable = ["empty", "freq", "duplex", "offset", "mode"] else: immutable = ["empty", "freq", "duplex", "offset"] elif self._pmr: if mem.freq in PMR_FREQS: if mem.number >= 1 and mem.number <= 16: PMR_FREQ = PMR_FREQS[mem.number - 1] mem.freq = PMR_FREQ mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable = ["empty", "freq", "duplex", "offset", "mode", "power"] elif self._gmrs: if mem.freq in GMRS_FREQS: if mem.number >= 1 and mem.number <= 30: GMRS_FREQ = GMRS_FREQS[mem.number - 1] mem.freq = GMRS_FREQ immutable = ["freq"] if mem.number >= 1 and mem.number <= 7: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 8 and mem.number <= 14: mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable += ["duplex", "offset", "mode", "power"] elif mem.number >= 15 and mem.number <= 22: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 23 and mem.number <= 30: mem.duplex = '+' mem.offset = 5000000 immutable += ["duplex", "offset"] mem.immutable = immutable return mem def set_memory(self, mem): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw("\xFF" * (_mem.size() // 8)) return if self.MODEL == "BF-V8A" or self.MODEL == "BF-T20FRS": _mem.set_raw("\x00" * 12 + "\x09\xFF\xFF\xFF") elif self.MODEL == "RB29" or self.MODEL == "RB629": _mem.set_raw("\x00" * 12 + "\xF7\xFF\xFF\xFF") else: _mem.set_raw("\x00" * 12 + "\xF9\xFF\xFF\xFF") _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 txtone, rxtone = chirp_common.split_tone_encode(mem) self._encode_tone(_mem.txtone, *txtone) self._encode_tone(_mem.rxtone, *rxtone) if self.MODEL != "T18" and self.MODEL != "RB18": _mem.highpower = mem.power == self.POWER_LEVELS[0] _mem.narrow = 'N' in mem.mode _mem.skip = mem.skip == "S" for setting in mem.extra: # NOTE: Only three settings right now, all are inverted setattr(_mem, setting.get_name(), not int(setting.value)) def get_settings(self): _settings = self._memobj.settings if self.MODEL == "FRS-B1" or self.MODEL == "BF-V8A" or \ self.MODEL == "BF-T20FRS": _settings2 = self._memobj.settings2 basic = RadioSettingGroup("basic", "Basic Settings") top = RadioSettings(basic) rs = RadioSetting("squelchlevel", "Squelch level", RadioSettingValueInteger( 0, 9, _settings.squelchlevel)) basic.append(rs) rs = RadioSetting("timeouttimer", "Timeout timer", RadioSettingValueList( TIMEOUTTIMER_LIST, TIMEOUTTIMER_LIST[ _settings.timeouttimer])) basic.append(rs) if self.MODEL == "RB18" or self.MODEL == "RB618": rs = RadioSetting("scan", "Scan", RadioSettingValueBoolean(_settings.scan)) basic.append(rs) elif self.MODEL == "FRS-B1" or self.MODEL == "BF-V8A" or \ self.MODEL == "BF-T20FRS": rs = RadioSetting("settings2.scan", "Scan", RadioSettingValueBoolean(_settings2.scan)) basic.append(rs) else: rs = RadioSetting("scanmode", "Scan mode", RadioSettingValueList( SCANMODE_LIST, SCANMODE_LIST[_settings.scanmode])) basic.append(rs) if self.MODEL == "RT20": rs = RadioSetting("voiceprompt", "Voice prompts", RadioSettingValueList( VOICE_LIST4, VOICE_LIST4[_settings.voiceprompt])) basic.append(rs) elif self.MODEL == "RT22S": rs = RadioSetting("voiceprompt", "Voice prompts", RadioSettingValueBoolean(_settings.voiceprompt)) basic.append(rs) elif self.MODEL == "RB18" or self.MODEL == "RB618": rs = RadioSetting("voice", "Voice prompts", RadioSettingValueBoolean(_settings.voice)) basic.append(rs) elif self.MODEL == "FRS-B1" or self.MODEL == "BF-V8A" or \ self.MODEL == "BF-T20FRS": rs = RadioSetting("settings2.voicesw", "Voice prompts", RadioSettingValueBoolean(_settings2.voicesw)) basic.append(rs) elif self.MODEL == "RT15": rs = RadioSetting("voiceprompt", "Voice prompts", RadioSettingValueList( VOICE_LIST3, VOICE_LIST3[_settings.voiceprompt])) basic.append(rs) else: if self.MODEL != "RB87": rs = RadioSetting("voiceprompt", "Voice prompts", RadioSettingValueList( VOICE_LIST, VOICE_LIST[_settings.voiceprompt])) basic.append(rs) rs = RadioSetting("batterysaver", "Battery saver", RadioSettingValueBoolean(_settings.batterysaver)) basic.append(rs) if self.MODEL not in ["RB29", "RB75", "RB87", "RB629", "RT15" ]: rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) if self.MODEL == "RB19" or self.MODEL == "RB19P" \ or self.MODEL == "RB619": rs = RadioSetting("vox", "VOX", RadioSettingValueBoolean(_settings.vox)) basic.append(rs) if self.MODEL == "RB87": rs = RadioSetting("beep", "VOX", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) if self.MODEL != "RB18" and self.MODEL != "RB618" \ and self.MODEL != "FRS-B1" \ and self.MODEL != "BF-V8A" \ and self.MODEL != "BF-T20FRS": rs = RadioSetting("voxlevel", "Vox level", RadioSettingValueList( VOXLEVEL_LIST, VOXLEVEL_LIST[_settings.voxlevel])) basic.append(rs) rs = RadioSetting("voxdelay", "VOX delay", RadioSettingValueList( VOXDELAY_LIST, VOXDELAY_LIST[_settings.voxdelay])) basic.append(rs) if self.MODEL == "RT22S": rs = RadioSetting("sidekey2", "Side Key 2(Long)", RadioSettingValueList( SIDEKEY2_LIST, SIDEKEY2_LIST[_settings.sidekey2])) basic.append(rs) if self.MODEL == "RB18" or self.MODEL == "RB618": rs = RadioSetting("language", "Language", RadioSettingValueList( VOICE_LIST2, VOICE_LIST2[_settings.language])) basic.append(rs) rs = RadioSetting("tail", "Tail", RadioSettingValueBoolean(_settings.tail)) basic.append(rs) rs = RadioSetting("hivoltnotx", "High voltage no TX", RadioSettingValueBoolean(_settings.hivoltnotx)) basic.append(rs) rs = RadioSetting("lovoltnotx", "Low voltage no TX", RadioSettingValueBoolean(_settings.lovoltnotx)) basic.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueBoolean(_settings.vox)) basic.append(rs) if _settings.vox_level > 4: val = 1 else: val = _settings.vox_level + 1 rs = RadioSetting("vox_level", "VOX level", RadioSettingValueInteger(1, 5, val)) basic.append(rs) rs = RadioSetting("rogerbeep", "Roger beep", RadioSettingValueBoolean(_settings.rogerbeep)) basic.append(rs) if self.MODEL == "RB85": rs = RadioSetting("speccode", "SpecCode Select", RadioSettingValueList( SPECCODE_LIST, SPECCODE_LIST[_settings.speccode])) basic.append(rs) rs = RadioSetting("sidekey2", "Side Key 1(Short)", RadioSettingValueList( SIDEKEY85SHORT_LIST, SIDEKEY85SHORT_LIST[_settings.sidekey2])) basic.append(rs) rs = RadioSetting("sidekey1L", "Side Key 1(Long)", RadioSettingValueList( SIDEKEY85LONG_LIST, SIDEKEY85LONG_LIST[_settings.sidekey1L])) basic.append(rs) rs = RadioSetting("sidekey2S", "Side Key 2(Short)", RadioSettingValueList( SIDEKEY85SHORT_LIST, SIDEKEY85SHORT_LIST[_settings.sidekey2S])) basic.append(rs) rs = RadioSetting("sidekey2L", "Side Key 2(Long)", RadioSettingValueList( SIDEKEY85LONG_LIST, SIDEKEY85LONG_LIST[_settings.sidekey2L])) basic.append(rs) rs = RadioSetting("power10w", "Power 10W", RadioSettingValueBoolean(_settings.power10w)) basic.append(rs) if self.MODEL == "RB75": rs = RadioSetting("sidekey2", "Side Key 1(Short)", RadioSettingValueList( SIDEKEY75_LIST, SIDEKEY75_LIST[_settings.sidekey2])) basic.append(rs) rs = RadioSetting("sidekey1L", "Side Key 1(Long)", RadioSettingValueList( SIDEKEY75_LIST, SIDEKEY75_LIST[_settings.sidekey1L])) basic.append(rs) rs = RadioSetting("sidekey2S", "Side Key 2(Short)", RadioSettingValueList( SIDEKEY75_LIST, SIDEKEY75_LIST[_settings.sidekey2S])) basic.append(rs) rs = RadioSetting("sidekey2L", "Side Key 2(Long)", RadioSettingValueList( SIDEKEY75_LIST, SIDEKEY75_LIST[_settings.sidekey2L])) basic.append(rs) rs = RadioSetting("power10w", "Low Voltage Stop TX", RadioSettingValueBoolean(_settings.power10w)) basic.append(rs) if self.MODEL == "RB87": rs = RadioSetting("sidekey2", "Side Key 1(Long)", RadioSettingValueList( SIDEKEY87_LIST, SIDEKEY87_LIST[_settings.sidekey2])) basic.append(rs) if self.MODEL == "FRS-B1": rs = RadioSetting("settings2.hivoltnotx", "High Voltage Inhibit TX", RadioSettingValueBoolean(_settings2.hivoltnotx)) basic.append(rs) rs = RadioSetting("settings2.lovoltnotx", "Low Voltage Inhibit TX", RadioSettingValueBoolean(_settings2.lovoltnotx)) basic.append(rs) rs = RadioSetting("settings2.vox", "Vox", RadioSettingValueBoolean(_settings2.vox)) basic.append(rs) rs = RadioSetting("settings2.voxnotxonrx", "Rx Disable VOX", RadioSettingValueBoolean(_settings2.voxnotxonrx)) basic.append(rs) rs = RadioSetting("settings2.voxgain", "Vox Gain", RadioSettingValueInteger( 1, 5, _settings2.voxgain)) basic.append(rs) if self.MODEL == "RB19" or self.MODEL == "RB19P" \ or self.MODEL == "RB619": rs = RadioSetting("sidekey2", "Left Navigation Button(Long)", RadioSettingValueList( SIDEKEY19_LIST, SIDEKEY19_LIST[_settings.sidekey2])) basic.append(rs) if self.MODEL == "RT47" or self.MODEL == "RT47V" or \ self.MODEL == "RT647": rs = RadioSetting("sidekey2", "Side Key 1(Long)", RadioSettingValueList( SIDEKEY47_LIST, SIDEKEY47_LIST[_settings.sidekey2])) basic.append(rs) rs = RadioSetting("sidekey2S", "Side Key 2(Long)", RadioSettingValueList( SIDEKEY47_LIST, SIDEKEY47_LIST[_settings.sidekey2S])) basic.append(rs) if self.MODEL == "BF-V8A" or self.MODEL == "BF-T20FRS": rs = RadioSetting("sidekey2", "Side key", RadioSettingValueList( SIDEKEYV8A_LIST, SIDEKEYV8A_LIST[_settings.sidekey2])) basic.append(rs) rs = RadioSetting("settings2.rxemergency", "RX emergency", RadioSettingValueBoolean(_settings2.rxemergency)) basic.append(rs) rs = RadioSetting("settings2.voiceselect", "Language", RadioSettingValueList( VOICE_LIST2, VOICE_LIST2[_settings2.voiceselect])) basic.append(rs) rs = RadioSetting("settings2.hivoltnotx", "High voltage inhibit TX", RadioSettingValueBoolean(_settings2.hivoltnotx)) basic.append(rs) rs = RadioSetting("settings2.lovoltnotx", "Low voltage inhibit TX", RadioSettingValueBoolean(_settings2.lovoltnotx)) basic.append(rs) rs = RadioSetting("settings2.vox", "VOX", RadioSettingValueBoolean(_settings2.vox)) basic.append(rs) rs = RadioSetting("settings2.voxnotxonrx", "RX disable VOX", RadioSettingValueBoolean(_settings2.voxnotxonrx)) basic.append(rs) rs = RadioSetting("settings2.voxgain", "Vox Gain", RadioSettingValueInteger( 1, 5, _settings2.voxgain)) basic.append(rs) if self.MODEL == "RB29" or self.MODEL == "RB629": rs = RadioSetting("codesw", "Code Switch", RadioSettingValueBoolean(_settings.codesw)) basic.append(rs) rs = RadioSetting("sidekey2S", "Side Key(Short)", RadioSettingValueList( SIDEKEY29_LIST, SIDEKEY29_LIST[_settings.sidekey2S])) basic.append(rs) rs = RadioSetting("sidekey2L", "Side Key(Long)", RadioSettingValueList( SIDEKEY29_LIST, SIDEKEY29_LIST[_settings.sidekey2L])) basic.append(rs) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "vox_level": setattr(obj, setting, int(element.value) - 1) else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): if cls.MODEL == "T18": match_size = False match_model = False # testing the file data size if len(filedata) == cls._memsize: match_size = True # testing the model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False else: # Radios that have always been post-metadata, so never do # old-school detection return False @directory.register class RT20Radio(T18Radio): """RETEVIS RT20""" VENDOR = "Retevis" MODEL = "RT20" ACK_BLOCK = True BLOCK_SIZE = 0x08 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"8AOGRAM" _fingerprint = [b"SMP558" + b"\x02"] _upper = 16 _mem_params = (_upper # number of channels ) @directory.register class RT22SRadio(T18Radio): """RETEVIS RT22S""" VENDOR = "Retevis" MODEL = "RT22S" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"9COGRAM" _fingerprint = [b"SMP558" + b"\x02"] _upper = 22 _mem_params = (_upper # number of channels ) _frs = True _pmr = False @directory.register class RB18Radio(T18Radio): """RETEVIS RB18""" VENDOR = "Retevis" MODEL = "RB18" BLOCK_SIZE = 0x10 CMD_EXIT = b"E" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PROGRAL" _fingerprint = [b"P3107" + b"\xF7"] _upper = 22 _mem_params = (_upper # number of channels ) _frs = True _pmr = False _ranges = [ (0x0000, 0x0660), ] _memsize = 0x0660 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_RB18 % self._mem_params, self._mmap) @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class RB618Radio(RB18Radio): """RETEVIS RB618""" VENDOR = "Retevis" MODEL = "RB618" _upper = 16 _mem_params = (_upper # number of channels ) _frs = False _pmr = True @directory.register class RT68Radio(T18Radio): """RETEVIS RT68""" VENDOR = "Retevis" MODEL = "RT68" ACK_BLOCK = False CMD_EXIT = b"" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"83OGRAM" _fingerprint = [b"\x06\x00\x00\x00\x00\x00\x00\x00"] _upper = 16 _mem_params = (_upper # number of channels ) _frs16 = True _pmr = False @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class RT668Radio(RT68Radio): """RETEVIS RT668""" VENDOR = "Retevis" MODEL = "RT668" _frs16 = False _pmr = True @directory.register class RB17Radio(RT68Radio): """RETEVIS RB17""" VENDOR = "Retevis" MODEL = "RB17" _magic = b"A5OGRAM" _fingerprint = [b"\x53\x00\x00\x00\x00\x00\x00\x00"] _frs16 = True _pmr = False _murs = False @directory.register class RB617Radio(RB17Radio): """RETEVIS RB617""" VENDOR = "Retevis" MODEL = "RB617" _frs16 = False _pmr = True _murs = False @directory.register class RB17VRadio(RB17Radio): """RETEVIS RB17V""" VENDOR = "Retevis" MODEL = "RB17V" VALID_BANDS = [(136000000, 174000000)] _upper = 5 _frs16 = False _pmr = False _murs = True @directory.register class RB85Radio(T18Radio): """Retevis RB85""" VENDOR = "Retevis" MODEL = "RB85" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=10.00), chirp_common.PowerLevel("Low", watts=5.00)] _magic = b"H19GRAM" _fingerprint = [b"SMP558" + b"\x02"] @directory.register class RB75Radio(T18Radio): """Retevis RB75""" VENDOR = "Retevis" MODEL = "RB75" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"KVOGRAM" _fingerprint = [b"SMP558" + b"\x00"] _upper = 30 _mem_params = (_upper # number of channels ) _gmrs = False # sold as GMRS radio but supports full band TX/RX @directory.register class FRSB1Radio(T18Radio): """BTECH FRS-B1""" VENDOR = "BTECH" MODEL = "FRS-B1" ACK_BLOCK = True POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"PROGRAM" _fingerprint = [b"P3107" + b"\xF7\x00"] _upper = 22 _mem_params = (_upper # number of channels ) _frs = True @directory.register class RB19Radio(T18Radio): """Retevis RB19""" VENDOR = "Retevis" MODEL = "RB19" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"9COGRAM" _fingerprint = [b"SMP558" + b"\x02"] _upper = 22 _mem_params = (_upper # number of channels ) _frs = True @directory.register class RB19PRadio(T18Radio): """Retevis RB19P""" VENDOR = "Retevis" MODEL = "RB19P" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=3.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"70OGRAM" _fingerprint = [b"SMP558" + b"\x02"] _upper = 30 _mem_params = (_upper # number of channels ) _gmrs = True @directory.register class RB619Radio(T18Radio): """Retevis RB619""" VENDOR = "Retevis" MODEL = "RB619" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=0.500), chirp_common.PowerLevel("Low", watts=0.499)] _magic = b"9COGRAM" _fingerprint = [b"SMP558" + b"\x02"] _upper = 16 _mem_params = (_upper # number of channels ) _pmr = True @directory.register class RT47Radio(T18Radio): """Retevis RT47""" VENDOR = "Retevis" MODEL = "RT47" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.000), chirp_common.PowerLevel("Low", watts=0.500)] _magic = b"47OGRAM" _fingerprint = [b"\x06\x00\x00\x00\x00\x00\x00\x00"] _upper = 16 _mem_params = (_upper # number of channels ) _frs16 = True _echo = True @directory.register class RT47VRadio(RT47Radio): """Retevis RT47V""" VENDOR = "Retevis" MODEL = "RT47V" VALID_BANDS = [(136000000, 174000000)] _upper = 5 _mem_params = (_upper # number of channels ) _frs16 = False _murs = True @directory.register class RT647Radio(RT47Radio): """Retevis RT647""" VENDOR = "Retevis" MODEL = "RT647" _frs16 = False _pmr = True @directory.register class BFV8ARadio(T18Radio): """Baofeng BF-V8A""" VENDOR = "Baofeng" MODEL = "BF-V8A" ACK_BLOCK = True POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.000), chirp_common.PowerLevel("Low", watts=0.500)] _magic = b"PROGRAM" _fingerprint = [b"P3107" + b"\xF7\x00\x00"] _upper = 16 _mem_params = (_upper # number of channels ) _echo = False @directory.register class RB29Radio(T18Radio): """Retevis RB29""" VENDOR = "Retevis" MODEL = "RB29" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"S19GRAM" _fingerprint = [b"SMP558" + b"\x02"] _upper = 16 _mem_params = (_upper # number of channels ) _frs16 = True @directory.register class RB629Radio(RB29Radio): """Retevis RB29""" VENDOR = "Retevis" MODEL = "RB629" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=0.500), chirp_common.PowerLevel("Low", watts=0.499)] _frs16 = False _pmr = True @directory.register class RT15Radio(T18Radio): """RETEVIS RT15""" VENDOR = "Retevis" MODEL = "RT15" ACK_BLOCK = False CMD_EXIT = b"b" POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"KAOGRAM" _fingerprint = [b"\x06\x00\x00\x00\x00\x00\x00\x00", b"\x06\x03\xE8\x08\xFF\xFF\xFF\xFF"] _upper = 16 _mem_params = (_upper # number of channels ) _frs16 = False # sold as FRS radio but supports full band TX/RX @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class RB87Radio(T18Radio): """RETEVIS RB87""" VENDOR = "Retevis" MODEL = "RB87" ACK_BLOCK = False CMD_EXIT = b"" ACK_BLOCK = False POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = b"C8OGRAN" _fingerprint = [b"SMP558"] _upper = 30 _mem_params = (_upper # number of channels ) _gmrs = True @directory.register class BFT20FRSRadio(T18Radio): """Baofeng BF-T20FRS""" VENDOR = "Baofeng" MODEL = "BF-T20FRS" ACK_BLOCK = True POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.000), chirp_common.PowerLevel("Low", watts=0.500)] _magic = b"PROGRAM" _fingerprint = [b"P3107" + b"\xF7\x00\x00"] _upper = 22 _mem_params = (_upper # number of channels ) _frs = False # sold as FRS radio but supports full band TX/RX _ranges = [ (0x0000, 0x0160), (0x02B0, 0x02D0), ] _memsize = 0x03F0 def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT_T20FRS % self._mem_params, self._mmap) chirp-20240224/chirp/drivers/id51.py0000644000175000017500000000603414411666130015740 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import logging from chirp.drivers import id31 from chirp import directory, bitwise MEM_FORMAT = """ struct { u24 freq; u16 offset; u16 rtone:6, ctone:6, unknown2:1, mode:3; u8 dtcs; u8 tune_step:4, dsql_mode:2, unknown5:2; u8 unknown4; u8 tmode:4, duplex:2, dtcs_polarity:2; char name[16]; u8 digcode; u8 urcall[7]; u8 rpt1call[7]; u8 rpt2call[7]; } memory[500]; #seekto 0x6A40; u8 used_flags[70]; #seekto 0x6A86; u8 skip_flags[69]; #seekto 0x6ACB; u8 pskp_flags[69]; #seekto 0x6B40; struct { u8 bank; u8 index; } banks[500]; #seekto 0x6FD0; struct { char name[16]; } bank_names[26]; #seekto 0xA8C0; struct { u24 freq; u16 offset; u8 unknown1[3]; u8 call[7]; char name[16]; char subname[8]; u8 unknown3[10]; } repeaters[750]; #seekto 0x1384E; struct { u8 call[7]; } rptcall[750]; #seekto 0x14E60; struct { char call[8]; char tag[4]; } mycall[6]; #seekto 0x14EA8; struct { char call[8]; } urcall[200]; """ LOG = logging.getLogger(__name__) @directory.register class ID51Radio(id31.ID31Radio): """Icom ID-51""" MODEL = "ID-51" _memsize = 0x1FB40 _model = "\x33\x90\x00\x01" _endframe = "Icom Inc\x2E\x44\x41" _ranges = [(0x00000, 0x1FB40, 32)] MODES = {0: "FM", 1: "NFM", 3: "AM", 5: "DV"} @classmethod def match_model(cls, filedata, filename): """Given contents of a stored file (@filedata), return True if this radio driver handles the represented model""" # The default check for ICOM is just to check memory size # Since the ID-51 and ID-51 Plus/Anniversary have exactly # the same memory size, we need to do a more detailed check. if len(filedata) == cls._memsize: snip = bytes(filedata[0x1AF40:0x1AF60]) if snip == bytes(b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF' b'\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'): return True return False def get_features(self): rf = super(ID51Radio, self).get_features() rf.valid_bands = [(108000000, 174000000), (400000000, 479000000)] return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) chirp-20240224/chirp/drivers/ic9x_ll.py0000644000175000017500000003532114551723752016553 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, util, errors, bitwise from chirp.memmap import MemoryMapBytes LOG = logging.getLogger(__name__) TUNING_STEPS = [ 5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15, 20, 25, 30, 50, 100, 125, 200 ] MODES = ["FM", "NFM", "WFM", "AM", "DV"] DUPLEX = ["", "-", "+"] TMODES = ["", "Tone", "TSQL", "TSQL", "DTCS", "DTCS"] DTCS_POL = ["NN", "NR", "RN", "RR"] MEM_LEN = 34 DV_MEM_LEN = 60 # Dirty hack until I clean up this IC9x mess class IC9xMemory(chirp_common.Memory): """A dirty hack to stash bank information in a memory""" _bank = None _bank_index = 0 def __init__(self): chirp_common.Memory.__init__(self) class IC9xDVMemory(chirp_common.DVMemory): """See above dirty hack""" _bank = None _bank_index = 0 def __init__(self): chirp_common.DVMemory.__init__(self) def _ic9x_parse_frames(buf): frames = [] while b"\xfe\xfe" in buf: try: start = buf.index(b"\xfe\xfe") end = buf[start:].index(b"\xfd") + start + 1 except Exception: LOG.error("No trailing bit") break framedata = buf[start:end] buf = buf[end:] try: frame = IC92Frame() frame.from_raw(framedata[2:-1]) frames.append(frame) except errors.InvalidDataError as e: LOG.error("Broken frame: %s" % e) # LOG.debug("Parsed %i frames" % len(frames)) return frames def ic9x_recv(pipe): data = b"" while b'\xfd' not in data: buf = pipe.read(1) if not buf: break data += buf return _ic9x_parse_frames(data) def ic9x_send(pipe, buf): """Send @buf to @pipe, wrapped in a header and trailer. Attempt to read any response frames, which are returned as a list""" # Add header and trailer realbuf = b"\xfe\xfe" + buf + b"\xfd" # LOG.debug("Sending:\n%s" % util.hexprint(realbuf)) pipe.write(realbuf) pipe.flush() return ic9x_recv(pipe) class IC92Frame: """IC9x frame base class""" def get_vfo(self): """Return the vfo number""" return ord(self._map[0]) def set_vfo(self, vfo): """Set the vfo number""" self._map[0] = vfo def from_raw(self, data): """Construct the frame from raw data""" self._map = MemoryMapBytes(data) def from_frame(self, frame): """Construct the frame by copying another frame""" self._map = MemoryMapBytes(frame.get_raw()) def __init__(self, subcmd=0, flen=0, cmd=0x1A): self._map = MemoryMapBytes(b"\x00" * (4 + flen)) self._map[0] = b"\x01\x80" + bytes([cmd, subcmd]) def get_payload(self): """Return the entire payload (sans header)""" return MemoryMapBytes(self._map[4:]) def get_raw(self): """Return the raw version of the frame""" return self._map.get_byte_compatible().get_packed() def __str__(self): string = "Frame VFO=%i (len = %i)\n" % (self.get_vfo(), len(self.get_payload())) string += util.hexprint(self.get_payload()) string += "\n" return string def send(self, pipe, verbose=False): """Send the frame to the radio via @pipe""" if verbose: LOG.debug("Sending:\n%s" % util.hexprint(self.get_raw())) response = ic9x_send(pipe, self.get_raw()) while (response and len(response[0].get_raw()) > 4 and response[0].get_raw()[4] != self.get_raw()[4]): LOG.warning('Skipping unexpected frame:\n%s', util.hexprint(response[0].get_raw())) response = ic9x_recv(pipe) if not response: raise errors.InvalidDataError("No response from radio") return response[0] def __setitem__(self, start, value): self._map[start+4] = value def __getitem__(self, index): return self.get_payload()[index] def __getslice__(self, start, end): return self._map[start+4:end+4] class IC92GetBankFrame(IC92Frame): """A frame for requesting bank information""" def __init__(self): IC92Frame.__init__(self, 0x09) def send(self, pipe, verbose=False): rframes = ic9x_send(pipe, self.get_raw()) if len(rframes) == 0: raise errors.InvalidDataError("No response from radio") return rframes class IC92BankFrame(IC92Frame): """A frame for bank information""" def __init__(self): # 1 byte for identifier # 8 bytes for name IC92Frame.__init__(self, 0x0B, 9) def get_name(self): """Return the bank name""" return self[1:] def get_identifier(self): """Return the letter for the bank (A-Z)""" return self[0] def set_name(self, name): """Set the bank name""" self[1] = name[:8].ljust(8) def set_identifier(self, ident): """Set the letter for the bank (A-Z)""" self[0] = ident[0] class IC92MemClearFrame(IC92Frame): """A frame for clearing (erasing) a memory""" def __init__(self, loc): # 2 bytes for location # 1 byte for 0xFF IC92Frame.__init__(self, 0x00, 4) self[0] = struct.pack(">BHB", 1, int("%i" % loc, 16), 0xFF) class IC92MemGetFrame(IC92Frame): """A frame for requesting a memory""" def __init__(self, loc, iscall=False): # 2 bytes for location IC92Frame.__init__(self, 0x00, 3) if iscall: call = 2 else: call = 1 self[0] = struct.pack(">BH", call, int("%i" % loc, 16)) class IC92GetCallsignFrame(IC92Frame): """A frame for getting callsign information""" def __init__(self, calltype, number): IC92Frame.__init__(self, calltype, 1, 0x1D) self[0] = chr(number) class IC92CallsignFrame(IC92Frame): """A frame to communicate callsign information""" command = 0 # Invalid width = 8 def __init__(self, number=0, callsign=""): # 1 byte for index # $width bytes for callsign IC92Frame.__init__(self, self.command, self.width+1, 0x1D) self[0] = chr(number) + callsign[:self.width].ljust(self.width) def get_callsign(self): """Return the actual callsign""" return self[1:self.width+1].rstrip() class IC92YourCallsignFrame(IC92CallsignFrame): """URCALL frame""" command = 6 # Your class IC92RepeaterCallsignFrame(IC92CallsignFrame): """RPTCALL frame""" command = 7 # Repeater class IC92MyCallsignFrame(IC92CallsignFrame): """MYCALL frame""" command = 8 # My width = 12 # 4 bytes for /STID MEMORY_FRAME_FORMAT = """ struct { u8 vfo; bbcd number[2]; lbcd freq[5]; lbcd offset[4]; u8 unknown8; bbcd rtone[2]; bbcd ctone[2]; bbcd dtcs[2]; u8 unknown9[2]; u8 unknown2:1, mode:3, tuning_step:4; u8 unknown1:3, tmode: 3, duplex: 2; u8 unknown5:4, dtcs_polarity:2, pskip:1, skip:1; char bank; bbcd bank_index[1]; char name[8]; u8 unknown10; u8 digital_code; char rpt2call[8]; char rpt1call[8]; char urcall[8]; } mem[1]; """ class IC92MemoryFrame(IC92Frame): """A frame for communicating memory information""" def __init__(self): IC92Frame.__init__(self, 0, DV_MEM_LEN) # For good measure, here is a whole, valid memory block # at 146.010 FM. Since the 9x will complain if any bits # are invalid, it's easiest to start with a known-good one # since we don't set everything. self[0] = \ b"\x01\x00\x03\x00\x00\x01\x46\x01" + \ b"\x00\x00\x60\x00\x00\x08\x85\x08" + \ b"\x85\x00\x23\x22\x80\x06\x00\x00" + \ b"\x00\x00\x20\x20\x20\x20\x20\x20" + \ b"\x20\x20\x00\x00\x20\x20\x20\x20" + \ b"\x20\x20\x20\x20\x4b\x44\x37\x52" + \ b"\x45\x58\x20\x43\x43\x51\x43\x51" + \ b"\x43\x51\x20\x20" def set_vfo(self, vfo): IC92Frame.set_vfo(self, vfo) if vfo == 1: self._map.truncate(MEM_LEN + 4) def set_iscall(self, iscall): """This frame refers to a call channel if @iscall is True""" if iscall: self[0] = 2 else: self[0] = 1 def get_iscall(self): """Return True if this frame refers to a call channel""" return ord(self[0]) == 2 def set_memory(self, mem): """Take Memory object @mem and configure the frame accordingly""" if mem.number < 0: self.set_iscall(True) mem.number = abs(mem.number) - 1 LOG.debug("Memory is %i (call %s)" % (mem.number, self.get_iscall())) _mem = bitwise.parse(MEMORY_FRAME_FORMAT, self).mem _mem.number = mem.number _mem.freq = mem.freq _mem.offset = mem.offset _mem.rtone = int(mem.rtone * 10) _mem.ctone = int(mem.ctone * 10) _mem.dtcs = int(mem.dtcs) _mem.mode = MODES.index(mem.mode) _mem.tuning_step = TUNING_STEPS.index(mem.tuning_step) _mem.duplex = DUPLEX.index(mem.duplex) _mem.tmode = TMODES.index(mem.tmode) _mem.dtcs_polarity = DTCS_POL.index(mem.dtcs_polarity) if mem._bank is not None: _mem.bank = chr(ord("A") + mem._bank) _mem.bank_index = mem._bank_index _mem.skip = mem.skip == "S" _mem.pskip = mem.skip == "P" _mem.name = mem.name.ljust(8)[:8] if mem.mode == "DV": _mem.urcall = mem.dv_urcall.upper().ljust(8)[:8] _mem.rpt1call = mem.dv_rpt1call.upper().ljust(8)[:8] _mem.rpt2call = mem.dv_rpt2call.upper().ljust(8)[:8] _mem.digital_code = mem.dv_code def get_memory(self): """Return a Memory object based on the contents of the frame""" _mem = bitwise.parse(MEMORY_FRAME_FORMAT, self.get_payload()).mem if MODES[_mem.mode] == "DV": mem = IC9xDVMemory() else: mem = IC9xMemory() mem.number = int(_mem.number) if self.get_iscall(): mem.number = -1 - mem.number mem.freq = int(_mem.freq) mem.offset = int(_mem.offset) mem.rtone = int(_mem.rtone) / 10.0 mem.ctone = int(_mem.ctone) / 10.0 mem.dtcs = int(_mem.dtcs) mem.mode = MODES[int(_mem.mode)] mem.tuning_step = TUNING_STEPS[int(_mem.tuning_step)] mem.duplex = DUPLEX[int(_mem.duplex)] mem.tmode = TMODES[int(_mem.tmode)] mem.dtcs_polarity = DTCS_POL[int(_mem.dtcs_polarity)] if int(_mem.bank) != 0: mem._bank = ord(str(_mem.bank)) - ord("A") mem._bank_index = int(_mem.bank_index) if _mem.skip: mem.skip = "S" elif _mem.pskip: mem.skip = "P" else: mem.skip = "" mem.name = str(_mem.name).rstrip() if mem.mode == "DV": mem.dv_urcall = str(_mem.urcall).rstrip() mem.dv_rpt1call = str(_mem.rpt1call).rstrip() mem.dv_rpt2call = str(_mem.rpt2call).rstrip() mem.dv_code = int(_mem.digital_code) return mem def get_memory_frame(pipe, vfo, number): """Get the memory frame for @vfo and @number via @pipe""" if number < 0: number = abs(number + 1) call = True else: call = False frame = IC92MemGetFrame(number, call) frame.set_vfo(vfo) return frame.send(pipe) def get_memory(pipe, vfo, number): """Get a memory object for @vfo and @number via @pipe""" rframe = get_memory_frame(pipe, vfo, number) if len(rframe.get_payload()) < 1: raise errors.InvalidMemoryLocation("No response from radio") if rframe.get_payload()[3] == b'\xff': raise errors.InvalidMemoryLocation("Radio says location is empty") mf = IC92MemoryFrame() mf.from_frame(rframe) if mf.get_memory().number != number: raise errors.RadioError('get_memory() wanted %i got %i' % ( number, mf.get_memory().number)) return mf.get_memory() def set_memory(pipe, vfo, memory): """Set memory @memory on @vfo via @pipe""" frame = IC92MemoryFrame() frame.set_memory(memory) frame.set_vfo(vfo) # LOG.debug("Sending (%i):" % (len(frame.get_raw()))) # LOG.debug(util.hexprint(frame.get_raw())) rframe = frame.send(pipe) if rframe.get_raw()[2] != 0xfb: raise errors.InvalidDataError("Radio reported error:\n%s" % util.hexprint(rframe.get_payload())) def erase_memory(pipe, vfo, number): """Erase memory @number on @vfo via @pipe""" frame = IC92MemClearFrame(number) frame.set_vfo(vfo) rframe = frame.send(pipe) if rframe.get_raw()[2] != 0xfb: raise errors.InvalidDataError("Radio reported error") def get_banks(pipe, vfo): """Get banks for @vfo via @pipe""" frame = IC92GetBankFrame() frame.set_vfo(vfo) rframes = frame.send(pipe) if vfo == 1: base = 180 else: base = 237 banks = [] for i in range(base, base+26): bframe = IC92BankFrame() bframe.from_frame(rframes[i]) banks.append(bframe.get_name().rstrip()) return banks def set_banks(pipe, vfo, banks): """Set banks for @vfo via @pipe""" for i in range(0, 26): bframe = IC92BankFrame() bframe.set_vfo(vfo) bframe.set_identifier(chr(i + ord("A"))) bframe.set_name(banks[i]) rframe = bframe.send(pipe) if rframe.get_payload() != "\xfb": raise errors.InvalidDataError("Radio reported error") def get_call(pipe, cstype, number): """Get @cstype callsign @number via @pipe""" cframe = IC92GetCallsignFrame(cstype.command, number) cframe.set_vfo(2) rframe = cframe.send(pipe) cframe = IC92CallsignFrame() cframe.from_frame(rframe) return cframe.get_callsign() def set_call(pipe, cstype, number, call): """Set @cstype @call at position @number via @pipe""" cframe = cstype(number, call) cframe.set_vfo(2) rframe = cframe.send(pipe) if rframe.get_payload() != "\xfb": raise errors.RadioError("Radio reported error") chirp-20240224/chirp/drivers/ft4.py0000644000175000017500000015163214527622514015706 0ustar hibbyhibby# Copyright 2019 Dan Clemmensen # Derives loosely from two sources released under GPLv2: # ./template.py, Copyright 2012 Dan Smith # ./ft60.py, Copyright 2011 Dan Smith # Edited 2020, 2023 Bernhard Hailer AE6YN # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ CHIRP driver for Yaesu radios that use the SCU-35 cable. This includes at least the FT-4X, FT-4V, FT-65, and FT-25. This driver will not work with older Yaesu models. """ import logging import struct import copy from chirp import chirp_common, directory, memmap, bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueString, RadioSettings LOG = logging.getLogger(__name__) # Layout of Radio memory image. # This module and the serial protocol treat the FT-4 memory as 16-byte blocks. # There in nothing magic about 16-byte blocks, but it simplifies the # description. There are 17 groups of blocks, each with a different purpose # and format. Five groups consist of channel memories, or "mems" in CHIRP. # A "mem" describes a radio channel, and all "mems" have the same internal # format. Three of the groups consist of bitmaps, which all have the same # internal mapping. also groups for Name, misc, DTMF digits, and prog, # plus some unused groups. The MEM_FORMAT describes the radio image memory. # MEM_FORMAT is parsed in module ../bitwise.py. Syntax is similar but not # identical to C data and structure definitions. # Define the structures for each type of group here, but do not associate them # with actual memory addresses yet MEM_FORMAT = """ struct slot { u8 tx_pwr; //0, 1, 2 == lo, medium, high bbcd freq[4]; // Hz/10 but must end in 00 u8 tx_ctcss; //see ctcss table, but radio code = CHIRP code+1. 0==off u8 rx_ctcss; //see ctcss table, but radio code = CHIRP code+1. 0==off u8 tx_dcs; //see dcs table, but radio code = CHIRP code+1. 0==off u8 rx_dcs; //see dcs table, but radio code = CHIRP code+1. 0==off u8 unknown1:5, duplex:3; //(auto,offset). (0,2,4,5)= (+,-,0, auto) ul16 offset; //little-endian binary * scaler, +- per duplex //scaler is 25 kHz for FT-4, 50 kHz for FT-65. u8 unknown2:7, tx_width:1; //0=wide, 1=narrow u8 step; //STEPS (0-9)=(auto,5,6.25,10,12.5,15,20,25,50,100) kHz u8 sql_type; //(0-6)==(off,r-tone,t-tone,tsql,rev tn,dcs,pager) u8 unused; }; // one bit per channel. 220 bits (200 mem+ 2*10 PMS) padded to fill //exactly 2 blocks struct bitmap { u8 b8[28]; u8 unused[4]; }; //name struct occupies half a block (8 bytes) //the code restricts the actual len to 6 for an FT-4 struct name { u8 chrs[8]; //[0-9,A-z,a-z, -] padded with spaces }; //txfreq struct occupies 4 bytes (1/4 slot) struct txfreq { bbcd freq[4]; }; //miscellaneous params. One 4-block group. //"SMI": "Set Mode Index" of the FT-4 radio keypad function to set parameter. //"SMI numbers on the FT-65 are different but the names in mem are the same. struct misc { u8 apo; //SMI 01. 0==off, (1-24) is the number of half-hours. u8 arts_beep; //SMI 02. 0==off, 1==inrange, 2==always u8 arts_intv; //SMI 03. 0==25 seconds, 1==15 seconds u8 battsave; //SMI 32. 0==off, (1-5)==(200,300,500,1000,2000) ms u8 bclo; //SMI 04. 0==off, 1==on u8 beep; //SMI 05. (0-2)==(key+scan,key, off) u8 bell; //SMI 06. (0-5)==(0,1,3,5,8,continuous) bells u8 cw_id[6]; //SMI 08. callsign (A_Z,0-9) (pad with space if <6) u8 unknown1[3]; // addr= 2010 u8 dtmf_mode; //SMI 12. 0==manual, 1==auto u8 dtmf_delay; //SMI 11. (0-4)==(50,250,450,750,1000) ms u8 dtmf_speed; //SMI 13. (0,1)=(50,100) ms u8 edg_beep; //SMI 14. 0==off, 1==on u8 key_lock; //SMI 18. (0-2)==(key,ptt,key+ptt) u8 lamp; //SMI 15. (0-4)==(5,10,30,continuous,off) secKEY u8 tx_led; //SMI 17. 0==off, 1==on u8 bsy_led; //SMI 16. 0==off, 1==on u8 moni_tcall; //SMI 19. (0-4)==(mon,1750,2100,1000,1450) tcall Hz. u8 pri_rvt; //SMI 23. 0==off, 1==on u8 scan_resume; //SMI 34. (0-2)==(busy,hold,time) u8 rf_squelch; //SMI 28. 0==off, 8==full, (1-7)==(S1-S7) u8 scan_lamp; //SMI 33 0==off,1==on u8 unknown2; u8 use_cwid; //SMI 7. 0==no, 1==yes u8 compander; // compander on FT_65 // addr 2020 u8 unknown3; u8 tx_save; //SMI 41. 0==off, 1==on (addr==2021) u8 vfo_spl; //SMI 42. 0==off, 1==on u8 vox; //SMI 43. 0==off, 1==on u8 wfm_rcv; //SMI 44. 0==off, 1==on u8 unknown4; u8 wx_alert; //SMI 46. 0==off, 1==0n u8 tot; //SMI 39. 0-off, (1-30)== (1-30) minutes u8 pager_tx1; //SMI 21. (0-49)=(1-50) epcs code (i.e., value is code-1) u8 pager_tx2; //SMI 21 same u8 pager_rx1; //SMI 23 same u8 pager_rx2; //SMI 23 same u8 pager_ack; //SMI 22 same u8 unknown5[3]; //possibly sql_setting and pgm_vfo_scan on FT-65? // addr 2030 u8 use_passwd; //SMI 26 0==no, 1==yes u8 passwd[4]; //SMI 27 ASCII (0-9) u8 unused2[11]; // pad out to a block boundary }; struct dtmfset { u8 digit[16]; //ASCII (*,#,-,0-9,A-D). (dash-filled) }; // area to be filled with 0xff, or just ignored struct notused { u8 unused[16]; }; // areas we are still analyzing struct unknown { u8 notknown[16]; }; struct progc { u8 usage; //P key is (0-2) == unused, use P channel, use parm u8 submode:2, //if parm!=0 submode 0-3 of mode parm:6; //if usage == 2: if 0, use m-channel, else mode }; """ # Actual memory layout. 0x215 blocks, in 20 groups. MEM_FORMAT += """ #seekto 0x0000; struct unknown radiotype; //0000 probably a radio type ID but not sure struct slot memory[200]; //0010 channel memory array struct slot pms[20]; //0c90 10 PMS (L,U) slot pairs struct slot vfo[5]; //0dd0 VFO (A UHF, A VHF, B FM, B UHF, B VHF) struct slot home[3]; //0e20 Home (FM, VHF, UHF) struct bitmap enable; //0e50 struct bitmap scan; //0e70 struct notused notused0; //0e90 struct bitmap bankmask[10]; //0ea0 struct notused notused1[2]; //0fe0 struct name names[220]; //1000 220 names in 110 blocks struct notused notused2[2]; //16e0 struct txfreq txfreqs[220]; //1700 220 freqs in 55 blocks struct notused notused3[89]; //1a20 struct misc settings; //2000 4-block collection of misc params struct notused notused4[2]; //2040 struct dtmfset dtmf[9]; //2060 sets 1-9 struct notused notused5; //20f0 //struct progs progkeys; //2100 not a struct. bitwise.py refuses struct progc progctl[4]; //2100 8 bytes. 1 2-byte struct per P key u8 pmemndx[4]; //2108 4 bytes, 1 per P key u8 notused6[4]; //210c fill out the block struct slot prog[4]; //2110 P key "channel" array //---------------- end of FT-4 mem? """ # The remaining mem is (apparently) not available on the FT4 but is # reported to be available on the FT-65. Not implemented here yet. # Possibly, memory-mapped control registers that allow for "live-mode" # operation instead of "clone-mode" operation. # 2150 27ff (unused?) # 2800 285f 6 MRU operation? # 2860 2fff (unused?) # 3000 310f 17 (version info, etc?) # ----------END of memory map # Begin Serial transfer utilities for the SCU-35 cable. # The serial transfer protocol was implemented here after snooping the wire. # After it was implemented, we noticed that it is identical to the protocol # implemented in th9000.py. A non-echo version is implemented in anytone_ht.py. # # The pipe.read and pipe.write functions use bytes, not strings. The serial # transfer utilities operate only to move data between the memory object and # the serial port. The code runs on either Python 2 or Python3, so some # constructs could be better optimized for one or the other, but not both. def get_mmap_data(radio): """ horrible kludge needed until we convert entirely to Python 3 OR we add a slightly less horrible kludge to the Py2 or Py3 versions of memmap.py. The minimal change have Py3 code return a bytestring instead of a string. This is the only function in this module that must explicitly test for the data string type. It is used only in the do_upload function. returns the memobj data as a byte-like object. """ data = radio.get_mmap().get_packed() if isinstance(data, bytes): return data return bytearray(radio.get_mmap()._data) def checkSum8(data): """ Calculate the 8 bit checksum of buffer Input: buffer - bytes returns: integer """ return sum(x for x in bytearray(data)) & 0xFF def variable_len_resp(pipe): """ when length of expected reply is not known, read byte at a time until the ack character is found. """ response = b"" i = 0 toolong = 256 # arbitrary while True: b = pipe.read(1) if b == b'\x06': break else: response += b i += 1 if i > toolong: LOG.debug("Response too long. got" + util.hexprint(response)) raise errors.RadioError("Response from radio too long.") return response def sendcmd(pipe, cmd, response_len, retry=0): """ send a command bytelist to radio,receive and return the resulting bytelist. Input: pipe - serial port object to use cmd - bytes to send response_len - number of bytes of expected response, not including the ACK. (if None, read until ack) This cable is "two-wire": The TxD and RxD are "or'ed" so we receive whatever we send and then whatever response the radio sends. We check the echo and strip it, returning only the radio's response. We also check and strip the ACK character at the end of the response. """ pipe.write(cmd) echo = pipe.read(len(cmd)) if echo != cmd: msg = "Bad echo. Sent:" + util.hexprint(cmd) + ", " msg += "Received:" + util.hexprint(echo) LOG.debug(msg) raise errors.RadioError( "Incorrect echo on serial port. Radio off? Bad cable?") if response_len is None: return variable_len_resp(pipe) if response_len > 0: response = pipe.read(response_len) else: response = b"" ack = pipe.read(1) if ack != b'\x06': if retry < 5: LOG.debug("retry: " + str(retry)) retry += 1 return sendcmd(pipe, cmd, response_len, retry) else: LOG.debug("missing ack: expected 0x06, got" + util.hexprint(ack)) raise errors.RadioError("Incorrect ACK on serial port.") return response def enter_clonemode(radio): """ Send the PROGRAM command and check the response. Retry if needed. After 3 tries, send an "END" and try some more if it is acknowledged. """ for use_end in range(0, 3): for i in range(0, 3): try: if b"QX" == sendcmd(radio.pipe, b"PROGRAM", 2): return except Exception: continue sendcmd(radio.pipe, b"END", 0) raise errors.RadioError("expected QX from radio.") def startcomms(radio, way): """ For either upload or download, put the radio into PROGRAM mode and check the radio's ID. In this preliminary version of the driver, the exact nature of the ID has been inferred from a single test case. set up the progress bar send "PROGRAM" to command the radio into clone mode read the initial string (version?) """ progressbar = chirp_common.Status() progressbar.msg = "Cloning " + way + " radio" progressbar.max = radio.numblocks enter_clonemode(radio) id_response = sendcmd(radio.pipe, b'\x02', None) # The last byte of the ID contains info about regional differences radio.subtype = id_response[-1] # Set last byte of the ID zero so that no ID warning is thrown # Unfortunately, the returned object is an immutable bytes object, # so we need to convert into a bytearray, modify, and convert back. ba_id_response = bytearray(id_response) ba_id_response[len(ba_id_response) - 1] = 0 id_response_mod = bytes(ba_id_response) if id_response != radio.id_str: substr0 = radio.id_str[:radio.id_str.find(b'\x00')] if id_response[:id_response.find(b'\x00')] != substr0: msg = "ID mismatch. Expected" + util.hexprint(radio.id_str) msg += ", Received:" + util.hexprint(id_response_mod) LOG.warning(msg) raise errors.RadioError("Incorrect ID read from radio.") else: msg = "ID suspect. Expected" + util.hexprint(radio.id_str) msg += ", Received:" + util.hexprint(id_response_mod) LOG.warning(msg) return progressbar def getblock(pipe, addr, image): """ read a single 16-byte block from the radio. send the command and check the response places the response into the correct offset in the supplied bytearray returns True if successful, False if error. """ cmd = struct.pack(">cHb", b"R", addr, 16) response = sendcmd(pipe, cmd, 21) if (response[0] != b"W"[0]) or (response[1:4] != cmd[1:4]): msg = "Bad response. Sent:\n%s" % util.hexprint(cmd) msg += "\nReceived:\n%s" % util.hexprint(response) LOG.debug(msg) return False if checkSum8(response[1:20]) != bytearray(response)[20]: LOG.debug("Bad checksum:\n%s" % util.hexprint(response)) LOG.debug('%r != %r' % (checkSum8(response[1:20]), bytearray(response)[20])) return False image[addr:addr+16] = response[4:20] return True def do_download(radio): """ Read memory from the radio. call startcomms to go into program mode and check version create an mmap read the memory blocks and place the data into the mmap send "END" """ image = bytearray(radio.get_memsize()) pipe = radio.pipe # Get the serial port connection progressbar = startcomms(radio, "from") for blocknum in range(radio.numblocks): for i in range(0, 3): if getblock(pipe, 16 * blocknum, image): break if i == 2: raise errors.RadioError( "read block from radio failed 3 times") progressbar.cur = blocknum radio.status_fn(progressbar) sendcmd(pipe, b"END", 0) return memmap.MemoryMapBytes(bytes(image)) def putblock(pipe, addr, data): """ write a single 16-byte block to the radio send the command and check the response """ chkstr = struct.pack(">Hb", addr, 16) + data msg = b'W' + chkstr + struct.pack('B', checkSum8(chkstr)) + b'\x06' sendcmd(pipe, msg, 0) def do_upload(radio): """ Write memory image to radio call startcomms to go into program mode and check version write the memory blocks. Skip the first block send "END" """ pipe = radio.pipe # Get the serial port connection progressbar = startcomms(radio, "to") data = get_mmap_data(radio) for _i in range(1, radio.numblocks): putblock(pipe, 16*_i, data[16*_i:16*(_i+1)]) progressbar.cur = _i radio.status_fn(progressbar) sendcmd(pipe, b"END", 0) return # End serial transfer utilities def bit_loc(bitnum): """ return the ndx and mask for a bit location """ return (bitnum // 8, 1 << (bitnum & 7)) def store_bit(bankmem, bitnum, val): """ store a bit in a bankmem. Store 0 or 1 for False or True """ ndx, mask = bit_loc(bitnum) if val: bankmem.b8[ndx] |= mask else: bankmem.b8[ndx] &= ~mask return def retrieve_bit(bankmem, bitnum): """ return True or False for a bit in a bankmem """ ndx, mask = bit_loc(bitnum) return (bankmem.b8[ndx] & mask) != 0 # A bank is a bitmap of 220 bits. 200 mem slots and 2*10 PMS slots. # There are 10 banks. class YaesuSC35GenericBankModel(chirp_common.BankModel): def get_num_mappings(self): return 10 def get_mappings(self): banks = [] for i in range(1, 1 + self.get_num_mappings()): bank = chirp_common.Bank(self, "%i" % i, "Bank %i" % i) bank.index = i - 1 banks.append(bank) return banks def add_memory_to_mapping(self, memory, bank): bankmem = self._radio._memobj.bankmask[bank.index] store_bit(bankmem, memory.number-1, True) def remove_memory_from_mapping(self, memory, bank): bankmem = self._radio._memobj.bankmask[bank.index] if not retrieve_bit(bankmem, memory.number-1): raise Exception("Memory %i is not in bank %s." % (memory.number, bank)) store_bit(bankmem, memory.number-1, False) # return a list of slots in a bank def get_mapping_memories(self, bank): memories = [] for i in range(*self._radio.get_features().memory_bounds): if retrieve_bit(self._radio._memobj.bankmask[bank.index], i - 1): memories.append(self._radio.get_memory(i)) return memories # return a list of banks a slot is a member of def get_memory_mappings(self, memory): memndx = memory.number - 1 banks = [] for bank in self.get_mappings(): if retrieve_bit(self._radio._memobj.bankmask[bank.index], memndx): banks.append(bank) return banks # the values in these lists must also be in the canonical UI list # we can re-arrange the order, and we don't need to have all # the values, but we cannot add our own values here. DUPLEX = ["+", "", "-", "", "off", "", "split"] # (0,2,4,5) = (+, -, 0, auto) # The radio implements duplex "auto" as 5. We map to "". It is a convenience # function in the radio that affects the offset, which sets the duplex value # according to the frequency in use. Yaesu doesn't entirely adhere to the band # plans; but worse, they save the value 'auto' instead of + or -. Why Yaesu # is doing such a thing is beyond me. [AE6YN] DUPLEX_AUTO_US = [ [145100000, 145495000, 2], [146000000, 146395000, 0], [146600000, 146995000, 2], [147000000, 147395000, 0], [147600000, 147995000, 2]] # (There are no automatic duplex values in IARU-2 70CM.) DUPLEX_AUTO_EU = [ [145600000, 145800000, 2], [438200000, 439425000, 2]] SKIPS = ["S", ""] POWER_LEVELS = [ chirp_common.PowerLevel("High", watts=5.0), # high must be first (0) chirp_common.PowerLevel("Mid", watts=2.5), chirp_common.PowerLevel("Low", watts=0.5)] # these steps encode to 0-9 on all radios, but encoding #2 is disallowed # on the US versions (FT-4XR) STEP_CODE = [0, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] US_LEGAL_STEPS = list(STEP_CODE) # copy to pass to UI on US radios US_LEGAL_STEPS.remove(6.25) # euro radios just use STEP_CODE # Map the radio image sql_type (0-6) to the CHIRP mem values. # Yaesu "TSQL" and "DCS" each map to different CHIRP values depending on the # radio values of the tx and rx tone codes. The table is a list of rows, one # per Yaesu sql_type (0-5). The code does not use this table when the sql_type # is 6 (PAGER). Each row is a tuple. Its first member is a list of # [tmode,cross] or [tmode, cross, suppress]. "Suppress" is used only when # encoding UI-->radio. When decoding radio-->UI, two of the sql_types each # result in 5 possible UI decodings depending on the tx and rx codes, and the # list in each of these rows has five members. These two row tuples each have # two additional members to specify which of the radio fields to examine. # The map from CHIRP UI to radio image types is also built from this table. RADIO_TMODES = [ ([["", None], ], ), # sql_type= 0. off ([["Cross", "->Tone"], ], ), # sql_type= 1. R-TONE ([["Tone", None], ], ), # sql_type= 2. T-TONE ([ # sql_type= 3. TSQL: ["", None], # tx==0, rx==0 : invalid ["TSQL", None], # tx==0 ["Tone", None], # rx==0 ["Cross", "Tone->Tone"], # tx!=rx ["TSQL", None] # tx==rx ], "tx_ctcss", "rx_ctcss"), # tx and rx fields to check ([["TSQL-R", None], ], ), # sql_type= 4. REV TN ([ # sql_type= 5.DCS: ["", None], # tx==0, rx==0 : invalid ["Cross", "->DTCS", "tx_dcs"], # tx==0. suppress tx ["Cross", "DTCS->", "rx_dcs"], # rx==0. suppress rx ["Cross", "DTCS->DTCS"], # tx!=rx ["DTCS", None] # tx==rx ], "tx_dcs", "rx_dcs"), # tx and rx fields to check # # sql_type= 6. PAGER is a CHIRP "extra" ] # Find all legal values for the tmode and cross fields for the UI. # We build two dictionaries to do the lookups when encoding. # The reversed range is a kludge: by happenstance, earlier duplicates # in the above table are the preferred mapping, they override the # later ones when we process the table backwards. TONE_DICT = {} # encode sql_type. CROSS_DICT = {} # encode sql_type. for sql_type in reversed(range(0, len(RADIO_TMODES))): sql_type_row = RADIO_TMODES[sql_type] for decode_row in sql_type_row[0]: suppress = None if len(decode_row) == 3: suppress = decode_row[2] TONE_DICT[decode_row[0]] = (sql_type, suppress) if decode_row[1]: CROSS_DICT[decode_row[1]] = (sql_type, suppress) # The keys are added to the "VALID" lists using code that puts those lists # in the same order as the UI's default order instead of the random dict # order or the arbitrary build order. VALID_TONE_MODES = [] # list for UI. VALID_CROSS_MODES = [] # list for UI. for name in chirp_common.TONE_MODES: if name in TONE_DICT: VALID_TONE_MODES += [name] for name in chirp_common.CROSS_MODES: if name in CROSS_DICT: VALID_CROSS_MODES += [name] DTMF_CHARS = "0123456789ABCD*#- " CW_ID_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ " PASSWD_CHARS = "0123456789" CHARSET = CW_ID_CHARS + "abcdefghijklmnopqrstuvwxyz*+-/@" PMSNAMES = ["%s%02d" % (c, i) for i in range(1, 11) for c in ('L', 'U')] # Four separate arrays of special channel mems. # Each special has unique constraints: band, name yes/no, and pms L/U # The FT-65 class replaces the "prog" entry in this list. # The name field must be the name of a slot array in MEM_FORMAT SPECIALS_FT4 = [ ("pms", PMSNAMES), ("vfo", ["VFO A UHF", "VFO A VHF", "VFO B FM", "VFO B VHF", "VFO B UHF"]), ("home", ["HOME FM", "HOME VHF", "HOME UHF"]), ("prog", ["P1", "P2"]) ] SPECIALS_FT65 = SPECIALS_FT4 FT65_PROGS = ("prog", ["P1", "P2", "P3", "P4"]) SPECIALS_FT65[-1] = FT65_PROGS # replace the last entry (P key names) VALID_BANDS_DUAL = [ (65000000, 108000000), # broadcast FM, receive only (136000000, 174000000), # VHF (400000000, 480000000) # UHF ] VALID_BANDS_VHF = [ (65000000, 108000000), # broadcast FM, receive only (136000000, 174000000), # VHF ] # bands for the five VFO and three home channel memories BAND_ASSIGNMENTS_DUALBAND = [2, 1, 0, 1, 2, 0, 1, 2] # all locations used BAND_ASSIGNMENTS_MONO_VHF = [1, 1, 0, 1, 1, 0, 1, 1] # UHF locations unused # None, and 50 Tones. Use this explicit array because the # one in chirp_common could change and no longer describe our radio TONE_MAP = [ None, 67.0, 69.3, 71.9, 74.4, 77.0, 79.7, 82.5, 85.4, 88.5, 91.5, 94.8, 97.4, 100.0, 103.5, 107.2, 110.9, 114.8, 118.8, 123.0, 127.3, 131.8, 136.5, 141.3, 146.2, 151.4, 156.7, 159.8, 162.2, 165.5, 167.9, 171.3, 173.8, 177.3, 179.9, 183.5, 186.2, 189.9, 192.8, 196.6, 199.5, 203.5, 206.5, 210.7, 218.1, 225.7, 229.1, 233.6, 241.8, 250.3, 254.1 ] # None, and 104 DTCS Codes. Use this explicit array because the # one in chirp_common could change and no longer describe our radio DTCS_MAP = [ None, 23, 25, 26, 31, 32, 36, 43, 47, 51, 53, 54, 65, 71, 72, 73, 74, 114, 115, 116, 122, 125, 131, 132, 134, 143, 145, 152, 155, 156, 162, 165, 172, 174, 205, 212, 223, 225, 226, 243, 244, 245, 246, 251, 252, 255, 261, 263, 265, 266, 271, 274, 306, 311, 315, 325, 331, 332, 343, 346, 351, 356, 364, 365, 371, 411, 412, 413, 423, 431, 432, 445, 446, 452, 454, 455, 462, 464, 465, 466, 503, 506, 516, 523, 526, 532, 546, 565, 606, 612, 624, 627, 631, 632, 654, 662, 664, 703, 712, 723, 731, 732, 734, 743, 754 ] # The legal PAGER codes are the same as the CTCSS codes, but we # pass them to the UI as a list of strings EPCS_CODES = [format(flt) for flt in [0] + TONE_MAP[1:]] # allow a child class to add a param to its class # description list. used when a specific radio class has # a param that is not in the generic list. def add_paramdesc(desc_list, group, param): for description in desc_list: groupname, title, parms = description if group == groupname: description[2].append(param) return class YaesuSC35GenericRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """ Base class for all Yaesu radios using the SCU-35 programming cable and its protocol. Classes for sub families extend this class and are found towards the end of this file. """ VENDOR = "Yaesu" MODEL = "SCU-35Generic" # No radio directly uses the base class BAUD_RATE = 9600 MAX_MEM_SLOT = 200 NEEDS_COMPAT_SERIAL = False # These settings are common to all radios in this family. _valid_chars = chirp_common.CHARSET_ASCII numblocks = 0x215 # number of 16-byte blocks in the radio _memsize = 16 * numblocks # used by CHIRP file loader to guess radio type MAX_MEM_SLOT = 200 # ID string last byte can contain extra info. It is usually 0; # however, on FT25R/65R sold in Asia we have seen that it can be 3, # which affects the scaler: instead of the default 50000 it's then 25000. @property def subtype(self): return self.metadata.get('ft4_subtype', 0) @subtype.setter def subtype(self, value): self.metadata = {'ft4_subtype': int(value)} @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ( 'Tested and mostly works, but may give you issues\n' 'when using lesser common radio variants.\n' 'Proceed at your own risk, and let us know about issues!' ) rp.pre_download = "".join([ "1. Connect programming cable to MIC jack.\n", "2. Press OK." ] ) rp.pre_upload = rp.pre_download return rp # identify the features that can be manipulated on this radio. # mentioned here only when different from defaults in chirp_common.py def get_features(self): rf = chirp_common.RadioFeatures() specials = [name for s in self.class_specials for name in s[1]] rf.valid_special_chans = specials rf.memory_bounds = (1, self.MAX_MEM_SLOT) rf.valid_duplexes = DUPLEX rf.valid_tmodes = VALID_TONE_MODES rf.valid_cross_modes = VALID_CROSS_MODES rf.valid_power_levels = POWER_LEVELS rf.valid_tuning_steps = self.legal_steps rf.valid_skips = SKIPS rf.valid_characters = CHARSET rf.valid_name_length = self.namelen rf.valid_modes = ["FM", "NFM"] rf.valid_bands = self.valid_bands rf.can_odd_split = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = False # REV TN reverses the tone, not the dcs rf.has_cross = True rf.has_settings = True return rf def get_bank_model(self): return YaesuSC35GenericBankModel(self) # read and parse the radio memory def sync_in(self): try: self._mmap = do_download(self) except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() # write the memory image to the radio def sync_out(self): try: do_upload(self) except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # There are about 40 settings and most are handled generically in # get_settings. get_settings invokes these handlers for the few # that are more complicated. # callback for setting byte arrays: DTMF[0-9], passwd, and CW_ID def apply_str_to_bytearray(self, element, obj): lng = len(obj) string = (element.value.get_value() + " ")[:lng] bytes = bytearray(string, "ascii") for x in range(0, lng): # memobj cannot iterate, so byte-by-byte obj[x] = bytes[x] return # add a string value to the RadioSettings def get_string_setting(self, obj, valid_chars, desc1, desc2, group): content = '' maxlen = len(obj) for x in range(0, maxlen): content += chr(obj[x]) val = RadioSettingValueString(0, maxlen, content, True, valid_chars) rs = RadioSetting(desc1, desc2, val) rs.set_apply_callback(self.apply_str_to_bytearray, obj) group.append(rs) # called when found in the group_descriptions table to handle string value def get_strset(self, group, parm): # parm =(paramname, paramtitle,(handler,[handler params])). objname, title, fparms = parm myparms = fparms[1] obj = getattr(self._memobj.settings, objname) self.get_string_setting(obj, myparms[0], objname, title, group) # called when found in the group_descriptions table for DTMF strings def get_dtmfs(self, group, parm): objname, title, fparms = parm for i in range(1, 10): dtmf_digits = self._memobj.dtmf[i - 1].digit self.get_string_setting( dtmf_digits, DTMF_CHARS, "dtmf_%i" % i, "DTMF Autodialer Memory %i" % i, group) def apply_P(self, element, pnum, memobj): memobj.progctl[pnum].usage = element.value def apply_Pmode(self, element, pnum, memobj): memobj.progctl[pnum].parm = element.value def apply_Psubmode(self, element, pnum, memobj): memobj.progctl[pnum].submode = element.value def apply_Pmem(self, element, pnum, memobj): memobj.pmemndx[pnum] = element.value MEMLIST = ["%d" % i for i in range(1, MAX_MEM_SLOT + 1)] + PMSNAMES USAGE_LIST = ["unused", "P channel", "mode or M channel"] # called when found in the group_descriptions table # returns the settings for the programmable keys (P1-P4) def get_progs(self, group, parm): _progctl = self._memobj.progctl _progndx = self._memobj.pmemndx def get_prog(i, val_list, valndx, sname, longname, f_apply): k = str(i + 1) val = val_list[valndx] valuelist = RadioSettingValueList(val_list, val) rs = RadioSetting(sname + k, longname + k, valuelist) rs.set_apply_callback(f_apply, i, self._memobj) group.append(rs) for i in range(0, self.Pkeys): get_prog(i, self.USAGE_LIST, _progctl[i].usage, "P", "Programmable key ", self.apply_P) get_prog(i, self.SETMODES, _progctl[i].parm, "modeP", "mode for Programmable key ", self.apply_Pmode) get_prog(i, ["0", "1", "2", "3"], _progctl[i].submode, "submodeP", "submode for Programmable key ", self.apply_Psubmode) get_prog(i, self.MEMLIST, _progndx[i], "memP", "mem for Programmable key ", self.apply_Pmem) # ------------ End of special settings handlers. # list of group description tuples: [groupame,group title, [param list]]. # A param is a tuple: # for a simple param: (paramname, paramtitle,[valuename list]) # for a handler param: (paramname, paramtitle,( handler,[handler params])) # This is a class variable. subclasses must create a variable named # class_group_descs. The FT-4 classes simply equate this, but the # FT-65 classes must copy and modify this. group_descriptions = [ ("misc", "Miscellaneous Settings", [ # misc ("apo", "Automatic Power Off", ["OFF"] + ["%0.1f" % (x * 0.5) for x in range(1, 24 + 1)]), ("bclo", "Busy Channel Lock-Out", ["OFF", "ON"]), ("beep", "Enable the Beeper", ["KEY+SC", "KEY", "OFF"]), ("bsy_led", "Busy LED", ["ON", "OFF"]), ("edg_beep", "Band Edge Beeper", ["OFF", "ON"]), ("vox", "VOX", ["OFF", "ON"]), ("rf_squelch", "RF Squelch Threshold", ["OFF", "S-1", "S-2", "S-3", "S-4", "S-5", "S-6", "S-7", "S-FULL"]), ("tot", "Timeout Timer", ["OFF"] + ["%dMIN" % (x) for x in range(1, 30 + 1)]), ("tx_led", "TX LED", ["OFF", "ON"]), ("use_cwid", "use CW ID", ["NO", "YES"]), ("cw_id", "CW ID Callsign", (get_strset, [CW_ID_CHARS])), # handler ("vfo_spl", "VFO Split", ["OFF", "ON"]), ("wfm_rcv", "Enable Broadband FM", ["OFF", "ON"]), ("passwd", "Password", (get_strset, [PASSWD_CHARS])) # handler ]), ("arts", "ARTS Settings", [ # arts ("arts_beep", "ARTS BEEP", ["OFF", "INRANG", "ALWAYS"]), ("arts_intv", "ARTS Polling Interval", ["25 SEC", "15 SEC"]) ]), ("ctcss", "CTCSS/DCS/DTMF Settings", [ # ctcss ("bell", "Bell Repetitions", ["OFF", "1T", "3T", "5T", "8T", "CONT"]), ("dtmf_mode", "DTMF Mode", ["Manual", "Auto"]), ("dtmf_delay", "DTMF Autodialer Delay Time", ["50 ms", "100 ms", "250 ms", "450 ms", "750 ms", "1000 ms"]), ("dtmf_speed", "DTMF Autodialer Sending Speed", ["50 ms", "100 ms"]), ("dtmf", "DTMF Autodialer Memory ", (get_dtmfs, [])) # handler ]), ("switch", "Switch/Knob Settings", [ # switch ("lamp", "Lamp Mode", ["5SEC", "10SEC", "30SEC", "KEY", "OFF"]), ("moni_tcall", "MONI Switch Function", ["MONI", "1750", "2100", "1000", "1450"]), ("key_lock", "Lock Function", ["KEY", "PTT", "KEY+PTT"]), ("Pkeys", "Pkey fields", (get_progs, [])) ]), ("scan", "Scan Settings", [ # scan ("scan_resume", "Scan Resume Mode", ["BUSY", "HOLD", "TIME"]), ("pri_rvt", "Priority Revert", ["OFF", "ON"]), ("scan_lamp", "Scan Lamp", ["OFF", "ON"]), ("wx_alert", "Weather Alert Scan", ["OFF", "ON"]) ]), ("power", "Power Saver Settings", [ # power ("battsave", "Receive Mode Battery Save Interval", ["OFF", "200 ms", "300 ms", "500 ms", "1 s", "2 s"]), ("tx_save", "Transmitter Battery Saver", ["OFF", "ON"]) ]), ("eai", "EAI/EPCS Settings", [ # eai ("pager_tx1", "TX pager frequency 1", EPCS_CODES), ("pager_tx2", "TX pager frequency 2", EPCS_CODES), ("pager_rx1", "RX pager frequency 1", EPCS_CODES), ("pager_rx2", "RX pager frequency 2", EPCS_CODES), ("pager_ack", "Pager answerback", ["NO", "YES"]) ]) ] # ----------------end of group_descriptions # returns the current values of all the settings in the radio memory image, # in the form of a RadioSettings list. Uses the class_group_descs # list to create the groups and params. Valuelist scalars are handled # inline. More complex params are built by calling the special handlers. def get_settings(self): _settings = self._memobj.settings groups = RadioSettings() for description in self.class_group_descs: groupname, title, parms = description group = RadioSettingGroup(groupname, title) groups.append(group) for parm in parms: param, title, opts = parm try: if isinstance(opts, list): # setting is a single value from the list objval = getattr(_settings, param) value = opts[objval] valuelist = RadioSettingValueList(opts, value) group.append(RadioSetting(param, title, valuelist)) else: # setting needs special handling. opts[0] is a # function name opts[0](self, group, parm) except Exception as e: LOG.debug( "%s: cannot set %s to %s" % (e, param, repr(objval)) ) return groups # end of get_settings # modify settings values in the radio memory image def set_settings(self, uisettings): _settings = self._memobj.settings for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: name = element.get_name() value = element.value if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: setattr(_settings, name, value) LOG.debug("Setting %s: %s" % (name, value)) except Exception: LOG.debug(element.get_name()) raise # maps a boolean pair (tx==0,rx==0) to the numbers 0-3 LOOKUP = [[True, True], [True, False], [False, True], [False, False]] def decode_sql(self, mem, chan): """ examine the radio channel fields and determine the correct CHIRP CSV values for tmode, cross_mode, and sql_override """ mem.extra = RadioSettingGroup("Extra", "extra") extra_modes = ["(None)", "PAGER"] value = extra_modes[chan.sql_type == 6] valuelist = RadioSettingValueList(extra_modes, value) rs = RadioSetting("sql_override", "Squelch override", valuelist) mem.extra.append(rs) if chan.sql_type == 6: return sql_map = RADIO_TMODES[chan.sql_type] ndx = 0 if len(sql_map[0]) > 1: # the sql_type is TSQL or DCS, so there are multiple UI mappings x = getattr(chan, sql_map[1]) r = getattr(chan, sql_map[2]) ndx = self.LOOKUP.index([x == 0, r == 0]) if ndx == 3 and x == r: ndx = 4 mem.tmode = sql_map[0][ndx][0] cross = sql_map[0][ndx][1] if cross: mem.cross_mode = cross if chan.rx_ctcss: mem.ctone = TONE_MAP[chan.rx_ctcss] if chan.tx_ctcss: mem.rtone = TONE_MAP[chan.tx_ctcss] if chan.tx_dcs: mem.dtcs = DTCS_MAP[chan.tx_dcs] if chan.rx_dcs: mem.rx_dtcs = DTCS_MAP[chan.rx_dcs] def encode_sql(self, mem, chan): """ examine CHIRP's mem.tmode and mem.cross_mode and set the values for the radio sql_type, dcs codes, and ctcss codes. We set all four codes, and then zero out a code if needed when Tone or DCS is one-way """ chan.tx_ctcss = TONE_MAP.index(mem.rtone) chan.tx_dcs = DTCS_MAP.index(mem.dtcs) chan.rx_ctcss = TONE_MAP.index(mem.ctone) chan.rx_dcs = DTCS_MAP.index(mem.rx_dtcs) if mem.tmode == "TSQL": chan.tx_ctcss = chan.rx_ctcss # CHIRP uses ctone for TSQL if mem.tmode == "DTCS": chan.tx_dcs = chan.rx_dcs # CHIRP uses rx_dtcs for DTCS # select the correct internal dictionary and key mode_dict, key = [ (TONE_DICT, mem.tmode), (CROSS_DICT, mem.cross_mode) ][mem.tmode == "Cross"] # now look up that key in that dictionary. chan.sql_type, suppress = mode_dict[key] if suppress: setattr(chan, suppress, 0) for setting in mem.extra: if (setting.get_name() == 'sql_override'): value = str(setting.value) if value == "PAGER": chan.sql_type = 6 return # given a CHIRP memory ref, get the radio memobj for it. # A memref is either a number or the name of a special # CHIRP will sometimes use numbers (>MAX_SLOTS) for specials # returns the obj and several attributes def slotloc(self, memref): array = None num = memref sname = memref if isinstance(memref, str): # named special? num = self.MAX_MEM_SLOT + 1 for x in self.class_specials: try: ndx = x[1].index(memref) array = x[0] break except Exception: num += len(x[1]) if array is None: LOG.debug("unknown Special %s", memref) raise num += ndx elif memref > self.MAX_MEM_SLOT: # numbered special? ndx = memref - (self.MAX_MEM_SLOT + 1) for x in self.class_specials: if ndx < len(x[1]): array = x[0] sname = x[1][ndx] break ndx -= len(x[1]) if array is None: LOG.debug("memref number %d out of range", memref) raise else: # regular memory slot array = "memory" ndx = memref - 1 memloc = getattr(self._memobj, array)[ndx] return (memloc, ndx, num, array, sname) # end of slotloc # return the raw info for a memory channel def get_raw_memory(self, memref): memloc, ndx, num, regtype, sname = self.slotloc(memref) if regtype == "memory": return repr(memloc) else: return repr(memloc) + repr(self._memobj.names[ndx]) # return the info for a memory channel In CHIRP canonical form def get_memory(self, memref): def clean_name(obj): # helper func to tidy up the name name = '' for x in range(0, self.namelen): y = obj[x] if y == 0: break if y == 0x7F: # when programmed from VFO y = 0x20 name += chr(y) return name.rstrip() def get_duplex(freq): # auto duplex to real duplex """ Select the duplex direction if duplex == 'auto'. 0 is +, 2 is -, and 4 is none. """ return_value = 4 # off, if not in auto range for x in self.DUPLEX_AUTO: if freq in range(x[0], x[1]): return_value = x[2] return return_value mem = chirp_common.Memory() _mem, ndx, num, regtype, sname = self.slotloc(memref) mem.number = num freq_offset_factor = self.freq_offset_factor # FT-25R/65R Asia version (US is 0)? if self.subtype == 3 and freq_offset_factor == 2: freq_offset_factor = 1 # 25000 scaler # First, we need to know whether a channel is enabled, # then we can process any channel parameters. # It was found (at least on an FT-25) that channels might be # uninitialized and memory is just completely filled with 0xFF. if regtype == "pms": mem.extd_number = sname if regtype in ["memory", "pms"]: ndx = num - 1 mem.name = clean_name(self._memobj.names[ndx].chrs) mem.empty = not retrieve_bit(self._memobj.enable, ndx) mem.skip = SKIPS[retrieve_bit(self._memobj.scan, ndx)] else: mem.empty = False mem.extd_number = sname mem.immutable = ["number", "extd_number", "name", "skip"] # So, now if channel is not empty, we can do the evaluation of # all parameters. Otherwise we set them to defaults. if mem.empty: mem.freq = 0 mem.offset = 0 mem.duplex = "off" mem.power = POWER_LEVELS[0] # "High" mem.mode = "FM" mem.tuning_step = 0 else: mem.freq = int(_mem.freq) * 10 txfreq = int(self._memobj.txfreqs[ndx].freq) * 10 if _mem.duplex == 5: # auto offset mem.duplex = DUPLEX[get_duplex(mem.freq)] else: mem.duplex = DUPLEX[_mem.duplex] if _mem.duplex == 6: # split: offset is tx frequency mem.offset = txfreq else: mem.offset = int(_mem.offset) * 25000 * freq_offset_factor self.decode_sql(mem, _mem) mem.power = POWER_LEVELS[2 - _mem.tx_pwr] mem.mode = ["FM", "NFM"][_mem.tx_width] mem.tuning_step = STEP_CODE[_mem.step] return mem def enforce_band(self, memloc, freq, mem_num, sname): """ vfo and home channels are each restricted to a particular band. If the frequency is not in the band, use the lower bound Raise an exception to cause UI to pop up an error message """ first_vfo_num = self.MAX_MEM_SLOT + len(PMSNAMES) + 1 band = self.BAND_ASSIGNMENTS[mem_num - first_vfo_num] frange = self.valid_bands[band] if freq >= frange[0] and freq <= frange[1]: memloc.freq = freq / 10 return freq memloc.freq = frange[0] / 10 raise Exception("freq out of range for %s" % sname) # modify a radio channel in memobj based on info in CHIRP canonical form def set_memory(self, mem): _mem, ndx, num, regtype, sname = self.slotloc(mem.number) assert _mem if mem.empty: if regtype in ["memory", "pms"]: store_bit(self._memobj.enable, ndx, False) return txfreq = mem.freq / 10 # really. RX freq is used for TX base _mem.freq = txfreq self.encode_sql(mem, _mem) if mem.power: _mem.tx_pwr = 2 - POWER_LEVELS.index(mem.power) else: _mem.tx_pwr = 0 # set to "High" if CHIRP canonical value is None _mem.tx_width = mem.mode == "NFM" _mem.step = STEP_CODE.index(mem.tuning_step) freq_offset_factor = self.freq_offset_factor # FT-25R/65R Asia version (US version is 0)? if self.subtype == 3 and freq_offset_factor == 2: freq_offset_factor = 1 # 25000 scaler _mem.offset = mem.offset / (25000 * freq_offset_factor) duplex = mem.duplex if regtype in ["memory", "pms"]: ndx = num - 1 store_bit(self._memobj.enable, ndx, True) store_bit(self._memobj.scan, ndx, SKIPS.index(mem.skip)) nametrim = (mem.name + " ")[:8] self._memobj.names[ndx].chrs = bytearray(nametrim, "ascii") if mem.duplex == "split": txfreq = mem.offset / 10 self._memobj.txfreqs[num-1].freq = txfreq _mem.duplex = DUPLEX.index(duplex) if regtype in ["vfo", "home"]: self.enforce_band(_mem, mem.freq, num, sname) return class YaesuFT4GenericRadio(YaesuSC35GenericRadio): """ FT-4 sub family class. Classes for individual radios extend these classes and are found at the end of this file. """ class_specials = SPECIALS_FT4 Pkeys = 2 # number of programmable keys namelen = 6 # length of the mem name display on the front-panel freq_offset_factor = 1 # 25000 * 1 class_group_descs = YaesuSC35GenericRadio.group_descriptions # names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [ "mem", "apo", "ar bep", "ar int", "beclo", # 00-04 "beep", "bell", "cw id", "cw wrt", "dc vlt", # 05-09 "dcs cod", "dt dly", "dt set", "dtc spd", "edg.bep", # 10-14 "lamp", "led.bsy", "led.tx", "lock", "m/t-cl", # 15-19 "mem.del", "mem.tag", "pag.abk", "pag.cdr", "pag.cdt", # 20-24 "pri.rvt", "pswd", "pswdwt", "rf sql", "rpt.ars", # 25-29 "rpt.frq", "rpt.sft", "rxsave", "scn.lmp", "scn.rsm", # 30-34 "skip", "sql.typ", "step", "tn frq", "tot", # 35-39 "tx pwr", "tx save", "vfo.spl", "vox", "wfm.rcv", # 40-44 "w/n.dev", "wx.alert" # 45-46 ] class YaesuFT65GenericRadio(YaesuSC35GenericRadio): """ FT-65 sub family class. Classes for individual radios extend these classes and are found at the end of this file. """ class_specials = SPECIALS_FT65 Pkeys = 4 # number of programmable keys namelen = 8 # length of the mem name display on the front-panel freq_offset_factor = 2 # 25000 * 2 # we need a deep copy here because we are adding deeper than the top level. class_group_descs = copy.deepcopy(YaesuSC35GenericRadio.group_descriptions) add_paramdesc( class_group_descs, "misc", ("compander", "Compander", ["OFF", "ON"])) # names for the setmode function for the programmable keys. Mode zero means # that the key is programmed for a memory not a setmode. SETMODES = [ "mem", "apo", "arts", "battsave", "b-ch.l/o", # 00-04 "beep", "bell", "compander", "ctcss", "cw id", # 05-09 "dc volt", "dcs code", "dtmf set", "dtmf wrt", "edg bep", # 10-14 "key lock", "lamp", "ledbsy", "mem del", "mon/t-cl", # 15-19 "name tag", "pager", "password", "pri.rvt", "repeater", # 20-24 "resume", "rf.sql", "scn.lamp", "skip", "sql type", # 25-29 "step", "tot", "tx pwr", "tx save", "vfo.spl", # 30-34 "vox", "wfm.rcv", "wide/nar", "wx alert", "scramble" # 35-39 ] # Classes for each individual radio. @directory.register class YaesuFT4XRRadio(YaesuFT4GenericRadio): """ FT-4X dual band, US version """ MODEL = "FT-4XR" id_str = b'IFT-35R\x00\x00V100\x00\x00' valid_bands = VALID_BANDS_DUAL DUPLEX_AUTO = DUPLEX_AUTO_US legal_steps = US_LEGAL_STEPS BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_DUALBAND @directory.register class YaesuFT4XERadio(YaesuFT4GenericRadio): """ FT-4X dual band, EU version """ MODEL = "FT-4XE" id_str = b'IFT-35R\x00\x00V100\x00\x00' valid_bands = VALID_BANDS_DUAL DUPLEX_AUTO = DUPLEX_AUTO_EU legal_steps = STEP_CODE BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_DUALBAND @directory.register class YaesuFT4VRRadio(YaesuFT4GenericRadio): """ FT-4V VHF, US version """ MODEL = "FT-4VR" id_str = b'IFT-15R\x00\x00V100\x00\x00' valid_bands = VALID_BANDS_VHF DUPLEX_AUTO = DUPLEX_AUTO_US legal_steps = US_LEGAL_STEPS BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_MONO_VHF # No image available yet # @directory.register # class YaesuFT4VERadio(YaesuFT4GenericRadio): # """ # FT-4V VHF, EU version # """ # MODEL = "FT-4VE" # id_str = b'IFT-15R\x00\x00V100\x00\x00' # valid_bands = VALID_BANDS_VHF # DUPLEX_AUTO = DUPLEX_AUTO_EU # legal_steps = STEP_CODE # BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_MONO_VHF @directory.register class YaesuFT65RRadio(YaesuFT65GenericRadio): """ FT-65 dual band, US/Asia version """ MODEL = "FT-65R" id_str = b'IH-420\x00\x00\x00V100\x00\x00' valid_bands = VALID_BANDS_DUAL DUPLEX_AUTO = DUPLEX_AUTO_US legal_steps = STEP_CODE BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_DUALBAND @directory.register class YaesuFT65ERadio(YaesuFT65GenericRadio): """ FT-65 dual band, EU version """ MODEL = "FT-65E" id_str = b'IH-420\x00\x00\x00V100\x00\x00' valid_bands = VALID_BANDS_DUAL DUPLEX_AUTO = DUPLEX_AUTO_EU legal_steps = STEP_CODE BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_DUALBAND @directory.register class YaesuFT25RRadio(YaesuFT65GenericRadio): """ FT-25 VHF, US/Asia version """ MODEL = "FT-25R" id_str = b'IFT-25R\x00\x00V100\x00\x00' valid_bands = VALID_BANDS_VHF DUPLEX_AUTO = DUPLEX_AUTO_US legal_steps = US_LEGAL_STEPS BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_MONO_VHF # No image available yet # @directory.register # class YaesuFT25ERadio(YaesuFT65GenericRadio): # """ # FT-25 VHF, EU version # """ # MODEL = "FT-25E" # id_str = b'IFT-25R\x00\x00V100\x00\x00' # valid_bands = VALID_BANDS_VHF # DUPLEX_AUTO = DUPLEX_AUTO_EU # legal_steps = STEP_CODE # BAND_ASSIGNMENTS = BAND_ASSIGNMENTS_MONO_VHF chirp-20240224/chirp/drivers/kguv9dplus.py0000644000175000017500000030745314560403070017321 0ustar hibbyhibby# Copyright 2022 Mel Terechenok # Updated Driver to support Wouxun KG-UV9PX # based on prior driver for KG-UV9D Plus by # Jim Lieb # # Borrowed from other chirp drivers, especially the KG-UV8D Plus # by Krystian Struzik # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun KG-UV9D Plus radio management module""" import time import logging import struct from chirp import chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, \ RadioSettingValueList, RadioSettingValueInteger, \ RadioSettingValueString, RadioSettings, \ InvalidValueError LOG = logging.getLogger(__name__) CMD_IDENT = 0x80 CMD_HANGUP = 0x81 CMD_RCONF = 0x82 CMD_WCONF = 0x83 CMD_RCHAN = 0x84 CMD_WCHAN = 0x85 cmd_name = { CMD_IDENT: "ident", CMD_HANGUP: "hangup", CMD_RCONF: "read config", CMD_WCONF: "write config", CMD_RCHAN: "read channel memory", # Unused CMD_WCHAN: "write channel memory" # Unused because it is a hack. } # This is used to write the configuration of the radio base on info # gleaned from the downloaded app. There are empty spaces and we honor # them because we don't know what they are (yet) although we read the # whole of memory. # # Channel memory is separate. There are 1000 (1-999) channels. # These are read/written to the radio in 4 channel (96 byte) # records starting at address 0xa00 and ending at # 0x4800 (presuming the end of channel 1000 is 0x4860-1 config_map = ( # map address, write size, write count (0x40, 16, 1), # Passwords (0x60, 20, 1), # RX frequency limits (0x74, 8, 1), # TX frequency limits (0x740, 40, 1), # FM chan 1-20 (0x780, 16, 1), # vfo-b-150 (0x790, 16, 1), # vfo-b-450 (0x800, 16, 1), # vfo-a-150 (0x810, 16, 1), # vfo-a-450 (0x820, 16, 1), # vfo-a-300 (0x830, 16, 1), # vfo-a-700 (0x840, 16, 1), # vfo-a-200 (0x860, 16, 1), # area-a-conf (0x870, 16, 1), # area-b-conf (0x880, 16, 1), # radio conf 0 (0x890, 16, 1), # radio conf 1 (0x8a0, 16, 1), # radio conf 2 (0x8b0, 16, 1), # radio conf 3 (0x8c0, 16, 1), # PTT-ANI (0x8d0, 16, 1), # SCC (0x8e0, 16, 1), # power save (0x8f0, 16, 1), # Display banner (0x940, 64, 2), # Scan groups and names (0xa00, 64, 249), # Memory Channels 1-996 (0x4840, 48, 1), # Memory Channels 997-999 (0x4900, 32, 249), # Memory Names 1-996 (0x6820, 24, 1), # Memory Names 997-999 (0x7000, 8, 124), # Valid Channel bytes 1-992 (0x73E0, 1, 7), # Valid Channel Bytes 993-999 (0x7400, 64, 5), # CALL-ID 1-20, names 1-20 ) config_map2 = ( # map address, write size, write count (0x40, 16, 1), # Passwords (0x50, 10, 1), # OEM Display Name (0x60, 20, 1), # Rx Freq Limits Area A (0x74, 8, 1), # TX Frequency Limits 150M and 450M (0x7c, 4, 1), # Rx 150M Freq Limits Area B # (0x80, 8, 1), # unknown Freq limits (0x740, 40, 1), # FM chan 1-20 (0x780, 16, 1), # vfo-b-150 (0x790, 16, 1), # vfo-b-450 (0x800, 16, 1), # vfo-a-150 (0x810, 16, 1), # vfo-a-450 (0x820, 16, 1), # vfo-a-300 (0x830, 16, 1), # vfo-a-700 (0x840, 16, 1), # vfo-a-200 (0x860, 16, 1), # area-a-conf (0x870, 16, 1), # area-b-conf (0x880, 16, 1), # radio conf 0 (0x890, 16, 1), # radio conf 1 (0x8a0, 16, 1), # radio conf 2 (0x8b0, 16, 1), # radio conf 3 (0x8c0, 16, 1), # PTT-ANI (0x8d0, 16, 1), # SCC (0x8e0, 16, 1), # power save (0x8f0, 16, 1), # Display banner (0x940, 64, 2), # Scan groups and names (0xa00, 64, 249), # Memory Channels 1-996 (0x4840, 48, 1), # Memory Channels 997-999 (0x4900, 32, 249), # Memory Names 1-996 (0x6820, 24, 1), # Memory Names 997-999 (0x7000, 8, 124), # Valid Channel bytes 1-992 (0x73E0, 1, 7), # Valid Channel Bytes 993-999 (0x7400, 64, 5), # CALL-ID 1-20, names 1-20 (0x7600, 1, 1) # Screen Mode ) MEM_VALID = 0xfc MEM_INVALID = 0xff VALID_MEM_VALUES = [MEM_VALID, 0x00, 0x02, 0x40, 0x3D] INVALID_MEM_VALUES = [MEM_INVALID] # new CHAN_VALID/INVALID mem values to address some radios not showing # new channels CHAN_VALID = 0x41 CHAN_INVALID = 0xFC # Radio memory map. This matches the reads/writes above. # structure elements whose name starts with x are currently unidentified _MEM_FORMAT02 = """ #seekto 0x40; struct { char reset[6]; char x46[2]; char mode_sw[6]; char x4e; } passwords; #seekto 0x60; struct freq_limit { u16 start; u16 stop; }; struct { struct freq_limit band_150; struct freq_limit band_450; struct freq_limit band_300; struct freq_limit band_700; struct freq_limit band_200; } rx_freq_limits; struct { struct freq_limit band_150; struct freq_limit band_450; } tx_freq_limits; #seekto 0x740; struct { u16 fm_freq; } fm_chans[20]; // each band has its own configuration, essentially its default params struct vfo { u32 freq; u32 offset; u16 encqt; u16 decqt; u8 bit7_4:3, qt:3, bit1_0:2; u8 bit7:1, scan:1, bit5:1, pwr:2, mod:1, fm_dev:2; u8 pad2:6, shift:2; u8 zeros; }; #seekto 0x780; struct { struct vfo band_150; struct vfo band_450; } vfo_b; #seekto 0x800; struct { struct vfo band_150; struct vfo band_450; struct vfo band_300; struct vfo band_700; struct vfo band_200; } vfo_a; // There are two independent radios, aka areas (as described // in the manual as the upper and lower portions of the display... struct area_conf { u8 w_mode; u16 w_chan; u8 scan_grp; u8 bcl; u8 sql; u8 cset; u8 step; u8 scan_mode; u8 x869; u8 scan_range; u8 x86b; u8 x86c; u8 x86d; u8 x86e; u8 x86f; }; #seekto 0x860; struct area_conf a_conf; #seekto 0x870; struct area_conf b_conf; #seekto 0x880; struct { u8 menu_avail; u8 reset_avail; u8 x882; u8 x883; u8 lang; u8 x885; u8 beep; u8 auto_am; u8 qt_sw; u8 lock; u8 x88a; u8 pf1; u8 pf2; u8 pf3; u8 s_mute; u8 type_set; u8 tot; u8 toa; u8 ptt_id; u8 x893; u8 id_dly; u8 x895; u8 voice_sw; u8 s_tone; u8 abr_lvl; u8 ring_time; u8 roger; u8 x89b; u8 abr; u8 save_m; u8 lock_m; u8 auto_lk; u8 rpt_ptt; u8 rpt_spk; u8 rpt_rct; u8 prich_sw; u16 pri_ch; u8 x8a6; u8 x8a7; u8 dtmf_st; u8 dtmf_tx; u8 x8aa; u8 sc_qt; u8 apo_tmr; u8 vox_grd; u8 vox_dly; u8 rpt_kpt; struct { u16 scan_st; u16 scan_end; } a; struct { u16 scan_st; u16 scan_end; } b; u8 x8b8; u8 x8b9; u8 x8ba; u8 ponmsg; u8 blcdsw; u8 bledsw; u8 x8be; u8 x8bf; } settings; #seekto 0x8c0; struct { u8 code[6]; char x8c6[10]; } my_callid; #seekto 0x8d0; struct { u8 scc[6]; char x8d6[10]; } stun; #seekto 0x8e0; struct { u16 wake; u16 sleep; } save[4]; #seekto 0x8f0; struct { char banner[16]; } display; #seekto 0x940; struct { struct { i16 scan_st; i16 scan_end; } addrs[10]; u8 x0968[8]; struct { char name[8]; } names[10]; } scn_grps; // this array of structs is marshalled via the R/WCHAN commands #seekto 0xa00; struct { u32 rxfreq; u32 txfreq; u16 encQT; u16 decQT; u8 bit7_5:3, // all ones qt:3, bit1_0:2; u8 bit7:1, scan:1, bit5:1, pwr:2, mod:1, fm_dev:2; u8 state; u8 c3; } chan_blk[999]; // nobody really sees this. It is marshalled with chan_blk // in 4 entry chunks #seekto 0x4900; // Tracks with the index of chan_blk[] struct { char name[8]; } chan_name[999]; #seekto 0x7000; struct { u8 ch_valid; } chan_valid[999]; #seekto 0x7400; struct { u8 cid[6]; u8 pad[2]; }call_ids[20]; // This array tracks with the index of call_ids[] struct { char name[6]; char pad[2]; } cid_names[20]; """ _MEM_FORMAT_9PX = """ #seekto 0x40; struct { char reset[6]; char x46[2]; char mode_sw[6]; char x4e; } passwords; #seekto 0x50; struct { char model[10]; } oemmodel; #seekto 0x60; struct { u16 lim_150M_area_a_rxlower_limit; // 0x60 u16 lim_150M_area_a_rxupper_limit; u16 lim_450M_rxlower_limit; u16 lim_450M_rxupper_limit; u16 lim_300M_rxlower_limit; u16 lim_300M_rxupper_limit; u16 lim_800M_rxlower_limit; u16 lim_800M_rxupper_limit; u16 lim_210M_rxlower_limit; u16 lim_210M_rxupper_limit; u16 lim_150M_Txlower_limit; u16 lim_150M_Txupper_limit; u16 lim_450M_Txlower_limit; u16 lim_450M_Txupper_limit; u16 lim_150M_area_b_rxlower_limit; u16 lim_150M_area_b_rxupper_limit; u16 unknown_lower_limit; u16 unknown_upper_limit; u16 unknown2_lower_limit; u16 unknown2_upper_limit; } limits; #seekto 0x740; struct { u16 fm_freq; } fm_chans[20]; // each band has its own configuration, essentially its default params struct vfo { u32 freq; u32 offset; u16 encqt; u16 decqt; u8 bit7_4:3, qt:3, bit1_0:2; u8 bit7:1, scan:1, bit5:1, pwr:2, mod:1, fm_dev:2; u8 pad2:6, shift:2; u8 zeros; }; #seekto 0x780; struct { struct vfo band_150; struct vfo band_450; } vfo_b; #seekto 0x800; struct { struct vfo band_150; struct vfo band_450; struct vfo band_300; struct vfo band_700; struct vfo band_200; } vfo_a; // There are two independent radios, aka areas (as described // in the manual as the upper and lower portions of the display... struct area_conf { u8 w_mode; u16 w_chan; // fix issue in 9D Plus - w_chan is 2bytes u8 scan_grp; u8 bcl; u8 sql; u8 cset; u8 step; u8 scan_mode; u8 x869; u8 scan_range; u8 x86b; u8 x86c; u8 x86d; u8 x86e; u8 x86f; }; #seekto 0x860; struct area_conf a_conf; #seekto 0x870; struct area_conf b_conf; #seekto 0x880; struct { u8 menu_avail; u8 reset_avail; u8 act_area; u8 tdr; u8 lang; u8 x885; u8 beep; u8 auto_am; u8 qt_sw; u8 lock; u8 x88a; u8 pf1; u8 pf2; u8 pf3; u8 s_mute; u8 type_set; u8 tot; u8 toa; u8 ptt_id; u8 x893; u8 id_dly; u8 x895; u8 voice_sw; u8 s_tone; u8 abr_lvl; u8 ring_time; u8 roger; u8 x89b; u8 abr; u8 save_m; u8 lock_m; u8 auto_lk; u8 rpt_ptt; u8 rpt_spk; u8 rpt_rct; u8 prich_sw; u16 pri_ch; u8 x8a6; u8 x8a7; u8 dtmf_st; u8 dtmf_tx; u8 x8aa; u8 sc_qt; u8 apo_tmr; u8 vox_grd; u8 vox_dly; u8 rpt_kpt; struct { u16 scan_st; u16 scan_end; } a; struct { u16 scan_st; u16 scan_end; } b; u8 x8b8; u8 x8b9; u8 x8ba; u8 ponmsg; u8 blcdsw; u8 bledsw; u8 x8be; u8 x8bf; } settings; #seekto 0x8c0; struct { u8 code[6]; char x8c6[10]; } my_callid; #seekto 0x8d0; struct { u8 scc[6]; char x8d6[10]; } stun; #seekto 0x8e0; struct { u16 wake; u16 sleep; } save[4]; #seekto 0x8f0; struct { char banner[16]; } display; #seekto 0x940; struct { struct { i16 scan_st; i16 scan_end; } addrs[10]; u8 x0968[8]; struct { char name[8]; } names[10]; } scn_grps; // this array of structs is marshalled via the R/WCHAN commands #seekto 0xa00; struct { u32 rxfreq; u32 txfreq; u16 encQT; u16 decQT; u8 bit7_5:3, // all ones qt:3, bit1_0:2; u8 bit7:1, scan:1, bit5:1, pwr:2, mod:1, fm_dev:2; u8 state; u8 c3; } chan_blk[999]; // nobody really sees this. It is marshalled with chan_blk // in 4 entry chunks #seekto 0x4900; // Tracks with the index of chan_blk[] struct { char name[8]; } chan_name[999]; #seekto 0x7400; struct { u8 cid[6]; u8 pad[2]; }call_ids[20]; // This array tracks with the index of call_ids[] struct { char name[6]; char pad[2]; } cid_names[20]; #seekto 0x7000; struct { u8 ch_valid; } chan_valid[999]; #seekto 0x7600; struct { u8 screen_mode; } screen; """ # Support for the Wouxun KG-UV9D Plus and KG-UV9PX radio # Serial coms are at 19200 baud # The data is passed in variable length records # Record structure: # Offset Usage # 0 start of record (\x7d) # 1 Command (6 commands, see above) # 2 direction (\xff PC-> Radio, \x00 Radio -> PC) # 3 length of payload (excluding header/checksum) (n) # 4 payload (n bytes) # 4+n+1 checksum - byte sum (% 256) of bytes 1 -> 4+n # # Memory Read Records: # the payload is 3 bytes, first 2 are offset (big endian), # 3rd is number of bytes to read # Memory Write Records: # the maximum payload size (from the Wouxun software) # seems to be 66 bytes (2 bytes location + 64 bytes data). def _pkt_encode(op, payload): """Assemble a packet for the radio and encode it for transmission. Yes indeed, the checksum we store is only 4 bits. Why? I suspect it's a bug in the radio firmware guys didn't want to fix, i.e. a typo 0xff -> 0xf...""" data = bytearray() data.append(0x7d) # tag that marks the beginning of the packet data.append(op) data.append(0xff) # 0xff is from app to radio # calc checksum from op to end cksum = op + 0xff if (payload): data.append(len(payload)) cksum += len(payload) for byte in payload: cksum += byte data.append(byte) else: data.append(0x00) # Yea, this is a 4 bit cksum (also known as a bug) data.append(cksum & 0xf) # now obfuscate by an xor starting with first payload byte ^ 0x52 # including the trailing cksum. xorbits = 0x52 for i, byte in enumerate(data[4:]): xord = xorbits ^ byte data[i + 4] = xord xorbits = xord return (data) def _pkt_decode(data): """Take a packet hot off the wire and decode it into clear text and return the fields. We say <> here because all it turns out to be is annoying obfuscation. This is the inverse of pkt_decode""" # we don't care about data[0]. # It is always 0x7d and not included in checksum op = data[1] direction = data[2] bytecount = data[3] # First un-obfuscate the payload and cksum payload = bytearray() xorbits = 0x52 for i, byte in enumerate(data[4:]): payload.append(xorbits ^ byte) xorbits = byte # Calculate the checksum starting with the 3 bytes of the header cksum = op + direction + bytecount for byte in payload[:-1]: cksum += byte # yes, a 4 bit cksum to match the encode cksum_match = (cksum & 0xf) == payload[-1] if (not cksum_match): LOG.debug( "Checksum mismatch: %x != %x; " % (cksum, payload[-1])) return (cksum_match, op, payload[:-1]) # UI callbacks to process input for mapping UI fields to memory cells def freq2int(val, min, max): """Convert a frequency as a string to a u32. Units is Hz """ _freq = chirp_common.parse_freq(str(val)) if _freq > max or _freq < min: raise InvalidValueError("Frequency %s is not with in %s-%s" % (chirp_common.format_freq(_freq), chirp_common.format_freq(min), chirp_common.format_freq(max))) return _freq def int2freq(freq): """ Convert a u32 frequency to a string for UI data entry/display This is stored in the radio as units of 10 Hz which we compensate to Hz. A value of -1 indicates , i.e. unused channel. """ if (int(freq) > 0): f = chirp_common.format_freq(freq) return f else: return "" def freq2short(val, min, max): """Convert a frequency as a string to a u16 which is units of 10 kHz """ _freq = chirp_common.parse_freq(str(val)) if _freq > max or _freq < min: raise InvalidValueError("Frequency %s is not with in %s-%s" % (chirp_common.format_freq(_freq), chirp_common.format_freq(min), chirp_common.format_freq(max))) return _freq // 100000 & 0xFFFF def short2freq(freq): """ Convert a short frequency to a string for UI data entry/display This is stored in the radio as units of 10 kHz which we compensate to Hz. A value of -1 indicates , i.e. unused channel. """ if (int(freq) > 0): f = chirp_common.format_freq(freq * 100000) return f else: return "" def tone2short(t): """Convert a string tone or DCS to an encoded u16 """ tone = str(t) if tone == "----": u16tone = 0x0000 elif tone[0] == 'D': # This is a DCS code c = tone[1: -1] code = int(c, 8) if tone[-1] == 'I': code |= 0x4000 u16tone = code | 0x8000 else: # This is an analog CTCSS u16tone = int(tone[0:-2]+tone[-1]) & 0xffff # strip the '.' return u16tone def short2tone(tone): """ Map a binary CTCSS/DCS to a string name for the tone """ if tone == 0 or tone == 0xffff: ret = "----" else: code = tone & 0x3fff if tone & 0x8000: # This is a DCS if tone & 0x4000: # This is an inverse code ret = "D%0.3oI" % code else: ret = "D%0.3oN" % code else: # Just plain old analog CTCSS ret = "%4.1f" % (code / 10.0) return ret def str2callid(val): """ Convert caller id strings from callid2str. """ ascii2bin = "0123456789" s = str(val).strip() if len(s) < 3 or len(s) > 6: raise InvalidValueError( "Caller ID must be at least 3 and no more than 6 digits") if s[0] == '0': raise InvalidValueError( "First digit of a Caller ID cannot be a zero '0'") blk = bytearray() for c in s: if c not in ascii2bin: raise InvalidValueError( "Caller ID must be all digits 0x%x" % c) b = (0xa, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9)[int(c)] blk.append(b) if len(blk) < 6: blk.append(0xc) # EOL a short ID if len(blk) < 6: for i in range(0, (6 - len(blk))): blk.append(0xf0) return blk def digits2str(digits, padding=' ', width=6): """Convert a password or SCC digit string to a string Passwords are expanded to and must be 6 chars. Fill them with '0' """ bin2ascii = "0123456789" digitsstr = "" for i in range(0, 6): b = digits[i].get_value() if b == 0xc: # the digits EOL break if b >= 0xa: raise InvalidValueError( "Value has illegal byte 0x%x" % ord(b)) digitsstr += bin2ascii[b] digitsstr = digitsstr.ljust(width, padding) return digitsstr def str2digits(val): """ Callback for edited strings from digits2str. """ ascii2bin = " 0123456789" s = str(val).strip() if len(s) < 3 or len(s) > 6: raise InvalidValueError( "Value must be at least 3 and no more than 6 digits") blk = bytearray() for c in s: if c not in ascii2bin: raise InvalidValueError("Value must be all digits 0x%x" % c) blk.append(int(c)) for i in range(len(blk), 6): blk.append(0xc) # EOL a short ID return blk def name2str(name): """ Convert a callid or scan group name to a string Deal with fixed field padding (\0 or \0xff) """ namestr = "" for i in range(0, len(name)): b = ord(name[i].get_value()) if b != 0 and b != 0xff: namestr += chr(b) return namestr def str2name(val, size=6, fillchar='\0', emptyfill='\0'): """ Convert a string to a name. A name is a 6 element bytearray with ascii chars. """ val = str(val).rstrip(' \t\r\n\0\xff') if len(val) == 0: name = "".ljust(size, emptyfill) else: name = val.ljust(size, fillchar) return name def pw2str(pw): """Convert a password string (6 digits) to a string Passwords must be 6 digits. If it is shorter, pad right with '0' """ pwstr = "" ascii2bin = "0123456789" for i in range(0, len(pw)): b = pw[i].get_value() if b not in ascii2bin: raise InvalidValueError("Value must be digits 0-9") pwstr += b pwstr = pwstr.ljust(6, '0') return pwstr def str2pw(val): """Store a password from UI to memory obj If we clear the password (make it go away), change the empty string to '000000' since the radio must have *something* Also, fill a < 6 digit pw with 0's """ ascii2bin = "0123456789" val = str(val).rstrip(' \t\r\n\0\0xff') if len(val) == 0: # a null password val = "000000" for i in range(0, len(val)): b = val[i] if b not in ascii2bin: raise InvalidValueError("Value must be digits 0-9") if len(val) == 0: pw = "".ljust(6, '\0') else: pw = val.ljust(6, '0') return pw # Helpers to replace python2 things like confused str/byte def _hex_print(data, addrfmt=None): """Return a hexdump-like encoding of @data We expect data to be a bytearray, not a string. Expanded from borrowed code to use the first 2 bytes as the address per comm packet format. """ if addrfmt is None: addrfmt = '%(addr)03i' addr = 0 else: # assume first 2 bytes are address a = struct.unpack(">H", data[0:2]) addr = a[0] data = data[2:] block_size = 16 lines = (len(data) // block_size) if (len(data) % block_size > 0): lines += 1 out = "" left = len(data) for block in range(0, lines): addr += block * block_size try: out += addrfmt % locals() except (OverflowError, ValueError, TypeError, KeyError): out += "%03i" % addr out += ': ' if left < block_size: limit = left else: limit = block_size for j in range(0, block_size): if (j < limit): out += "%02x " % data[(block * block_size) + j] else: out += " " out += " " for j in range(0, block_size): if (j < limit): _byte = data[(block * block_size) + j] if _byte >= 0x20 and _byte < 0x7F: out += "%s" % chr(_byte) else: out += "." else: out += " " out += "\n" if (left > block_size): left -= block_size return out # Useful UI lists STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] STEPS_9K = [2.5, 5.0, 6.25, 8.33, 10.0, 12.5, 25.0, 50.0, 100.0] S_TONES = [str(x) for x in [1000, 1450, 1750, 2100]] STEP_LIST = [str(x)+"kHz" for x in STEPS] STEP_LIST_9K = [str(x)+"kHz" for x in STEPS_9K] ROGER_LIST = ["Off", "Begin", "End", "Both"] TIMEOUT_LIST = [str(x) + "s" for x in range(15, 601, 15)] TOA_LIST = ["Off"] + ["%ds" % t for t in range(1, 11)] BANDWIDTH_LIST = ["Wide", "Narrow"] LANGUAGE_LIST = ["English", "Chinese"] LANGUAGE_LIST2 = ["English", "Chinese-DISABLED"] PF1KEY_LIST = ["OFF", "call id", "r-alarm", "SOS", "SF-TX"] PF1KEY_LIST9GX = ["OFF", "call id", "r-alarm", "SOS", "SF-TX", "Scan", "Second", "Lamp"] PF2KEY_LIST = ["OFF", "Scan", "Second", "Lamp", "SDF-DIR", "K-lamp"] PF2KEY_LIST9GX = ["OFF", "Scan", "Second", "Lamp", "K-lamp"] PF3KEY_LIST2 = ["OFF", "Call ID", "R-ALARM", "SOS", "SF-TX", "Scan", "Second", "Lamp"] PF3KEY_LIST9GX = ["OFF", "call id", "r-alarm", "SOS", "SF-TX", "Scan", "Second", "Lamp"] PF3KEY_LIST = ["OFF", "Call ID", "R-ALARM", "SOS", "SF-TX"] WORKMODE_LIST = ["VFO freq", "Channel No.", "Ch. No.+Freq.", "Ch. No.+Name"] BACKLIGHT_LIST = ["Off"] + ["%sS" % t for t in range(1, 31)] + \ ["Always On"] BACKLIGHT_BRIGHT_MIN = 1 BACKLIGHT_BRIGHT_MAX = 5 SAVE_MODES = ["Off", "1", "2", "3", "4"] LOCK_MODES = ["key-lk", "key+pg", "key+ptt", "all"] APO_TIMES = ["Off"] + ["%dm" % t for t in range(15, 151, 15)] OFFSET_LIST = ["none", "+", "-"] PONMSG_LIST = ["Battery Volts", "Bitmap"] PONMSG_LIST2 = ["Battery Volts", "Bitmap-DISABLED"] SPMUTE_LIST = ["QT", "QT*T", "QT&T"] DTMFST_LIST = ["Off", "DT-ST", "ANI-ST", "DT-ANI"] DTMF_TIMES = ["%d" % x for x in range(80, 501, 20)] PTTID_LIST = ["Off", "Begin", "End", "Both"] ID_DLY_LIST = ["%dms" % t for t in range(100, 3001, 100)] VOX_GRDS = ["Off"] + ["%dlevel" % l for l in range(1, 11)] VOX_DLYS = ["Off"] + ["%ds" % t for t in range(1, 5)] RPT_KPTS = ["Off"] + ["%dms" % t for t in range(100, 5001, 100)] ABR_LVL_MAP = [("1", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5)] LIST_1_5 = ["%s" % x for x in range(1, 6)] LIST_0_9 = ["%s" % x for x in range(0, 10)] LIST_1_20 = ["%s" % x for x in range(1, 21)] LIST_OFF_10 = ["Off"] + ["%s" % x for x in range(1, 11)] SCANGRP_LIST = ["All"] + ["%s" % x for x in range(1, 11)] SCANMODE_LIST = ["TO", "CO", "SE"] SCANRANGE_LIST = ["Current band", "freq range", "ALL"] SCQT_LIST = ["Decoder", "Encoder", "Both"] S_MUTE_LIST = ["off", "rx mute", "tx mute", "r/t mute"] POWER_LIST = ["Low", "Med", "High"] RPTMODE_LIST = ["Radio/Talkie", "One direction Repeater", "Two direction repeater"] TONE_LIST = ["----"] + ["%s" % str(t) for t in chirp_common.TONES] + \ ["D%0.3dN" % dts for dts in chirp_common.DTCS_CODES] + \ ["D%0.3dI" % dts for dts in chirp_common.DTCS_CODES] SCREEN_MODE_LIST = ["Classic", "Covert", "Day_1", "Day_2"] ACTIVE_AREA_LIST = ["Receiver A - Top", "Receiver B - Bottom"] TDR_LIST = ["TDR ON", "TDR OFF"] @directory.register class KGUV9DPlusRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-UV9D Plus""" VENDOR = "Wouxun" MODEL = "KG-UV9D Plus" _model = b"KG-UV9D" _rev = b"00" # default rev for the radio I know about... _file_ident = b"kg-uv9d" NEEDS_COMPAT_SERIAL = False BAUD_RATE = 19200 POWER_LEVELS = [chirp_common.PowerLevel("L", watts=1), chirp_common.PowerLevel("M", watts=2), chirp_common.PowerLevel("H", watts=5)] _step_list = STEP_LIST _valid_steps = STEPS _mmap = "" def _read_record(self): """ Read and validate the header of a radio reply. A record is a formatted byte stream as follows: 0x7D All records start with this opcode This is in the set of legal commands. The radio reply matches the request dir This is the direction, 0xFF to the radio, 0x00 from the radio. cnt Count of bytes in payload (not including the trailing checksum byte) """ # first get the header and validate it data = bytearray(self.pipe.read(4)) if (len(data) < 4): raise errors.RadioError('Radio did not respond') if (data[0] != 0x7D): raise errors.RadioError( 'Radio reply garbled (%02x)' % data[0]) if (data[1] not in cmd_name): raise errors.RadioError( "Unrecognized opcode (%02x)" % data[1]) if (data[2] != 0x00): raise errors.RadioError( "Direction incorrect. Got (%02x)" % data[2]) payload_len = data[3] # don't forget to read the checksum byte data.extend(self.pipe.read(payload_len + 1)) if (len(data) != (payload_len + 5)): # we got a short read raise errors.RadioError( "Radio reply wrong size. Wanted %d, got %d" % ((payload_len + 1), (len(data) - 4))) return _pkt_decode(data) def _write_record(self, cmd, payload=None): """ Write a request packet to the radio. """ packet = _pkt_encode(cmd, payload) self.pipe.write(packet) @classmethod def match_model(cls, filedata, filename): """Look for bits in the file image and see if it looks like ours... TODO: there is a bunch of rubbish between 0x50 and 0x160 that is still a known unknown """ return cls._file_ident in filedata[0x51:0x59].lower() def _identify(self): """ Identify the radio The ident block identifies the radio and its capabilities. This block is always 78 bytes. The rev == '01' is the base radio and '02' seems to be the '-Plus' version. I don't really trust the content after the model and revision. One would assume this is pretty much constant data but I have seen differences between my radio and the dump named KG-UV9D-Plus-OutOfBox-Read.txt from bug #3509. The first five bands match the OEM windows app except the 350-400 band. The OOB trace has the 700 MHz band different. This is speculation at this point. TODO: This could be smarter and reject a radio not actually a UV9D... """ for _i in range(0, 10): # retry 10 times if we get junk self._write_record(CMD_IDENT) chksum_match, op, _resp = self._read_record() if len(_resp) == 0: raise Exception("Radio not responding") if len(_resp) != 74: LOG.error( "Expected and IDENT reply of 78 bytes. Got (%d)" % len(_resp)) continue if not chksum_match: LOG.error("Checksum error: retrying ident...") time.sleep(0.100) continue if op != CMD_IDENT: LOG.error("Expected IDENT reply. Got (%02x)" % op) continue LOG.debug("Got:\n%s" % _hex_print(_resp)) (mod, rev) = struct.unpack(">7s2s", _resp[0:9]) LOG.debug("Model %s, rev %s" % (mod, rev)) if mod == self._model: self._rev = rev return else: raise Exception("Unable to identify radio") raise Exception("All retries to identify failed") def process_mmap(self): if self._rev != b"02" and self._rev != b"00": # new revision found - log it and assume same map and proceed LOG.debug("Unrecognized model variation (%s) Using default Map" % self._rev) self._memobj = bitwise.parse(_MEM_FORMAT02, self._mmap) def sync_in(self): """ Public sync_in Download contents of the radio. Throw errors back to the core if the radio does not respond. """ try: self._identify() self._mmap = self._do_download() self._write_record(CMD_HANGUP) except errors.RadioError: raise except Exception as e: LOG.exception('Unknown error during download process') raise errors.RadioError( "Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): """ Public sync_out Upload the modified memory image into the radio. """ try: self._identify() self._do_upload() self._write_record(CMD_HANGUP) except errors.RadioError: raise except Exception as e: raise errors.RadioError( "Failed to communicate with radio: %s" % e) return def _do_download(self): """ Read the whole of radio memory in 64 byte chunks. We load the config space followed by loading memory channels. The radio seems to be a "clone" type and the memory channels are actually within the config space. There are separate commands (CMD_RCHAN, CMD_WCHAN) for reading channel memory but these seem to be a hack that can only do 4 channels at a time. Since the radio only supports 999, (can only support 3 chars in the display UI?) although the vendors app reads 1000 channels, it hacks back to config writes (CMD_WCONF) for the last 3 channels and names. We keep it simple and just read the whole thing even though the vendor app doesn't. Channels are separate in their app simply because the radio protocol has read/write commands to access it. What they do is simply marshal the frequency+mode bits in 4 channel chunks followed by a separate chunk of for names. In config space, they are two separate arrays 1..999. Given that this space is not a multiple of 4, there is hackery on upload to do the writes to config space. See upload for this. """ mem = bytearray(0x8000) # The radio's memory map is 32k for addr in range(0, 0x8000, 64): req = bytearray(struct.pack(">HB", addr, 64)) self._write_record(CMD_RCONF, req) chksum_match, op, resp = self._read_record() if not chksum_match: LOG.debug(_hex_print(resp)) raise Exception( "Checksum error while reading configuration (0x%x)" % addr) pa = struct.unpack(">H", resp[0:2]) pkt_addr = pa[0] payload = resp[2:] if op != CMD_RCONF or addr != pkt_addr: raise Exception( "Expected CMD_RCONF (%x) reply. Got (%02x: %x)" % (addr, op, pkt_addr)) LOG.debug("Config read (0x%x):\n%s" % (addr, _hex_print(resp, '0x%(addr)04x'))) # Orig Code from 9D Plus driver was len(Payload)-1: # This Caused every 64th byte to = 00 for i in range(0, len(payload)): mem[addr + i] = payload[i] if self.status_fn: status = chirp_common.Status() status.cur = addr status.max = 0x8000 status.msg = "Cloning from radio" self.status_fn(status) return memmap.MemoryMapBytes(bytes(mem)) def _do_upload(self): """Walk through the config map and write updated records to the radio. The config map contains only the regions we know about. We don't use the channel memory commands to avoid the hackery of using config write commands to fill in the last 3 channel memory and names slots. As we discover other useful goodies in the map, we can add more slots... """ if (self.MODEL == "KG-UV9PX" or self.MODEL == "KG-UV9GX"): cfgmap = config_map2 else: cfgmap = config_map for start, blocksize, count in cfgmap: end = start + (blocksize * count) for addr in range(start, end, blocksize): req = bytearray(struct.pack(">H", addr)) req.extend(self.get_mmap()[addr:addr + blocksize]) self._write_record(CMD_WCONF, req) LOG.debug("Config write (0x%x):\n%s" % (addr, _hex_print(req))) chksum_match, op, ack = self._read_record() LOG.debug("Config write ack [%x]\n%s" % (addr, _hex_print(ack))) a = struct.unpack(">H", ack) # big endian short... ack = a[0] if not chksum_match or op != CMD_WCONF or addr != ack: msg = "" if not chksum_match: msg += "Checksum err, " if op != CMD_WCONF: msg += "cmd mismatch %x != %x, " % \ (op, CMD_WCONF) if addr != ack: msg += "ack error %x != %x, " % (addr, ack) raise Exception("Radio did not ack block: %s error" % msg) if self.status_fn: status = chirp_common.Status() status.cur = addr status.max = 0x8000 status.msg = "Cloning to radio" self.status_fn(status) def get_features(self): """ Public get_features Return the features of this radio once we have identified it and gotten its bits """ rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM", "AM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_bands = [(108000000, 136000000), # Aircraft AM (136000000, 180000000), # supports 2m (230000000, 250000000), (350000000, 400000000), (400000000, 520000000), # supports 70cm (700000000, 985000000)] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_tuning_steps = self._valid_steps rf.memory_bounds = (1, 999) # 999 memories return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is currently under development. " "There are no known issues with it, but you should " "proceed with caution.") return rp def get_raw_memory(self, number): return repr(self._memobj.chan_blk[number - 1]) def _get_tone(self, _mem, mem): """Decode both the encode and decode CTSS/DCS codes from the memory channel and stuff them into the UI memory channel row. """ txtone = short2tone(_mem.encQT) rxtone = short2tone(_mem.decQT) pt = "N" pr = "N" if txtone == "----": txmode = "" elif txtone[0] == "D": mem.dtcs = int(txtone[1:4]) if txtone[4] == "I": pt = "R" txmode = "DTCS" else: mem.rtone = float(txtone) txmode = "Tone" if rxtone == "----": rxmode = "" elif rxtone[0] == "D": mem.rx_dtcs = int(rxtone[1:4]) if rxtone[4] == "I": pr = "R" rxmode = "DTCS" else: mem.ctone = float(rxtone) rxmode = "Tone" if txmode == "Tone" and len(rxmode) == 0: mem.tmode = "Tone" elif (txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone): mem.tmode = "TSQL" elif (txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs): mem.tmode = "DTCS" elif (len(rxmode) + len(txmode)) > 0: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = pt + pr LOG.debug("_get_tone: Got TX %s (%i) RX %s (%i)" % (txmode, _mem.encQT, rxmode, _mem.decQT)) def get_memory(self, number): """ Public get_memory Return the channel memory referenced by number to the UI. """ _mem = self._memobj.chan_blk[number - 1] _nam = self._memobj.chan_name[number - 1] _val = self._memobj.chan_valid[number - 1] mem = chirp_common.Memory() mem.number = number _valid = _mem.state # This code attempts to robustly decipher what Wouxun considers valid # memory locations on the 9 series radios and the factory CPS. # It appears they use a combination of State and Rx Freq to determine # validity rather than just the State value. # It is possible the State value is not even used at all. # Rather than continuously adding new Mem Valid values as they are # found, assume any value other than 0xFF is likely valid and use # Rx Freq to further assess validity if _mem.rxfreq == 0xFFFFFFFF: # Rx freq indicates empty channel memory # assume empty regardless of _valid and proceed to next channel if _valid not in INVALID_MEM_VALUES: # only log if _valid indicates the channel is not invalid LOG.debug("CH %s Rx Freq = 0xFFFFFFFF - " "Treating chan as empty", mem.number) mem.empty = True _val.ch_valid = CHAN_INVALID return mem elif _valid in INVALID_MEM_VALUES: # Check for 9PX case where CPS creates a valid channel with # 0xFF for State - accept it as valid as long as Rx Freq is # <= max value if _mem.rxfreq > 99999999: # Max poss Value = 999.99999 MHz LOG.debug("CH %s State invalid - Rx Frq > 999.99999 MHz: " "Treating chan as empty", mem.number) mem.empty = True _val.ch_valid = CHAN_INVALID return mem else: LOG.debug("CH %s State invalid - Rx Freq valid: " "Assume chan valid", mem.number) mem.empty = False _val.ch_valid = CHAN_VALID else: # State not Invalid and Rx Freq not 0xFFFFFFFF if _mem.rxfreq > 99999999: # Max poss Value = 999.99999 MHz LOG.debug("CH %s Invalid Rx Frq: %s MHz - " "Treating chan as empty", mem.number, int(_mem.rxfreq) / 100000) mem.empty = True _val.ch_valid = CHAN_INVALID return mem else: _val.ch_valid = CHAN_VALID mem.empty = False mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.name = name2str(_nam.name) self._get_tone(_mem, mem) mem.skip = "" if bool(_mem.scan) else "S" mem.power = self.POWER_LEVELS[_mem.pwr] if _mem.mod == 1: mem.mode = "AM" elif _mem.fm_dev == 0: mem.mode = "FM" else: mem.mode = "NFM" # qt has no home in the UI return mem def _set_tone(self, mem, _mem): """Update the memory channel block CTCC/DCS tones from the UI fields """ def _set_dcs(code, pol): val = int("%i" % code, 8) | 0x8000 if pol == "R": val |= 0x4000 return val rx_mode = tx_mode = None rxtone = txtone = 0x0000 if mem.tmode == "Tone": tx_mode = "Tone" txtone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) _mem.decQT = rxtone _mem.encQT = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.encQT, rx_mode, _mem.decQT)) def set_memory(self, mem): """ Public set_memory Inverse of get_memory. Update the radio memory image from the mem object """ number = mem.number _mem = self._memobj.chan_blk[number - 1] _nam = self._memobj.chan_name[number - 1] _val = self._memobj.chan_valid[number - 1] if mem.empty: # consider putting in a check for chan # that is empty but # listed as one of the 2 working channels and change them # to channel 1 to be consistent with CPS and allow # complete deletion from radio. Otherwise, # a deleted channel will still show on radio with no name. # MRT implement the above working channel check if self._memobj.a_conf.w_chan == number: self._memobj.a_conf.w_chan = 1 if self._memobj.b_conf.w_chan == number: self._memobj.b_conf.w_chan = 1 _mem.set_raw("\xFF" * (_mem.size() // 8)) _nam.name = str2name("", 8, '\0', '\0') _mem.state = MEM_INVALID _val.ch_valid = CHAN_INVALID return _mem.rxfreq = int(mem.freq / 10) if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = int(mem.offset / 10) elif mem.duplex == "+": _mem.txfreq = int(mem.freq / 10) + int(mem.offset / 10) elif mem.duplex == "-": _mem.txfreq = int(mem.freq / 10) - int(mem.offset / 10) else: _mem.txfreq = int(mem.freq / 10) _mem.scan = int(mem.skip != "S") if mem.mode == "FM": _mem.mod = 0 # make sure forced AM is off _mem.fm_dev = 0 elif mem.mode == "NFM": _mem.mod = 0 _mem.fm_dev = 1 elif mem.mode == "AM": _mem.mod = 1 # AM on _mem.fm_dev = 1 # set NFM bandwidth else: _mem.mod = 0 _mem.fm_dev = 0 # Catchall default is FM # set the tone self._set_tone(mem, _mem) # set the power if mem.power: _mem.pwr = self.POWER_LEVELS.index(mem.power) else: _mem.pwr = True # Set fields we can't access via the UI table to safe defaults _mem.qt = 0 # mute mode to QT _mem.bit5 = 0 # clear this bit to ensure accurate CPS power level _nam.name = str2name(mem.name, 8, '\0', '\0') _mem.state = MEM_VALID _val.ch_valid = CHAN_VALID # Build the UI configuration tabs # the channel memory tab is built by the core. # We have no control over it def _core_tab(self): """ Build Core Configuration tab Radio settings common to all modes and areas go here. """ s = self._memobj.settings if (self.MODEL == "KG-UV9PX" or self.MODEL == "KG-UV9GX"): sm = self._memobj.screen cf = RadioSettingGroup("cfg_grp", "Configuration") cf.append(RadioSetting("auto_am", "Auto detect AM (Menu 53)", RadioSettingValueBoolean(s.auto_am))) cf.append(RadioSetting("qt_sw", "Scan tone detect (Menu 59)", RadioSettingValueBoolean(s.qt_sw))) cf.append( RadioSetting("s_mute", "SubFreq Mute (Menu 60)", RadioSettingValueList(S_MUTE_LIST, S_MUTE_LIST[s.s_mute]))) cf.append( RadioSetting("tot", "Transmit timeout Timer (Menu 10)", RadioSettingValueList(TIMEOUT_LIST, TIMEOUT_LIST[s.tot]))) cf.append( RadioSetting("toa", "Transmit Timeout Alarm (Menu 11)", RadioSettingValueList(TOA_LIST, TOA_LIST[s.toa]))) cf.append( RadioSetting("ptt_id", "PTT Caller ID mode (Menu 23)", RadioSettingValueList(PTTID_LIST, PTTID_LIST[s.ptt_id]))) cf.append( RadioSetting("id_dly", "Caller ID Delay time (Menu 25)", RadioSettingValueList(ID_DLY_LIST, ID_DLY_LIST[s.id_dly]))) cf.append(RadioSetting("voice_sw", "Voice Guide (Menu 12)", RadioSettingValueBoolean(s.voice_sw))) cf.append(RadioSetting("beep", "Keypad Beep (Menu 13)", RadioSettingValueBoolean(s.beep))) cf.append( RadioSetting("s_tone", "Side Tone (Menu 36)", RadioSettingValueList(S_TONES, S_TONES[s.s_tone]))) cf.append( RadioSetting("ring_time", "Ring Time (Menu 26)", RadioSettingValueList( LIST_OFF_10, LIST_OFF_10[s.ring_time]))) cf.append( RadioSetting("roger", "Roger Beep (Menu 9)", RadioSettingValueList(ROGER_LIST, ROGER_LIST[s.roger]))) cf.append(RadioSetting("blcdsw", "Backlight (Menu 41)", RadioSettingValueBoolean(s.blcdsw))) cf.append( RadioSetting("abr", "Auto Backlight Time (Menu 1)", RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[s.abr]))) cf.append( RadioSetting("abr_lvl", "Backlight Brightness (Menu 27)", RadioSettingValueInteger(BACKLIGHT_BRIGHT_MIN, BACKLIGHT_BRIGHT_MAX, s.abr_lvl))) cf.append(RadioSetting("lock", "Keypad Lock", RadioSettingValueBoolean(s.lock))) cf.append( RadioSetting("lock_m", "Keypad Lock Mode (Menu 35)", RadioSettingValueList(LOCK_MODES, LOCK_MODES[s.lock_m]))) cf.append(RadioSetting("auto_lk", "Keypad Autolock (Menu 34)", RadioSettingValueBoolean(s.auto_lk))) cf.append(RadioSetting("prich_sw", "Priority Channel Scan (Menu 33)", RadioSettingValueBoolean(s.prich_sw))) cf.append(RadioSetting("pri_ch", "Priority Channel (Menu 32)", RadioSettingValueInteger(1, 999, s.pri_ch))) cf.append( RadioSetting("dtmf_st", "DTMF Sidetone (Menu 22)", RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[s.dtmf_st]))) cf.append(RadioSetting("sc_qt", "Scan QT Save Mode (Menu 38)", RadioSettingValueList( SCQT_LIST, SCQT_LIST[s.sc_qt]))) cf.append( RadioSetting("apo_tmr", "Automatic Power-off (Menu 39)", RadioSettingValueList(APO_TIMES, APO_TIMES[s.apo_tmr]))) cf.append( # VOX "guard" is really VOX trigger audio level RadioSetting("vox_grd", "VOX level (Menu 7)", RadioSettingValueList(VOX_GRDS, VOX_GRDS[s.vox_grd]))) cf.append( RadioSetting("vox_dly", "VOX Delay (Menu 37)", RadioSettingValueList(VOX_DLYS, VOX_DLYS[s.vox_dly]))) cf.append(RadioSetting("bledsw", "Receive LED (Menu 42)", RadioSettingValueBoolean(s.bledsw))) if (self.MODEL == "KG-UV9PX" or self.MODEL == "KG-UV9GX"): cf.append(RadioSetting("screen.screen_mode", "Screen Mode (Menu 62)", RadioSettingValueList( SCREEN_MODE_LIST, SCREEN_MODE_LIST[ sm.screen_mode]))) if (self.MODEL == "KG-UV9PX" or self.MODEL == "KG-UV9GX"): langlst = LANGUAGE_LIST2 else: langlst = LANGUAGE_LIST cf.append( RadioSetting("lang", "Menu Language (Menu 14)", RadioSettingValueList(langlst, langlst[s.lang]))) if (self.MODEL == "KG-UV9PX" or self.MODEL == "KG-UV9GX"): ponmsglst = PONMSG_LIST2 else: ponmsglst = PONMSG_LIST cf.append(RadioSetting("ponmsg", "Poweron message (Menu 40)", RadioSettingValueList( ponmsglst, ponmsglst[s.ponmsg]))) return cf def _repeater_tab(self): """Repeater mode functions """ s = self._memobj.settings cf = RadioSettingGroup("repeater", "Repeater Functions") cf.append( RadioSetting("type_set", "Radio Mode (Menu 43)", RadioSettingValueList( RPTMODE_LIST, RPTMODE_LIST[s.type_set]))) cf.append(RadioSetting("rpt_ptt", "Repeater PTT (Menu 45)", RadioSettingValueBoolean(s.rpt_ptt))) cf.append(RadioSetting("rpt_spk", "Repeater Mode Speaker (Menu 44)", RadioSettingValueBoolean(s.rpt_spk))) cf.append( RadioSetting("rpt_kpt", "Repeater Hold Time (Menu 46)", RadioSettingValueList(RPT_KPTS, RPT_KPTS[s.rpt_kpt]))) cf.append(RadioSetting("rpt_rct", "Repeater Receipt Tone (Menu 47)", RadioSettingValueBoolean(s.rpt_rct))) return cf def _admin_tab(self): """Admin functions not present in radio menu... These are admin functions not radio operation configuration """ def apply_cid(setting, obj): c = str2callid(setting.value) obj.code = c def apply_scc(setting, obj): c = str2digits(setting.value) obj.scc = c def apply_mode_sw(setting, obj): pw = str2pw(setting.value) obj.mode_sw = pw setting.value = pw2str(obj.mode_sw) def apply_reset(setting, obj): pw = str2pw(setting.value) obj.reset = pw setting.value = pw2str(obj.reset) def apply_wake(setting, obj): obj.wake = int(setting.value)/10 def apply_sleep(setting, obj): obj.sleep = int(setting.value)/10 pw = self._memobj.passwords # admin passwords s = self._memobj.settings cf = RadioSettingGroup("admin", "Admin Functions") cf.append(RadioSetting("menu_avail", "Menu available in channel mode", RadioSettingValueBoolean(s.menu_avail))) mode_sw = RadioSettingValueString(0, 6, pw2str(pw.mode_sw), False) rs = RadioSetting("passwords.mode_sw", "Mode Switch Password", mode_sw) rs.set_apply_callback(apply_mode_sw, pw) cf.append(rs) cf.append(RadioSetting("reset_avail", "Radio Reset Available", RadioSettingValueBoolean(s.reset_avail))) reset = RadioSettingValueString(0, 6, pw2str(pw.reset), False) rs = RadioSetting("passwords.reset", "Radio Reset Password", reset) rs.set_apply_callback(apply_reset, pw) cf.append(rs) cf.append( RadioSetting("dtmf_tx", "DTMF Tx Duration", RadioSettingValueList(DTMF_TIMES, DTMF_TIMES[s.dtmf_tx]))) cid = self._memobj.my_callid my_callid = RadioSettingValueString(3, 6, self.callid2str(cid.code), False) rs = RadioSetting("my_callid.code", "PTT Caller ID code (Menu 24)", my_callid) rs.set_apply_callback(apply_cid, cid) cf.append(rs) stun = self._memobj.stun st = RadioSettingValueString(0, 6, digits2str(stun.scc), False) rs = RadioSetting("stun.scc", "Security code", st) rs.set_apply_callback(apply_scc, stun) cf.append(rs) cf.append( RadioSetting("settings.save_m", "Save Mode (Menu 2)", RadioSettingValueList(SAVE_MODES, SAVE_MODES[s.save_m]))) for i in range(0, 4): sm = self._memobj.save[i] wake = RadioSettingValueInteger(0, 18000, sm.wake * 10, 1) wf = RadioSetting("save[%i].wake" % i, "Save Mode %d Wake Time" % (i+1), wake) wf.set_apply_callback(apply_wake, sm) cf.append(wf) slp = RadioSettingValueInteger(0, 18000, sm.sleep * 10, 1) wf = RadioSetting("save[%i].sleep" % i, "Save Mode %d Sleep Time" % (i+1), slp) wf.set_apply_callback(apply_sleep, sm) cf.append(wf) _msg = str(self._memobj.display.banner).split("\0")[0] val = RadioSettingValueString(0, 16, _msg) val.set_mutable(True) cf.append(RadioSetting("display.banner", "Display Message", val)) if (self.MODEL == "KG-UV9PX" or self.MODEL == "KG-UV9GX"): _str = str(self._memobj.oemmodel.model).split("\0")[0] val = RadioSettingValueString(0, 10, _str) val.set_mutable(True) cf.append(RadioSetting("oemmodel.model", "Custom Sub-Receiver Message", val)) val = RadioSettingValueList( TDR_LIST, TDR_LIST[s.tdr]) val.set_mutable(True) cf.append(RadioSetting("tdr", "TDR", val)) val = RadioSettingValueList( ACTIVE_AREA_LIST, ACTIVE_AREA_LIST[s.act_area]) val.set_mutable(True) cf.append(RadioSetting("act_area", "Active Receiver(BAND)", val)) return cf def _fm_tab(self): """FM Broadcast channels """ def apply_fm(setting, obj): f = freq2short(setting.value, 76000000, 108000000) obj.fm_freq = f fm = RadioSettingGroup("fm_chans", "FM Broadcast") for ch in range(0, 20): chan = self._memobj.fm_chans[ch] freq = RadioSettingValueString(0, 20, short2freq(chan.fm_freq)) rs = RadioSetting("fm_%d" % (ch + 1), "FM Channel %d" % (ch + 1), freq) rs.set_apply_callback(apply_fm, chan) fm.append(rs) return fm def _scan_grp(self): """Scan groups """ def apply_name(setting, obj): name = str2name(setting.value, 8, '\0', '\0') obj.name = name def apply_start(setting, obj): """Do a callback to deal with RadioSettingInteger limitation on memory address resolution """ obj.scan_st = int(setting.value) def apply_end(setting, obj): """Do a callback to deal with RadioSettingInteger limitation on memory address resolution """ obj.scan_end = int(setting.value) sgrp = self._memobj.scn_grps scan = RadioSettingGroup("scn_grps", "Channel Scanner Groups") for i in range(0, 10): s_grp = sgrp.addrs[i] s_name = sgrp.names[i] rs_name = RadioSettingValueString(0, 8, name2str(s_name.name)) rs = RadioSetting("scn_grps.names[%i].name" % i, "Group %i Name" % (i + 1), rs_name) rs.set_apply_callback(apply_name, s_name) scan.append(rs) rs_st = RadioSettingValueInteger(1, 999, s_grp.scan_st) rs = RadioSetting("scn_grps.addrs[%i].scan_st" % i, "Starting Channel", rs_st) rs.set_apply_callback(apply_start, s_grp) scan.append(rs) rs_end = RadioSettingValueInteger(1, 999, s_grp.scan_end) rs = RadioSetting("scn_grps.addrs[%i].scan_end" % i, "Last Channel", rs_end) rs.set_apply_callback(apply_end, s_grp) scan.append(rs) return scan def _callid_grp(self): """Caller IDs to be recognized by radio This really should be a table in the UI """ def apply_callid(setting, obj): c = str2callid(setting.value) obj.cid = c def apply_name(setting, obj): name = str2name(setting.value, 6, '\0', '\xff') obj.name = name cid = RadioSettingGroup("callids", "Caller IDs") for i in range(0, 20): callid = self._memobj.call_ids[i] name = self._memobj.cid_names[i] c_name = RadioSettingValueString(0, 6, name2str(name.name)) rs = RadioSetting("cid_names[%i].name" % i, "Caller ID %i Name" % (i + 1), c_name) rs.set_apply_callback(apply_name, name) cid.append(rs) c_id = RadioSettingValueString(0, 6, self.callid2str(callid.cid), False) rs = RadioSetting("call_ids[%i].cid" % i, "Caller ID Code", c_id) rs.set_apply_callback(apply_callid, callid) cid.append(rs) return cid def _band_tab(self, area, band): """ Build a band tab inside a VFO/Area """ def apply_freq(setting, lo, hi, obj): f = freq2int(setting.value, lo, hi) obj.freq = f/10 def apply_offset(setting, obj): f = freq2int(setting.value, 0, 5000000) obj.offset = f/10 def apply_enc(setting, obj): t = tone2short(setting.value) obj.encqt = t def apply_dec(setting, obj): t = tone2short(setting.value) obj.decqt = t if area == "a": if band == 150: c = self._memobj.vfo_a.band_150 lo = 108000000 hi = 180000000 elif band == 200: c = self._memobj.vfo_a.band_200 lo = 230000000 hi = 250000000 elif band == 300: c = self._memobj.vfo_a.band_300 lo = 350000000 hi = 400000000 elif band == 450: c = self._memobj.vfo_a.band_450 lo = 400000000 hi = 512000000 else: # 700 c = self._memobj.vfo_a.band_700 lo = 700000000 hi = 985000000 else: # area 'b' if band == 150: c = self._memobj.vfo_b.band_150 lo = 136000000 hi = 180000000 else: # 450 c = self._memobj.vfo_b.band_450 lo = 400000000 hi = 512000000 prefix = "vfo_%s.band_%d" % (area, band) bf = RadioSettingGroup(prefix, "%d MHz Band" % band) freq = RadioSettingValueString(0, 15, int2freq(c.freq * 10)) rs = RadioSetting(prefix + ".freq", "Rx Frequency", freq) rs.set_apply_callback(apply_freq, lo, hi, c) bf.append(rs) off = RadioSettingValueString(0, 15, int2freq(c.offset * 10)) rs = RadioSetting(prefix + ".offset", "Tx Offset (Menu 28)", off) rs.set_apply_callback(apply_offset, c) bf.append(rs) rs = RadioSetting(prefix + ".encqt", "Encode QT (Menu 17,19)", RadioSettingValueList(TONE_LIST, short2tone(c.encqt))) rs.set_apply_callback(apply_enc, c) bf.append(rs) rs = RadioSetting(prefix + ".decqt", "Decode QT (Menu 16,18)", RadioSettingValueList(TONE_LIST, short2tone(c.decqt))) rs.set_apply_callback(apply_dec, c) bf.append(rs) bf.append(RadioSetting(prefix + ".qt", "Mute Mode (Menu 21)", RadioSettingValueList(SPMUTE_LIST, SPMUTE_LIST[c.qt]))) bf.append(RadioSetting(prefix + ".scan", "Scan this (Menu 48)", RadioSettingValueBoolean(c.scan))) bf.append(RadioSetting(prefix + ".pwr", "Power (Menu 5)", RadioSettingValueList( POWER_LIST, POWER_LIST[c.pwr]))) bf.append(RadioSetting(prefix + ".mod", "AM Modulation (Menu 54)", RadioSettingValueBoolean(c.mod))) bf.append(RadioSetting(prefix + ".fm_dev", "FM Deviation (Menu 4)", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[c.fm_dev]))) bf.append( RadioSetting(prefix + ".shift", "Frequency Shift (Menu 6)", RadioSettingValueList(OFFSET_LIST, OFFSET_LIST[c.shift]))) return bf def _area_tab(self, area): """Build a VFO tab """ def apply_scan_st(setting, scan_lo, scan_hi, obj): f = freq2short(setting.value, scan_lo, scan_hi) obj.scan_st = f def apply_scan_end(setting, scan_lo, scan_hi, obj): f = freq2short(setting.value, scan_lo, scan_hi) obj.scan_end = f if area == "a": desc = "Area A Settings" c = self._memobj.a_conf scan_lo = 108000000 scan_hi = 985000000 scan_rng = self._memobj.settings.a band_list = (150, 200, 300, 450, 700) else: desc = "Area B Settings" c = self._memobj.b_conf scan_lo = 136000000 scan_hi = 512000000 scan_rng = self._memobj.settings.b band_list = (150, 450) prefix = "%s_conf" % area af = RadioSettingGroup(prefix, desc) af.append( RadioSetting(prefix + ".w_mode", "Workmode", RadioSettingValueList( WORKMODE_LIST, WORKMODE_LIST[c.w_mode]))) af.append(RadioSetting(prefix + ".w_chan", "Channel", RadioSettingValueInteger(1, 999, c.w_chan))) af.append( RadioSetting(prefix + ".scan_grp", "Scan Group (Menu 49)", RadioSettingValueList( SCANGRP_LIST, SCANGRP_LIST[c.scan_grp]))) af.append(RadioSetting(prefix + ".bcl", "Busy Channel Lock-out (Menu 15)", RadioSettingValueBoolean(c.bcl))) af.append( RadioSetting(prefix + ".sql", "Squelch Level (Menu 8)", RadioSettingValueList(LIST_0_9, LIST_0_9[c.sql]))) af.append( RadioSetting(prefix + ".cset", "Call ID Group (Menu 52)", RadioSettingValueList(LIST_1_20, LIST_1_20[c.cset]))) af.append( RadioSetting(prefix + ".step", "Frequency Step (Menu 3)", RadioSettingValueList( self._step_list, self._step_list[c.step]))) af.append( RadioSetting(prefix + ".scan_mode", "Scan Mode (Menu 20)", RadioSettingValueList( SCANMODE_LIST, SCANMODE_LIST[c.scan_mode]))) af.append( RadioSetting(prefix + ".scan_range", "Scan Range (Menu 50)", RadioSettingValueList( SCANRANGE_LIST, SCANRANGE_LIST[c.scan_range]))) st = RadioSettingValueString(0, 15, short2freq(scan_rng.scan_st)) rs = RadioSetting("settings.%s.scan_st" % area, "Frequency Scan Start", st) rs.set_apply_callback(apply_scan_st, scan_lo, scan_hi, scan_rng) af.append(rs) end = RadioSettingValueString(0, 15, short2freq(scan_rng.scan_end)) rs = RadioSetting("settings.%s.scan_end" % area, "Frequency Scan End", end) rs.set_apply_callback(apply_scan_end, scan_lo, scan_hi, scan_rng) af.append(rs) # Each area has its own set of bands for band in (band_list): af.append(self._band_tab(area, band)) return af def _key_tab(self): """Build radio key/button menu """ s = self._memobj.settings if self.MODEL == "KG-UV9PX": pfkey1 = PF1KEY_LIST pfkey2 = PF2KEY_LIST pfkey3 = PF3KEY_LIST2 elif (self.MODEL == "KG-UV9GX" or self.MODEL == "KG-UV9G Pro"): pfkey1 = PF1KEY_LIST9GX pfkey2 = PF2KEY_LIST9GX pfkey3 = PF3KEY_LIST9GX else: pfkey1 = PF1KEY_LIST pfkey2 = PF2KEY_LIST pfkey3 = PF3KEY_LIST kf = RadioSettingGroup("key_grp", "Key Settings") kf.append(RadioSetting("settings.pf1", "PF1 Key function (Menu 55)", RadioSettingValueList( pfkey1, pfkey1[s.pf1]))) kf.append(RadioSetting("settings.pf2", "PF2 Key function (Menu 56)", RadioSettingValueList( pfkey2, pfkey2[s.pf2]))) kf.append(RadioSetting("settings.pf3", "PF3 Key function (Menu 57)", RadioSettingValueList( pfkey3, pfkey3[s.pf3]))) return kf def _fl_tab(self): """Build the frequency limits tab """ # The stop limits in the factory KG-UV9D Mate memory image are 1 MHz # higher than the published specs. The settings panel will crash if # it encounters a value outside of these ranges. hard_limits = { "band_150": (108000000, 181000000), "band_450": (400000000, 513000000), "band_300": (350000000, 401000000), "band_700": (700000000, 987000000), "band_200": (230000000, 251000000) } def apply_freq_start(setting, low, high, obj): f = freq2short(setting.value, low, high) obj.start = f def apply_freq_stop(setting, low, high, obj): """Sets the stop limit to 1 MHz below the input value""" # The firmware has an off-by-1MHz error with stop limits. # If you set the stop limit to 1480 (148 MHz), you can still tune # up to 148.99 MHz. To compensate for this, # we subtract 10 increments of 100 MHz before storing the value. f = freq2short(setting.value, low, high) - 10 obj.stop = f fl = RadioSettingGroup("freq_limit_grp", "Frequency Limits") rx = self._memobj.rx_freq_limits tx = self._memobj.tx_freq_limits for rx_band in rx.items(): name, limits = rx_band start_freq = RadioSettingValueString(1, 20, short2freq(limits.start)) start_rs = RadioSetting("rx_start_" + name, name + " Receive Start", start_freq) start_rs.set_apply_callback(apply_freq_start, hard_limits[name][0], hard_limits[name][1], limits) fl.append(start_rs) # Add 10 increments of 100 MHz before displaying to compensate for # the firmware off-by-1MHz problem. stop_freq = RadioSettingValueString(1, 20, short2freq(limits.stop + 10)) stop_rs = RadioSetting("rx_stop_" + name, name + " Receive Stop", stop_freq) stop_rs.set_apply_callback(apply_freq_stop, hard_limits[name][0], hard_limits[name][1], limits) fl.append(stop_rs) for tx_band in tx.items(): name, limits = tx_band start_freq = RadioSettingValueString(1, 20, short2freq(limits.start)) start_rs = RadioSetting("tx_start_" + name, name + " Transmit Start", start_freq) start_rs.set_apply_callback(apply_freq_start, hard_limits[name][0], hard_limits[name][1], limits) fl.append(start_rs) # Add 10 increments of 100 MHz before displaying to compensate for # the firmware off-by-1MHz problem. stop_freq = RadioSettingValueString(1, 20, short2freq(limits.stop + 10)) stop_rs = RadioSetting("tx_stop_" + name, name + " Transmit Stop", stop_freq) stop_rs.set_apply_callback(apply_freq_stop, hard_limits[name][0], hard_limits[name][1], limits) fl.append(stop_rs) return fl def _get_settings(self): """Build the radio configuration settings menus """ core_grp = self._core_tab() fm_grp = self._fm_tab() area_a_grp = self._area_tab("a") area_b_grp = self._area_tab("b") key_grp = self._key_tab() scan_grp = self._scan_grp() callid_grp = self._callid_grp() admin_grp = self._admin_tab() rpt_grp = self._repeater_tab() freq_limit_grp = self._fl_tab() core_grp.append(key_grp) core_grp.append(admin_grp) core_grp.append(rpt_grp) core_grp.append(freq_limit_grp) group = RadioSettings(core_grp, area_a_grp, area_b_grp, fm_grp, scan_grp, callid_grp ) return group def get_settings(self): """ Public build out linkage between radio settings and UI """ try: return self._get_settings() except Exception: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def _is_freq(self, element): """This is a hack to smoke out whether we need to do frequency translations for otherwise innocent u16s and u32s """ return "rxfreq" in element.get_name() or \ "txfreq" in element.get_name() or \ "scan_st" in element.get_name() or \ "scan_end" in element.get_name() or \ "offset" in element.get_name() or \ "fm_stop" in element.get_name() def _is_limit(self, element): return "lower_limit" in element.get_name() or\ "upper_limit" in element.get_name() def set_settings(self, settings): """ Public update radio settings via UI callback A lot of this should be in common code.... """ for element in settings: if not isinstance(element, RadioSetting): LOG.debug("set_settings: not instance %s" % element.get_name()) self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: # decode an array index if "[" in bit and "]" in bit: bit, index = bit.split("[", 1) index, junk = index.split("]", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) if self._is_freq(element): setattr(obj, setting, int(element.value)/10) elif self._is_limit(element): setattr(obj, setting, int(element.value)*10) else: setattr(obj, setting, element.value) except Exception: LOG.debug("set_settings: Exception with %s" % element.get_name()) raise def callid2str(self, cid): """Caller ID per MDC-1200 spec? Must be 3-6 digits (100 - 999999). One digit (binary) per byte, terminated with '0xc' """ bin2ascii = " 1234567890" cidstr = "" for i in range(0, 6): b = cid[i].get_value() if b == 0xc: # the cid EOL break if b == 0 or b > 0xa: raise InvalidValueError( "Caller ID code has illegal byte 0x%x" % b) cidstr += bin2ascii[b] return cidstr @directory.register class KGUV9PXRadio(KGUV9DPlusRadio): """Wouxun KG-UV9PX""" VENDOR = "Wouxun" MODEL = "KG-UV9PX" _model = b"KG-UV9D" _rev = b"02" # default rev for the radio I know about... _file_ident = b"kg-uv9px" NEEDS_COMPAT_SERIAL = False _valid_steps = STEPS _step_list = STEP_LIST @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False def process_mmap(self): if self._rev != b"02" and self._rev != b"00": # new revision found - log it and assume same map and proceed LOG.debug("Unrecognized model variation (%s) Using default Map" % self._rev) self._memobj = bitwise.parse(_MEM_FORMAT_9PX, self._mmap) def get_features(self): """ Public get_features Return the features of this radio once we have identified it and gotten its bits """ rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM", "AM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_bands = [(108000000, 135997500), # Aircraft AM (136000000, 180997500), # supports 2m (219000000, 250997500), (350000000, 399997500), (400000000, 512997500), # supports 70cm (700000000, 986997500)] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_tuning_steps = STEPS rf.memory_bounds = (1, 999) # 999 memories return rf def callid2str(self, cid): """Caller ID per MDC-1200 spec? Must be 3-6 digits (100 - 999999). One digit (binary) per byte, terminated with '0xc' """ bin2ascii = " 1234567890" cidstr = "" for i in range(0, 6): b = cid[i].get_value() # 9PX factory reset CID use 0x00 for 0 digit - instead of 0x0a # remap 0x00 to 0x0a if b == 0x00: b = 0x0a if b == 0xc or b == 0xf0: # the cid EOL break if b > 0xa: raise InvalidValueError( "Caller ID code has illegal byte 0x%x" % b) cidstr += bin2ascii[b] return cidstr def _get_settings(self): """Build the radio configuration settings menus """ core_grp = self._core_tab() fm_grp = self._fm_tab() area_a_grp = self._area_tab("a") area_b_grp = self._area_tab("b") key_grp = self._key_tab() scan_grp = self._scan_grp() callid_grp = self._callid_grp() admin_grp = self._admin_tab() rpt_grp = self._repeater_tab() freq_limit_grp = self._fl_tab() core_grp.append(key_grp) core_grp.append(admin_grp) core_grp.append(rpt_grp) group = RadioSettings(core_grp, area_a_grp, area_b_grp, fm_grp, scan_grp, callid_grp, freq_limit_grp,) return group def _area_tab(self, area): """Build a VFO tab """ def apply_scan_st(setting, scan_lo, scan_hi, obj): f = freq2short(setting.value, scan_lo, scan_hi) obj.scan_st = f def apply_scan_end(setting, scan_lo, scan_hi, obj): f = freq2short(setting.value, scan_lo, scan_hi) obj.scan_end = f if area == "a": desc = "Receiver A Settings" c = self._memobj.a_conf scan_lo = 108000000 scan_hi = 985997500 scan_rng = self._memobj.settings.a band_list = (150, 200, 300, 450, 700) else: desc = "Receiver B Settings" c = self._memobj.b_conf scan_lo = 136000000 scan_hi = 512997500 scan_rng = self._memobj.settings.b band_list = (150, 450) prefix = "%s_conf" % area af = RadioSettingGroup(prefix, desc) af.append( RadioSetting(prefix + ".w_mode", "Workmode", RadioSettingValueList( WORKMODE_LIST, WORKMODE_LIST[c.w_mode]))) af.append(RadioSetting(prefix + ".w_chan", "Channel", RadioSettingValueInteger(1, 999, c.w_chan))) af.append( RadioSetting(prefix + ".scan_grp", "Scan Group (Menu 49)", RadioSettingValueList( SCANGRP_LIST, SCANGRP_LIST[c.scan_grp]))) af.append(RadioSetting(prefix + ".bcl", "Busy Channel Lock-out (Menu 15)", RadioSettingValueBoolean(c.bcl))) af.append( RadioSetting(prefix + ".sql", "Squelch Level (Menu 8)", RadioSettingValueList(LIST_0_9, LIST_0_9[c.sql]))) af.append( RadioSetting(prefix + ".cset", "Call ID Group (Menu 52)", RadioSettingValueList(LIST_1_20, LIST_1_20[c.cset]))) af.append( RadioSetting(prefix + ".step", "Frequency Step (Menu 3)", RadioSettingValueList( self._step_list, self._step_list[c.step]))) af.append( RadioSetting(prefix + ".scan_mode", "Scan Mode (Menu 20)", RadioSettingValueList( SCANMODE_LIST, SCANMODE_LIST[c.scan_mode]))) af.append( RadioSetting(prefix + ".scan_range", "Scan Range (Menu 50)", RadioSettingValueList( SCANRANGE_LIST, SCANRANGE_LIST[c.scan_range]))) st = RadioSettingValueString(0, 15, short2freq(scan_rng.scan_st)) rs = RadioSetting("settings.%s.scan_st" % area, "Frequency Scan Start", st) rs.set_apply_callback(apply_scan_st, scan_lo, scan_hi, scan_rng) af.append(rs) end = RadioSettingValueString(0, 15, short2freq(scan_rng.scan_end)) rs = RadioSetting("settings.%s.scan_end" % area, "Frequency Scan End", end) rs.set_apply_callback(apply_scan_end, scan_lo, scan_hi, scan_rng) af.append(rs) # Each area has its own set of bands for band in (band_list): af.append(self._band_tab(area, band)) return af def _band_tab(self, area, band): """ Build a band tab inside a VFO/Area """ def apply_freq(setting, lo, hi, obj): f = freq2int(setting.value, lo, hi) obj.freq = f/10 def apply_offset(setting, obj): f = freq2int(setting.value, 0, 5000000) obj.offset = f/10 def apply_enc(setting, obj): t = tone2short(setting.value) obj.encqt = t def apply_dec(setting, obj): t = tone2short(setting.value) obj.decqt = t if area == "a": if band == 150: c = self._memobj.vfo_a.band_150 lo = 108000000 hi = 180997500 elif band == 200: c = self._memobj.vfo_a.band_200 lo = 219000000 hi = 250997500 elif band == 300: c = self._memobj.vfo_a.band_300 lo = 350000000 hi = 399997500 elif band == 450: c = self._memobj.vfo_a.band_450 lo = 400000000 hi = 512997500 else: # 700 c = self._memobj.vfo_a.band_700 lo = 700000000 hi = 986997500 else: # area 'b' if band == 150: c = self._memobj.vfo_b.band_150 lo = 136000000 hi = 180997500 else: # 450 c = self._memobj.vfo_b.band_450 lo = 400000000 hi = 512997500 prefix = "vfo_%s.band_%d" % (area, band) bf = RadioSettingGroup(prefix, "%d MHz Band" % band) freq = RadioSettingValueString(0, 15, int2freq(c.freq * 10)) rs = RadioSetting(prefix + ".freq", "Rx Frequency", freq) rs.set_apply_callback(apply_freq, lo, hi, c) bf.append(rs) off = RadioSettingValueString(0, 15, int2freq(c.offset * 10)) rs = RadioSetting(prefix + ".offset", "Tx Offset (Menu 28)", off) rs.set_apply_callback(apply_offset, c) bf.append(rs) rs = RadioSetting(prefix + ".encqt", "Encode QT (Menu 17,19)", RadioSettingValueList(TONE_LIST, short2tone(c.encqt))) rs.set_apply_callback(apply_enc, c) bf.append(rs) rs = RadioSetting(prefix + ".decqt", "Decode QT (Menu 16,18)", RadioSettingValueList(TONE_LIST, short2tone(c.decqt))) rs.set_apply_callback(apply_dec, c) bf.append(rs) bf.append(RadioSetting(prefix + ".qt", "Mute Mode (Menu 21)", RadioSettingValueList(SPMUTE_LIST, SPMUTE_LIST[c.qt]))) bf.append(RadioSetting(prefix + ".scan", "Scan this (Menu 48)", RadioSettingValueBoolean(c.scan))) bf.append(RadioSetting(prefix + ".pwr", "Power (Menu 5)", RadioSettingValueList( POWER_LIST, POWER_LIST[c.pwr]))) bf.append(RadioSetting(prefix + ".mod", "AM Modulation (Menu 54)", RadioSettingValueBoolean(c.mod))) bf.append(RadioSetting(prefix + ".fm_dev", "FM Deviation (Menu 4)", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[c.fm_dev]))) bf.append( RadioSetting(prefix + ".shift", "Frequency Shift (Menu 6)", RadioSettingValueList(OFFSET_LIST, OFFSET_LIST[c.shift]))) return bf def _fl_tab(self): freq_limit_grp = RadioSettingGroup("limits", "Freq Limits") limgrp = freq_limit_grp l = self._memobj.limits if self.MODEL == "KG-UV9PX": val = RadioSettingValueInteger(136, 180, (l.lim_150M_Txlower_limit) / 10.0) rs = RadioSetting("limits.lim_150M_Txlower_limit", "150M Tx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(136, 180, (l.lim_150M_Txupper_limit) / 10.0) rs = RadioSetting("limits.lim_150M_Txupper_limit", "150M Tx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) val = RadioSettingValueInteger(400, 512, (l.lim_450M_Txlower_limit) / 10.0) rs = RadioSetting("limits.lim_450M_Txlower_limit", "450M Tx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(400, 512, (l.lim_450M_Txupper_limit) / 10.0) rs = RadioSetting("limits.lim_450M_Txupper_limit", "450M Tx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) val = RadioSettingValueInteger(108, 180, (l.lim_150M_area_a_rxlower_limit) / 10.0) rs = RadioSetting("limits.lim_150M_area_a_rxlower_limit", "Rcvr A 150M Rx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(108, 180, (l.lim_150M_area_a_rxupper_limit) / 10.0) rs = RadioSetting("limits.lim_150M_area_a_rxupper_limit", "Rcvr A 150M Rx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) val = RadioSettingValueInteger(136, 180, (l.lim_150M_area_b_rxlower_limit) / 10.0) rs = RadioSetting("limits.lim_150M_area_b_rxlower_limit", "Rcvr B 150M Rx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(136, 180, (l.lim_150M_area_b_rxupper_limit) / 10.0) rs = RadioSetting("limits.lim_150M_area_b_rxupper_limit", "Rcvr B 150M Rx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) val = RadioSettingValueInteger(400, 512, (l.lim_450M_rxlower_limit) / 10.0) rs = RadioSetting("limits.lim_450M_rxlower_limit", "450M Rx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(400, 512, (l.lim_450M_rxupper_limit) / 10.0) rs = RadioSetting("limits.lim_450M_rxupper_limit", "450M Rx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) val = RadioSettingValueInteger(350, 399, (l.lim_300M_rxlower_limit) / 10.0) rs = RadioSetting("limits.lim_300M_rxlower_limit", "300M Rx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(350, 399, (l.lim_300M_rxupper_limit) / 10.0) rs = RadioSetting("limits.lim_300M_rxupper_limit", "300M Rx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) val = RadioSettingValueInteger(700, 986, (l.lim_800M_rxlower_limit) / 10.0) rs = RadioSetting("limits.lim_800M_rxlower_limit", "800M Rx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(700, 986, (l.lim_800M_rxupper_limit) / 10.0) rs = RadioSetting("limits.lim_800M_rxupper_limit", "800M Rx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) val = RadioSettingValueInteger(219, 250, (l.lim_210M_rxlower_limit) / 10.0) rs = RadioSetting("limits.lim_210M_rxlower_limit", "210M Rx Lower Limit (MHz)", val) limgrp.append(rs) val = RadioSettingValueInteger(219, 250, (l.lim_210M_rxupper_limit) / 10.0) rs = RadioSetting("limits.lim_210M_rxupper_limit", "210M Rx Upper Limit (MHz + 0.9975)", val) limgrp.append(rs) return limgrp @directory.register class KGUV9GXRadio(KGUV9PXRadio): """Wouxun KG-UV9GX""" VENDOR = "Wouxun" MODEL = "KG-UV9GX" _model = b"KG-UV9D" _rev = b"02" # default rev for the radio I know about... NEEDS_COMPAT_SERIAL = False _valid_steps = STEPS _step_list = STEP_LIST @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class KGUV9KRadio(KGUV9DPlusRadio): """Wouxun KG-UV9K""" VENDOR = "Wouxun" MODEL = "KG-UV9K" _model = b"KG-UV9D" _file_ident = b"kg-uv9k" _rev = b"02" # default rev for the radio I know about... NEEDS_COMPAT_SERIAL = False _step_list = STEP_LIST_9K _valid_steps = STEPS_9K @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class KGUV9GProRadio(KGUV9DPlusRadio): """Wouxun KG-UV9G Pro""" VENDOR = "Wouxun" MODEL = "KG-UV9G Pro" _model = b"KG-UV9D" _file_ident = b"kg-uv9gpro" _rev = b"02" # default rev for the radio I know about... NEEDS_COMPAT_SERIAL = False _step_list = STEP_LIST _valid_steps = STEPS @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False chirp-20240224/chirp/drivers/uv5r.py0000644000175000017500000021325614562116574016116 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import struct import time import logging from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, errors, util, directory, memmap from chirp import bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ InvalidValueError, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0008; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unused1:3, isuhf:1, scode:4; u8 unknown1:7, txtoneicon:1; u8 mailicon:3, unknown2:3, lowpower:2; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[128]; #seekto 0x0B08; struct { u8 code[5]; u8 unused[11]; } pttid[15]; #seekto 0x0C88; struct { u8 code222[3]; u8 unused222[2]; u8 code333[3]; u8 unused333[2]; u8 alarmcode[3]; u8 unused119[2]; u8 unknown1; u8 code555[3]; u8 unused555[2]; u8 code666[3]; u8 unused666[2]; u8 code777[3]; u8 unused777[2]; u8 unknown2; u8 code60606[5]; u8 code70707[5]; u8 code[5]; u8 unused1:6, aniid:2; u8 unknown[2]; u8 dtmfon; u8 dtmfoff; } ani; #seekto 0x0E28; struct { u8 squelch; u8 step; u8 unknown1; u8 save; u8 vox; u8 unknown2; u8 abr; u8 tdr; u8 beep; u8 timeout; u8 unknown3[4]; u8 voice; u8 unknown4; u8 dtmfst; u8 unknown5; u8 unknown12:6, screv:2; u8 pttid; u8 pttlt; u8 mdfa; u8 mdfb; u8 bcl; u8 autolk; // NOTE: The UV-6 calls this byte voxenable, but the UV-5R // calls it autolk. Since this is a minor difference, it will // be referred to by the wrong name for the UV-6. u8 sftd; u8 unknown6[3]; u8 wtled; u8 rxled; u8 txled; u8 almod; u8 band; u8 tdrab; u8 ste; u8 rpste; u8 rptrl; u8 ponmsg; u8 roger; u8 rogerrx; u8 tdrch; // NOTE: The UV-82HP calls this byte rtone, but the UV-6 // calls it tdrch. Since this is a minor difference, it will // be referred to by the wrong name for the UV-82HP. u8 displayab:1, unknown7:2, fmradio:1, alarm:1, unknown8:1, reset:1, menu:1; u8 unknown9:6, singleptt:1, vfomrlock:1; u8 workmode; u8 keylock; } settings; #seekto 0x0E7E; struct { u8 unused1:1, mrcha:7; u8 unused2:1, mrchb:7; } wmchannel; #seekto 0x0F10; struct { u8 freq[8]; u8 offset[6]; ul16 rxtone; ul16 txtone; u8 unused1:7, band:1; u8 unknown3; u8 unused2:2, sftd:2, scode:4; u8 unknown4; u8 unused3:1, step:3, unused4:4; u8 txpower:1, widenarr:1, unknown5:4, txpower3:2; } vfoa; #seekto 0x0F30; struct { u8 freq[8]; u8 offset[6]; ul16 rxtone; ul16 txtone; u8 unused1:7, band:1; u8 unknown3; u8 unused2:2, sftd:2, scode:4; u8 unknown4; u8 unused3:1, step:3, unused4:4; u8 txpower:1, widenarr:1, unknown5:4, txpower3:2; } vfob; #seekto 0x0F56; u16 fm_presets; #seekto 0x1008; struct { char name[7]; u8 unknown2[9]; } names[128]; #seekto 0x1818; struct { char line1[7]; char line2[7]; } sixpoweron_msg; #seekto 0x%04X; struct { char line1[7]; char line2[7]; } poweron_msg; #seekto 0x1838; struct { char line1[7]; char line2[7]; } firmware_msg; struct squelch { u8 sql0; u8 sql1; u8 sql2; u8 sql3; u8 sql4; u8 sql5; u8 sql6; u8 sql7; u8 sql8; u8 sql9; }; #seekto 0x18A8; struct { struct squelch vhf; u8 unknown1[6]; u8 unknown2[16]; struct squelch uhf; } squelch_new; #seekto 0x18E8; struct { struct squelch vhf; u8 unknown[6]; struct squelch uhf; } squelch_old; struct limit { u8 enable; bbcd lower[2]; bbcd upper[2]; }; #seekto 0x1908; struct { struct limit vhf; struct limit uhf; } limits_new; #seekto 0x1910; struct { u8 unknown1[2]; struct limit vhf; u8 unknown2; u8 unknown3[8]; u8 unknown4[2]; struct limit uhf; } limits_old; """ # 0x1EC0 - 0x2000 vhf_220_radio = b"\x02" BASETYPE_UV5R = [b"BFS", b"BFB", b"N5R-2", b"N5R2", b"N5RV", b"BTS", b"D5R2", b"B5R2"] BASETYPE_F11 = [b"USA"] BASETYPE_UV82 = [b"US2S2", b"B82S", b"BF82", b"N82-2", b"N822"] BASETYPE_BJ55 = [b"BJ55"] # needed for for the Baojie UV-55 in bjuv55.py BASETYPE_UV6 = [b"BF1", b"UV6"] BASETYPE_KT980HP = [b"BFP3V3 B"] BASETYPE_F8HP = [b"BFP3V3 F", b"N5R-3", b"N5R3", b"F5R3", b"BFT", b"N5RV"] BASETYPE_UV82HP = [b"N82-3", b"N823", b"N5R2"] BASETYPE_UV82X3 = [b"HN5RV01"] BASETYPE_LIST = BASETYPE_UV5R + BASETYPE_F11 + BASETYPE_UV82 + \ BASETYPE_BJ55 + BASETYPE_UV6 + BASETYPE_KT980HP + \ BASETYPE_F8HP + BASETYPE_UV82HP + BASETYPE_UV82X3 AB_LIST = ["A", "B"] ALMOD_LIST = ["Site", "Tone", "Code"] BANDWIDTH_LIST = ["Wide", "Narrow"] COLOR_LIST = ["Off", "Blue", "Orange", "Purple"] DTMFSPEED_LIST = ["%s ms" % x for x in range(50, 2010, 10)] DTMFST_LIST = ["OFF", "DT-ST", "ANI-ST", "DT+ANI"] MODE_LIST = ["Channel", "Name", "Frequency"] PONMSG_LIST = ["Full", "Message"] PTTID_LIST = ["Off", "BOT", "EOT", "Both"] PTTIDCODE_LIST = ["%s" % x for x in range(1, 16)] RTONE_LIST = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] RESUME_LIST = ["TO", "CO", "SE"] ROGERRX_LIST = ["Off"] + AB_LIST RPSTE_LIST = ["OFF"] + ["%s" % x for x in range(1, 11)] SAVE_LIST = ["Off", "1:1", "1:2", "1:3", "1:4"] SCODE_LIST = ["%s" % x for x in range(1, 16)] SHIFTD_LIST = ["Off", "+", "-"] STEDELAY_LIST = ["OFF"] + ["%s ms" % x for x in range(100, 1100, 100)] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0] STEP_LIST = [str(x) for x in STEPS] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] STEP291_LIST = [str(x) for x in STEPS] TDRAB_LIST = ["Off"] + AB_LIST TDRCH_LIST = ["CH%s" % x for x in range(1, 129)] TIMEOUT_LIST = ["%s sec" % x for x in range(15, 615, 15)] + \ ["Off (if supported by radio)"] TXPOWER_LIST = ["High", "Low"] TXPOWER3_LIST = ["High", "Mid", "Low"] VOICE_LIST = ["Off", "English", "Chinese"] VOX_LIST = ["OFF"] + ["%s" % x for x in range(1, 11)] WORKMODE_LIST = ["Frequency", "Channel"] GMRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] GMRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] GMRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] GMRS_FREQS = GMRS_FREQS1 + GMRS_FREQS2 + GMRS_FREQS3 * 2 def _do_status(radio, direction, block): status = chirp_common.Status() status.msg = "Cloning %s radio" % direction status.cur = block status.max = radio.get_memsize() radio.status_fn(status) UV5R_MODEL_ORIG = b"\x50\xBB\xFF\x01\x25\x98\x4D" UV5R_MODEL_291 = b"\x50\xBB\xFF\x20\x12\x07\x25" UV5R_MODEL_F11 = b"\x50\xBB\xFF\x13\xA1\x11\xDD" UV5R_MODEL_UV82 = b"\x50\xBB\xFF\x20\x13\x01\x05" UV5R_MODEL_UV6 = b"\x50\xBB\xFF\x20\x12\x08\x23" UV5R_MODEL_UV6_ORIG = b"\x50\xBB\xFF\x12\x03\x98\x4D" UV5R_MODEL_A58 = b"\x50\xBB\xFF\x20\x14\x04\x13" UV5R_MODEL_UV5G = b"\x50\xBB\xFF\x20\x12\x06\x25" def _upper_band_from_data(data): return data[0x03:0x04] def _upper_band_from_image(radio): return _upper_band_from_data(radio.get_mmap()) def _read_from_data(data, data_start, data_stop): data = data[data_start:data_stop] return data def _get_data_from_image(radio, _data_start, _data_stop): image_data = _read_from_data(radio.get_mmap(), _data_start, _data_stop) return image_data def _firmware_version_from_data(data, version_start, version_stop): version_tag = data[version_start:version_stop] return version_tag def _firmware_version_from_image(radio): version = _firmware_version_from_data( radio.get_mmap().get_byte_compatible(), radio._fw_ver_file_start, radio._fw_ver_file_stop) return version def _do_ident(radio, magic, secondack=True): serial = radio.pipe serial.timeout = 1 LOG.info("Sending Magic: %s" % util.hexprint(magic)) for byte in magic: serial.write(bytes([byte])) time.sleep(0.01) ack = serial.read(1) if ack != b"\x06": if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond") serial.write(b"\x02") # Until recently, the "ident" returned by the radios supported by this # driver have always been 8 bytes long. The image structure is the 8 byte # "ident" followed by the downloaded memory data. So all of the settings # structures are offset by 8 bytes. The ident returned from a UV-6 radio # can be 8 bytes (original model) or now 12 bytes. # # To accommodate this, the "ident" is now read one byte at a time until the # last byte ("\xdd") is encountered. The bytes containing the value "\x01" # are discarded to shrink the "ident" length down to 8 bytes to keep the # image data aligned with the existing settings structures. # Ok, get the response response = b"" for i in range(1, 13): byte = serial.read(1) response += byte # stop reading once the last byte ("\xdd") is encountered if byte == b"\xDD": break # check if response is OK if len(response) in [8, 12]: # DEBUG LOG.info("Valid response, got this:") LOG.debug(util.hexprint(response)) if len(response) == 12: ident = (bytes([response[0], response[3], response[5]]) + response[7:]) else: ident = response else: # bad response msg = "Unexpected response, got this:" msg += util.hexprint(response) LOG.debug(msg) raise errors.RadioError("Unexpected response from radio.") if secondack: serial.write(b"\x06") ack = serial.read(1) if ack != b"\x06": raise errors.RadioError("Radio refused clone") return ident def _read_block(radio, start, size, first_command=False): msg = struct.pack(">BHB", ord("S"), start, size) radio.pipe.write(msg) if first_command is False: ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError( "Radio refused to send second block 0x%04x" % start) answer = radio.pipe.read(4) if len(answer) != 4: raise errors.RadioError("Radio refused to send block 0x%04x" % start) cmd, addr, length = struct.unpack(">BHB", answer) if cmd != ord("X") or addr != start or length != size: LOG.error("Invalid answer for block 0x%04x:" % start) LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (cmd, addr, length)) raise errors.RadioError("Unknown response from radio") chunk = radio.pipe.read(size) if not chunk: raise errors.RadioError("Radio did not send block 0x%04x" % start) elif len(chunk) != size: LOG.error("Chunk length was 0x%04i" % len(chunk)) raise errors.RadioError("Radio sent incomplete block 0x%04x" % start) radio.pipe.write(b"\x06") time.sleep(0.05) return chunk def _get_aux_data_from_radio(radio): block0 = _read_block(radio, 0x1E80, 0x40, True) block1 = _read_block(radio, 0x1EC0, 0x40, False) block2 = _read_block(radio, 0x1F00, 0x40, False) block3 = _read_block(radio, 0x1F40, 0x40, False) block4 = _read_block(radio, 0x1F80, 0x40, False) block5 = _read_block(radio, 0x1FC0, 0x40, False) version = block1[48:62] area1 = block2 + block3[0:32] area2 = block3[48:64] area3 = block4[16:64] # check for dropped byte dropped_byte = block5[15:16] == b"\xFF" # True/False return version, area1, area2, area3, dropped_byte def _get_radio_firmware_version(radio): if radio.MODEL == "BJ-UV55": block = _read_block(radio, 0x1FF0, 0x40, True) version = block[0:6] return version else: # New radios will reply with 'alternative' (aka: bad) data if the Aux # memory area is read without first reading a block from another area # of memory. Reading any block that is outside of the Aux memory area # (which starts at 0x1EC0) prior to reading blocks in the Aux mem area # turns out to be a workaround for this problem. # read and disregard block0 block0 = _read_block(radio, 0x1E80, 0x40, True) block1 = _read_block(radio, 0x1EC0, 0x40, False) block2 = _read_block(radio, 0x1FC0, 0x40, False) version = block1[48:62] # firmware version # Some new radios will drop the byte at 0x1FCF when read in 0x40 byte # blocks. This results in the next 0x30 bytes being moved forward one # position (putting 0xFF in position 0x1FCF and pads the now missing # byte at the end, 0x1FFF, with 0x80). # detect dropped byte dropped_byte = (block2[15:16] == b"\xFF") # dropped byte? return version, dropped_byte IDENT_BLACKLIST = { b"\x50\x0D\x0C\x20\x16\x03\x28": "Radio identifies as BTECH UV-5X3", b"\x50\xBB\xFF\x20\x12\x06\x25": "Radio identifies as Radioddity UV-5G", } def _ident_radio(radio): for magic in radio._idents: error = None try: data = _do_ident(radio, magic) return data except errors.RadioError as e: LOG.error("uv5r._ident_radio: %s", e) error = e time.sleep(2) for magic, reason in list(IDENT_BLACKLIST.items()): try: _do_ident(radio, magic, secondack=False) except errors.RadioError: # No match, try the next one continue # If we got here, it means we identified the radio as # something other than one of our valid idents. Warn # the user so they can do the right thing. LOG.warning(('Identified radio as a blacklisted model ' '(details: %s)') % reason) raise errors.RadioError(('%s. Please choose the proper vendor/' 'model and try again.') % reason) if error: raise error raise errors.RadioError("Radio did not respond") def _do_download(radio): data = _ident_radio(radio) if radio.MODEL == "BJ-UV55": radio_version = _get_radio_firmware_version(radio) else: radio_version, has_dropped_byte = \ _get_radio_firmware_version(radio) LOG.info("Radio Version is %s" % repr(radio_version)) LOG.info("Radio has dropped byte issue: %s" % repr(has_dropped_byte)) # Main block LOG.debug("downloading main block...") for i in range(0, 0x1800, 0x40): data += _read_block(radio, i, 0x40, False) _do_status(radio, "from", i) _do_status(radio, "from", radio.get_memsize()) LOG.debug("done.") if radio._aux_block: if has_dropped_byte: LOG.debug("downloading aux block...") # Auxiliary block starts at 0x1ECO (?) for i in range(0x1EC0, 0x1FC0, 0x40): data += _read_block(radio, i, 0x40, False) # Shift to 0x10 block sizes as a workaround for new radios that # will drop byte 0x1FCF if the last 0x40 bytes are read using a # 0x40 block size for i in range(0x1FC0, 0x2000, 0x10): data += _read_block(radio, i, 0x10, False) else: # Retain 0x40 byte block download for legacy radios (the # 'original' radios with firmware versions prior to BFB291 do not # support reading the Aux memory are with 0x10 bytes blocks. LOG.debug("downloading aux block...") # Auxiliary block starts at 0x1ECO (?) for i in range(0x1EC0, 0x2000, 0x40): data += _read_block(radio, i, 0x40, False) LOG.debug("done.") return memmap.MemoryMapBytes(data) def _send_block(radio, addr, data): msg = struct.pack(">BHB", ord("X"), addr, len(data)) radio.pipe.write(msg + data) time.sleep(0.05) ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio refused to accept block 0x%04x" % addr) def _do_upload(radio): ident = _ident_radio(radio) radio_upper_band = ident[3:4] image_upper_band = _upper_band_from_image(radio) if image_upper_band == vhf_220_radio or radio_upper_band == vhf_220_radio: if image_upper_band != radio_upper_band: raise errors.RadioError("Image not supported by radio") image_version = _firmware_version_from_image(radio) if radio.MODEL == "BJ-UV55": radio_version = _get_radio_firmware_version(radio) # default ranges _ranges_main_default = radio._ranges_main _ranges_aux_default = radio._ranges_aux else: radio_version, aux_r1, aux_r2, aux_r3, \ has_dropped_byte = _get_aux_data_from_radio(radio) LOG.info("Radio has dropped byte issue: %s" % repr(has_dropped_byte)) # determine if radio is 'original' radio if b'BFB' in radio_version: idx = radio_version.index(b"BFB") + 3 version = int(radio_version[idx:idx + 3]) _radio_is_orig = version < 291 else: _radio_is_orig = False # determine if image is from 'original' radio _image_is_orig = radio._is_orig() if _image_is_orig != _radio_is_orig: raise errors.RadioError("Image not supported by radio") aux_i1 = _get_data_from_image(radio, 0x1848, 0x18A8) aux_i2 = _get_data_from_image(radio, 0x18B8, 0x18C8) aux_i3 = _get_data_from_image(radio, 0x18D8, 0x1908) # check if Aux memory of image matches Aux memory of radio aux_matched = False if aux_i1 != aux_r1: # Area 1 does not match # The safest thing to do is to skip uploading Aux mem area. LOG.info("Aux memory mismatch") LOG.info("Aux area 1 from image is %s" % repr(aux_i1)) LOG.info("Aux area 1 from radio is %s" % repr(aux_r1)) elif aux_i2 != aux_r2: # Area 2 does not match # The safest thing to do is to skip uploading Aux mem area. LOG.info("Aux memory mismatch") LOG.info("Aux area 2 from image is %s" % repr(aux_i2)) LOG.info("Aux area 2 from radio is %s" % repr(aux_r2)) elif aux_i3 != aux_r3: # Area 3 does not match # The safest thing to do is to skip uploading Aux mem area. LOG.info("Aux memory mismatch") LOG.info("Aux area 3 from image is %s" % repr(aux_i3)) LOG.info("Aux area 3 from radio is %s" % repr(aux_r3)) else: # All areas matched # Uploading full Aux mem area is permitted aux_matched = True if not radio._all_range_flag: if has_dropped_byte and not aux_matched: msg = ("Image not supported by radio. You must...\n" "1. Download from radio.\n" "2. Make changes.\n" "3. Upload back to same radio.") raise errors.RadioError(msg) # default ranges _ranges_main_default = [ (0x0008, 0x0CF8), # skip 0x0CF8 - 0x0D08 (0x0D08, 0x0DF8), # skip 0x0DF8 - 0x0E08 (0x0E08, 0x1808), ] if _image_is_orig: # default Aux mem ranges for radios before BFB291 _ranges_aux_default = [ (0x1EE0, 0x1EF0), # welcome message (0x1FC0, 0x1FE0), # old band limits ] elif has_dropped_byte or aux_matched: # default Aux mem ranges for radios with dropped byte issue _ranges_aux_default = [ (0x1EC0, 0x2000), # the full Aux mem range ] else: # default Aux mem ranges for radios from BFB291 to present # (that don't have dropped byte issue) _ranges_aux_default = [ (0x1EE0, 0x1EF0), # welcome message (0x1F60, 0x1F70), # vhf squelch thresholds (0x1F80, 0x1F90), # uhf squelch thresholds (0x1FC0, 0x1FD0), # new band limits ] LOG.info("Image Version is %s" % repr(image_version)) LOG.info("Radio Version is %s" % repr(radio_version)) if radio._all_range_flag: # user enabled 'Range Override Parameter', upload everything ranges_main = radio._ranges_main ranges_aux = radio._ranges_aux LOG.warning('Sending all ranges to radio as instructed') else: # set default ranges ranges_main = _ranges_main_default ranges_aux = _ranges_aux_default # Main block mmap = radio.get_mmap().get_byte_compatible() for start_addr, end_addr in ranges_main: for i in range(start_addr, end_addr, 0x10): _send_block(radio, i - 0x08, mmap[i:i + 0x10]) _do_status(radio, "to", i) _do_status(radio, "to", radio.get_memsize()) if len(mmap.get_packed()) == 0x1808: LOG.info("Old image, not writing aux block") return # Old image, no aux block # Auxiliary block at radio address 0x1EC0, our offset 0x1808 for start_addr, end_addr in ranges_aux: for i in range(start_addr, end_addr, 0x10): addr = 0x1808 + (i - 0x1EC0) _send_block(radio, i, mmap[addr:addr + 0x10]) if radio._all_range_flag: radio._all_range_flag = False LOG.warning('Sending all ranges to radio has completed') raise errors.RadioError( "This is NOT an error.\n" "The upload has finished successfully.\n" "Please restart CHIRP.") UV5R_POWER_LEVELS = [chirp_common.PowerLevel("High", watts=4.00), chirp_common.PowerLevel("Low", watts=1.00)] UV5R_POWER_LEVELS3 = [chirp_common.PowerLevel("High", watts=8.00), chirp_common.PowerLevel("Med", watts=4.00), chirp_common.PowerLevel("Low", watts=1.00)] UV5R_DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) UV5R_CHARSET = chirp_common.CHARSET_UPPER_NUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" def model_match(cls, data): """Match the opened/downloaded image to the correct version""" if len(data) == 0x1950: rid = data[0x1948:0x1950] return rid.startswith(cls.MODEL) elif len(data) == 0x1948: rid = data[cls._fw_ver_file_start:cls._fw_ver_file_stop] if any(type in rid for type in cls._basetype): return True else: return False class BaofengUV5R(chirp_common.CloneModeRadio): """Baofeng UV-5R""" VENDOR = "Baofeng" MODEL = "UV-5R" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _memsize = 0x1808 _basetype = BASETYPE_UV5R _idents = [UV5R_MODEL_291, UV5R_MODEL_ORIG ] _vhf_range = (130000000, 176000000) _220_range = (220000000, 260000000) _uhf_range = (400000000, 520000000) _aux_block = True _tri_power = False _bw_shift = False _mem_params = (0x1828 # poweron_msg offset ) # offset of fw version in image file _fw_ver_file_start = 0x1838 _fw_ver_file_stop = 0x1846 _ranges_main = [ (0x0008, 0x1808), ] _ranges_aux = [ (0x1EC0, 0x2000), ] _valid_chars = UV5R_CHARSET @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('Due to the fact that the manufacturer continues to ' 'release new versions of the firmware with obscure and ' 'hard-to-track changes, this driver may not work with ' 'your device. Thus far and to the best knowledge of the ' 'author, no UV-5R radios have been harmed by using CHIRP. ' 'However, proceed at your own risk!') rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on (volume may need to be set at 100%).\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to download image from device.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to mic/spkr connector.\n" "3. Make sure connector is firmly connected.\n" "4. Turn radio on (volume may need to be set at 100%).\n" "5. Ensure that the radio is tuned to channel with no" " activity.\n" "6. Click OK to upload image to device.\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.valid_name_length = 7 rf.valid_characters = self._valid_chars rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = UV5R_POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["FM", "NFM"] rf.valid_tuning_steps = STEPS rf.valid_dtcs_codes = UV5R_DTCS normal_bands = [self._vhf_range, self._uhf_range] rax_bands = [self._vhf_range, self._220_range] if self._mmap is None: rf.valid_bands = [normal_bands[0], rax_bands[1], normal_bands[1]] elif not self._is_orig() and self._my_upper_band() == vhf_220_radio: rf.valid_bands = rax_bands else: rf.valid_bands = normal_bands rf.memory_bounds = (0, 127) return rf @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False if len(filedata) in [0x1808, 0x1948, 0x1950]: match_size = True match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) self._all_range_flag = False def sync_in(self): try: self._mmap = _do_download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: _do_upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _is_txinh(self, _mem): raw_tx = b"" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw() return raw_tx == b"\xFF\xFF\xFF\xFF" def _get_mem(self, number): return self._memobj.memory[number] def _get_nam(self, number): return self._memobj.names[number] def get_memory(self, number): _mem = self._get_mem(number) _nam = self._get_nam(number) mem = chirp_common.Memory() mem.number = number if _mem.get_raw()[:1] == b"\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if self._is_txinh(_mem): mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _nam.name: if str(char) == "\xFF": char = " " # The UV-5R software may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() dtcs_pol = ["N", "N"] if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 elif _mem.txtone <= 0x0258: txmode = "DTCS" if _mem.txtone > 0x69: index = _mem.txtone - 0x6A dtcs_pol[0] = "R" else: index = _mem.txtone - 1 mem.dtcs = UV5R_DTCS[index] else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 elif _mem.rxtone <= 0x0258: rxmode = "DTCS" if _mem.rxtone >= 0x6A: index = _mem.rxtone - 0x6A dtcs_pol[1] = "R" else: index = _mem.rxtone - 1 mem.rx_dtcs = UV5R_DTCS[index] else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) if not _mem.scan: mem.skip = "S" if self._tri_power: levels = UV5R_POWER_LEVELS3 else: levels = UV5R_POWER_LEVELS try: mem.power = levels[_mem.lowpower] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.lowpower, levels)) mem.power = levels[0] mem.mode = _mem.wide and "FM" or "NFM" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("scode", "PTT ID Code", RadioSettingValueList(PTTIDCODE_LIST, PTTIDCODE_LIST[_mem.scode])) mem.extra.append(rs) immutable = [] if self.MODEL == "GT-5R": if not ((mem.freq >= self.vhftx[0] and mem.freq < self.vhftx[1]) or (mem.freq >= self.uhftx[0] and mem.freq < self.uhftx[1])): mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] mem.immutable = immutable return mem def _set_mem(self, number): return self._memobj.memory[number] def _set_nam(self, number): return self._memobj.names[number] def set_memory(self, mem): _mem = self._get_mem(mem.number) _nam = self._get_nam(mem.number) if mem.empty: _mem.set_raw("\xff" * 16) _nam.set_raw("\xff" * 16) return was_empty = False # same method as used in get_memory to find # out whether a raw memory is empty if _mem.get_raw(asbytes=False)[0] == "\xff": was_empty = True LOG.debug("UV5R: this mem was empty") else: # memorize old extra-values before erasing the whole memory # used to solve issue 4121 LOG.debug("mem was not empty, memorize extra-settings") prev_bcl = _mem.bcl.get_value() prev_scode = _mem.scode.get_value() prev_pttid = _mem.pttid.get_value() _mem.set_raw("\x00" * 16) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": rxmode = txmode = "DTCS" _mem.txtone = UV5R_DTCS.index(mem.dtcs) + 1 _mem.rxtone = UV5R_DTCS.index(mem.dtcs) + 1 elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) elif txmode == "DTCS": _mem.txtone = UV5R_DTCS.index(mem.dtcs) + 1 else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCS": _mem.rxtone = UV5R_DTCS.index(mem.rx_dtcs) + 1 else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 if txmode == "DTCS" and mem.dtcs_polarity[0] == "R": _mem.txtone += 0x69 if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R": _mem.rxtone += 0x69 _mem.scan = mem.skip != "S" _mem.wide = mem.mode == "FM" if mem.power: if self._tri_power: levels = [str(l) for l in UV5R_POWER_LEVELS3] _mem.lowpower = levels.index(str(mem.power)) else: _mem.lowpower = UV5R_POWER_LEVELS.index(mem.power) else: _mem.lowpower = 0 if not was_empty: # restoring old extra-settings (issue 4121 _mem.bcl.set_value(prev_bcl) _mem.scode.set_value(prev_scode) _mem.pttid.set_value(prev_pttid) for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def _is_orig(self): version_tag = _firmware_version_from_image(self) try: if b'BFB' in version_tag: idx = version_tag.index(b"BFB") + 3 version = int(version_tag[idx:idx + 3]) return version < 291 return False except: pass raise errors.RadioError("Unable to parse version string %s" % version_tag) def _my_version(self): version_tag = _firmware_version_from_image(self) if b'BFB' in version_tag: idx = version_tag.index(b"BFB") + 3 return int(version_tag[idx:idx + 3]) raise Exception("Unrecognized firmware version string") def _my_upper_band(self): band_tag = _upper_band_from_image(self) return band_tag def _get_settings(self): _mem = self._memobj _ani = self._memobj.ani _settings = self._memobj.settings _squelch = self._memobj.squelch_new _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob _wmchannel = self._memobj.wmchannel basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") group = RadioSettings(basic, advanced) rs = RadioSetting("squelch", "Carrier Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("save", "Battery Saver", RadioSettingValueList( SAVE_LIST, SAVE_LIST[_settings.save])) basic.append(rs) rs = RadioSetting("vox", "VOX Sensitivity", RadioSettingValueList( VOX_LIST, VOX_LIST[_settings.vox])) advanced.append(rs) if self.MODEL == "UV-6": # NOTE: The UV-6 calls this byte voxenable, but the UV-5R calls it # autolk. Since this is a minor difference, it will be referred to # by the wrong name for the UV-6. rs = RadioSetting("autolk", "Vox", RadioSettingValueBoolean(_settings.autolk)) advanced.append(rs) if self.MODEL != "UV-6": rs = RadioSetting("abr", "Backlight Timeout", RadioSettingValueInteger(0, 24, _settings.abr)) basic.append(rs) rs = RadioSetting("tdr", "Dual Watch", RadioSettingValueBoolean(_settings.tdr)) advanced.append(rs) if self.MODEL == "UV-6": rs = RadioSetting("tdrch", "Dual Watch Channel", RadioSettingValueList( TDRCH_LIST, TDRCH_LIST[_settings.tdrch])) advanced.append(rs) rs = RadioSetting("tdrab", "Dual Watch TX Priority", RadioSettingValueBoolean(_settings.tdrab)) advanced.append(rs) else: rs = RadioSetting("tdrab", "Dual Watch TX Priority", RadioSettingValueList( TDRAB_LIST, TDRAB_LIST[_settings.tdrab])) advanced.append(rs) if self.MODEL == "UV-6": rs = RadioSetting("alarm", "Alarm Sound", RadioSettingValueBoolean(_settings.alarm)) advanced.append(rs) if _settings.almod > 0x02: val = 0x01 else: val = _settings.almod rs = RadioSetting("almod", "Alarm Mode", RadioSettingValueList( ALMOD_LIST, ALMOD_LIST[val])) advanced.append(rs) rs = RadioSetting("beep", "Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) rs = RadioSetting("timeout", "Timeout Timer", RadioSettingValueList( TIMEOUT_LIST, TIMEOUT_LIST[_settings.timeout])) basic.append(rs) if ((self._is_orig() and self._my_version() < 251) or (self.MODEL in ["TI-F8+", "TS-T9+"])): rs = RadioSetting("voice", "Voice", RadioSettingValueBoolean(_settings.voice)) advanced.append(rs) else: rs = RadioSetting("voice", "Voice", RadioSettingValueList( VOICE_LIST, VOICE_LIST[_settings.voice])) advanced.append(rs) rs = RadioSetting("screv", "Scan Resume", RadioSettingValueList( RESUME_LIST, RESUME_LIST[_settings.screv])) advanced.append(rs) if self.MODEL != "UV-6": rs = RadioSetting("mdfa", "Display Mode (A)", RadioSettingValueList( MODE_LIST, MODE_LIST[_settings.mdfa])) basic.append(rs) rs = RadioSetting("mdfb", "Display Mode (B)", RadioSettingValueList( MODE_LIST, MODE_LIST[_settings.mdfb])) basic.append(rs) rs = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueBoolean(_settings.bcl)) advanced.append(rs) if self.MODEL != "UV-6": rs = RadioSetting("autolk", "Automatic Key Lock", RadioSettingValueBoolean(_settings.autolk)) advanced.append(rs) rs = RadioSetting("fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_settings.fmradio)) advanced.append(rs) if self.MODEL != "UV-6": rs = RadioSetting("wtled", "Standby LED Color", RadioSettingValueList( COLOR_LIST, COLOR_LIST[_settings.wtled])) basic.append(rs) rs = RadioSetting("rxled", "RX LED Color", RadioSettingValueList( COLOR_LIST, COLOR_LIST[_settings.rxled])) basic.append(rs) rs = RadioSetting("txled", "TX LED Color", RadioSettingValueList( COLOR_LIST, COLOR_LIST[_settings.txled])) basic.append(rs) if isinstance(self, BaofengUV82Radio): rs = RadioSetting("roger", "Roger Beep (TX)", RadioSettingValueBoolean(_settings.roger)) basic.append(rs) rs = RadioSetting("rogerrx", "Roger Beep (RX)", RadioSettingValueList( ROGERRX_LIST, ROGERRX_LIST[_settings.rogerrx])) basic.append(rs) else: rs = RadioSetting("roger", "Roger Beep", RadioSettingValueBoolean(_settings.roger)) basic.append(rs) rs = RadioSetting("ste", "Squelch Tail Eliminate (HT to HT)", RadioSettingValueBoolean(_settings.ste)) advanced.append(rs) rs = RadioSetting("rpste", "Squelch Tail Eliminate (repeater)", RadioSettingValueList( RPSTE_LIST, RPSTE_LIST[_settings.rpste])) advanced.append(rs) rs = RadioSetting("rptrl", "STE Repeater Delay", RadioSettingValueList( STEDELAY_LIST, STEDELAY_LIST[_settings.rptrl])) advanced.append(rs) if self.MODEL != "UV-6": rs = RadioSetting("reset", "RESET Menu", RadioSettingValueBoolean(_settings.reset)) advanced.append(rs) rs = RadioSetting("menu", "All Menus", RadioSettingValueBoolean(_settings.menu)) advanced.append(rs) if self.MODEL == "F-11": # this is an F-11 only feature rs = RadioSetting("vfomrlock", "VFO/MR Button", RadioSettingValueBoolean(_settings.vfomrlock)) advanced.append(rs) if isinstance(self, BaofengUV82Radio): # this is a UV-82C only feature rs = RadioSetting("vfomrlock", "VFO/MR Switching (UV-82C only)", RadioSettingValueBoolean(_settings.vfomrlock)) advanced.append(rs) if self.MODEL == "UV-82HP": # this is a UV-82HP only feature rs = RadioSetting( "vfomrlock", "VFO/MR Switching (BTech UV-82HP only)", RadioSettingValueBoolean(_settings.vfomrlock)) advanced.append(rs) if isinstance(self, BaofengUV82Radio): # this is an UV-82C only feature rs = RadioSetting("singleptt", "Single PTT (UV-82C only)", RadioSettingValueBoolean(_settings.singleptt)) advanced.append(rs) if self.MODEL == "UV-82HP": # this is an UV-82HP only feature rs = RadioSetting("singleptt", "Single PTT (BTech UV-82HP only)", RadioSettingValueBoolean(_settings.singleptt)) advanced.append(rs) if self.MODEL == "UV-82HP": # this is an UV-82HP only feature rs = RadioSetting( "tdrch", "Tone Burst Frequency (BTech UV-82HP only)", RadioSettingValueList(RTONE_LIST, RTONE_LIST[_settings.tdrch])) advanced.append(rs) def set_range_flag(setting): val = [85, 115, 101, 65, 116, 79, 119, 110, 82, 105, 115, 107] if [ord(x) for x in str(setting.value).strip()] == val: self._all_range_flag = True else: self._all_range_flag = False LOG.debug('Set range flag to %s' % self._all_range_flag) rs = RadioSetting("allrange", "Range Override Parameter", RadioSettingValueString(0, 12, "Default")) rs.set_apply_callback(set_range_flag) advanced.append(rs) if len(self._mmap.get_packed()) == 0x1808: # Old image, without aux block return group if self.MODEL != "UV-6": other = RadioSettingGroup("other", "Other Settings") group.append(other) try: self._get_aux_other_settings(other) except Exception as e: LOG.exception('Failed to get aux-block other settings: %s', e) rs = RadioSetting("ponmsg", "Power-On Message", RadioSettingValueList( PONMSG_LIST, PONMSG_LIST[_settings.ponmsg])) other.append(rs) if self.MODEL != "UV-6": workmode = RadioSettingGroup("workmode", "Work Mode Settings") group.append(workmode) rs = RadioSetting("displayab", "Display", RadioSettingValueList( AB_LIST, AB_LIST[_settings.displayab])) workmode.append(rs) rs = RadioSetting("workmode", "VFO/MR Mode", RadioSettingValueList( WORKMODE_LIST, WORKMODE_LIST[_settings.workmode])) workmode.append(rs) rs = RadioSetting("keylock", "Keypad Lock", RadioSettingValueBoolean(_settings.keylock)) workmode.append(rs) rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(0, 127, _wmchannel.mrcha)) workmode.append(rs) rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(0, 127, _wmchannel.mrchb)) workmode.append(rs) def my_validate(value): value = chirp_common.parse_freq(value) if 17400000 <= value and value < 40000000: msg = ("Can't be between 174.00000-400.00000") raise InvalidValueError(msg) return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 obj.band = value >= 40000000 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_vfoa.freq)) val1a.set_validate_callback(my_validate) rs = RadioSetting("vfoa.freq", "VFO A Frequency", val1a) rs.set_apply_callback(apply_freq, _vfoa) workmode.append(rs) val1b = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_vfob.freq)) val1b.set_validate_callback(my_validate) rs = RadioSetting("vfob.freq", "VFO B Frequency", val1b) rs.set_apply_callback(apply_freq, _vfob) workmode.append(rs) rs = RadioSetting("vfoa.sftd", "VFO A Shift", RadioSettingValueList( SHIFTD_LIST, SHIFTD_LIST[_vfoa.sftd])) workmode.append(rs) rs = RadioSetting("vfob.sftd", "VFO B Shift", RadioSettingValueList( SHIFTD_LIST, SHIFTD_LIST[_vfob.sftd])) workmode.append(rs) def convert_bytes_to_offset(bytes): real_offset = 0 for byte in bytes: real_offset = (real_offset * 10) + byte return chirp_common.format_freq(real_offset * 1000) def apply_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 1000 for i in range(5, -1, -1): obj.offset[i] = value % 10 value /= 10 val1a = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_vfoa.offset)) rs = RadioSetting("vfoa.offset", "VFO A Offset (0.0-999.999)", val1a) rs.set_apply_callback(apply_offset, _vfoa) workmode.append(rs) val1b = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_vfob.offset)) rs = RadioSetting("vfob.offset", "VFO B Offset (0.0-999.999)", val1b) rs.set_apply_callback(apply_offset, _vfob) workmode.append(rs) if self._tri_power: if _vfoa.txpower3 > 0x02: val = 0x00 else: val = _vfoa.txpower3 rs = RadioSetting("vfoa.txpower3", "VFO A Power", RadioSettingValueList( TXPOWER3_LIST, TXPOWER3_LIST[val])) workmode.append(rs) if _vfob.txpower3 > 0x02: val = 0x00 else: val = _vfob.txpower3 rs = RadioSetting("vfob.txpower3", "VFO B Power", RadioSettingValueList( TXPOWER3_LIST, TXPOWER3_LIST[val])) workmode.append(rs) else: rs = RadioSetting("vfoa.txpower", "VFO A Power", RadioSettingValueList( TXPOWER_LIST, TXPOWER_LIST[_vfoa.txpower])) workmode.append(rs) rs = RadioSetting("vfob.txpower", "VFO B Power", RadioSettingValueList( TXPOWER_LIST, TXPOWER_LIST[_vfob.txpower])) workmode.append(rs) rs = RadioSetting("vfoa.widenarr", "VFO A Bandwidth", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfoa.widenarr])) workmode.append(rs) rs = RadioSetting("vfob.widenarr", "VFO B Bandwidth", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfob.widenarr])) workmode.append(rs) rs = RadioSetting("vfoa.scode", "VFO A PTT-ID", RadioSettingValueList( PTTIDCODE_LIST, PTTIDCODE_LIST[_vfoa.scode])) workmode.append(rs) rs = RadioSetting("vfob.scode", "VFO B PTT-ID", RadioSettingValueList( PTTIDCODE_LIST, PTTIDCODE_LIST[_vfob.scode])) workmode.append(rs) if not self._is_orig(): rs = RadioSetting("vfoa.step", "VFO A Tuning Step", RadioSettingValueList( STEP291_LIST, STEP291_LIST[_vfoa.step])) workmode.append(rs) rs = RadioSetting("vfob.step", "VFO B Tuning Step", RadioSettingValueList( STEP291_LIST, STEP291_LIST[_vfob.step])) workmode.append(rs) else: rs = RadioSetting("vfoa.step", "VFO A Tuning Step", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfoa.step])) workmode.append(rs) rs = RadioSetting("vfob.step", "VFO B Tuning Step", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfob.step])) workmode.append(rs) dtmf = RadioSettingGroup("dtmf", "DTMF Settings") group.append(dtmf) # broadcast FM settings # radios with the dropped byte issue also does not expose the broadcast # FM frequency to CHIRP and ignores any frequency provided by CHIRP. # Older radios that do expose the broadcast FM frequency to CHIRP have # a minimum of 3 different know definitions for storing the # frequencies. Since some frequencies have collisions for some of the # storage methods, it is not always obvious to know which definition # is being used. It is for these reasons that the FM Radio Preset tab # and its associated FM Preset(MHz) setting have been removed. if str(self._memobj.firmware_msg.line1) == "HN5RV01": dtmfchars = "0123456789ABCD*#" else: dtmfchars = "0123456789 *#ABCD" for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("pttid/%i.code" % i, "PTT ID Code %i" % (i + 1), val) def apply_code(setting, obj): code = [] for j in range(0, 5): try: code.append(dtmfchars.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, self._memobj.pttid[i]) dtmf.append(rs) dtmfcharsani = "0123456789" _codeobj = self._memobj.ani.code _code = "".join([dtmfcharsani[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(dtmfcharsani) rs = RadioSetting("ani.code", "ANI Code", val) def apply_code(setting, obj): code = [] for j in range(0, 5): try: code.append(dtmfchars.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code rs.set_apply_callback(apply_code, _ani) dtmf.append(rs) rs = RadioSetting("ani.aniid", "ANI ID", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_ani.aniid])) dtmf.append(rs) _codeobj = self._memobj.ani.alarmcode _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 3, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("ani.alarmcode", "Alarm Code", val) def apply_code(setting, obj): alarmcode = [] for j in range(0, 3): try: alarmcode.append(dtmfchars.index(str(setting.value)[j])) except IndexError: alarmcode.append(0xFF) obj.alarmcode = alarmcode rs.set_apply_callback(apply_code, _ani) dtmf.append(rs) rs = RadioSetting("dtmfst", "DTMF Sidetone", RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[_settings.dtmfst])) dtmf.append(rs) if _ani.dtmfon > 0xC3: val = 0x00 else: val = _ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(DTMFSPEED_LIST, DTMFSPEED_LIST[val])) dtmf.append(rs) if _ani.dtmfoff > 0xC3: val = 0x00 else: val = _ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(DTMFSPEED_LIST, DTMFSPEED_LIST[val])) dtmf.append(rs) rs = RadioSetting("pttlt", "PTT ID Delay", RadioSettingValueInteger(0, 50, _settings.pttlt)) dtmf.append(rs) try: service = self._get_service_settings() if service: group.append(service) except Exception as e: LOG.exception('Failed to load service settings: %s', e) return group def _get_aux_other_settings(self, other): def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = self._memobj.firmware_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val) other.append(rs) _msg = self._memobj.sixpoweron_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2", val) other.append(rs) _msg = self._memobj.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 7, _filter(_msg.line2))) other.append(rs) if self._is_orig(): limit = "limits_old" else: limit = "limits_new" vhf_limit = getattr(self._memobj, limit).vhf rs = RadioSetting("%s.vhf.lower" % limit, "VHF Lower Limit (MHz)", RadioSettingValueInteger(1, 1000, vhf_limit.lower)) other.append(rs) rs = RadioSetting("%s.vhf.upper" % limit, "VHF Upper Limit (MHz)", RadioSettingValueInteger(1, 1000, vhf_limit.upper)) other.append(rs) rs = RadioSetting("%s.vhf.enable" % limit, "VHF TX Enabled", RadioSettingValueBoolean(vhf_limit.enable)) other.append(rs) uhf_limit = getattr(self._memobj, limit).uhf rs = RadioSetting("%s.uhf.lower" % limit, "UHF Lower Limit (MHz)", RadioSettingValueInteger(1, 1000, uhf_limit.lower)) other.append(rs) rs = RadioSetting("%s.uhf.upper" % limit, "UHF Upper Limit (MHz)", RadioSettingValueInteger(1, 1000, uhf_limit.upper)) other.append(rs) rs = RadioSetting("%s.uhf.enable" % limit, "UHF TX Enabled", RadioSettingValueBoolean(uhf_limit.enable)) other.append(rs) def _get_service_settings(self): if not self._is_orig() and self._aux_block: service = RadioSettingGroup("service", "Service Settings") for band in ["vhf", "uhf"]: for index in range(0, 10): key = "squelch_new.%s.sql%i" % (band, index) if band == "vhf": _obj = self._memobj.squelch_new.vhf elif band == "uhf": _obj = self._memobj.squelch_new.uhf name = "%s Squelch %i" % (band.upper(), index) rs = RadioSetting(key, name, RadioSettingValueInteger( 0, 123, getattr(_obj, "sql%i" % (index)))) service.append(rs) return service def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise class UV5XAlias(chirp_common.Alias): VENDOR = "Baofeng" MODEL = "UV-5X" class RT5RAlias(chirp_common.Alias): VENDOR = "Retevis" MODEL = "RT5R" class RT5RVAlias(chirp_common.Alias): VENDOR = "Retevis" MODEL = "RT5RV" class RT5Alias(chirp_common.Alias): VENDOR = "Retevis" MODEL = "RT5" class RT5_TPAlias(chirp_common.Alias): VENDOR = "Retevis" MODEL = "RT5(tri-power)" class RH5RAlias(chirp_common.Alias): VENDOR = "Rugged" MODEL = "RH5R" class ROUV5REXAlias(chirp_common.Alias): VENDOR = "Radioddity" MODEL = "UV-5R EX" class A5RAlias(chirp_common.Alias): VENDOR = "Ansoko" MODEL = "A-5R" @directory.register class BaofengUV5RGeneric(BaofengUV5R): ALIASES = [UV5XAlias, RT5RAlias, RT5RVAlias, RT5Alias, RH5RAlias, ROUV5REXAlias, A5RAlias] @directory.register class BaofengF11Radio(BaofengUV5R): VENDOR = "Baofeng" MODEL = "F-11" _basetype = BASETYPE_F11 _idents = [UV5R_MODEL_F11] def _is_orig(self): # Override this for F11 to always return False return False @directory.register class BaofengUV82Radio(BaofengUV5R): MODEL = "UV-82" _basetype = BASETYPE_UV82 _idents = [UV5R_MODEL_UV82] _vhf_range = (130000000, 176000000) _uhf_range = (400000000, 521000000) _valid_chars = chirp_common.CHARSET_ASCII def _is_orig(self): # Override this for UV82 to always return False return False @directory.register class Radioddity82X3Radio(BaofengUV82Radio): VENDOR = "Radioddity" MODEL = "UV-82X3" _basetype = BASETYPE_UV82X3 def get_features(self): rf = BaofengUV5R.get_features(self) rf.valid_bands = [self._vhf_range, (200000000, 260000000), self._uhf_range] return rf @directory.register class BaofengUV6Radio(BaofengUV5R): """Baofeng UV-6/UV-7""" VENDOR = "Baofeng" MODEL = "UV-6" _basetype = BASETYPE_UV6 _idents = [UV5R_MODEL_UV6, UV5R_MODEL_UV6_ORIG ] _aux_block = False def get_features(self): rf = BaofengUV5R.get_features(self) rf.memory_bounds = (1, 128) return rf def _get_mem(self, number): return self._memobj.memory[number - 1] def _get_nam(self, number): return self._memobj.names[number - 1] def _set_mem(self, number): return self._memobj.memory[number - 1] def _set_nam(self, number): return self._memobj.names[number - 1] def _is_orig(self): # Override this for UV6 to always return False return False @directory.register class IntekKT980Radio(BaofengUV5R): VENDOR = "Intek" MODEL = "KT-980HP" _basetype = BASETYPE_KT980HP _idents = [UV5R_MODEL_291] _vhf_range = (130000000, 180000000) _uhf_range = (400000000, 521000000) _tri_power = True def get_features(self): rf = BaofengUV5R.get_features(self) rf.valid_power_levels = UV5R_POWER_LEVELS3 return rf def _is_orig(self): # Override this for KT980HP to always return False return False class ROGA5SAlias(chirp_common.Alias): VENDOR = "Radioddity" MODEL = "GA-5S" class UV5XPAlias(chirp_common.Alias): VENDOR = "Baofeng" MODEL = "UV-5XP" class TSTIF8Alias(chirp_common.Alias): VENDOR = "TechSide" MODEL = "TI-F8+" class TenwayUV5RPro(chirp_common.Alias): VENDOR = 'Tenway' MODEL = 'UV-5R Pro' class TSTST9Alias(chirp_common.Alias): VENDOR = "TechSide" MODEL = "TS-T9+" class TDUV5RRadio(chirp_common.Alias): VENDOR = "TIDRADIO" MODEL = "TD-UV5R TriPower" @directory.register class BaofengBFF8HPRadio(BaofengUV5R): VENDOR = "Baofeng" MODEL = "BF-F8HP" ALIASES = [RT5_TPAlias, ROGA5SAlias, UV5XPAlias, TSTIF8Alias, TenwayUV5RPro, TSTST9Alias, TDUV5RRadio] _basetype = BASETYPE_F8HP _idents = [UV5R_MODEL_291, UV5R_MODEL_A58 ] _vhf_range = (130000000, 180000000) _uhf_range = (400000000, 521000000) _tri_power = True def get_features(self): rf = BaofengUV5R.get_features(self) rf.valid_power_levels = UV5R_POWER_LEVELS3 return rf def _is_orig(self): # Override this for BFF8HP to always return False return False class TenwayUV82Pro(chirp_common.Alias): VENDOR = 'Tenway' MODEL = 'UV-82 Pro' @directory.register class BaofengUV82HPRadio(BaofengUV5R): VENDOR = "Baofeng" MODEL = "UV-82HP" ALIASES = [TenwayUV82Pro] _basetype = BASETYPE_UV82HP _idents = [UV5R_MODEL_UV82] _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 521000000) _valid_chars = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" _tri_power = True def get_features(self): rf = BaofengUV5R.get_features(self) rf.valid_power_levels = UV5R_POWER_LEVELS3 return rf def _is_orig(self): # Override this for UV82HP to always return False return False @directory.register class RadioddityUV5RX3Radio(BaofengUV5R): VENDOR = "Radioddity" MODEL = "UV-5RX3" def get_features(self): rf = BaofengUV5R.get_features(self) rf.valid_bands = [self._vhf_range, (200000000, 260000000), self._uhf_range] return rf @classmethod def match_model(cls, filename, filedata): return False @directory.register class RadioddityGT5RRadio(BaofengUV5R): VENDOR = 'Baofeng' MODEL = 'GT-5R' vhftx = [144000000, 148000000] uhftx = [420000000, 450000000] def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if not ((mem.freq >= self.vhftx[0] and mem.freq < self.vhftx[1]) or (mem.freq >= self.uhftx[0] and mem.freq < self.uhftx[1])): if mem.duplex != "off": msgs.append(chirp_common.ValidationWarning(_msg_duplex)) return msgs def check_set_memory_immutable_policy(self, existing, new): existing.immutable = [] super().check_set_memory_immutable_policy(existing, new) @classmethod def match_model(cls, filename, filedata): return False @directory.register class RadioddityUV5GRadio(BaofengUV5R): VENDOR = 'Radioddity' MODEL = 'UV-5G' _basetype = BASETYPE_UV5R _idents = [UV5R_MODEL_UV5G] @classmethod def match_model(cls, filename, filedata): return False chirp-20240224/chirp/drivers/baofeng_wp970i.py0000644000175000017500000010121714565075506017730 0ustar hibbyhibby# Copyright 2016: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings, \ InvalidValueError LOG = logging.getLogger(__name__) # #### MAGICS ######################################################### # Baofeng WP970I magic string MSTRING_WP970I = b"\x50\xBB\xFF\x20\x14\x04\x13" # Baofeng UV-9G magic string MSTRING_UV9G = b"\x50\xBB\xFF\x20\x12\x05\x25" # Baofeng UV-S9X3 magic string MSTRING_UVS9X3 = b"\x50\xBB\xFF\x20\x12\x07\x25" DTMF_CHARS = "0123456789 *#ABCD" STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] LIST_AB = ["A", "B"] LIST_ALMOD = ["Site", "Tone", "Code"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_COLOR = ["Off", "Blue", "Orange", "Purple"] LIST_DTMFSPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_DTMFST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] LIST_MODE = ["Channel", "Name", "Frequency"] LIST_OFF1TO9 = ["Off"] + list("123456789") LIST_OFF1TO10 = LIST_OFF1TO9 + ["10"] LIST_OFFAB = ["Off"] + LIST_AB LIST_RESUME = ["TO", "CO", "SE"] LIST_PONMSG = ["Full", "Message"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_SCODE = ["%s" % x for x in range(1, 16)] LIST_RPSTE = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SHIFTD = ["Off", "+", "-"] LIST_STEDELAY = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] LIST_STEP = [str(x) for x in STEPS] LIST_TIMEOUT = ["%s sec" % x for x in range(15, 615, 15)] LIST_TXPOWER = ["High", "Mid", "Low"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_WORKMODE = ["Frequency", "Channel"] TXP_CHOICES = ["High", "Low"] TXP_VALUES = [0x00, 0x02] def model_match(cls, data): """Match the opened/downloaded image to the correct version""" if len(data) > 0x2008: rid = data[0x2008:0x2010] return rid.startswith(cls.MODEL.encode()) elif len(data) == 0x2008: rid = data[0x1EF0:0x1EF7] return rid in cls._fileid else: return False class WP970I(bfc.BaofengCommonHT): """Baofeng WP970I""" VENDOR = "Baofeng" MODEL = "WP970I" NEEDS_COMPAT_SERIAL = False _tri_band = False _fileid = [] _magic = [MSTRING_WP970I, ] _magic_response_length = 8 _fw_ver_start = 0x1EF0 _recv_block_size = 0x40 _mem_size = 0x2000 _ack_block = True _ranges = [(0x0000, 0x0DF0), (0x0E00, 0x1800), (0x1EE0, 0x1EF0), (0x1F60, 0x1F70), (0x1F80, 0x1F90), (0x1FC0, 0x1FD0)] _send_block_size = 0x10 MODES = ["NFM", "FM"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" LENGTH_NAME = 6 SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Med", watts=3.00), chirp_common.PowerLevel("Low", watts=1.00)] _vhf_range = (130000000, 180000000) _vhf2_range = (200000000, 260000000) _uhf_range = (400000000, 521000000) VALID_BANDS = [_vhf_range, _uhf_range] PTTID_LIST = LIST_PTTID SCODE_LIST = LIST_SCODE MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unused1:3, isuhf:1, scode:4; u8 unknown1:7, txtoneicon:1; u8 mailicon:3, unknown2:3, lowpower:2; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[128]; #seekto 0x0B00; struct { u8 code[5]; u8 unused[11]; } pttid[15]; #seekto 0x0CAA; struct { u8 code[5]; u8 unused1:6, aniid:2; u8 unknown[2]; u8 dtmfon; u8 dtmfoff; } ani; #seekto 0x0E20; struct { u8 squelch; u8 step; u8 unknown_e22; u8 save; u8 vox; u8 unknown_e25; u8 abr; u8 tdr; u8 beep; u8 timeout; u8 unknown_e2a[4]; u8 voice; u8 unknown_e2f; u8 dtmfst; u8 unknown_e31; u8 unknown_e32:6, screv:2; u8 pttid; u8 pttlt; u8 mdfa; u8 mdfb; u8 bcl; u8 autolk; u8 sftd; u8 unknown_e3a[3]; u8 wtled; u8 rxled; u8 txled; u8 almod; u8 band; u8 tdrab; u8 ste; u8 rpste; u8 rptrl; u8 ponmsg; u8 roger; u8 rogerrx; u8 tdrch; u8 displayab:1, unknown_e4a1:2, fmradio:1, alarm:1, unknown_e4a2:1, reset:1, menu:1; u8 unknown_e4b:6, singleptt:1, vfomrlock:1; u8 workmode; u8 keylock; } settings; #seekto 0x0E76; struct { u8 unused1:1, mrcha:7; u8 unused2:1, mrchb:7; } wmchannel; struct vfo { u8 unknown0[8]; u8 freq[8]; u8 offset[6]; ul16 rxtone; ul16 txtone; u8 unused1:7, band:1; u8 unknown3; u8 unused2:2, sftd:2, scode:4; u8 unknown4; u8 unused3:1, step:3, unused4:4; u8 unused5:1, widenarr:1, unused6:4, txpower3:2; }; #seekto 0x0F00; struct { struct vfo a; struct vfo b; } vfo; #seekto 0x0F4E; u16 fm_presets; #seekto 0x1000; struct { char name[7]; u8 unknown1[9]; } names[128]; #seekto 0x1ED0; struct { char line1[7]; char line2[7]; } sixpoweron_msg; #seekto 0x1EE0; struct { char line1[7]; char line2[7]; } poweron_msg; #seekto 0x1EF0; struct { char line1[7]; char line2[7]; } firmware_msg; struct squelch { u8 sql0; u8 sql1; u8 sql2; u8 sql3; u8 sql4; u8 sql5; u8 sql6; u8 sql7; u8 sql8; u8 sql9; }; #seekto 0x1F60; struct { struct squelch vhf; u8 unknown1[6]; u8 unknown2[16]; struct squelch uhf; } squelch; struct limit { u8 enable; bbcd lower[2]; bbcd upper[2]; }; #seekto 0x1FC0; struct { struct limit vhf; struct limit uhf; struct limit vhf2; } limits; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def get_features(self): rf = bfc.BaofengCommonHT.get_features(self) rf.valid_tuning_steps = STEPS return rf def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") fm_preset = RadioSettingGroup("fm_preset", "FM Preset") dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") service = RadioSettingGroup("service", "Service Settings") top = RadioSettings(basic, advanced, other, work, fm_preset, dtmfe, service) # Basic settings if _mem.settings.squelch > 0x09: val = 0x00 else: val = _mem.settings.squelch rs = RadioSetting("settings.squelch", "Squelch", RadioSettingValueList( LIST_OFF1TO9, LIST_OFF1TO9[val])) basic.append(rs) if _mem.settings.save > 0x04: val = 0x00 else: val = _mem.settings.save rs = RadioSetting("settings.save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) if _mem.settings.vox > 0x0A: val = 0x00 else: val = _mem.settings.vox rs = RadioSetting("settings.vox", "Vox", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) if _mem.settings.abr > 0x0A: val = 0x00 else: val = _mem.settings.abr rs = RadioSetting("settings.abr", "Backlight Timeout", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) rs = RadioSetting("settings.tdr", "Dual Watch", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean(_mem.settings.beep)) basic.append(rs) if _mem.settings.timeout > 0x27: val = 0x03 else: val = _mem.settings.timeout rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( LIST_TIMEOUT, LIST_TIMEOUT[val])) basic.append(rs) if _mem.settings.voice > 0x02: val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) if _mem.settings.screv > 0x02: val = 0x01 else: val = _mem.settings.screv rs = RadioSetting("settings.screv", "Scan Resume", RadioSettingValueList( LIST_RESUME, LIST_RESUME[val])) basic.append(rs) rs = RadioSetting("settings.pttid", "When to send PTT ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[ _mem.settings.pttid])) basic.append(rs) if _mem.settings.pttlt > 0x1E: val = 0x05 else: val = _mem.settings.pttlt rs = RadioSetting("pttlt", "PTT ID Delay", RadioSettingValueInteger(0, 50, val)) basic.append(rs) rs = RadioSetting("settings.mdfa", "Display Mode (A)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfa])) basic.append(rs) rs = RadioSetting("settings.mdfb", "Display Mode (B)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfb])) basic.append(rs) rs = RadioSetting("settings.autolk", "Automatic Key Lock", RadioSettingValueBoolean(_mem.settings.autolk)) basic.append(rs) rs = RadioSetting("settings.wtled", "Standby LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.wtled])) basic.append(rs) rs = RadioSetting("settings.rxled", "RX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.rxled])) basic.append(rs) rs = RadioSetting("settings.txled", "TX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.txled])) basic.append(rs) val = _mem.settings.almod rs = RadioSetting("settings.almod", "Alarm Mode", RadioSettingValueList( LIST_ALMOD, LIST_ALMOD[val])) basic.append(rs) if _mem.settings.tdrab > 0x02: val = 0x00 else: val = _mem.settings.tdrab rs = RadioSetting("settings.tdrab", "Dual Watch TX Priority", RadioSettingValueList( LIST_OFFAB, LIST_OFFAB[val])) basic.append(rs) rs = RadioSetting("settings.ste", "Squelch Tail Eliminate (HT to HT)", RadioSettingValueBoolean(_mem.settings.ste)) basic.append(rs) if _mem.settings.rpste > 0x0A: val = 0x00 else: val = _mem.settings.rpste rs = RadioSetting("settings.rpste", "Squelch Tail Eliminate (repeater)", RadioSettingValueList( LIST_RPSTE, LIST_RPSTE[val])) basic.append(rs) if _mem.settings.rptrl > 0x0A: val = 0x00 else: val = _mem.settings.rptrl rs = RadioSetting("settings.rptrl", "STE Repeater Delay", RadioSettingValueList( LIST_STEDELAY, LIST_STEDELAY[val])) basic.append(rs) rs = RadioSetting("settings.ponmsg", "Power-On Message", RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[ _mem.settings.ponmsg])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger Beep", RadioSettingValueBoolean(_mem.settings.roger)) basic.append(rs) # Advanced settings rs = RadioSetting("settings.reset", "RESET Menu", RadioSettingValueBoolean(_mem.settings.reset)) advanced.append(rs) rs = RadioSetting("settings.menu", "All Menus", RadioSettingValueBoolean(_mem.settings.menu)) advanced.append(rs) rs = RadioSetting("settings.fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_mem.settings.fmradio)) advanced.append(rs) rs = RadioSetting("settings.alarm", "Alarm Sound", RadioSettingValueBoolean(_mem.settings.alarm)) advanced.append(rs) # Other settings def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = _mem.firmware_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val) other.append(rs) _msg = _mem.sixpoweron_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2", val) other.append(rs) _msg = _mem.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 7, _filter(_msg.line2))) other.append(rs) lower = 130 upper = 179 rs = RadioSetting("limits.vhf.lower", "VHF Lower Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.vhf.lower)) other.append(rs) rs = RadioSetting("limits.vhf.upper", "VHF Upper Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.vhf.upper)) other.append(rs) if self._tri_band: lower = 200 upper = 260 rs = RadioSetting("limits.vhf2.lower", "VHF2 Lower Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.vhf2.lower)) other.append(rs) rs = RadioSetting("limits.vhf2.upper", "VHF2 Upper Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.vhf2.upper)) other.append(rs) lower = 400 upper = 520 rs = RadioSetting("limits.uhf.lower", "UHF Lower Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.uhf.lower)) other.append(rs) rs = RadioSetting("limits.uhf.upper", "UHF Upper Limit (MHz)", RadioSettingValueInteger( lower, upper, _mem.limits.uhf.upper)) other.append(rs) # Work mode settings rs = RadioSetting("settings.displayab", "Display", RadioSettingValueList( LIST_AB, LIST_AB[_mem.settings.displayab])) work.append(rs) rs = RadioSetting("settings.workmode", "VFO/MR Mode", RadioSettingValueList( LIST_WORKMODE, LIST_WORKMODE[_mem.settings.workmode])) work.append(rs) rs = RadioSetting("settings.keylock", "Keypad Lock", RadioSettingValueBoolean(_mem.settings.keylock)) work.append(rs) rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrcha)) work.append(rs) rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrchb)) work.append(rs) def my_validate(value): value = chirp_common.parse_freq(value) msg = ("Can't be less than %i.0000") if value > 99000000 and value < 130 * 1000000: raise InvalidValueError(msg % (130)) msg = ("Can't be between %i.9975-%i.0000") if (179 + 1) * 1000000 <= value and value < 400 * 1000000: raise InvalidValueError(msg % (179, 400)) msg = ("Can't be greater than %i.9975") if value > 99000000 and value > (520 + 1) * 1000000: raise InvalidValueError(msg % (520)) return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.a.freq)) val1a.set_validate_callback(my_validate) rs = RadioSetting("vfo.a.freq", "VFO A Frequency", val1a) rs.set_apply_callback(apply_freq, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.b.freq)) val1b.set_validate_callback(my_validate) rs = RadioSetting("vfo.b.freq", "VFO B Frequency", val1b) rs.set_apply_callback(apply_freq, _mem.vfo.b) work.append(rs) rs = RadioSetting("vfo.a.sftd", "VFO A Shift", RadioSettingValueList( LIST_SHIFTD, LIST_SHIFTD[_mem.vfo.a.sftd])) work.append(rs) rs = RadioSetting("vfo.b.sftd", "VFO B Shift", RadioSettingValueList( LIST_SHIFTD, LIST_SHIFTD[_mem.vfo.b.sftd])) work.append(rs) def convert_bytes_to_offset(bytes): real_offset = 0 for byte in bytes: real_offset = (real_offset * 10) + byte return chirp_common.format_freq(real_offset * 1000) def apply_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 1000 for i in range(5, -1, -1): obj.offset[i] = value % 10 value /= 10 val1a = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.a.offset)) rs = RadioSetting("vfo.a.offset", "VFO A Offset", val1a) rs.set_apply_callback(apply_offset, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.b.offset)) rs = RadioSetting("vfo.b.offset", "VFO B Offset", val1b) rs.set_apply_callback(apply_offset, _mem.vfo.b) work.append(rs) def apply_txpower_listvalue(setting, obj): LOG.debug("Setting value: " + str( setting.value) + " from list") val = str(setting.value) index = TXP_CHOICES.index(val) val = TXP_VALUES[index] obj.set_value(val) if self._tri_band: if _mem.vfo.a.txpower3 in TXP_VALUES: idx = TXP_VALUES.index(_mem.vfo.a.txpower3) else: idx = TXP_VALUES.index(0x00) rs = RadioSettingValueList(TXP_CHOICES, TXP_CHOICES[idx]) rset = RadioSetting("vfo.a.txpower3", "VFO A Power", rs) rset.set_apply_callback(apply_txpower_listvalue, _mem.vfo.a.txpower3) work.append(rset) if _mem.vfo.b.txpower3 in TXP_VALUES: idx = TXP_VALUES.index(_mem.vfo.b.txpower3) else: idx = TXP_VALUES.index(0x00) rs = RadioSettingValueList(TXP_CHOICES, TXP_CHOICES[idx]) rset = RadioSetting("vfo.b.txpower3", "VFO B Power", rs) rset.set_apply_callback(apply_txpower_listvalue, _mem.vfo.b.txpower3) work.append(rset) else: rs = RadioSetting("vfo.a.txpower3", "VFO A Power", RadioSettingValueList( LIST_TXPOWER, LIST_TXPOWER[min(_mem.vfo.a.txpower3, 0x02)] )) work.append(rs) rs = RadioSetting("vfo.b.txpower3", "VFO B Power", RadioSettingValueList( LIST_TXPOWER, LIST_TXPOWER[min(_mem.vfo.b.txpower3, 0x02)] )) work.append(rs) rs = RadioSetting("vfo.a.widenarr", "VFO A Bandwidth", RadioSettingValueList( LIST_BANDWIDTH, LIST_BANDWIDTH[_mem.vfo.a.widenarr])) work.append(rs) rs = RadioSetting("vfo.b.widenarr", "VFO B Bandwidth", RadioSettingValueList( LIST_BANDWIDTH, LIST_BANDWIDTH[_mem.vfo.b.widenarr])) work.append(rs) rs = RadioSetting("vfo.a.scode", "VFO A S-CODE", RadioSettingValueList( LIST_SCODE, LIST_SCODE[_mem.vfo.a.scode])) work.append(rs) rs = RadioSetting("vfo.b.scode", "VFO B S-CODE", RadioSettingValueList( LIST_SCODE, LIST_SCODE[_mem.vfo.b.scode])) work.append(rs) rs = RadioSetting("vfo.a.step", "VFO A Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.a.step])) work.append(rs) rs = RadioSetting("vfo.b.step", "VFO B Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.b.step])) work.append(rs) # broadcast FM settings value = self._memobj.fm_presets value_shifted = ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8) if value_shifted >= 65.0 * 10 and value_shifted <= 108.0 * 10: # storage method 3 (discovered 2022) self._bw_shift = True preset = value_shifted / 10.0 elif value >= 65.0 * 10 and value <= 108.0 * 10: # storage method 2 preset = value / 10.0 elif value <= 108.0 * 10 - 650: # original storage method (2012) preset = value / 10.0 + 65 else: # unknown (undiscovered method or no FM chip?) preset = False if preset: rs = RadioSettingValueFloat(65, 108.0, preset, 0.1, 1) rset = RadioSetting("fm_presets", "FM Preset(MHz)", rs) fm_preset.append(rset) # DTMF settings def apply_code(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) pttid = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) pttid.set_apply_callback(apply_code, self._memobj.pttid[i], 5) dtmfe.append(pttid) if _mem.ani.dtmfon > 0xC3: val = 0x03 else: val = _mem.ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if _mem.ani.dtmfoff > 0xC3: val = 0x03 else: val = _mem.ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) _codeobj = self._memobj.ani.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.code", "ANI Code", val) rs.set_apply_callback(apply_code, self._memobj.ani, 5) dtmfe.append(rs) rs = RadioSetting("ani.aniid", "When to send ANI ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[_mem.ani.aniid])) dtmfe.append(rs) # Service settings for band in ["vhf", "uhf"]: for index in range(0, 10): key = "squelch.%s.sql%i" % (band, index) if band == "vhf": _obj = self._memobj.squelch.vhf elif band == "uhf": _obj = self._memobj.squelch.uhf val = RadioSettingValueInteger(0, 123, getattr( _obj, "sql%i" % (index))) if index == 0: val.set_mutable(False) name = "%s Squelch %i" % (band.upper(), index) rs = RadioSetting(key, name, val) service.append(rs) return top @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) in [0x2008, 0x2010]: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False class RH5XAlias(chirp_common.Alias): VENDOR = "Rugged" MODEL = "RH5X" class UV82IIIAlias(chirp_common.Alias): VENDOR = "Baofeng" MODEL = "UV-82III" class UV9RPROAlias(chirp_common.Alias): VENDOR = "Baofeng" MODEL = "UV-9R Pro" @directory.register class BFA58(WP970I): """Baofeng BF-A58""" VENDOR = "Baofeng" MODEL = "BF-A58" LENGTH_NAME = 7 ALIASES = [RH5XAlias, UV9RPROAlias] _fileid = ["BFT515 ", "BFT517 "] @directory.register class UV82WP(WP970I): """Baofeng UV82-WP""" VENDOR = "Baofeng" MODEL = "UV-82WP" @directory.register class GT3WP(WP970I): """Baofeng GT-3WP""" VENDOR = "Baofeng" MODEL = "GT-3WP" LENGTH_NAME = 7 @directory.register class RT6(WP970I): """Retevis RT6""" VENDOR = "Retevis" MODEL = "RT6" @directory.register class BFA58S(WP970I): VENDOR = "Baofeng" MODEL = "BF-A58S" LENGTH_NAME = 7 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] ALIASES = [UV82IIIAlias] _tri_band = True def get_features(self): rf = WP970I.get_features(self) rf.valid_bands = [self._vhf_range, self._vhf2_range, self._uhf_range] return rf @directory.register class UVS9X3(BFA58S): VENDOR = "Baofeng" MODEL = "UV-S9X3" ALIASES = [] _magic = [MSTRING_UVS9X3, ] @directory.register class BF5RXRadio(BFA58S): VENDOR = "Baofeng" MODEL = "5RX" ALIASES = [] _magic = [MSTRING_UVS9X3, ] _air_range = (108000000, 136000000) _vhf_range = (136000000, 174000000) _vhf2_range = (200000000, 260000000) _uhf2_range = (350000000, 390000000) _uhf_range = (400000000, 520000000) def get_features(self): rf = WP970I.get_features(self) rf.valid_bands = [self._air_range, self._vhf_range, self._vhf2_range, self._uhf2_range, self._uhf_range] return rf @directory.register class UV9R(WP970I): """Baofeng UV-9R""" VENDOR = "Baofeng" MODEL = "UV-9R" LENGTH_NAME = 7 @directory.register class UV9G(WP970I): """Baofeng UV-9G""" VENDOR = "Baofeng" MODEL = "UV-9G" LENGTH_NAME = 7 POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Med", watts=1.00), chirp_common.PowerLevel("Low", watts=0.50)] _magic = [MSTRING_UV9G, ] _gmrs = False # sold as GMRS radio but supports full band TX/RX @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False chirp-20240224/chirp/drivers/ts2000.py0000644000175000017500000002476514411666130016141 0ustar hibbyhibby# Copyright 2012 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import re from chirp import chirp_common, directory, util, errors from chirp.drivers import kenwood_live from chirp.drivers.kenwood_live import KenwoodLiveRadio, \ command, iserr, NOCACHE TS2000_SSB_STEPS = [1.0, 2.5, 5.0, 10.0] TS2000_FM_STEPS = [5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] TS2000_DUPLEX = dict(kenwood_live.DUPLEX) TS2000_DUPLEX[3] = "=" TS2000_DUPLEX[4] = "split" TS2000_MODES = ["?", "LSB", "USB", "CW", "FM", "AM", "FSK", "CWR", "?", "FSKR"] TS2000_TMODES = ["", "Tone", "TSQL", "DTCS"] TS2000_TONES = list(chirp_common.OLD_TONES) TS2000_TONES.remove(69.3) @directory.register class TS2000Radio(KenwoodLiveRadio): """Kenwood TS-2000""" MODEL = "TS-2000" _upper = 289 _kenwood_split = True _kenwood_valid_tones = list(TS2000_TONES) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.has_bank = False rf.can_odd_split = True rf.valid_modes = ["LSB", "USB", "CW", "FM", "AM"] rf.valid_tmodes = list(TS2000_TMODES) rf.valid_tuning_steps = list(TS2000_SSB_STEPS + TS2000_FM_STEPS) rf.valid_bands = [(1000, 1300000000)] rf.valid_skips = ["", "S"] rf.valid_duplexes = list(TS2000_DUPLEX.values()) # TS-2000 uses ";" as a message separator even though it seems to # allow you to to use all printable ASCII characters at the manual # controls. The radio doesn't send the name after the ";" if you # input one from the manual controls. rf.valid_characters = chirp_common.CHARSET_ASCII.replace(';', '') rf.valid_name_length = 7 # 7 character channel names rf.memory_bounds = (0, self._upper) return rf def _cmd_set_memory(self, number, spec): return "MW0%03i%s" % (number, spec) def _cmd_set_split(self, number, spec): return "MW1%03i%s" % (number, spec) def _cmd_get_memory(self, number): return "MR0%03i" % number def _cmd_get_split(self, number): return "MR1%03i" % number def _cmd_recall_memory(self, number): return "MC%03i" % (number) def _cmd_cur_memory(self, number): return "MC" def _cmd_erase_memory(self, number): # write a memory channel that's effectively zeroed except # for the channel number return "MW%04i%035i" % (number, 0) def erase_memory(self, number): if number not in self._memcache: return resp = command(self.pipe, *self._cmd_erase_memory(number)) if iserr(resp): raise errors.RadioError("Radio refused delete of %i" % number) del self._memcache[number] def get_memory(self, number): if number < 0 or number > self._upper: raise errors.InvalidMemoryLocation( "Number must be between 0 and %i" % self._upper) if number in self._memcache and not NOCACHE: return self._memcache[number] result = command(self.pipe, *self._cmd_get_memory(number)) if result == "N": mem = chirp_common.Memory() mem.number = number mem.empty = True self._memcache[mem.number] = mem return mem mem = self._parse_mem_spec(result) self._memcache[mem.number] = mem # check for split frequency operation if mem.duplex == "" and self._kenwood_split: result = command(self.pipe, *self._cmd_get_split(number)) self._parse_split_spec(mem, result) return mem def _parse_mem_spec(self, spec): mem = chirp_common.Memory() # pad string so indexes match Kenwood docs spec = " " + spec # use the same variable names as the Kenwood docs # _p1 = spec[3] _p2 = spec[4] _p3 = spec[5:7] _p4 = spec[7:18] _p5 = spec[18] _p6 = spec[19] _p7 = spec[20] _p8 = spec[21:23] _p9 = spec[23:25] _p10 = spec[25:28] # _p11 = spec[28] _p12 = spec[29] _p13 = spec[30:39] _p14 = spec[39:41] # _p15 = spec[41] _p16 = spec[42:49] mem.number = int(_p2 + _p3) # concat bank num and chan num if _p5 == '0': # NOTE(danms): Apparently some TS2000s will return unset # memory records with all zeroes for the fields instead of # NAKing the command with an N response. If that happens here, # return an empty memory. mem.empty = True return mem mem.freq = int(_p4) mem.mode = TS2000_MODES[int(_p5)] mem.skip = ["", "S"][int(_p6)] mem.tmode = TS2000_TMODES[int(_p7)] # PL and T-SQL are 1 indexed, DTCS is 0 indexed mem.rtone = self._kenwood_valid_tones[int(_p8) - 1] mem.ctone = self._kenwood_valid_tones[int(_p9) - 1] mem.dtcs = chirp_common.DTCS_CODES[int(_p10)] mem.duplex = TS2000_DUPLEX[int(_p12)] mem.offset = int(_p13) # 9-digit if mem.mode in ["AM", "FM"]: mem.tuning_step = TS2000_FM_STEPS[int(_p14)] else: mem.tuning_step = TS2000_SSB_STEPS[int(_p14)] mem.name = _p16 return mem def _parse_split_spec(self, mem, spec): # pad string so indexes match Kenwood docs spec = " " + spec # use the same variable names as the Kenwood docs split_freq = int(spec[7:18]) if mem.freq != split_freq: mem.duplex = "split" mem.offset = split_freq return mem def set_memory(self, memory): if memory.number < 0 or memory.number > self._upper: raise errors.InvalidMemoryLocation( "Number must be between 0 and %i" % self._upper) spec = self._make_mem_spec(memory) spec = "".join(spec) r1 = command(self.pipe, *self._cmd_set_memory(memory.number, spec)) if not iserr(r1): memory.name = memory.name.rstrip() self._memcache[memory.number] = memory # if we're tuned to the channel, reload it r1 = command(self.pipe, *self._cmd_cur_memory(memory.number)) if not iserr(r1): pattern = re.compile("MC([0-9]{3})") match = pattern.search(r1) if match is not None: cur_mem = int(match.group(1)) if cur_mem == memory.number: cur_mem = \ command(self.pipe, *self._cmd_recall_memory(memory.number)) else: raise errors.InvalidDataError("Radio refused %i" % memory.number) # FIXME if memory.duplex == "split" and self._kenwood_split: spec = "".join(self._make_split_spec(memory)) result = command(self.pipe, *self._cmd_set_split(memory.number, spec)) if iserr(result): raise errors.InvalidDataError("Radio refused %i" % memory.number) def _make_mem_spec(self, mem): if mem.duplex in " +-": duplex = util.get_dict_rev(TS2000_DUPLEX, mem.duplex) offset = mem.offset elif mem.duplex == "split": duplex = 0 offset = 0 else: print("Bug: unsupported duplex `%s'" % mem.duplex) if mem.mode in ["AM", "FM"]: step = TS2000_FM_STEPS.index(mem.tuning_step) else: step = TS2000_SSB_STEPS.index(mem.tuning_step) # TS-2000 won't accept channels with tone mode off if they have # tone values if mem.tmode == "": rtone = 0 ctone = 0 dtcs = 0 else: # PL and T-SQL are 1 indexed, DTCS is 0 indexed rtone = (self._kenwood_valid_tones.index(mem.rtone) + 1) ctone = (self._kenwood_valid_tones.index(mem.ctone) + 1) dtcs = (chirp_common.DTCS_CODES.index(mem.dtcs)) spec = ( "%011i" % mem.freq, "%i" % (TS2000_MODES.index(mem.mode)), "%i" % (mem.skip == "S"), "%i" % TS2000_TMODES.index(mem.tmode), "%02i" % (rtone), "%02i" % (ctone), "%03i" % (dtcs), "0", # REVERSE status "%i" % duplex, "%09i" % offset, "%02i" % step, "0", # Memory Group number (0-9) "%s" % mem.name, ) return spec def _make_split_spec(self, mem): if mem.duplex in " +-": duplex = util.get_dict_rev(TS2000_DUPLEX, mem.duplex) elif mem.duplex == "split": duplex = 0 else: print("Bug: unsupported duplex `%s'" % mem.duplex) if mem.mode in ["AM", "FM"]: step = TS2000_FM_STEPS.index(mem.tuning_step) else: step = TS2000_SSB_STEPS.index(mem.tuning_step) # TS-2000 won't accept channels with tone mode off if they have # tone values if mem.tmode == "": rtone = 0 ctone = 0 dtcs = 0 else: # PL and T-SQL are 1 indexed, DTCS is 0 indexed rtone = (self._kenwood_valid_tones.index(mem.rtone) + 1) ctone = (self._kenwood_valid_tones.index(mem.ctone) + 1) dtcs = (chirp_common.DTCS_CODES.index(mem.dtcs)) spec = ( "%011i" % mem.offset, "%i" % (TS2000_MODES.index(mem.mode)), "%i" % (mem.skip == "S"), "%i" % TS2000_TMODES.index(mem.tmode), "%02i" % (rtone), "%02i" % (ctone), "%03i" % (dtcs), "0", # REVERSE status "%i" % duplex, "%09i" % 0, "%02i" % step, "0", # Memory Group number (0-9) "%s" % mem.name, ) return spec chirp-20240224/chirp/drivers/thd72.py0000644000175000017500000005703514563632215016142 0ustar hibbyhibby# Copyright 2010 Vernon Mauery # Copyright 2016 Angus Ainslie # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, errors, directory from chirp import bitwise, memmap from chirp.drivers import kenwood_live from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings from chirp.settings import RadioSettingValueString from chirp.settings import RadioSettingValueList import time import struct import sys import logging LOG = logging.getLogger(__name__) # TH-D72 memory map # 0x0000..0x0200: startup password and other stuff # 0x0200..0x0400: current channel and other settings # 0x244,0x246: last menu numbers # 0x249: last f menu number # 0x0400..0x0c00: APRS settings and likely other settings # 0x0c00..0x1500: memory channel flags # 0x1500..0x5380: 0-999 channels # 0x5380..0x54c0: 0-9 scan channels # 0x54c0..0x5560: 0-9 wx channels # 0x5560..0x5e00: ? # 0x5e00..0x7d40: 0-999 channel names # 0x7d40..0x7de0: ? # 0x7de0..0x7e30: wx channel names # 0x7e30..0x7ed0: ? # 0x7ed0..0x7f20: group names # 0x7f20..0x8b00: ? # 0x8b00..0x9c00: last 20 APRS entries # 0x9c00..0xe500: ? # 0xe500..0xe7d0: startup bitmap # 0xe7d0..0xe800: startup bitmap filename # 0xe800..0xead0: gps-logger bitmap # 0xe8d0..0xeb00: gps-logger bipmap filename # 0xeb00..0xff00: ? # 0xff00..0xffff: stuff? # memory channel # 0 1 2 3 4 5 6 7 8 9 a b c d e f # [freq ] ? mode tmode/duplex rtone ctone dtcs cross_mode [offset] ? mem_format = """ #seekto 0x0000; struct { ul16 version; u8 shouldbe32; u8 efs[11]; u8 unknown0[3]; u8 radio_custom_image; u8 gps_custom_image; u8 unknown1[7]; u8 passwd[6]; } frontmatter; #seekto 0x02c0; struct { ul32 start_freq; ul32 end_freq; } prog_vfo[6]; #seekto 0x0300; struct { char power_on_msg[8]; u8 unknown0[8]; u8 unknown1[2]; u8 lamp_timer; u8 contrast; u8 battery_saver; u8 APO; u8 unknown2; u8 key_beep; u8 unknown3[8]; u8 unknown4; u8 balance; u8 unknown5[23]; u8 lamp_control; } settings; #seekto 0x0c00; struct { u8 disabled:4, prog_vfo:4; u8 skip; } flag[1032]; #seekto 0x1500; struct { ul32 freq; u8 unknown1:4, tune_step:4; u8 mode; u8 tone_mode:4, duplex:4; u8 rtone; u8 ctone; u8 dtcs; u8 cross_mode; ul32 offset; u8 unknown2:4, split_tune_step:4; } memory[1032]; #seekto 0x5e00; struct { char name[8]; } channel_name[1000]; #seekto 0x7de0; struct { char name[8]; } wx_name[10]; #seekto 0x7ed0; struct { char name[8]; } group_name[10]; """ THD72_SPECIAL = {} for i in range(0, 10): THD72_SPECIAL["L%i" % i] = 1000 + (i * 2) THD72_SPECIAL["U%i" % i] = 1000 + (i * 2) + 1 for i in range(0, 10): THD72_SPECIAL["WX%i" % (i + 1)] = 1020 + i THD72_SPECIAL["C VHF"] = 1030 THD72_SPECIAL["C UHF"] = 1031 THD72_SPECIAL_REV = {} for k, v in THD72_SPECIAL.items(): THD72_SPECIAL_REV[v] = k TMODES = { 0x08: "Tone", 0x04: "TSQL", 0x02: "DTCS", 0x01: "Cross", 0x00: "", } TMODES_REV = { "": 0x00, "Cross": 0x01, "DTCS": 0x02, "TSQL": 0x04, "Tone": 0x08, } MODES = { 0x00: "FM", 0x01: "NFM", 0x02: "AM", } MODES_REV = { "FM": 0x00, "NFM": 0x01, "AM": 0x2, } DUPLEX = { 0x00: "", 0x01: "+", 0x02: "-", 0x04: "split", } DUPLEX_REV = { "": 0x00, "+": 0x01, "-": 0x02, "split": 0x04, } TUNE_STEPS = [5.0, 6.25, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] EXCH_R = "R\x00\x00\x00\x00" EXCH_W = "W\x00\x00\x00\x00" DEFAULT_PROG_VFO = ( (136000000, 174000000), (410000000, 470000000), (118000000, 136000000), (136000000, 174000000), (320000000, 400000000), (400000000, 524000000), ) D72_FILE_HEADER = ( b'MCP-4A\xFF\xFFV1.04\xFF\xFF\xFF' + b'TH-D72' + (b'\xFF' * 10) + b'\x31' + (b'\xFF' * 15) + b'\xFF' * (5 * 16) + b'AMB0' + (b'\xFF' * 12) + b'\xFF' * (7 * 16)) def get_prog_vfo(frequency): for i, (start, end) in enumerate(DEFAULT_PROG_VFO): if start <= frequency < end: return i raise ValueError("Frequency is out of range.") @directory.register class THD72Radio(chirp_common.CloneModeRadio): BAUD_RATE = 9600 VENDOR = "Kenwood" MODEL = "TH-D72 (clone mode)" HARDWARE_FLOW = sys.platform == "darwin" # only OS X driver needs hw flow NEEDS_COMPAT_SERIAL = False FORMATS = [directory.register_format('Kenwood MCP4A', '*.mc4')] mem_upper_limit = 1022 _memsize = 65536 _model = "" # FIXME: REMOVE _dirty_blocks = [] _LCD_CONTRAST = ["Level %d" % x for x in range(1, 16)] _LAMP_CONTROL = ["Manual", "Auto"] _LAMP_TIMER = ["Seconds %d" % x for x in range(2, 11)] _BATTERY_SAVER = ["OFF", "0.03 Seconds", "0.2 Seconds", "0.4 Seconds", "0.6 Seconds", "0.8 Seconds", "1 Seconds", "2 Seconds", "3 Seconds", "4 Seconds", "5 Seconds"] _APO = ["OFF", "15 Minutes", "30 Minutes", "60 Minutes"] _AUDIO_BALANCE = ["Center", "A +50%", "A +100%", "B +50%", "B +100%"] _KEY_BEEP = ["OFF", "Radio & GPS", "Radio Only", "GPS Only"] def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 999) rf.valid_bands = [(118000000, 174000000), (320000000, 524000000)] rf.has_cross = True rf.can_odd_split = True rf.has_dtcs_polarity = False rf.has_tuning_step = True rf.has_bank = False rf.has_settings = True rf.valid_tuning_steps = [] rf.valid_modes = list(MODES_REV.keys()) rf.valid_tmodes = list(TMODES_REV.keys()) rf.valid_duplexes = list(DUPLEX_REV.keys()) rf.valid_tuning_steps = list(TUNE_STEPS) rf.valid_tones = list(kenwood_live.KENWOOD_TONES) rf.valid_skips = ["", "S"] rf.valid_characters = chirp_common.CHARSET_ALPHANUMERIC rf.valid_name_length = 8 return rf def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) self._dirty_blocks = [] def _detect_baud(self): for baud in [9600, 19200, 38400, 57600]: self.pipe.baudrate = baud try: self.pipe.write(b"\r\r") except: break self.pipe.read(32) try: id = self.get_id() LOG.info("Radio %s at %i baud" % (id, baud)) return True except errors.RadioError: pass raise errors.RadioError("No response from radio") def get_special_locations(self): return sorted(THD72_SPECIAL.keys()) def add_dirty_block(self, memobj): block = memobj._offset // 256 if block not in self._dirty_blocks: self._dirty_blocks.append(block) self._dirty_blocks.sort() print("dirty blocks: ", self._dirty_blocks) def get_channel_name(self, number): if number < 999: name = str(self._memobj.channel_name[number].name) + '\xff' elif number >= 1020 and number < 1030: number -= 1020 name = str(self._memobj.wx_name[number].name) + '\xff' else: return '' return name[:name.index('\xff')].rstrip() def set_channel_name(self, number, name): name = name[:8] + '\xff' * 8 if number < 999: self._memobj.channel_name[number].name = name[:8] self.add_dirty_block(self._memobj.channel_name[number]) elif number >= 1020 and number < 1030: number -= 1020 self._memobj.wx_name[number].name = name[:8] self.add_dirty_block(self._memobj.wx_name[number]) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) + \ repr(self._memobj.flag[number]) def get_memory(self, number): if isinstance(number, str): try: number = THD72_SPECIAL[number] except KeyError: raise errors.InvalidMemoryLocation("Unknown channel %s" % number) if number < 0 or number > (max(THD72_SPECIAL.values()) + 1): raise errors.InvalidMemoryLocation( "Number must be between 0 and 999") _mem = self._memobj.memory[number] flag = self._memobj.flag[number] mem = chirp_common.Memory() mem.number = number if number > 999: mem.extd_number = THD72_SPECIAL_REV[number] if flag.disabled == 0xf: mem.empty = True return mem mem.name = self.get_channel_name(number) mem.freq = int(_mem.freq) mem.tmode = TMODES[int(_mem.tone_mode)] mem.rtone = kenwood_live.KENWOOD_TONES[_mem.rtone] mem.ctone = kenwood_live.KENWOOD_TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.duplex = DUPLEX[int(_mem.duplex)] mem.offset = int(_mem.offset) mem.mode = MODES[int(_mem.mode)] mem.tuning_step = TUNE_STEPS[int(_mem.tune_step)] if number < 999: mem.skip = chirp_common.SKIP_VALUES[int(flag.skip)] mem.cross_mode = chirp_common.CROSS_MODES[_mem.cross_mode] if number > 999: mem.cross_mode = chirp_common.CROSS_MODES[0] mem.immutable = ["number", "bank", "extd_number", "cross_mode"] if number >= 1020 and number < 1030: mem.immutable += ["freq", "offset", "tone", "mode", "tmode", "ctone", "skip"] # FIXME: ALL else: mem.immutable += ["name"] return mem def set_memory(self, mem): LOG.debug("set_memory(%d)" % mem.number) if mem.number < 0 or mem.number > (max(THD72_SPECIAL.values()) + 1): raise errors.InvalidMemoryLocation( "Number must be between 0 and 999") # weather channels can only change name, nothing else if mem.number >= 1020 and mem.number < 1030: self.set_channel_name(mem.number, mem.name) return flag = self._memobj.flag[mem.number] self.add_dirty_block(self._memobj.flag[mem.number]) # only delete non-WX channels was_empty = flag.disabled == 0xf if mem.empty: flag.disabled = 0xf return flag.disabled = 0 _mem = self._memobj.memory[mem.number] self.add_dirty_block(_mem) if was_empty: self.initialize(_mem) _mem.freq = mem.freq if mem.number < 999: self.set_channel_name(mem.number, mem.name) _mem.tone_mode = TMODES_REV[mem.tmode] _mem.rtone = kenwood_live.KENWOOD_TONES.index(mem.rtone) _mem.ctone = kenwood_live.KENWOOD_TONES.index(mem.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.cross_mode = chirp_common.CROSS_MODES.index(mem.cross_mode) _mem.duplex = DUPLEX_REV[mem.duplex] _mem.offset = mem.offset _mem.mode = MODES_REV[mem.mode] _mem.tune_step = TUNE_STEPS.index(mem.tuning_step) if mem.duplex == 'split': _mem.split_tune_step = TUNE_STEPS.index( chirp_common.required_step(mem.offset)) else: _mem.split_tune_step = _mem.tune_step prog_vfo = get_prog_vfo(mem.freq) flag.prog_vfo = prog_vfo if mem.number < 999: flag.skip = chirp_common.SKIP_VALUES.index(mem.skip) def sync_in(self): self._detect_baud() self._mmap = self.download() self.process_mmap() def sync_out(self): self._detect_baud() if len(self._dirty_blocks): self.upload(self._dirty_blocks) else: self.upload() def read_block(self, block, count=256): self.pipe.write(struct.pack("D72: %s" % cmd) self.pipe.write((cmd + "\r").encode()) while not data.endswith(b"\r") and (time.time() - start) < timeout: data += self.pipe.read(1) LOG.debug("D72->PC: %s" % data.strip()) return data.decode().strip() def get_id(self): r = self.command("ID") if r.startswith("ID "): return r.split(" ")[1] else: raise errors.RadioError("No response to ID command") def initialize(self, mmap): mmap.set_raw("\x00\xc8\xb3\x08\x00\x01\x00\x08" "\x08\x00\xc0\x27\x09\x00\x00\x00") def _get_settings(self): top = RadioSettings(self._get_display_settings(), self._get_audio_settings(), self._get_battery_settings()) return top def set_settings(self, settings): _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: if element.has_apply_callback(): LOG.debug("Using apply callback") try: element.run_apply_callback() except NotImplementedError as e: LOG.error("thd72: %s", e) continue # Find the object containing setting. obj = _mem bits = element.get_name().split(".") setting = bits[-1] for name in bits[:-1]: if name.endswith("]"): name, index = name.split("[") index = int(index[:-1]) obj = getattr(obj, name)[index] else: obj = getattr(obj, name) try: old_val = getattr(obj, setting) LOG.debug("Setting %s(%r) <= %s" % ( element.get_name(), old_val, element.value)) setattr(obj, setting, element.value) except AttributeError as e: LOG.error("Setting %s is not in the memory map: %s" % (element.get_name(), e)) except Exception: LOG.debug(element.get_name()) raise def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None @classmethod def apply_power_on_msg(cls, setting, obj): message = setting.value.get_value() setattr(obj, "power_on_msg", cls._add_ff_pad(message, 8)) def apply_lcd_contrast(cls, setting, obj): rawval = setting.value.get_value() val = cls._LCD_CONTRAST.index(rawval) + 1 obj.contrast = val def apply_lamp_control(cls, setting, obj): rawval = setting.value.get_value() val = cls._LAMP_CONTROL.index(rawval) obj.lamp_control = val def apply_lamp_timer(cls, setting, obj): rawval = setting.value.get_value() val = cls._LAMP_TIMER.index(rawval) + 2 obj.lamp_timer = val def _get_display_settings(self): menu = RadioSettingGroup("display", "Display") display_settings = self._memobj.settings val = RadioSettingValueString( 0, 8, str(display_settings.power_on_msg).rstrip("\xFF")) rs = RadioSetting("display.power_on_msg", "Power on message", val) rs.set_apply_callback(self.apply_power_on_msg, display_settings) menu.append(rs) val = RadioSettingValueList( self._LCD_CONTRAST, self._LCD_CONTRAST[display_settings.contrast - 1]) rs = RadioSetting("display.contrast", "LCD Contrast", val) rs.set_apply_callback(self.apply_lcd_contrast, display_settings) menu.append(rs) val = RadioSettingValueList( self._LAMP_CONTROL, self._LAMP_CONTROL[display_settings.lamp_control]) rs = RadioSetting("display.lamp_control", "Lamp Control", val) rs.set_apply_callback(self.apply_lamp_control, display_settings) menu.append(rs) val = RadioSettingValueList( self._LAMP_TIMER, self._LAMP_TIMER[display_settings.lamp_timer - 2]) rs = RadioSetting("display.lamp_timer", "Lamp Timer", val) rs.set_apply_callback(self.apply_lamp_timer, display_settings) menu.append(rs) return menu def apply_battery_saver(cls, setting, obj): rawval = setting.value.get_value() val = cls._BATTERY_SAVER.index(rawval) obj.battery_saver = val def apply_APO(cls, setting, obj): rawval = setting.value.get_value() val = cls._APO.index(rawval) obj.APO = val def _get_battery_settings(self): menu = RadioSettingGroup("battery", "Battery") battery_settings = self._memobj.settings val = RadioSettingValueList( self._BATTERY_SAVER, self._BATTERY_SAVER[battery_settings.battery_saver]) rs = RadioSetting("battery.battery_saver", "Battery Saver", val) rs.set_apply_callback(self.apply_battery_saver, battery_settings) menu.append(rs) val = RadioSettingValueList( self._APO, self._APO[battery_settings.APO]) rs = RadioSetting("battery.APO", "Auto Power Off", val) rs.set_apply_callback(self.apply_APO, battery_settings) menu.append(rs) return menu def apply_balance(cls, setting, obj): rawval = setting.value.get_value() val = cls._AUDIO_BALANCE.index(rawval) obj.balance = val def apply_key_beep(cls, setting, obj): rawval = setting.value.get_value() val = cls._KEY_BEEP.index(rawval) obj.key_beep = val def _get_audio_settings(self): menu = RadioSettingGroup("audio", "Audio") audio_settings = self._memobj.settings val = RadioSettingValueList( self._AUDIO_BALANCE, self._AUDIO_BALANCE[audio_settings.balance]) rs = RadioSetting("audio.balance", "Balance", val) rs.set_apply_callback(self.apply_balance, audio_settings) menu.append(rs) val = RadioSettingValueList( self._KEY_BEEP, self._KEY_BEEP[audio_settings.key_beep]) rs = RadioSetting("audio.key_beep", "Key Beep", val) rs.set_apply_callback(self.apply_key_beep, audio_settings) menu.append(rs) return menu @staticmethod def _add_ff_pad(val, length): return val.ljust(length, "\xFF")[:length] @classmethod def _strip_ff_pads(cls, messages): result = [] for msg_text in messages: result.append(str(msg_text).rstrip("\xFF")) return result def load_mmap(self, filename): if filename.lower().endswith('.mc4'): with open(filename, 'rb') as f: f.seek(0x100) self._mmap = memmap.MemoryMapBytes(f.read()) LOG.info('Loaded MCP file at offset 0x100') self.process_mmap() else: chirp_common.CloneModeRadio.load_mmap(self, filename) def save_mmap(self, filename): if filename.lower().endswith('.mc4'): with open(filename, 'wb') as f: f.write(D72_FILE_HEADER) f.write(self._mmap.get_packed()) LOG.info('Wrote MCP file') else: chirp_common.CloneModeRadio.save_mmap(self, filename) @classmethod def match_model(cls, filedata, filename): if filename.endswith('.mc4'): return True else: return super(THD72Radio, cls).match_model(filedata, filename) chirp-20240224/chirp/drivers/ft60.py0000644000175000017500000006457614520142245015771 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging from chirp.drivers import yaesu_clone from chirp import chirp_common, memmap, bitwise, directory, errors from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) ACK = b"\x06" def _send(pipe, data): pipe.write(data) echo = pipe.read(len(data)) if echo != data: raise errors.RadioError("Error reading echo (Bad cable?)") def _download(radio): data = b"" for i in range(0, 10): chunk = radio.pipe.read(8) if len(chunk) == 8: data += chunk break elif chunk: raise Exception("Received invalid response from radio") time.sleep(1) LOG.info("Trying again...") if not data: raise Exception("Radio is not responding") _send(radio.pipe, ACK) for i in range(0, 448): chunk = radio.pipe.read(64) data += chunk _send(radio.pipe, ACK) if len(chunk) == 1 and i == 447: break elif len(chunk) != 64: raise Exception("Reading block %i was short (%i)" % (i, len(chunk))) if radio.status_fn: status = chirp_common.Status() status.cur = i * 64 status.max = radio.get_memsize() status.msg = "Cloning from radio" radio.status_fn(status) return memmap.MemoryMapBytes(data) def _upload(radio): _send(radio.pipe, radio.get_mmap()[0:8]) ack = radio.pipe.read(1) if ack != ACK: raise Exception("Radio did not respond") for i in range(0, 448): offset = 8 + (i * 64) _send(radio.pipe, radio.get_mmap()[offset:offset + 64]) ack = radio.pipe.read(1) if ack != ACK: raise Exception(_("Radio did not ack block %i") % i) if radio.status_fn: status = chirp_common.Status() status.cur = offset + 64 status.max = radio.get_memsize() status.msg = "Cloning to radio" radio.status_fn(status) def _decode_freq(freqraw): freq = int(freqraw) * 10000 if freq > 8000000000: freq = (freq - 8000000000) + 5000 if freq > 4000000000: freq -= 4000000000 for i in range(0, 3): freq += 2500 if chirp_common.required_step(freq) == 12.5: break return freq def _encode_freq(freq): freqraw = freq / 10000 flags = 0x00 if ((freq / 1000) % 10) >= 5: flags += 0x80 if chirp_common.is_fractional_step(freq): flags += 0x40 return freqraw, flags def _decode_name(mem): name = "" for i in mem: if i == 0xFF: break try: name += CHARSET[i] except IndexError: LOG.error("Unknown char index: %i " % (i)) return name def _encode_name(mem): name = [None] * 6 for i in range(0, 6): try: name[i] = CHARSET.index(mem[i]) except IndexError: name[i] = CHARSET.index(" ") return name MEM_FORMAT = """ #seekto 0x0024; struct { u8 apo; u8 x25:3, tot:5; u8 x26; u8 x27; u8 x28:4, rf_sql:4; u8 x29:4, int_cd:4; u8 x2A:4, int_mr:4; u8 x2B:5, lock:3; u8 x2C:5, dt_dly:3; u8 x2D:7, dt_spd:1; u8 ar_bep; u8 x2F:6, lamp:2; u8 x30:5, bell:3; u8 x31:5, rxsave:3; u8 x32; u8 x33; u8 x34; u8 x35; u8 x36; u8 x37; u8 wx_alt:1, x38_1:3, ar_int:1, x38_5:3; u8 x39:3, ars:1, vfo_bnd:1, dcs_nr:2, ssrch:1; u8 pri_rvt:1, x3A_1:1, beep_sc:1, edg_bep:1, beep_key:1, inet:2, x3A_7:1; u8 x3B_0:5, scn_md:1, x3B_6:2; u8 x3C_0:2, rev_hm:1, mt_cl:1, resume:2, txsave:1, pag_abk:1; u8 x3D_0:1, scn_lmp:1, x3D_2:1, bsy_led:1, x3D_4:1, tx_led:1, x3D_6:2; u8 x3E_0:2, bclo:1, x3E_3:5; } settings; #seekto 0x09E; ul16 mbs; #seekto 0x0C8; struct { u8 memory[16]; } dtmf[9]; struct mem { u8 used:1, unknown1:1, isnarrow:1, isam:1, duplex:4; bbcd freq[3]; u8 unknown2:1, step:3, unknown2_1:1, tmode:3; bbcd tx_freq[3]; u8 power:2, tone:6; u8 unknown4:1, dtcs:7; u8 unknown5; u16 unknown5_1:1, offset:15; u8 unknown6[3]; }; #seekto 0x0248; struct mem memory[1000]; #seekto 0x40c8; struct mem pms[100]; #seekto 0x6EC8; // skips:2 for Memory M in [1, 1000] is in flags[(M-1)/4].skip((M-1)%4). // Interpret with SKIPS[]. // PMS memories L0 - U50 aka memory 1001 - 1100 don't have skip flags. struct { u8 skip3:2, skip2:2, skip1:2, skip0:2; } flags[250]; #seekto 0x4708; struct { u8 name[6]; u8 use_name:1, unknown1:7; u8 valid:1, unknown2:7; } names[1000]; #seekto 0x69C8; struct { bbcd memory[128]; } banks[10]; #seekto 0x6FC8; u8 checksum; """ DUPLEX = ["", "", "-", "+", "split", "off"] TMODES = ["", "Tone", "TSQL", "TSQL-R", "DTCS", "DTCS->", "Tone->DTCS", "DTCS->Tone"] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.0), chirp_common.PowerLevel("Mid", watts=2.0), chirp_common.PowerLevel("Low", watts=0.5)] STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0] SKIPS = ["", "S", "P"] DTMF_CHARS = list("0123456789ABCD*#") CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ !`o$%&'()*+,-./|;/=>?@[u]^_" SPECIALS = ["%s%d" % (c, i + 1) for i in range(0, 50) for c in ('L', 'U')] class FT60BankModel(chirp_common.BankModel): def get_num_mappings(self): return 10 def get_mappings(self): banks = [] for i in range(0, self.get_num_mappings()): bank = chirp_common.Bank(self, "%i" % (i + 1), "Bank %i" % (i + 1)) bank.index = i banks.append(bank) return banks def add_memory_to_mapping(self, memory, bank): number = (memory.number - 1) / 8 mask = 1 << ((memory.number - 1) & 7) self._radio._memobj.banks[bank.index].memory[number].set_bits(mask) def remove_memory_from_mapping(self, memory, bank): number = (memory.number - 1) / 8 mask = 1 << ((memory.number - 1) & 7) m = self._radio._memobj.banks[bank.index].memory[number] if m.get_bits(mask) != mask: raise Exception("Memory %i is not in bank %s." % (memory.number, bank)) self._radio._memobj.banks[bank.index].memory[number].clr_bits(mask) def get_mapping_memories(self, bank): memories = [] for i in range(*self._radio.get_features().memory_bounds): number = (i - 1) / 8 mask = 1 << ((i - 1) & 7) m = self._radio._memobj.banks[bank.index].memory[number] if m.get_bits(mask) == mask: memories.append(self._radio.get_memory(i)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): number = (memory.number - 1) / 8 mask = 1 << ((memory.number - 1) & 7) m = self._radio._memobj.banks[bank.index].memory[number] if m.get_bits(mask) == mask: banks.append(bank) return banks @directory.register class FT60Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu FT-60""" BAUD_RATE = 9600 VENDOR = "Yaesu" MODEL = "FT-60" _model = b"AH017" _memsize = 28617 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [MONI] switch while turning the\n" " radio on.\n" "4. Rotate the DIAL job to select \"F8 CLONE\".\n" "5. Press the [F/W] key momentarily.\n" "6. After clicking OK, hold the [PTT] switch\n" " for one second to send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [MONI] switch while turning the\n" " radio on.\n" "4. Rotate the DIAL job to select \"F8 CLONE\".\n" "5. Press the [F/W] key momentarily.\n" "6. Press the [MONI] switch (\"--RX--\" will appear on the" " LCD).\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 1000) rf.valid_duplexes = DUPLEX[1:] rf.valid_tmodes = [x for x in TMODES if '->' not in x] + ['Cross'] rf.valid_cross_modes = ['Tone->DTCS', 'DTCS->Tone', 'DTCS->'] rf.valid_power_levels = POWER_LEVELS rf.valid_tuning_steps = STEPS rf.valid_skips = SKIPS rf.valid_special_chans = SPECIALS rf.valid_characters = CHARSET rf.valid_name_length = 6 rf.valid_modes = ["FM", "NFM", "AM"] rf.valid_bands = [(108000000, 520000000), (700000000, 999990000)] rf.can_odd_split = True rf.has_ctone = False rf.has_bank = True rf.has_settings = True rf.has_dtcs_polarity = False return rf def get_bank_model(self): return FT60BankModel(self) def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x6FC7)] def sync_in(self): try: self._mmap = _download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() self.check_checksums() def sync_out(self): self.update_checksums() try: _upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_settings(self): _settings = self._memobj.settings repeater = RadioSettingGroup("repeater", "Repeater Settings") ctcss = RadioSettingGroup("ctcss", "CTCSS/DCS/DTMF Settings") arts = RadioSettingGroup("arts", "ARTS Settings") scan = RadioSettingGroup("scan", "Scan Settings") power = RadioSettingGroup("power", "Power Saver Settings") wires = RadioSettingGroup("wires", "WiRES(tm) Settings") eai = RadioSettingGroup("eai", "EAI/EPCS Settings") switch = RadioSettingGroup("switch", "Switch/Knob Settings") misc = RadioSettingGroup("misc", "Miscellaneous Settings") mbls = RadioSettingGroup("banks", "Memory Bank Link Scan") setmode = RadioSettings(repeater, ctcss, arts, scan, power, wires, eai, switch, misc, mbls) # APO opts = ["OFF"] + ["%0.1f" % (x * 0.5) for x in range(1, 24 + 1)] misc.append( RadioSetting( "apo", "Automatic Power Off", RadioSettingValueList(opts, opts[_settings.apo]))) # AR.BEP opts = ["OFF", "INRANG", "ALWAYS"] arts.append( RadioSetting( "ar_bep", "ARTS Beep", RadioSettingValueList(opts, opts[_settings.ar_bep]))) # AR.INT opts = ["25 SEC", "15 SEC"] arts.append( RadioSetting( "ar_int", "ARTS Polling Interval", RadioSettingValueList(opts, opts[_settings.ar_int]))) # ARS opts = ["OFF", "ON"] repeater.append( RadioSetting( "ars", "Automatic Repeater Shift", RadioSettingValueList(opts, opts[_settings.ars]))) # BCLO opts = ["OFF", "ON"] misc.append(RadioSetting( "bclo", "Busy Channel Lock-Out", RadioSettingValueList(opts, opts[_settings.bclo]))) # BEEP opts = ["OFF", "KEY", "KEY+SC"] rs = RadioSetting( "beep_key", "Enable the Beeper", RadioSettingValueList( opts, opts[_settings.beep_key + _settings.beep_sc])) def apply_beep(s, obj): setattr(obj, "beep_key", (int(s.value) & 1) or ((int(s.value) >> 1) & 1)) setattr(obj, "beep_sc", (int(s.value) >> 1) & 1) rs.set_apply_callback(apply_beep, self._memobj.settings) switch.append(rs) # BELL opts = ["OFF", "1T", "3T", "5T", "8T", "CONT"] ctcss.append(RadioSetting("bell", "Bell Repetitions", RadioSettingValueList(opts, opts[ _settings.bell]))) # BSY.LED opts = ["ON", "OFF"] misc.append(RadioSetting("bsy_led", "Busy LED", RadioSettingValueList(opts, opts[ _settings.bsy_led]))) # DCS.NR opts = ["TR/X N", "RX R", "TX R", "T/RX R"] ctcss.append(RadioSetting("dcs_nr", "\"Inverted\" DCS Code Decoding", RadioSettingValueList(opts, opts[ _settings.dcs_nr]))) # DT.DLY opts = ["50 ms", "100 ms", "250 ms", "450 ms", "750 ms", "1000 ms"] ctcss.append(RadioSetting("dt_dly", "DTMF Autodialer Delay Time", RadioSettingValueList(opts, opts[ _settings.dt_dly]))) # DT.SPD opts = ["50 ms", "100 ms"] ctcss.append(RadioSetting("dt_spd", "DTMF Autodialer Sending Speed", RadioSettingValueList(opts, opts[ _settings.dt_spd]))) # DT.WRT for i in range(0, 9): dtmf = self._memobj.dtmf[i] str = "" for c in dtmf.memory: if c == 0xFF: break if c < len(DTMF_CHARS): str += DTMF_CHARS[c] val = RadioSettingValueString(0, 16, str, False) val.set_charset(DTMF_CHARS + list("abcd")) rs = RadioSetting("dtmf_%i" % i, "DTMF Autodialer Memory %i" % (i + 1), val) def apply_dtmf(s, obj): str = s.value.get_value().upper().rstrip() val = [DTMF_CHARS.index(x) for x in str] for x in range(len(val), 16): val.append(0xFF) obj.memory = val rs.set_apply_callback(apply_dtmf, dtmf) ctcss.append(rs) # EDG.BEP opts = ["OFF", "ON"] misc.append(RadioSetting("edg_bep", "Band Edge Beeper", RadioSettingValueList(opts, opts[ _settings.edg_bep]))) # I.NET opts = ["OFF", "COD", "MEM"] rs = RadioSetting("inet", "Internet Link Connection", RadioSettingValueList( opts, opts[_settings.inet - 1])) def apply_inet(s, obj): setattr(obj, s.get_name(), int(s.value) + 1) rs.set_apply_callback(apply_inet, self._memobj.settings) wires.append(rs) # INT.CD opts = ["CODE 0", "CODE 1", "CODE 2", "CODE 3", "CODE 4", "CODE 5", "CODE 6", "CODE 7", "CODE 8", "CODE 9", "CODE A", "CODE B", "CODE C", "CODE D", "CODE E", "CODE F"] wires.append(RadioSetting("int_cd", "Access Number for WiRES(TM)", RadioSettingValueList(opts, opts[ _settings.int_cd]))) # INT.MR opts = ["d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9"] wires.append(RadioSetting( "int_mr", "Access Number (DTMF) for Non-WiRES(TM)", RadioSettingValueList(opts, opts[_settings.int_mr]))) # LAMP opts = ["KEY", "5SEC", "TOGGLE"] switch.append(RadioSetting("lamp", "Lamp Mode", RadioSettingValueList(opts, opts[ _settings.lamp]))) # LOCK opts = ["LK KEY", "LKDIAL", "LK K+D", "LK PTT", "LK P+K", "LK P+D", "LK ALL"] rs = RadioSetting("lock", "Control Locking", RadioSettingValueList( opts, opts[_settings.lock - 1])) def apply_lock(s, obj): setattr(obj, s.get_name(), int(s.value) + 1) rs.set_apply_callback(apply_lock, self._memobj.settings) switch.append(rs) # M/T-CL opts = ["MONI", "T-CALL"] switch.append(RadioSetting("mt_cl", "MONI Switch Function", RadioSettingValueList(opts, opts[ _settings.mt_cl]))) # PAG.ABK opts = ["OFF", "ON"] eai.append(RadioSetting("pag_abk", "Paging Answer Back", RadioSettingValueList(opts, opts[ _settings.pag_abk]))) # RESUME opts = ["TIME", "HOLD", "BUSY"] scan.append(RadioSetting("resume", "Scan Resume Mode", RadioSettingValueList(opts, opts[ _settings.resume]))) # REV/HM opts = ["REV", "HOME"] switch.append(RadioSetting("rev_hm", "HM/RV Key Function", RadioSettingValueList(opts, opts[ _settings.rev_hm]))) # RF.SQL opts = ["OFF", "S-1", "S-2", "S-3", "S-4", "S-5", "S-6", "S-7", "S-8", "S-FULL"] misc.append(RadioSetting("rf_sql", "RF Squelch Threshold", RadioSettingValueList(opts, opts[ _settings.rf_sql]))) # PRI.RVT opts = ["OFF", "ON"] scan.append(RadioSetting("pri_rvt", "Priority Revert", RadioSettingValueList(opts, opts[ _settings.pri_rvt]))) # RXSAVE opts = ["OFF", "200 ms", "300 ms", "500 ms", "1 s", "2 s"] power.append(RadioSetting( "rxsave", "Receive Mode Battery Savery Interval", RadioSettingValueList(opts, opts[_settings.rxsave]))) # S.SRCH opts = ["SINGLE", "CONT"] misc.append(RadioSetting("ssrch", "Smart Search Sweep Mode", RadioSettingValueList(opts, opts[ _settings.ssrch]))) # SCN.MD opts = ["MEM", "ONLY"] scan.append(RadioSetting( "scn_md", "Memory Scan Channel Selection Mode", RadioSettingValueList(opts, opts[_settings.scn_md]))) # SCN.LMP opts = ["OFF", "ON"] scan.append(RadioSetting("scn_lmp", "Scan Lamp", RadioSettingValueList(opts, opts[ _settings.scn_lmp]))) # TOT opts = ["OFF"] + ["%dMIN" % (x) for x in range(1, 30 + 1)] misc.append(RadioSetting("tot", "Timeout Timer", RadioSettingValueList(opts, opts[ _settings.tot]))) # TX.LED opts = ["ON", "OFF"] misc.append(RadioSetting("tx_led", "TX LED", RadioSettingValueList(opts, opts[ _settings.tx_led]))) # TXSAVE opts = ["OFF", "ON"] power.append(RadioSetting("txsave", "Transmitter Battery Saver", RadioSettingValueList(opts, opts[ _settings.txsave]))) # VFO.BND opts = ["BAND", "ALL"] misc.append(RadioSetting("vfo_bnd", "VFO Band Edge Limiting", RadioSettingValueList(opts, opts[ _settings.vfo_bnd]))) # WX.ALT opts = ["OFF", "ON"] scan.append(RadioSetting("wx_alt", "Weather Alert Scan", RadioSettingValueList(opts, opts[ _settings.wx_alt]))) # MBS for i in range(0, 10): opts = ["OFF", "ON"] mbs = (self._memobj.mbs >> i) & 1 rs = RadioSetting("mbs%i" % i, "Bank %s Scan" % (i + 1), RadioSettingValueList(opts, opts[mbs])) def apply_mbs(s, index): if int(s.value): self._memobj.mbs |= (1 << index) else: self._memobj.mbs &= ~(1 << index) rs.set_apply_callback(apply_mbs, i) mbls.append(rs) return setmode def set_settings(self, uisettings): _settings = self._memobj.settings for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: name = element.get_name() value = element.value if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: obj = getattr(_settings, name) setattr(_settings, name, value) LOG.debug("Setting %s: %s" % (name, value)) except Exception: LOG.debug(element.get_name()) raise def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) + \ repr(self._memobj.flags[(number - 1) / 4]) + \ repr(self._memobj.names[number - 1]) def get_memory(self, number): mem = chirp_common.Memory() if isinstance(number, str): # pms channel mem.number = 1001 + SPECIALS.index(number) mem.extd_number = number mem.immutable = ["number", "extd_number", "name", "skip"] _mem = self._memobj.pms[mem.number - 1001] _nam = _skp = None elif number > 1000: # pms channel mem.number = number mem.extd_number = SPECIALS[number - 1001] mem.immutable = ["number", "extd_number", "name", "skip"] _mem = self._memobj.pms[mem.number - 1001] _nam = _skp = None else: mem.number = number _mem = self._memobj.memory[mem.number - 1] _nam = self._memobj.names[mem.number - 1] _skp = self._memobj.flags[(mem.number - 1) / 4] if not _mem.used: mem.empty = True return mem mem.freq = _decode_freq(_mem.freq) mem.offset = int(_mem.offset) * 50000 mem.duplex = DUPLEX[_mem.duplex] if mem.duplex == "split": if int(_mem.tx_freq) == 0: mem.duplex = "off" else: mem.offset = _decode_freq(_mem.tx_freq) tmode = TMODES[_mem.tmode] if '->' in tmode: mem.tmode = 'Cross' mem.cross_mode = tmode else: mem.tmode = tmode mem.rtone = chirp_common.TONES[_mem.tone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.power = POWER_LEVELS[_mem.power] mem.mode = _mem.isam and "AM" or _mem.isnarrow and "NFM" or "FM" mem.tuning_step = STEPS[_mem.step] if _skp is not None: skip = _skp["skip%i" % ((mem.number - 1) % 4)] mem.skip = SKIPS[skip] if _nam is not None: if _nam.use_name and _nam.valid: mem.name = _decode_name(_nam.name).rstrip() return mem def set_memory(self, mem): if mem.number > 1000: # pms channel _mem = self._memobj.pms[mem.number - 1001] _nam = _skp = None else: _mem = self._memobj.memory[mem.number - 1] _nam = self._memobj.names[mem.number - 1] _skp = self._memobj.flags[(mem.number - 1) / 4] assert (_mem) if mem.empty: _mem.used = False return if not _mem.used: _mem.set_raw("\x00" * 16) _mem.used = 1 _mem.freq, flags = _encode_freq(mem.freq) _mem.freq[0].set_bits(flags) if mem.duplex == "split": _mem.tx_freq, flags = _encode_freq(mem.offset) _mem.tx_freq[0].set_bits(flags) _mem.offset = 0 elif mem.duplex == "off": _mem.tx_freq = 0 _mem.offset = 0 else: _mem.tx_freq = 0 _mem.offset = mem.offset / 50000 _mem.duplex = DUPLEX.index(mem.duplex) if mem.tmode == 'Cross': _mem.tmode = TMODES.index(mem.cross_mode) else: _mem.tmode = TMODES.index(mem.tmode) _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.dtcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.power = mem.power and POWER_LEVELS.index(mem.power) or 0 _mem.isnarrow = mem.mode == "NFM" _mem.isam = mem.mode == "AM" _mem.step = STEPS.index(mem.tuning_step) if _skp is not None: _skp["skip%i" % ((mem.number - 1) % 4)] = SKIPS.index(mem.skip) if _nam is not None: _nam.name = _encode_name(mem.name) _nam.use_name = mem.name.strip() and True or False _nam.valid = _nam.use_name chirp-20240224/chirp/drivers/hg_uv98.py0000644000175000017500000006324614565075506016512 0ustar hibbyhibby# -*- coding: utf-8 -*- # Copyright 2022 Masen Furer # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # Lanchonlh HG-UV98 driver written by # Masen Furer # With assistance from # KG7KMV and BartХ‚omiej ZieliХ„ski # Based on the implementation of Kenwood TK-8102 import logging import struct from chirp import chirp_common, directory, memmap, errors, util from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting from chirp.settings import RadioSettingValueBoolean, RadioSettingValueList from chirp.settings import RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { lbcd rx_freq[4]; lbcd tx_freq[4]; ul16 rx_tone; ul16 tx_tone; u8 unknown1:6, wide:1, highpower:1; u8 unknown2:5, bcl:1, scan:1, unknown3:1; u8 unknown4[2]; } memory[130]; #seekto 0x0a00; struct { u8 abr; // 0x0a00 u8 save; u8 ch_a_step; u8 ch_b_step; u8 vox_grd; u8 ch_a_sql; u8 ch_b_sql; u8 roger; u8 ch_a_v_m; u8 ch_b_v_m; u8 ch_a_ch_mdf; u8 ch_b_ch_mdf; u8 tdr; u8 unknown5[3]; u8 unknown6[5]; // 0x0a10 u8 english; u8 beep; u8 voice; u8 night_mode; u8 abr_lv; // backlight level u8 tot; u8 toa; u8 vox_dly; u8 sc_rev; u8 lockmode; u8 autolock; u8 unknown7; // 0x0a20 u8 pf1_short; u8 pf1_long; u8 pf2_short; u8 pf2_long; u8 top_short; u8 top_long; u8 rpt_rct; u8 sc_qt; u8 pri_ch; u8 pri_scn; u8 unknown8; u8 aprs_rx_band; u8 ch_a_mute; u8 ch_b_mute; u8 unknown9[7]; // 0x0a30 u8 tx_priority; u8 aprs_rx_popup; u8 aprs_rx_tone; u8 aprs_tx_tone; u8 unknown10; u8 auto_lock_dly; u8 menu_dly; u8 beacon_exit_dly; u8 unknown11; u8 unknown12[2]; // 0x0a40 u8 ch_a_mem_ch; u8 ch_b_mem_ch; u8 unknown13[12]; } settings; #seekto 0x1000; struct { char name[11]; u8 unknown[5]; } name[128]; struct { char callsign[9]; u8 null; } aprs; #seekto 0x1f80; struct { ul32 unknown[8]; } unknown_settings; """ BOUNDS = [(136000000, 174000000), (400000000, 500000000)] OFFSETS = [600000, 5000000] MAX_CHANNELS = 128 MAX_NAME = 8 NAME_FIELD_SIZE = 11 CHUNK_SIZE = 64 MAX_ADDR = 0x2000 POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1), chirp_common.PowerLevel("High", watts=5)] MODES = ["FM", "NFM"] SPECIAL_CHANNELS = ['VFO-A', 'VFO-B'] # Settings maps ABR_LIST = [str(v) for v in range(0, 151, 5)] STEP_LIST = ["5.0", "6.25", "10.0", "12.5", "25.0", "50.0", "100.0"] VOX_LIST = ["OFF", "1", "2", "3", "4", "5", "6", "7", "8", "9"] SQL_LIST = [str(v) for v in range(0, 10)] ROGER_LIST = ["OFF", "BEGIN", "END", "BOTH"] MDF_LIST = ["NUM+FREQ", "NUMBER", "NAME"] VM_LIST = ["VFO", "MEMORY"] LANG_LIST = ["CHINESE", "ENGLISH"] ABR_LV_LIST = [str(v) for v in range(1, 11)] TOT_LIST = [str(v) for v in range(0, 601, 15)] TOA_LIST = ["OFF"] + ["{} S".format(v) for v in range(1, 11)] VOX_DLY_LIST = [str(v) for v in range(1, 11)] SC_REV_LIST = ["TIME", "BUSY", "HOLD"] LOCKMODE_LIST = ["KEY", "KEY+DIAL", "KEY+DIAL+PTT"] AUTOLOCK_LIST = ["AUTO", "Manual"] PF1_LIST = ["BACK LIGHT", "SCAN", "SQUELCH", "TORCH", "BAND A/B"] PF2_LIST = ["BEACON", "LIST", "TORCH", "BACK LIGHT"] TOP_LIST = ["ALERT", "REMOTE ALERT", "TORCH", "TXP", "CH MDF", "OFF_NET_KEY"] SC_QT_LIST = ["Decode", "Encode", "Decode+Encode"] APRS_RX_LIST = ["OFF", "BAND A", "BAND B"] TX_PRIORITY_LIST = ["VOICE", "APRS"] AUTOLOCK_DLY_LIST = ["{} S".format(v) for v in range(5, 31)] BEACON_EXIT_DLY_LIST = MENU_DLY_LIST = AUTOLOCK_DLY_LIST def make_frame(cmd, addr, length, data=b""): if not isinstance(data, bytes): data = data.decode("ascii") return struct.pack(">BHB", ord(cmd), addr, length) + data def send(radio, frame): LOG.debug("%04i P>R: %s" % (len(frame), util.hexprint(frame))) radio.pipe.write(frame) def recv(radio, readdata=True): hdr = radio.pipe.read(4) cmd, addr, length = struct.unpack(">BHB", hdr) if readdata: data = radio.pipe.read(length) LOG.debug(" PTone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_power_levels = POWER_LEVELS rf.valid_skips = ["", "S"] rf.valid_bands = [(136000000, 174000000), (400000000, 500000000)] rf.valid_name_length = 8 rf.valid_special_chans = SPECIAL_CHANNELS rf.memory_bounds = (1, self._upper) return rf def sync_in(self): try: self._mmap = do_download(self) except errors.RadioError: self.pipe.write(b"\x45") raise except Exception as e: raise errors.RadioError("Failed to download from radio: %s" % e) self.process_mmap() def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_out(self): try: do_upload(self) except errors.RadioError: self.pipe.write(b"\x45") raise except Exception as e: raise errors.RadioError("Failed to upload to radio: %s" % e) def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x8000) and "R" or "N" return code, pol if _mem.tx_tone != 0xFFFF and _mem.tx_tone > 0x2800: tcode, tpol = _get_dcs(_mem.tx_tone) mem.dtcs = tcode txmode = "DTCS" elif _mem.tx_tone != 0xFFFF: mem.rtone = _mem.tx_tone / 10.0 txmode = "Tone" else: txmode = "" if _mem.rx_tone != 0xFFFF and _mem.rx_tone > 0x2800: rcode, rpol = _get_dcs(_mem.rx_tone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rx_tone != 0xFFFF: mem.ctone = _mem.rx_tone / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) if mem.tmode == "DTCS": mem.dtcs_polarity = "%s%s" % (tpol, rpol) def get_memory(self, number): mem = chirp_common.Memory() if isinstance(number, str): mem.number = MAX_CHANNELS + SPECIAL_CHANNELS.index(number) + 1 mem.extd_number = number elif number > MAX_CHANNELS: mem.number = number else: mem.number = number _name = self._memobj.name[mem.number - 1] _mem = self._memobj.memory[mem.number - 1] if mem.number > MAX_CHANNELS: mem.immutable = ['name'] else: mem.name, _, _ = _name.name.get_raw().partition(b"\xFF") mem.name = mem.name.decode('ascii').rstrip() if _mem.get_raw()[:4] == b"\xFF\xFF\xFF\xFF": mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 offset = (int(_mem.tx_freq) * 10) - mem.freq if offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 self._get_tone(_mem, mem) mem.power = POWER_LEVELS[_mem.highpower] mem.mode = MODES[_mem.wide] mem.skip = not _mem.scan and "S" or "" mem.extra = RadioSettingGroup("all", "All Settings") bcl = RadioSetting("bcl", "Busy Channel Lockout", RadioSettingValueBoolean(bool(_mem.bcl))) mem.extra.append(bcl) return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x2800 if pol == "R": val += 0xA000 return val rx_mode = tx_mode = None rx_tone = tx_tone = 0xFFFF if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None tx_tone = int(mem.rtone * 10) elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rx_tone = tx_tone = int(mem.ctone * 10) elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": tx_tone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": tx_tone = int(mem.rtone * 10) if rx_mode == "DTCS": rx_tone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rx_tone = int(mem.ctone * 10) _mem.rx_tone = rx_tone _mem.tx_tone = tx_tone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.tx_tone, rx_mode, _mem.rx_tone)) def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw(b"\xFF" * 16) return if mem.number < 129: _name = self._memobj.name[mem.number - 1] _namelength = self.get_features().valid_name_length for i in range(NAME_FIELD_SIZE): try: _name.name[i] = mem.name[i] except IndexError: _name.name[i] = "\xFF" # clear reserved fields _mem.unknown1 = 0xFF _mem.unknown2 = 0xFF _mem.unknown3 = 0xFF _mem.unknown4 = (0xFF, 0xFF) _mem.rx_freq = mem.freq / 10 mem_offset = mem.offset or offset_for(mem.freq) if mem.duplex == "+": _mem.tx_freq = (mem.freq + mem_offset) / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem_offset) / 10 else: _mem.tx_freq = mem.freq / 10 self._set_tone(mem, _mem) _mem.highpower = mem.power == POWER_LEVELS[1] _mem.wide = mem.mode == "NFM" _mem.scan = mem.skip != "S" for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _mem = self._memobj _settings = _mem.settings basic = RadioSettingGroup("basic", "Basic") display = RadioSettingGroup("display", "Display") scan = RadioSettingGroup("scan", "Scan") buttons = RadioSettingGroup("buttons", "Buttons") vfo = RadioSettingGroup("vfo", "VFO") advanced = RadioSettingGroup("advanced", "Advanced") aprs = RadioSettingGroup("aprs", "APRS") top = RadioSettings(basic, display, scan, buttons, vfo, advanced, aprs) basic.append( RadioSetting("save", "Power Save", RadioSettingValueBoolean(_settings.save))) basic.append( RadioSetting("roger", "Roger Beep", RadioSettingValueList(ROGER_LIST, ROGER_LIST[_settings.roger]))) basic.append( RadioSetting("beep", "System Beep", RadioSettingValueBoolean(_settings.beep))) basic.append( RadioSetting("tot", "Timeout Timer (sec)", RadioSettingValueList(TOT_LIST, TOT_LIST[_settings.tot]))) basic.append( RadioSetting("toa", "Timeout Timer Alarm", RadioSettingValueList(TOA_LIST, TOA_LIST[_settings.toa]))) basic.append( RadioSetting("lockmode", "Lock Mode", RadioSettingValueList( LOCKMODE_LIST, LOCKMODE_LIST[_settings.lockmode]))) basic.append( RadioSetting("autolock", "Auto Lock", RadioSettingValueList( AUTOLOCK_LIST, AUTOLOCK_LIST[_settings.autolock]))) basic.append( RadioSetting("auto_lock_dly", "Auto Lock Delay", RadioSettingValueList( AUTOLOCK_DLY_LIST, AUTOLOCK_DLY_LIST[_settings.auto_lock_dly]))) display.append( RadioSetting("abr", "Screen Save", RadioSettingValueList(ABR_LIST, ABR_LIST[_settings.abr]))) display.append( RadioSetting("abr_lv", "Back Light Brightness", RadioSettingValueList(ABR_LV_LIST, ABR_LV_LIST[_settings.abr_lv]))) display.append( RadioSetting("night_mode", "Night Mode (Light on Dark)", RadioSettingValueBoolean(_settings.night_mode))) display.append( RadioSetting("menu_dly", "Menu Delay", RadioSettingValueList( MENU_DLY_LIST, MENU_DLY_LIST[_settings.menu_dly]))) display.append( RadioSetting("english", "Language", RadioSettingValueList(LANG_LIST, LANG_LIST[_settings.english]))) scan.append( RadioSetting("pri_scn", "Priority Scan", RadioSettingValueBoolean(_settings.pri_scn))) scan.append( RadioSetting("pri_ch", "Priority Channel", RadioSettingValueChannel(self, _settings.pri_ch))) scan.append( RadioSetting("sc_rev", "Scan Resume", RadioSettingValueList(SC_REV_LIST, SC_REV_LIST[_settings.sc_rev]))) scan.append( RadioSetting("sc_qt", "Code Save", RadioSettingValueList(SC_QT_LIST, SC_QT_LIST[_settings.sc_qt]))) buttons.append( RadioSetting("pf1_short", "PF1 (Side, Upper) Button Short Press", RadioSettingValueList(PF1_LIST, PF1_LIST[_settings.pf1_short]))) buttons.append( RadioSetting("pf1_long", "PF1 (Side, Upper) Button Long Press", RadioSettingValueList(PF1_LIST, PF1_LIST[_settings.pf1_long]))) buttons.append( RadioSetting("pf2_short", "PF2 (Side, Lower) Button Short Press", RadioSettingValueList(PF2_LIST, PF2_LIST[_settings.pf2_short]))) buttons.append( RadioSetting("pf2_long", "PF2 (Side, Lower) Button Long Press", RadioSettingValueList(PF2_LIST, PF2_LIST[_settings.pf2_long]))) buttons.append( RadioSetting("top_short", "Top Button Short Press", RadioSettingValueList(TOP_LIST, TOP_LIST[_settings.top_short]))) buttons.append( RadioSetting("top_long", "Top Button Long Press", RadioSettingValueList(TOP_LIST, TOP_LIST[_settings.top_long]))) vfo.append( RadioSetting("tdr", "VFO B Enabled", RadioSettingValueBoolean(_settings.tdr))) vfo.append( RadioSetting("ch_a_step", "VFO Frequency Step (A)", RadioSettingValueList( STEP_LIST, STEP_LIST[_settings.ch_a_step]))) vfo.append( RadioSetting("ch_b_step", "VFO Frequency Step (B)", RadioSettingValueList( STEP_LIST, STEP_LIST[_settings.ch_b_step]))) vfo.append( RadioSetting("ch_a_sql", "Squelch (A)", RadioSettingValueList(SQL_LIST, SQL_LIST[_settings.ch_a_sql]))) vfo.append( RadioSetting("ch_b_sql", "Squelch (B)", RadioSettingValueList(SQL_LIST, SQL_LIST[_settings.ch_b_sql]))) vfo.append( RadioSetting("ch_a_mem_ch", "Memory Channel (A)", RadioSettingValueChannel(self, _settings.ch_a_mem_ch))) vfo.append( RadioSetting("ch_b_mem_ch", "Memory Channel (B)", RadioSettingValueChannel(self, _settings.ch_b_mem_ch))) vfo.append( RadioSetting("ch_a_ch_mdf", "Memory Display Format (A)", RadioSettingValueList( MDF_LIST, MDF_LIST[_settings.ch_a_ch_mdf]))) vfo.append( RadioSetting("ch_b_ch_mdf", "Memory Display Format (B)", RadioSettingValueList( MDF_LIST, MDF_LIST[_settings.ch_b_ch_mdf]))) vfo.append( RadioSetting("ch_a_v_m", "VFO/MEM (A)", RadioSettingValueList( VM_LIST, VM_LIST[_settings.ch_a_v_m]))) vfo.append( RadioSetting("ch_b_v_m", "VFO/MEM (B)", RadioSettingValueList( VM_LIST, VM_LIST[_settings.ch_b_v_m]))) advanced.append( RadioSetting("vox_grd", "VOX Sensitivity", RadioSettingValueList( VOX_LIST, VOX_LIST[_settings.vox_grd]))) advanced.append( RadioSetting("vox_dly", "VOX Delay", RadioSettingValueList( VOX_DLY_LIST, VOX_DLY_LIST[_settings.vox_dly]))) advanced.append( RadioSetting("voice", "Voice Assist", RadioSettingValueBoolean(_settings.voice))) advanced.append( RadioSetting("rpt_rct", "RPT Roger", RadioSettingValueBoolean(_settings.rpt_rct))) aprs.append( RadioSetting("aprs_rx_band", "RX Band", RadioSettingValueList( APRS_RX_LIST, APRS_RX_LIST[_settings.aprs_rx_band]))) aprs.append( RadioSetting("ch_a_mute", "Band A Mute", RadioSettingValueBoolean(_settings.ch_a_mute))) aprs.append( RadioSetting("ch_b_mute", "Band B Mute", RadioSettingValueBoolean(_settings.ch_b_mute))) aprs.append( RadioSetting("tx_priority", "TX Priority", RadioSettingValueList( TX_PRIORITY_LIST, TX_PRIORITY_LIST[_settings.tx_priority]))) aprs.append( RadioSetting("aprs_rx_popup", "APRS Popup", RadioSettingValueBoolean(_settings.aprs_rx_popup))) aprs.append( RadioSetting("aprs_rx_tone", "RX Tone", RadioSettingValueBoolean(_settings.aprs_rx_tone))) aprs.append( RadioSetting("aprs_tx_tone", "TX Tone", RadioSettingValueBoolean(_settings.aprs_tx_tone))) aprs.append( RadioSetting("beacon_exit_dly", "Beacon Message Delay", RadioSettingValueList( BEACON_EXIT_DLY_LIST, BEACON_EXIT_DLY_LIST[_settings.beacon_exit_dly]))) return top def set_settings(self, settings): _mem = self._memobj _settings = _mem.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue name = element.get_name() value = element.value if hasattr(_settings, name): setattr(_settings, name, value) chirp-20240224/chirp/drivers/btech.py0000644000175000017500000055324214563632215016300 0ustar hibbyhibby# Copyright 2016-2023: # * Pavel Milanes CO7WT, # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import struct import logging from time import sleep from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings, InvalidValueError LOG = logging.getLogger(__name__) # A note about the memory in these radios # # The real memory of these radios extends to 0x4000 # On read the factory software only uses up to 0x3200 # On write it just uploads the contents up to 0x3100 # # The mem beyond 0x3200 holds the ID data MEM_SIZE = 0x4000 BLOCK_SIZE = 0x40 TX_BLOCK_SIZE = 0x10 ACK_CMD = 0x06 MODES = ["FM", "NFM"] SKIP_VALUES = ["S", ""] TONES = chirp_common.TONES DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) # lists related to "extra" settings PTTID_LIST = ["OFF", "BOT", "EOT", "BOTH"] PTTIDCODE_LIST = ["%s" % x for x in range(1, 16)] OPTSIG_LIST = ["OFF", "DTMF", "2TONE", "5TONE"] SPMUTE_LIST = ["Tone/DTCS", "Tone/DTCS and Optsig", "Tone/DTCS or Optsig"] # lists LIST_AB = ["A", "B"] LIST_ABC = LIST_AB + ["C"] LIST_ABCD = LIST_AB + ["C", "D"] LIST_ANIL = ["3", "4", "5"] LIST_APO = ["Off"] + ["%s minutes" % x for x in range(30, 330, 30)] LIST_COLOR4 = ["Off", "Blue", "Orange", "Purple"] LIST_COLOR8 = ["White", "Red", "Blue", "Green", "Yellow", "Indigo", "Purple", "Gray"] LIST_COLOR9 = ["Black"] + LIST_COLOR8 LIST_DTMFST = ["OFF", "Keyboard", "ANI", "Keyboard + ANI"] LIST_EARPH = ["Off", "Earphone", "Earphone + Speaker"] LIST_EMCTP = ["TX alarm sound", "TX ANI", "Both"] LIST_EMCTPX = ["Off"] + LIST_EMCTP LIST_LANGUA = ["English", "Chinese"] LIST_MDF = ["Frequency", "Channel", "Name"] LIST_OFF1TO9 = ["Off"] + ["%s seconds" % x for x in range(1, 10)] LIST_OFF1TO10 = ["Off"] + ["%s seconds" % x for x in range(1, 11)] LIST_OFF1TO50 = ["Off"] + ["%s seconds" % x for x in range(1, 51)] LIST_OFF1TO60 = ["Off"] + ["%s seconds" % x for x in range(1, 61)] LIST_PONMSG = ["Full", "Message", "Battery voltage"] LIST_REPM = ["Off", "Carrier", "CTCSS or DCS", "Tone", "DTMF"] LIST_REPS = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] LIST_REPSW = ["Off", "RX", "TX"] LIST_RPTDL = ["Off"] + ["%s ms" % x for x in range(1, 11)] LIST_SCMODE = ["Off", "PTT-SC", "MEM-SC", "PON-SC"] LIST_SHIFT = ["Off", "+", "-"] LIST_SKIPTX = ["Off", "Skip 1", "Skip 2"] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0] LIST_STEP = [str(x) for x in STEPS] LIST_SYNC = ["Off", "AB", "CD", "AB+CD"] LIST_SYNCV2 = ["Off", "AB", "AC", "BC", "ABC"] # the first 12 TMR choices common to all 4-line color display mobile radios LIST_TMR12 = ["OFF", "M+A", "M+B", "M+C", "M+D", "M+A+B", "M+A+C", "M+A+D", "M+B+C", "M+B+D", "M+C+D", "M+A+B+C"] # the 16 choice list for color display mobile radios that correctly implement # the full 16 TMR choices LIST_TMR16 = LIST_TMR12 + ["M+A+B+D", "M+A+C+D", "M+B+C+D", "A+B+C+D"] # the 15 choice list for color mobile radios that are missing the M+A+B+D # choice in the TMR menu LIST_TMR15 = LIST_TMR12 + ["M+A+C+D", "M+B+C+D", "A+B+C+D"] # the 7 TMR choices for the 3-line color display mobile radios LIST_TMR7 = ["OFF", "M+A", "M+B", "M+C", "M+AB", "M+AC", "M+BC", "M+ABC"] LIST_TMRTX = ["Track", "Fixed"] LIST_TOT = ["%s sec" % x for x in range(15, 615, 15)] LIST_TXDISP = ["Power", "Mic Volume"] LIST_TXP = ["High", "Low"] LIST_TXP3 = ["High", "Mid", "Low"] LIST_SCREV = ["TO (timeout)", "CO (carrier operated)", "SE (search)"] LIST_VFOMR = ["Frequency", "Channel"] LIST_VOICE = ["Off"] + LIST_LANGUA LIST_VOX = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_VOXT = ["%s seconds" % x for x in range(0, 21)] LIST_WIDE = ["Wide", "Narrow"] # lists related to DTMF, 2TONE and 5TONE settings LIST_5TONE_STANDARDS = ["CCIR1", "CCIR2", "PCCIR", "ZVEI1", "ZVEI2", "ZVEI3", "PZVEI", "DZVEI", "PDZVEI", "EEA", "EIA", "EURO", "CCITT", "NATEL", "MODAT", "none"] LIST_5TONE_STANDARDS_without_none = ["CCIR1", "CCIR2", "PCCIR", "ZVEI1", "ZVEI2", "ZVEI3", "PZVEI", "DZVEI", "PDZVEI", "EEA", "EIA", "EURO", "CCITT", "NATEL", "MODAT"] LIST_5TONE_STANDARD_PERIODS = ["20", "30", "40", "50", "60", "70", "80", "90", "100", "110", "120", "130", "140", "150", "160", "170", "180", "190", "200"] LIST_5TONE_DIGITS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F"] LIST_5TONE_DELAY = ["%s ms" % x for x in range(0, 1010, 10)] LIST_5TONE_RESET = ["%s ms" % x for x in range(100, 8100, 100)] LIST_5TONE_RESET_COLOR = ["%s ms" % x for x in range(100, 20100, 100)] LIST_DTMF_SPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_DTMF_DIGITS = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "#", "*"] LIST_DTMF_VALUES = [0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0D, 0x0E, 0x0F, 0x00, 0x0C, 0x0B] LIST_DTMF_SPECIAL_DIGITS = ["*", "#", "A", "B", "C", "D"] LIST_DTMF_SPECIAL_VALUES = [0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00] LIST_DTMF_DELAY = ["%s ms" % x for x in range(100, 4100, 100)] CHARSET_DTMF_DIGITS = "0123456789AaBbCcDd#*" LIST_2TONE_DEC = ["A-B", "A-C", "A-D", "B-A", "B-C", "B-D", "C-A", "C-B", "C-D", "D-A", "D-B", "D-C"] LIST_2TONE_RESPONSE = ["None", "Alert", "Transpond", "Alert+Transpond"] # This is a general serial timeout for all serial read functions. STIMEOUT = 0.25 # this var controls the verbosity in the debug and by default it's low (False) # make it True and you will to get a very verbose debug.log debug = False # valid chars on the LCD, Note that " " (space) is stored as "\xFF" VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`{|}!\"#$%&'()*+,-./:;<=>?@[]^_" GMRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] GMRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] GMRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] GMRS_FREQS = GMRS_FREQS1 + GMRS_FREQS2 + GMRS_FREQS3 * 2 # #### ID strings ##################################################### # BTECH UV2501 pre-production units UV2501pp_fp = b"M2C294" # BTECH UV2501 pre-production units 2 + and 1st Gen radios UV2501pp2_fp = b"M29204" # B-TECH UV-2501 second generation (2G) radios UV2501G2_fp = b"BTG214" # B-TECH UV-2501 third generation (3G) radios UV2501G3_fp = b"BTG324" # B-TECH UV-2501+220 pre-production units UV2501_220pp_fp = b"M3C281" # B-TECH UV-2501+220 UV2501_220_fp = b"M3G201" # new variant, let's call it Generation 2 UV2501_220G2_fp = b"BTG211" # B-TECH UV-2501+220 third generation (3G) UV2501_220G3_fp = b"BTG311" # B-TECH UV-5001 pre-production units + 1st Gen radios UV5001pp_fp = b"V19204" # B-TECH UV-5001 alpha units UV5001alpha_fp = b"V28204" # B-TECH UV-5001 second generation (2G) radios UV5001G2_fp = b"BTG214" # B-TECH UV-5001 second generation (2G2) UV5001G22_fp = b"V2G204" # B-TECH UV-5001 third generation (3G) UV5001G3_fp = b"BTG304" # B-TECH UV-25X2 UV25X2_fp = b"UC2012" # B-TECH UV-25X2 Second Generation (G2) UV25X2G2_fp = b"UCB282" # B-TECH UV-25X4 UV25X4_fp = b"UC4014" # B-TECH UV-25X4 Second Generation (G2) UV25X4G2_fp = b"UCB284" # B-TECH UV-50X2 UV50X2_fp = b"UC2M12" # B-TECH GMRS-50X1 GMRS50X1_fp = b"NC1802" GMRS50X1_fp1 = b"NC1932" # B-TECH GMRS-20V2 GMRS20V2_fp = b"WP4204" GMRS20V2_fp1 = b"VW2112" GMRS20V2_fp2 = b"VWG728" # special var to know when we found a BTECH Gen 3 BTECH3 = [UV2501G3_fp, UV2501_220G3_fp, UV5001G3_fp] # WACCOM Mini-8900 MINI8900_fp = b"M28854" # QYT KT-UV980 KTUV980_fp = b"H28854" # QYT KT8900 KT8900_fp = b"M29154" # New generations KT8900 KT8900_fp1 = b"M2C234" KT8900_fp2 = b"M2G1F4" KT8900_fp3 = b"M2G2F4" KT8900_fp4 = b"M2G304" KT8900_fp5 = b"M2G314" KT8900_fp6 = b"M2G424" KT8900_fp7 = b"M27184" # KT8900R KT8900R_fp = b"M3G1F4" # Second Generation KT8900R_fp1 = b"M3G214" # another model KT8900R_fp2 = b"M3C234" # another model G4? KT8900R_fp3 = b"M39164" # another model KT8900R_fp4 = b"M3G314" # AC3MB: another id KT8900R_fp5 = b"M3B064" # KT7900D (quad band) KT7900D_fp = b"VC4004" KT7900D_fp1 = b"VC4284" KT7900D_fp2 = b"VC4264" KT7900D_fp3 = b"VC4114" KT7900D_fp4 = b"VC4104" KT7900D_fp5 = b"VC4254" KT7900D_fp6 = b"VC5264" KT7900D_fp7 = b"VC9204" KT7900D_fp8 = b"VC9214" KT7900D_fp9 = b"VC5302" # QB25 (quad band) - a clone of KT7900D QB25_fp = b"QB-25" # KT8900D (dual band) KT8900D_fp = b"VC2002" KT8900D_fp1 = b"VC8632" KT8900D_fp2 = b"VC3402" KT8900D_fp3 = b"VC7062" # LUITON LT-588UV LT588UV_fp = b"V2G1F4" # Added by rstrickoff gen 2 id LT588UV_fp1 = b"V2G214" # QYT KT-8R (quad band ht) KT8R_fp = b"MCB264" KT8R_fp1 = b"MCB284" KT8R_fp2 = b"MC5264" # QYT KT5800 (dual band) KT5800_fp = b"VCB222" # QYT KT980Plus (dual band) KT980PLUS_fp = b"VC2002" KT980PLUS_fp1 = b"VC6042" # Radioddity DB25-G (gmrs) DB25G_fp = b"VC6182" DB25G_fp1 = b"VC7062" # QYT KT-WP12 and KT-9900 KTWP12_fp = b"WP3094" # Anysecu WP-9900 WP9900_fp = b"WP3094" # ### MAGICS # for the Waccom Mini-8900 MSTRING_MINI8900 = b"\x55\xA5\xB5\x45\x55\x45\x4d\x02" # for the B-TECH UV-2501+220 (including pre production ones) MSTRING_220 = b"\x55\x20\x15\x12\x12\x01\x4d\x02" # for the QYT KT8900 & R MSTRING_KT8900 = b"\x55\x20\x15\x09\x16\x45\x4D\x02" MSTRING_KT8900R = b"\x55\x20\x15\x09\x25\x01\x4D\x02" # magic string for all other models MSTRING = b"\x55\x20\x15\x09\x20\x45\x4d\x02" # for the QYT KT7900D & KT8900D MSTRING_KT8900D = b"\x55\x20\x16\x08\x01\xFF\xDC\x02" # for the BTECH UV-25X2 and UV-50X2 MSTRING_UV25X2 = b"\x55\x20\x16\x12\x28\xFF\xDC\x02" # for the BTECH UV-25X4 MSTRING_UV25X4 = b"\x55\x20\x16\x11\x18\xFF\xDC\x02" # for the BTECH GMRS-50X1 MSTRING_GMRS50X1 = b"\x55\x20\x18\x10\x18\xFF\xDC\x02" # for the BTECH GMRS-20V2 MSTRING_GMRS20V2 = b"\x55\x20\x21\x03\x27\xFF\xDC\x02" # for the QYT KT-8R MSTRING_KT8R = b"\x55\x20\x17\x07\x03\xFF\xDC\x02" # for the QYT KT-WP12, KT-9900 and Anysecu WP-9900 MSTRING_KTWP12 = b"\x55\x20\x18\x11\x02\xFF\xDC\x02" def _clean_buffer(radio): """Cleaning the read serial buffer, hard timeout to survive an infinite data stream""" # touching the serial timeout to optimize the flushing # restored at the end to the default value radio.pipe.timeout = 0.1 dump = b"1" datacount = 0 try: while len(dump) > 0: dump = radio.pipe.read(100) datacount += len(dump) # hard limit to survive a infinite serial data stream # 5 times bigger than a normal rx block (69 bytes) if datacount > 345: seriale = "Please check your serial port selection." raise errors.RadioError(seriale) # restore the default serial timeout radio.pipe.timeout = STIMEOUT except Exception: raise errors.RadioError("Unknown error cleaning the serial buffer") def _rawrecv(radio, amount): """Raw read from the radio device, less intensive way""" data = b"" try: data = radio.pipe.read(amount) # DEBUG if debug is True: LOG.debug("<== (%d) bytes:\n\n%s" % (len(data), util.hexprint(data))) # fail if no data is received if len(data) == 0: raise errors.RadioError("No data received from radio") # notice on the logs if short if len(data) < amount: LOG.warn("Short reading %d bytes from the %d requested." % (len(data), amount)) except: raise errors.RadioError("Error reading data from radio") return data def _send(radio, data): """Send data to the radio device""" try: radio.pipe.write(bytes(data)) # DEBUG if debug is True: LOG.debug("==> (%d) bytes:\n\n%s" % (len(data), util.hexprint(data))) except: raise errors.RadioError("Error sending data to radio") def _make_frame(cmd, addr, length, data=""): """Pack the info in the header format""" frame = b"\x06" + struct.pack(">BHB", ord(cmd), addr, length) # add the data if set if len(data) != 0: frame += data return frame def _recv(radio, addr): """Get data from the radio all at once to lower syscalls load""" # Get the full 69 bytes at a time to reduce load # 1 byte ACK + 4 bytes header + 64 bytes of data (BLOCK_SIZE) # get the whole block block = _rawrecv(radio, BLOCK_SIZE + 5) # basic check if len(block) < (BLOCK_SIZE + 5): raise errors.RadioError("Short read of the block 0x%04x" % addr) # checking for the ack if block[0] != ACK_CMD: raise errors.RadioError("Bad ack from radio in block 0x%04x" % addr) # header validation c, a, l = struct.unpack(">BHB", block[1:5]) if a != addr or l != BLOCK_SIZE or c != ord("X"): LOG.debug("Invalid header for block 0x%04x" % addr) LOG.debug("CMD: %s ADDR: %04x SIZE: %02x" % (c, a, l)) raise errors.RadioError("Invalid header for block 0x%04x:" % addr) # return the data return block[5:] def _do_ident(radio, status, upload=False): """Put the radio in PROGRAM mode & identify it""" # set the serial discipline radio.pipe.baudrate = 9600 radio.pipe.parity = "N" # lengthen the timeout here as these radios are resetting due to timeout radio.pipe.timeout = 0.75 # send the magic word _send(radio, radio._magic) # Now you get a 50 byte reply if all goes well ident = _rawrecv(radio, 50) # checking for the ack if ident[0] != ACK_CMD: raise errors.RadioError("Bad ack from radio") # basic check for the ident block if len(ident) != 50: raise errors.RadioError("Radio send a short ident block.") # check if ident is OK itis = False for fp in radio._fileid: if fp in ident: # got it! itis = True # checking if we are dealing with a Gen 3 BTECH if radio.VENDOR == "BTECH" and fp in BTECH3: radio.btech3 = True break if itis is False: LOG.debug("Incorrect model ID, got this:\n\n" + util.hexprint(ident)) raise errors.RadioError("Radio identification failed.") # pause here for the radio to catch up sleep(0.1) # the OEM software reads this additional block, so we will, too # Get the full 21 bytes at a time to reduce load # 1 byte ACK + 4 bytes header + 16 bytes of data (BLOCK_SIZE) frame = _make_frame("S", 0x3DF0, 16) _send(radio, frame) id2 = _rawrecv(radio, 21) # restore the default serial timeout radio.pipe.timeout = STIMEOUT # checking for the ack if id2[:1] not in b"\x06\x05": raise errors.RadioError("Bad ack from radio") # basic check for the additional block if len(id2) < 21: raise errors.RadioError("The extra ID is short, aborting.") # this radios need a extra request/answer here on the upload # the amount of data received depends of the radio type # # also the first block of TX must no have the ACK at the beginning # see _upload for this. if upload is True: # send an ACK _send(radio, b"\x06") # the amount of data depend on the radio, so far we have two radios # reading two bytes with an ACK at the end and just ONE with just # one byte (QYT KT8900) # the JT-6188 appears a clone of the last, but reads TWO bytes. # # we will read two bytes with a custom timeout to not penalize the # users for this. # # we just check for a response and last byte being a ACK, that is # the common stone for all radios (3 so far) ack = _rawrecv(radio, 2) # checking if len(ack) == 0 or ack[-1] != ACK_CMD: raise errors.RadioError("Radio didn't ACK the upload") # DEBUG LOG.info("Positive ident, this is a %s %s" % (radio.VENDOR, radio.MODEL)) return True def _download(radio): """Get the memory map""" # UI progress status = chirp_common.Status() # put radio in program mode and identify it _do_ident(radio, status) # reset the progress bar in the UI status.max = MEM_SIZE // BLOCK_SIZE status.msg = "Cloning from radio..." status.cur = 0 radio.status_fn(status) data = b"" for addr in range(0, MEM_SIZE, BLOCK_SIZE): # sending the read request _send(radio, _make_frame("S", addr, BLOCK_SIZE)) # read d = _recv(radio, addr) # aggregate the data data += d # UI Update status.cur = addr // BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) return data def _upload(radio): """Upload procedure""" # The UPLOAD mem is restricted to lower than 0x3100, # so we will override that here locally MEM_SIZE = radio.UPLOAD_MEM_SIZE # UI progress status = chirp_common.Status() # put radio in program mode and identify it _do_ident(radio, status, True) # get the data to upload to radio data = radio.get_mmap().get_byte_compatible() # Reset the UI progress status.max = MEM_SIZE // TX_BLOCK_SIZE status.cur = 0 status.msg = "Cloning to radio..." radio.status_fn(status) # the fun start here for addr in range(0, MEM_SIZE, TX_BLOCK_SIZE): # getting the block of data to send d = data[addr:addr + TX_BLOCK_SIZE] # build the frame to send frame = _make_frame("X", addr, TX_BLOCK_SIZE, d) # first block must not send the ACK at the beginning for the # ones that has the extra id, since this have to do a extra step if addr == 0: frame = frame[1:] # send the frame _send(radio, frame) # receiving the response ack = _rawrecv(radio, 1) # basic check if len(ack) != 1: raise errors.RadioError("No ACK when writing block 0x%04x" % addr) if ack not in bytes(b"\x06\x05"): raise errors.RadioError("Bad ACK writing block 0x%04x:" % addr) # UI Update status.cur = addr // TX_BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0x3f70:0x3f76] if rid in cls._fileid: return True return False def _decode_ranges(low, high): """Unpack the data in the ranges zones in the memmap and return a tuple with the integer corresponding to the MHz it means""" ilow = int(low[0]) * 100 + int(low[1]) * 10 + int(low[2]) ihigh = int(high[0]) * 100 + int(high[1]) * 10 + int(high[2]) ilow *= 1000000 ihigh *= 1000000 return (ilow, ihigh) def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True class BTechMobileCommon(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """BTECH's UV-5001 and alike radios""" VENDOR = "BTECH" MODEL = "" IDENT = "" BANDS = 2 COLOR_LCD = False COLOR_LCD2 = False # BTech Original GMRS Radios COLOR_LCD3 = False # Color HT Radios COLOR_LCD4 = False # Waterproof Mobile Radios NAME_LENGTH = 6 NEEDS_COMPAT_SERIAL = False UPLOAD_MEM_SIZE = 0X3100 _power_levels = [chirp_common.PowerLevel("High", watts=25), chirp_common.PowerLevel("Low", watts=10)] _vhf_range = (130000000, 180000000) _220_range = (200000000, 271000000) _uhf_range = (400000000, 521000000) _350_range = (350000000, 391000000) _upper = 199 _magic = MSTRING _fileid = [] _id2 = False btech3 = False _gmrs = False @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is experimental.\n' '\n' 'Please keep a copy of your memories with the original software ' 'if you treasure them, this driver is new and may contain' ' bugs.\n' '\n' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow these instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def get_features(self): """Get the radio's features""" # we will use the following var as global global POWER_LEVELS rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = MODES rf.valid_characters = VALID_CHARS rf.valid_name_length = self.NAME_LENGTH rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = SKIP_VALUES rf.valid_dtcs_codes = DTCS rf.valid_tuning_steps = STEPS rf.memory_bounds = (0, self._upper) # power levels POWER_LEVELS = self._power_levels rf.valid_power_levels = POWER_LEVELS # normal dual bands rf.valid_bands = [self._vhf_range, self._uhf_range] # 220 band if self.BANDS == 3 or self.BANDS == 4: rf.valid_bands.append(self._220_range) # 350 band if self.BANDS == 4: rf.valid_bands.append(self._350_range) return rf def sync_in(self): """Download from radio""" data = _download(self) self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Error: %s" % e) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _decode_tone(self, val): """Parse the tone data to decode from mem, it returns: Mode (''|DTCS|Tone), Value (None|###), Polarity (None,N,R)""" pol = None if val in [0, 65535]: return '', None, None elif val > 0x0258: a = val / 10.0 return 'Tone', a, pol else: if val > 0x69: index = val - 0x6A pol = "R" else: index = val - 1 pol = "N" tone = DTCS[index] return 'DTCS', tone, pol def _encode_tone(self, memval, mode, val, pol): """Parse the tone data to encode from UI to mem""" if mode == '' or mode is None: memval.set_raw("\x00\x00") elif mode == 'Tone': memval.set_value(val * 10) elif mode == 'DTCS': # detect the index in the DTCS list try: index = DTCS.index(val) if pol == "N": index += 1 else: index += 0x6A memval.set_value(index) except: msg = "Digital Tone '%d' is not supported" % val LOG.error(msg) raise errors.RadioError(msg) else: msg = "Internal error: invalid mode '%s'" % mode LOG.error(msg) raise errors.InvalidDataError(msg) def _is_txinh(self, _mem): raw_tx = b"" for i in range(0, 4): raw_tx += _mem.txfreq[i].get_raw() return raw_tx == b"\xFF\xFF\xFF\xFF" def get_memory(self, number): """Get the mem representation from the radio image""" _mem = self._memobj.memory[number] _names = self._memobj.names[number] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Memory number mem.number = number if _mem.get_raw()[:1] == b"\xFF": mem.empty = True return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if self._is_txinh(_mem): # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 # name TAG of the channel mem.name = str(_names.name).rstrip("\xFF").replace("\xFF", " ") # power mem.power = POWER_LEVELS[int(_mem.power)] # wide/narrow mem.mode = MODES[int(_mem.wide)] # skip mem.skip = SKIP_VALUES[_mem.add] # tone data rxtone = txtone = None txtone = self._decode_tone(_mem.txtone) rxtone = self._decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) # Extra mem.extra = RadioSettingGroup("extra", "Extra") if not self.COLOR_LCD or \ (self.COLOR_LCD and not self.VENDOR == "BTECH"): scramble = RadioSetting("scramble", "Scramble", RadioSettingValueBoolean(bool( _mem.scramble))) mem.extra.append(scramble) bcl = RadioSetting("bcl", "Busy channel lockout", RadioSettingValueBoolean(bool(_mem.bcl))) mem.extra.append(bcl) pttid = RadioSetting("pttid", "PTT ID", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_mem.pttid])) mem.extra.append(pttid) # validating scode scode = _mem.scode if _mem.scode != 15 else 0 pttidcode = RadioSetting("scode", "PTT ID signal code", RadioSettingValueList( PTTIDCODE_LIST, PTTIDCODE_LIST[scode])) mem.extra.append(pttidcode) optsig = RadioSetting("optsig", "Optional signaling", RadioSettingValueList( OPTSIG_LIST, OPTSIG_LIST[_mem.optsig])) mem.extra.append(optsig) spmute = RadioSetting("spmute", "Speaker mute", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_mem.spmute])) mem.extra.append(spmute) immutable = [] if self._gmrs: if self.MODEL == "GMRS-50X1": if mem.number >= 1 and mem.number <= 30: if mem.freq in GMRS_FREQS: GMRS_FREQ = GMRS_FREQS[mem.number - 1] mem.freq = GMRS_FREQ immutable = ["empty", "freq"] if mem.number >= 1 and mem.number <= 7: mem.duplex = '' mem.offset = 0 mem.power = POWER_LEVELS[2] immutable += ["duplex", "offset", "power"] elif mem.number >= 8 and mem.number <= 14: mem.duplex = 'off' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 15 and mem.number <= 22: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 23 and mem.number <= 30: mem.duplex = '+' mem.offset = 5000000 immutable += ["duplex", "offset"] else: # Not a GMRS channel, so restrict duplex since it will be # forced to off. mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] elif self.MODEL in ["GMRS-20V2", "GMRS-50V2"]: if mem.freq in GMRS_FREQS: if mem.freq in GMRS_FREQS1: # Non-repeater GMRS channels (limit duplex) mem.duplex = '' mem.offset = 0 mem.power = POWER_LEVELS[2] immutable = ["duplex", "offset", "power"] elif mem.freq in GMRS_FREQS2: # Non-repeater FRS channels (receive only) mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] elif mem.freq in GMRS_FREQS3: # GMRS repeater channels, always either simplex or # +5 MHz if mem.duplex != '+': mem.duplex = '' mem.offset = 0 else: mem.offset = 5000000 else: # Not a GMRS channel, so restrict duplex since it will be # forced to off. mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] elif self.MODEL == "DB25-G": if mem.freq in GMRS_FREQS: if mem.freq in GMRS_FREQS1: # Non-repeater GMRS channels (limit duplex) mem.duplex = '' mem.offset = 0 immutable = ["duplex", "offset"] elif mem.freq in GMRS_FREQS2: # Non-repeater FRS channels (receive only) mem.duplex = 'off' mem.offset = 0 immutable = ["duplex", "offset"] elif mem.freq in GMRS_FREQS3: # GMRS repeater channels, always either simplex or # +5 MHz if mem.duplex != '+': mem.duplex = '' mem.offset = 0 else: mem.offset = 5000000 mem.immutable = immutable return mem def set_memory(self, mem): """Set the memory data in the eeprom img from the UI""" # get the eprom representation of this channel _mem = self._memobj.memory[mem.number] _names = self._memobj.names[mem.number] mem_was_empty = False # same method as used in get_memory for determining if mem is empty # doing this BEFORE overwriting it with new values ... if _mem.get_raw(asbytes=False)[0] == "\xFF": LOG.debug("This mem was empty before") mem_was_empty = True # if empty memory if mem.empty: # the channel itself _mem.set_raw("\xFF" * 16) # the name tag _names.set_raw("\xFF" * 16) return if mem_was_empty: # Zero the whole memory if we're making it unempty for # the first time LOG.debug('Zeroing new memory') _mem.set_raw('\x00' * 16) # frequency _mem.rxfreq = mem.freq / 10 # duplex if mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 elif mem.duplex == "off": for i in _mem.txfreq: i.set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 else: _mem.txfreq = mem.freq / 10 # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self._encode_tone(_mem.txtone, txmode, txtone, txpol) self._encode_tone(_mem.rxtone, rxmode, rxtone, rxpol) # name TAG of the channel _names.name = mem.name.rstrip(' ').ljust(self.NAME_LENGTH, "\xFF") # power, # default power level is high _mem.power = 0 if mem.power is None else POWER_LEVELS.index(mem.power) # wide/narrow _mem.wide = MODES.index(mem.mode) # scan add property _mem.add = SKIP_VALUES.index(mem.skip) # resetting unknowns, this have to be set by hand _mem.unknown0 = 0 _mem.unknown1 = 0 _mem.unknown2 = 0 _mem.unknown3 = 0 _mem.unknown4 = 0 _mem.unknown5 = 0 _mem.unknown6 = 0 def _zero_settings(): _mem.spmute = 0 _mem.optsig = 0 _mem.scramble = 0 _mem.bcl = 0 _mem.pttid = 0 _mem.scode = 0 if self.COLOR_LCD and _mem.scramble: LOG.info('Resetting scramble bit for BTECH COLOR_LCD variant') _mem.scramble = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse LOG.debug("Extra-Setting supplied. Setting them.") # Zero them all first so any not provided by model don't # stay set _zero_settings() for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) else: if mem.empty: LOG.debug("New mem is empty.") else: LOG.debug("New mem is NOT empty") # set extra-settings to default ONLY when a previously empty or # deleted memory was edited to prevent errors such as #4121 if mem_was_empty: LOG.debug("old mem was empty. Setting default for extras.") _zero_settings() return mem def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") top = RadioSettings(basic, advanced, other, work) # Basic if self.COLOR_LCD: val = min(_mem.settings.tmr, len(self.LIST_TMR) - 1) rs = RadioSettingValueList(self.LIST_TMR, self.LIST_TMR[val]) tmr = RadioSetting("settings.tmr", "Transceiver multi-receive", rs) basic.append(tmr) else: tdr = RadioSetting("settings.tdr", "Transceiver dual receive", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(tdr) val = min(_mem.settings.sql, 9) rs = RadioSettingValueInteger(0, 9, val) sql = RadioSetting("settings.sql", "Squelch level", rs) basic.append(sql) if self.MODEL == "GMRS-50X1" or self.MODEL == "GMRS-50V2": rs = RadioSettingValueBoolean(_mem.settings.autolk) autolk = RadioSetting("settings.autolk", "Auto keylock", rs) basic.append(autolk) if self.MODEL == "DB25-G": val = min(_mem.settings.mgain2, 127) rs = RadioSettingValueInteger(0, 127, val) mgain2 = RadioSetting("settings.mgain2", "Mic gain", rs) basic.append(mgain2) val = min(_mem.settings.tot, len(LIST_TOT) - 1) rs = RadioSettingValueList(LIST_TOT, LIST_TOT[val]) tot = RadioSetting("settings.tot", "Time out timer", rs) basic.append(tot) if self.MODEL == "KT-8R": rs = RadioSettingValueBoolean(_mem.settings.save) save = RadioSetting("settings.save", "Battery Save", rs) basic.append(save) model_list = ["KT-8R", "KT-WP12", "WP-9900"] if self.MODEL not in model_list: if self.VENDOR == "BTECH" or self.COLOR_LCD: val = min(_mem.settings.apo, len(LIST_APO) - 1) rs = RadioSettingValueList(LIST_APO, LIST_APO[val]) apo = RadioSetting("settings.apo", "Auto power off timer", rs) basic.append(apo) else: val = min(_mem.settings.apo, len(LIST_OFF1TO10) - 1) rs = RadioSettingValueList(LIST_OFF1TO10, LIST_OFF1TO10[val]) toa = RadioSetting("settings.apo", "Time out alert timer", rs) basic.append(toa) val = min(_mem.settings.abr, len(LIST_OFF1TO50) - 1) rs = RadioSettingValueList(LIST_OFF1TO50, LIST_OFF1TO50[val]) abr = RadioSetting("settings.abr", "Backlight timer", rs) basic.append(abr) rs = RadioSettingValueBoolean(_mem.settings.beep) beep = RadioSetting("settings.beep", "Key beep", rs) basic.append(beep) if self.MODEL == "GMRS-20V2": val = min(_mem.settings.volume, 58) rs = RadioSettingValueInteger(0, 58, val) volume = RadioSetting("settings.volume", "Volume", rs) basic.append(volume) if self.MODEL == "KT-WP12" or self.MODEL == "WP-9900": val = min(_mem.settings.volume, 50) rs = RadioSettingValueInteger(1, 51, val + 1) volume = RadioSetting("settings.volume", "Volume", rs) basic.append(volume) if self.MODEL == "KT-8R": rs = RadioSettingValueBoolean(_mem.settings.dsub) dsub = RadioSetting("settings.dsub", "CTCSS/DCS code display", rs) basic.append(dsub) if self.MODEL == "KT-8R" or self.COLOR_LCD4: rs = RadioSettingValueBoolean(_mem.settings.dtmfst) dtmfst = RadioSetting("settings.dtmfst", "DTMF side tone", rs) basic.append(dtmfst) else: val = min(_mem.settings.dtmfst, len(LIST_DTMFST) - 1) rs = RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[val]) dtmfst = RadioSetting("settings.dtmfst", "DTMF side tone", rs) basic.append(dtmfst) if not self.COLOR_LCD: rs = RadioSettingValueBoolean(_mem.settings.prisc) prisc = RadioSetting("settings.prisc", "Priority scan", rs) basic.append(prisc) val = min(_mem.settings.prich, self._upper) rs = RadioSettingValueInteger(0, self._upper, val) prich = RadioSetting("settings.prich", "Priority channel", rs) basic.append(prich) val = min(_mem.settings.screv, len(LIST_SCREV) - 1) rs = RadioSettingValueList(LIST_SCREV, LIST_SCREV[val]) screv = RadioSetting("settings.screv", "Scan resume method", rs) basic.append(screv) val = min(_mem.settings.pttlt, 30) rs = RadioSettingValueInteger(0, 30, val) pttlt = RadioSetting("settings.pttlt", "PTT transmit delay", rs) basic.append(pttlt) if self.VENDOR == "BTECH" and self.COLOR_LCD and not \ self.MODEL == "GMRS-20V2": val = min(_mem.settings.emctp, len(LIST_EMCTPX) - 1) rs = RadioSettingValueList(LIST_EMCTPX, LIST_EMCTPX[val]) emctp = RadioSetting("settings.emctp", "Alarm mode", rs) basic.append(emctp) else: val = min(_mem.settings.emctp, len(LIST_EMCTP) - 1) rs = RadioSettingValueList(LIST_EMCTP, LIST_EMCTP[val]) emctp = RadioSetting("settings.emctp", "Alarm mode", rs) basic.append(emctp) val = min(_mem.settings.emcch, self._upper) rs = RadioSettingValueInteger(0, self._upper, val) emcch = RadioSetting("settings.emcch", "Alarm channel", rs) basic.append(emcch) if self.COLOR_LCD: rs = RadioSettingValueBoolean(_mem.settings.sigbp) sigbp = RadioSetting("settings.sigbp", "Signal beep", rs) basic.append(sigbp) else: val = min(_mem.settings.ringt, len(LIST_OFF1TO9) - 1) rs = RadioSettingValueList(LIST_OFF1TO9, LIST_OFF1TO9[val]) ringt = RadioSetting("settings.ringt", "Ring time", rs) basic.append(ringt) val = min(_mem.settings.camdf, len(LIST_MDF) - 1) rs = RadioSettingValueList(LIST_MDF, LIST_MDF[val]) camdf = RadioSetting("settings.camdf", "Display mode A", rs) basic.append(camdf) val = min(_mem.settings.cbmdf, len(LIST_MDF) - 1) rs = RadioSettingValueList(LIST_MDF, LIST_MDF[val]) cbmdf = RadioSetting("settings.cbmdf", "Display mode B", rs) basic.append(cbmdf) if self.COLOR_LCD: val = min(_mem.settings.ccmdf, len(LIST_MDF) - 1) rs = RadioSettingValueList(LIST_MDF, LIST_MDF[val]) ccmdf = RadioSetting("settings.ccmdf", "Display mode C", rs) basic.append(ccmdf) if not self.COLOR_LCD4: val = min(_mem.settings.cdmdf, len(LIST_MDF) - 1) rs = RadioSettingValueList(LIST_MDF, LIST_MDF[val]) cdmdf = RadioSetting("settings.cdmdf", "Display mode D", rs) basic.append(cdmdf) if self.MODEL in ["UV-50X2_G2", "UV-25X2_G2", "UV-25X4_G2"]: val = min(_mem.settings.langua, len(LIST_VOX) - 1) rs = RadioSettingValueList(LIST_VOX, LIST_VOX[val]) vox = RadioSetting("settings.langua", "VOX", rs) basic.append(vox) elif self.MODEL == "GMRS-50V2": val = min(_mem.settings.vox, len(LIST_VOX) - 1) rs = RadioSettingValueList(LIST_VOX, LIST_VOX[val]) vox = RadioSetting("settings.vox", "VOX", rs) basic.append(vox) else: val = min(_mem.settings.langua, len(LIST_LANGUA) - 1) rs = RadioSettingValueList(LIST_LANGUA, LIST_LANGUA[val]) langua = RadioSetting("settings.langua", "Language", rs) basic.append(langua) if self.MODEL == "KT-8R": val = min(_mem.settings.voice, len(LIST_VOICE) - 1) rs = RadioSettingValueList(LIST_VOICE, LIST_VOICE[val]) voice = RadioSetting("settings.voice", "Voice prompt", rs) basic.append(voice) if self.MODEL == "KT-8R" or self.COLOR_LCD4: val = min(_mem.settings.vox, len(LIST_VOX) - 1) rs = RadioSettingValueList(LIST_VOX, LIST_VOX[val]) vox = RadioSetting("settings.vox", "VOX", rs) basic.append(vox) val = min(_mem.settings.voxt, len(LIST_VOX) - 1) rs = RadioSettingValueList(LIST_VOXT, LIST_VOXT[val]) voxt = RadioSetting("settings.voxt", "VOX delay time", rs) basic.append(voxt) if self.VENDOR == "BTECH": if self.COLOR_LCD: if self.MODEL == "GMRS-20V2": val = min(_mem.settings.sync, len(LIST_SYNCV2) - 1) rs = RadioSettingValueList(LIST_SYNCV2, LIST_SYNCV2[val]) sync = RadioSetting("settings.sync", "Channel display sync", rs) basic.append(sync) else: val = min(_mem.settings.sync, len(LIST_SYNC) - 1) rs = RadioSettingValueList(LIST_SYNC, LIST_SYNC[val]) sync = RadioSetting("settings.sync", "Channel display sync", rs) basic.append(sync) else: rs = RadioSettingValueBoolean(_mem.settings.sync) sync = RadioSetting("settings.sync", "A/B channel sync", rs) basic.append(sync) if self.COLOR_LCD4: rs = RadioSettingValueBoolean(_mem.settings.autolock) autolk = RadioSetting("settings.autolock", "Auto keylock", rs) basic.append(autolk) if not self.COLOR_LCD: val = min(_mem.settings.ponmsg, len(LIST_PONMSG) - 1) rs = RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[val]) ponmsg = RadioSetting("settings.ponmsg", "Power-on message", rs) basic.append(ponmsg) if self.COLOR_LCD and not (self.COLOR_LCD2 or self.COLOR_LCD3 or self.COLOR_LCD4): val = min(_mem.settings.mainfc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) mainfc = RadioSetting("settings.mainfc", "Main LCD foreground color", rs) basic.append(mainfc) if not self.COLOR_LCD4: val = min(_mem.settings.mainbc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) mainbc = RadioSetting("settings.mainbc", "Main LCD background color", rs) basic.append(mainbc) val = min(_mem.settings.menufc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) menufc = RadioSetting("settings.menufc", "Menu foreground color", rs) basic.append(menufc) if not self.COLOR_LCD4: val = min(_mem.settings.menubc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) menubc = RadioSetting("settings.menubc", "Menu background color", rs) basic.append(menubc) val = min(_mem.settings.stafc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) stafc = RadioSetting("settings.stafc", "Top status foreground color", rs) basic.append(stafc) if not self.COLOR_LCD4: val = min(_mem.settings.stabc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) stabc = RadioSetting("settings.stabc", "Top status background color", rs) basic.append(stabc) val = min(_mem.settings.sigfc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) sigfc = RadioSetting("settings.sigfc", "Bottom status foreground color", rs) basic.append(sigfc) if not self.COLOR_LCD4: val = min(_mem.settings.sigbc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) sigbc = RadioSetting("settings.sigbc", "Bottom status background color", rs) basic.append(sigbc) val = min(_mem.settings.rxfc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) rxfc = RadioSetting("settings.rxfc", "Receiving character color", rs) basic.append(rxfc) val = min(_mem.settings.txfc, len(LIST_COLOR9) - 1) rs = RadioSettingValueList(LIST_COLOR9, LIST_COLOR9[val]) txfc = RadioSetting("settings.txfc", "Transmitting character color", rs) basic.append(txfc) if not self.COLOR_LCD4: val = min(_mem.settings.txdisp, len(LIST_TXDISP) - 1) rs = RadioSettingValueList(LIST_TXDISP, LIST_TXDISP[val]) txdisp = RadioSetting("settings.txdisp", "Transmitting status display", rs) basic.append(txdisp) elif self.COLOR_LCD2 or self.COLOR_LCD3: val = min(_mem.settings.stfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) stfc = RadioSetting("settings.stfc", "ST-FC", rs) basic.append(stfc) val = min(_mem.settings.mffc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) mffc = RadioSetting("settings.mffc", "MF-FC", rs) basic.append(mffc) val = min(_mem.settings.sfafc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) sfafc = RadioSetting("settings.sfafc", "SFA-FC", rs) basic.append(sfafc) val = min(_mem.settings.sfbfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) sfbfc = RadioSetting("settings.sfbfc", "SFB-FC", rs) basic.append(sfbfc) val = min(_mem.settings.sfcfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) sfcfc = RadioSetting("settings.sfcfc", "SFC-FC", rs) basic.append(sfcfc) val = min(_mem.settings.sfdfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) sfdfc = RadioSetting("settings.sfdfc", "SFD-FC", rs) basic.append(sfdfc) val = min(_mem.settings.subfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) subfc = RadioSetting("settings.subfc", "SUB-FC", rs) basic.append(subfc) val = min(_mem.settings.fmfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) fmfc = RadioSetting("settings.fmfc", "FM-FC", rs) basic.append(fmfc) val = min(_mem.settings.sigfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) sigfc = RadioSetting("settings.sigfc", "SIG-FC", rs) basic.append(sigfc) if not self.MODEL == "KT-8R": val = min(_mem.settings.modfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) modfc = RadioSetting("settings.modfc", "MOD-FC", rs) basic.append(modfc) val = min(_mem.settings.menufc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) menufc = RadioSetting("settings.menufc", "MENUFC", rs) basic.append(menufc) val = min(_mem.settings.txfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) txfc = RadioSetting("settings.txfc", "TX-FC", rs) basic.append(txfc) if self.MODEL == "KT-8R": val = min(_mem.settings.rxfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) rxfc = RadioSetting("settings.rxfc", "RX-FC", rs) basic.append(rxfc) if not self.MODEL == "KT-8R" and not self.MODEL == "GMRS-50V2": val = min(_mem.settings.txdisp, len(LIST_TXDISP) - 1) rs = RadioSettingValueList(LIST_TXDISP, LIST_TXDISP[val]) txdisp = RadioSetting("settings.txdisp", "Transmitting status display", rs) basic.append(txdisp) elif self.COLOR_LCD4: val = min(_mem.settings.asfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) asfc = RadioSetting("settings.asfc", "Above Stat fore color", rs) basic.append(asfc) val = min(_mem.settings.mainfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) mainfc = RadioSetting("settings.mainfc", "Main fore color", rs) basic.append(mainfc) val = min(_mem.settings.a_fc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) a_fc = RadioSetting("settings.a_fc", "A - fore color", rs) basic.append(a_fc) val = min(_mem.settings.b_fc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) b_fc = RadioSetting("settings.b_fc", "B - fore color", rs) basic.append(b_fc) val = min(_mem.settings.c_fc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) c_fc = RadioSetting("settings.c_fc", "C - fore color", rs) basic.append(c_fc) val = min(_mem.settings.subfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) subfc = RadioSetting("settings.subfc", "Sub fore color", rs) basic.append(subfc) val = min(_mem.settings.battfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) battfc = RadioSetting("settings.battfc", "Battery fore color", rs) basic.append(battfc) val = min(_mem.settings.sigfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) sigfc = RadioSetting("settings.sigfc", "Signal fore color", rs) basic.append(sigfc) val = min(_mem.settings.menufc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) menufc = RadioSetting("settings.menufc", "Menu fore color", rs) basic.append(menufc) val = min(_mem.settings.txfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) txfc = RadioSetting("settings.txfc", "TX fore color", rs) basic.append(txfc) val = min(_mem.settings.rxfc, len(LIST_COLOR8) - 1) rs = RadioSettingValueList(LIST_COLOR8, LIST_COLOR8[val]) rxfc = RadioSetting("settings.rxfc", "RX fore color", rs) basic.append(rxfc) else: val = min(_mem.settings.wtled, len(LIST_COLOR4) - 1) rs = RadioSettingValueList(LIST_COLOR4, LIST_COLOR4[val]) wtled = RadioSetting("settings.wtled", "Standby backlight Color", rs) basic.append(wtled) val = min(_mem.settings.rxled, len(LIST_COLOR4) - 1) rs = RadioSettingValueList(LIST_COLOR4, LIST_COLOR4[val]) rxled = RadioSetting("settings.rxled", "RX backlight Color", rs) basic.append(rxled) val = min(_mem.settings.txled, len(LIST_COLOR4) - 1) rs = RadioSettingValueList(LIST_COLOR4, LIST_COLOR4[val]) txled = RadioSetting("settings.txled", "TX backlight Color", rs) basic.append(txled) val = min(_mem.settings.anil, len(LIST_ANIL) - 1) rs = RadioSettingValueList(LIST_ANIL, LIST_ANIL[val]) anil = RadioSetting("settings.anil", "ANI length", rs) basic.append(anil) val = min(_mem.settings.reps, len(LIST_REPS) - 1) rs = RadioSettingValueList(LIST_REPS, LIST_REPS[val]) reps = RadioSetting("settings.reps", "Relay signal (tone burst)", rs) basic.append(reps) if self.COLOR_LCD4: rs = RadioSettingValueBoolean(_mem.settings.dsub) dsub = RadioSetting("settings.dsub", "Subtone display", rs) basic.append(dsub) if self.MODEL == "GMRS-20V2": val = min(_mem.settings.repsw, len(LIST_REPSW) - 1) rs = RadioSettingValueList(LIST_REPSW, LIST_REPSW[val]) repsw = RadioSetting("settings.repsw", "Repeater SW", rs) basic.append(repsw) model_list = ["KT-8R", "KT-WP12", "WP-9900"] if self.MODEL not in model_list: val = min(_mem.settings.repm, len(LIST_REPM) - 1) rs = RadioSettingValueList(LIST_REPM, LIST_REPM[val]) repm = RadioSetting("settings.repm", "Relay condition", rs) basic.append(repm) if self.VENDOR == "BTECH" or self.COLOR_LCD: if self.COLOR_LCD: val = min(_mem.settings.tmrmr, len(LIST_OFF1TO50) - 1) rs = RadioSettingValueList(LIST_OFF1TO50, LIST_OFF1TO50[val]) tmrmr = RadioSetting("settings.tmrmr", "TMR return time", rs) basic.append(tmrmr) else: val = min(_mem.settings.tdrab, len(LIST_OFF1TO50) - 1) rs = RadioSettingValueList(LIST_OFF1TO50, LIST_OFF1TO50[val]) tdrab = RadioSetting("settings.tdrab", "TDR return time", rs) basic.append(tdrab) rs = RadioSettingValueBoolean(_mem.settings.ste) ste = RadioSetting("settings.ste", "Squelch tail eliminate", rs) basic.append(ste) if self.COLOR_LCD4: val = min(_mem.settings.rpste, len(LIST_OFF1TO10) - 1) rs = RadioSettingValueList(LIST_OFF1TO10, LIST_OFF1TO10[val]) rpste = RadioSetting("settings.rpste", "Repeater STE", rs) basic.append(rpste) else: val = min(_mem.settings.rpste, len(LIST_OFF1TO9) - 1) rs = RadioSettingValueList(LIST_OFF1TO9, LIST_OFF1TO9[val]) rpste = RadioSetting("settings.rpste", "Repeater STE", rs) basic.append(rpste) if self.COLOR_LCD4: val = min(_mem.settings.rptdl, len(LIST_OFF1TO60) - 1) rs = RadioSettingValueList(LIST_OFF1TO60, LIST_OFF1TO60[val]) rptdl = RadioSetting("settings.rptdl", "Repeater STE delay", rs) basic.append(rptdl) else: val = min(_mem.settings.rptdl, len(LIST_RPTDL) - 1) rs = RadioSettingValueList(LIST_RPTDL, LIST_RPTDL[val]) rptdl = RadioSetting("settings.rptdl", "Repeater STE delay", rs) basic.append(rptdl) if self.MODEL == "DB25-G": val = min(_mem.settings.mgain, 1) rs = RadioSettingValueBoolean(val) mgain = RadioSetting("settings.mgain", "Auto power-on", rs) basic.append(mgain) if str(_mem.fingerprint.fp) in BTECH3: val = min(_mem.settings.mgain, 120) rs = RadioSettingValueInteger(0, 120, val) mgain = RadioSetting("settings.mgain", "Mic gain", rs) basic.append(mgain) if str(_mem.fingerprint.fp) in BTECH3 or self.COLOR_LCD: val = min(_mem.settings.dtmfg, 60) rs = RadioSettingValueInteger(0, 60, val) dtmfg = RadioSetting("settings.dtmfg", "DTMF gain", rs) basic.append(dtmfg) if self.VENDOR == "BTECH" and self.COLOR_LCD: val = min(_mem.settings.mgain, 127) rs = RadioSettingValueInteger(0, 127, val) mgain = RadioSetting("settings.mgain", "Mic gain", rs) basic.append(mgain) val = min(_mem.settings.skiptx, len(LIST_SKIPTX) - 1) rs = RadioSettingValueList(LIST_SKIPTX, LIST_SKIPTX[val]) skiptx = RadioSetting("settings.skiptx", "Skip TX", rs) basic.append(skiptx) val = min(_mem.settings.scmode, len(LIST_SCMODE) - 1) rs = RadioSettingValueList(LIST_SCMODE, LIST_SCMODE[val]) scmode = RadioSetting("settings.scmode", "Scan mode", rs) basic.append(scmode) if self.MODEL in ["KT-8R", "UV-25X2", "UV-25X4", "UV-50X2", "GMRS-20V2", "UV-50X2_G2", "GMRS-50V2", "UV-25X2_G2", "UV-25X4_G2"]: val = min(_mem.settings.tmrtx, len(LIST_TMRTX) - 1) rs = RadioSettingValueList(LIST_TMRTX, LIST_TMRTX[val]) tmrtx = RadioSetting("settings.tmrtx", "TX in multi-standby", rs) basic.append(tmrtx) if self.MODEL in ["UV-50X2_G2", "GMRS-50V2", "UV-25X2_G2", "UV-25X4_G2"]: val = min(_mem.settings.earpho, len(LIST_EARPH) - 1) rs = RadioSettingValueList(LIST_EARPH, LIST_EARPH[val]) earpho = RadioSetting("settings.earpho", "Earphone", rs) basic.append(earpho) # Advanced def _filter(name): filtered = "" for char in str(name): if char in VALID_CHARS: filtered += char else: filtered += " " return filtered if self.COLOR_LCD and not (self.COLOR_LCD2 or self.COLOR_LCD3 or self.COLOR_LCD4): _msg = self._memobj.poweron_msg line1 = RadioSetting("poweron_msg.line1", "Power-on message line 1", RadioSettingValueString(0, 8, _filter( _msg.line1))) advanced.append(line1) line2 = RadioSetting("poweron_msg.line2", "Power-on message line 2", RadioSettingValueString(0, 8, _filter( _msg.line2))) advanced.append(line2) line3 = RadioSetting("poweron_msg.line3", "Power-on message line 3", RadioSettingValueString(0, 8, _filter( _msg.line3))) advanced.append(line3) line4 = RadioSetting("poweron_msg.line4", "Power-on message line 4", RadioSettingValueString(0, 8, _filter( _msg.line4))) advanced.append(line4) line5 = RadioSetting("poweron_msg.line5", "Power-on message line 5", RadioSettingValueString(0, 8, _filter( _msg.line5))) advanced.append(line5) line6 = RadioSetting("poweron_msg.line6", "Power-on message line 6", RadioSettingValueString(0, 8, _filter( _msg.line6))) advanced.append(line6) line7 = RadioSetting("poweron_msg.line7", "Power-on message line 7", RadioSettingValueString(0, 8, _filter( _msg.line7))) advanced.append(line7) line8 = RadioSetting("poweron_msg.line8", "Static message", RadioSettingValueString(0, 8, _filter( _msg.line8))) advanced.append(line8) elif self.COLOR_LCD2 or self.COLOR_LCD3 or self.COLOR_LCD4: _msg = self._memobj.static_msg line = RadioSetting("static_msg.line", "Static message", RadioSettingValueString(0, 16, _filter( _msg.line))) advanced.append(line) else: _msg = self._memobj.poweron_msg line1 = RadioSetting("poweron_msg.line1", "Power-on message line 1", RadioSettingValueString(0, 6, _filter( _msg.line1))) advanced.append(line1) line2 = RadioSetting("poweron_msg.line2", "Power-on message line 2", RadioSettingValueString(0, 6, _filter( _msg.line2))) advanced.append(line2) if self.MODEL in ("UV-2501", "UV-5001"): vfomren = RadioSetting("settings2.vfomren", "VFO/MR switching", RadioSettingValueBoolean( _mem.settings2.vfomren)) advanced.append(vfomren) reseten = RadioSetting("settings2.reseten", "RESET", RadioSettingValueBoolean( _mem.settings2.reseten)) advanced.append(reseten) menuen = RadioSetting("settings2.menuen", "Menu", RadioSettingValueBoolean( _mem.settings2.menuen)) advanced.append(menuen) # Other def convert_bytes_to_limit(bytes): limit = "" for byte in bytes: if byte < 10: limit += chr(byte + 0x30) else: break return limit if self.MODEL in ["UV-2501+220", "KT8900R"]: _ranges = self._memobj.ranges220 ranges = "ranges220" else: _ranges = self._memobj.ranges ranges = "ranges" _limit = convert_bytes_to_limit(_ranges.vhf_low) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) vhf_low = RadioSetting("%s.vhf_low" % ranges, "VHF low", val) other.append(vhf_low) _limit = convert_bytes_to_limit(_ranges.vhf_high) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) vhf_high = RadioSetting("%s.vhf_high" % ranges, "VHF high", val) other.append(vhf_high) if self.BANDS == 3 or self.BANDS == 4: _limit = convert_bytes_to_limit(_ranges.vhf2_low) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) vhf2_low = RadioSetting("%s.vhf2_low" % ranges, "VHF2 low", val) other.append(vhf2_low) _limit = convert_bytes_to_limit(_ranges.vhf2_high) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) vhf2_high = RadioSetting("%s.vhf2_high" % ranges, "VHF2 high", val) other.append(vhf2_high) _limit = convert_bytes_to_limit(_ranges.uhf_low) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) uhf_low = RadioSetting("%s.uhf_low" % ranges, "UHF low", val) other.append(uhf_low) _limit = convert_bytes_to_limit(_ranges.uhf_high) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) uhf_high = RadioSetting("%s.uhf_high" % ranges, "UHF high", val) other.append(uhf_high) if self.BANDS == 4: _limit = convert_bytes_to_limit(_ranges.uhf2_low) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) uhf2_low = RadioSetting("%s.uhf2_low" % ranges, "UHF2 low", val) other.append(uhf2_low) _limit = convert_bytes_to_limit(_ranges.uhf2_high) val = RadioSettingValueString(0, 3, _limit) val.set_mutable(False) uhf2_high = RadioSetting("%s.uhf2_high" % ranges, "UHF2 high", val) other.append(uhf2_high) val = RadioSettingValueString(0, 6, _filter(_mem.fingerprint.fp)) val.set_mutable(False) fp = RadioSetting("fingerprint.fp", "Fingerprint", val) other.append(fp) # Work if self.COLOR_LCD4: val = min(_mem.settings2.dispab, len(LIST_ABC) - 1) rs = RadioSettingValueList(LIST_ABC, LIST_ABC[val]) dispab = RadioSetting("settings2.dispab", "Display", rs) work.append(dispab) elif self.COLOR_LCD: val = min(_mem.settings2.dispab, len(LIST_ABCD) - 1) rs = RadioSettingValueList(LIST_ABCD, LIST_ABCD[val]) dispab = RadioSetting("settings2.dispab", "Display", rs) work.append(dispab) else: val = min(_mem.settings2.dispab, len(LIST_AB) - 1) rs = RadioSettingValueList(LIST_AB, LIST_AB[val]) dispab = RadioSetting("settings2.dispab", "Display", rs) work.append(dispab) if self.COLOR_LCD: val = min(_mem.settings2.vfomra, len(LIST_VFOMR) - 1) rs = RadioSettingValueList(LIST_VFOMR, LIST_VFOMR[val]) vfomra = RadioSetting("settings2.vfomra", "VFO/MR A mode", rs) work.append(vfomra) val = min(_mem.settings2.vfomrb, len(LIST_VFOMR) - 1) rs = RadioSettingValueList(LIST_VFOMR, LIST_VFOMR[val]) vfomrb = RadioSetting("settings2.vfomrb", "VFO/MR B mode", rs) work.append(vfomrb) val = min(_mem.settings2.vfomrc, len(LIST_VFOMR) - 1) rs = RadioSettingValueList(LIST_VFOMR, LIST_VFOMR[val]) vfomrc = RadioSetting("settings2.vfomrc", "VFO/MR C mode", rs) work.append(vfomrc) if not self.COLOR_LCD4: val = min(_mem.settings2.vfomrd, len(LIST_VFOMR) - 1) rs = RadioSettingValueList(LIST_VFOMR, LIST_VFOMR[val]) vfomrd = RadioSetting("settings2.vfomrd", "VFO/MR D mode", rs) work.append(vfomrd) else: val = min(_mem.settings2.vfomr, len(LIST_VFOMR) - 1) rs = RadioSettingValueList(LIST_VFOMR, LIST_VFOMR[val]) vfomr = RadioSetting("settings2.vfomr", "VFO/MR mode", rs) work.append(vfomr) rs = RadioSettingValueBoolean(_mem.settings2.keylock) keylock = RadioSetting("settings2.keylock", "Keypad lock", rs) work.append(keylock) val = min(_mem.settings2.mrcha, self._upper) rs = RadioSettingValueInteger(0, self._upper, val) mrcha = RadioSetting("settings2.mrcha", "MR A channel", rs) work.append(mrcha) val = min(_mem.settings2.mrchb, self._upper) rs = RadioSettingValueInteger(0, self._upper, val) mrchb = RadioSetting("settings2.mrchb", "MR B channel", rs) work.append(mrchb) if self.COLOR_LCD: val = min(_mem.settings2.mrchc, self._upper) rs = RadioSettingValueInteger(0, self._upper, val) mrchc = RadioSetting("settings2.mrchc", "MR C channel", rs) work.append(mrchc) if not self.COLOR_LCD4: val = min(_mem.settings2.mrchd, self._upper) rs = RadioSettingValueInteger(0, self._upper, val) mrchd = RadioSetting("settings2.mrchd", "MR D channel", rs) work.append(mrchd) def my_validate(value): _vhf_lower = int(convert_bytes_to_limit(_ranges.vhf_low)) _vhf_upper = int(convert_bytes_to_limit(_ranges.vhf_high)) _uhf_lower = int(convert_bytes_to_limit(_ranges.uhf_low)) _uhf_upper = int(convert_bytes_to_limit(_ranges.uhf_high)) if self.BANDS == 3 or self.BANDS == 4: _vhf2_lower = int(convert_bytes_to_limit(_ranges.vhf2_low)) _vhf2_upper = int(convert_bytes_to_limit(_ranges.vhf2_high)) if self.BANDS == 4: _uhf2_lower = int(convert_bytes_to_limit(_ranges.uhf2_low)) _uhf2_upper = int(convert_bytes_to_limit(_ranges.uhf2_high)) value = chirp_common.parse_freq(value) msg = ("Can't be less then %i.0000") if value > 99000000 and value < _vhf_lower * 1000000: raise InvalidValueError(msg % (_vhf_lower)) msg = ("Can't be betweeb %i.9975-%i.0000") if self.BANDS == 2: if (_vhf_upper + 1) * 1000000 <= value and \ value < _uhf_lower * 1000000: raise InvalidValueError(msg % (_vhf_upper, _uhf_lower)) if self.BANDS == 3: if (_vhf_upper + 1) * 1000000 <= value and \ value < _vhf2_lower * 1000000: raise InvalidValueError(msg % (_vhf_upper, _vhf2_lower)) if (_vhf2_upper + 1) * 1000000 <= value and \ value < _uhf_lower * 1000000: raise InvalidValueError(msg % (_vhf2_upper, _uhf_lower)) if self.BANDS == 4: if (_vhf_upper + 1) * 1000000 <= value and \ value < _vhf2_lower * 1000000: raise InvalidValueError(msg % (_vhf_upper, _vhf2_lower)) if (_vhf2_upper + 1) * 1000000 <= value and \ value < _uhf2_lower * 1000000: raise InvalidValueError(msg % (_vhf2_upper, _uhf2_lower)) if (_uhf2_upper + 1) * 1000000 <= value and \ value < _uhf_lower * 1000000: raise InvalidValueError(msg % (_uhf2_upper, _uhf_lower)) msg = ("Can't be greater then %i.9975") if value > 99000000 and value >= _uhf_upper * 1000000: raise InvalidValueError(msg % (_uhf_upper)) return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 _vhf_upper = (convert_bytes_to_limit(_ranges.vhf_high)) _uhf_lower = (convert_bytes_to_limit(_ranges.uhf_low)) val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.a.freq)) val1a.set_validate_callback(my_validate) vfoafreq = RadioSetting("vfo.a.freq", "VFO A frequency", val1a) vfoafreq.set_apply_callback(apply_freq, _mem.vfo.a) work.append(vfoafreq) val = bfc.bcd_decode_freq(_mem.vfo.b.freq) if self.MODEL in ["GMRS-50V2", "GMRS-50X1"]: if val[:3] > _vhf_upper and val[:3] < _uhf_lower: val = "462.562500" val1b = RadioSettingValueString(0, 10, val) val1b.set_validate_callback(my_validate) vfobfreq = RadioSetting("vfo.b.freq", "VFO B frequency", val1b) vfobfreq.set_apply_callback(apply_freq, _mem.vfo.b) work.append(vfobfreq) if self.COLOR_LCD: val1c = RadioSettingValueString(0, 10, bfc.bcd_decode_freq( _mem.vfo.c.freq)) val1c.set_validate_callback(my_validate) vfocfreq = RadioSetting("vfo.c.freq", "VFO C frequency", val1c) vfocfreq.set_apply_callback(apply_freq, _mem.vfo.c) work.append(vfocfreq) if not self.COLOR_LCD4: val = bfc.bcd_decode_freq(_mem.vfo.d.freq) if self.MODEL in ["GMRS-50V2", "GMRS-50X1"]: if val[:3] > _vhf_upper and val[:3] < _uhf_lower: val = "462.562500" val1d = RadioSettingValueString(0, 10, val) val1d.set_validate_callback(my_validate) vfodfreq = RadioSetting("vfo.d.freq", "VFO D frequency", val1d) vfodfreq.set_apply_callback(apply_freq, _mem.vfo.d) work.append(vfodfreq) if not self.MODEL == "GMRS-50X1": val = min(_mem.vfo.a.shiftd, len(LIST_SHIFT) - 1) rs = RadioSettingValueList(LIST_SHIFT, LIST_SHIFT[val]) vfoashiftd = RadioSetting("vfo.a.shiftd", "VFO A shift", rs) work.append(vfoashiftd) val = min(_mem.vfo.b.shiftd, len(LIST_SHIFT) - 1) rs = RadioSettingValueList(LIST_SHIFT, LIST_SHIFT[val]) vfobshiftd = RadioSetting("vfo.b.shiftd", "VFO B shift", rs) work.append(vfobshiftd) if self.COLOR_LCD: val = min(_mem.vfo.c.shiftd, len(LIST_SHIFT) - 1) rs = RadioSettingValueList(LIST_SHIFT, LIST_SHIFT[val]) vfocshiftd = RadioSetting("vfo.c.shiftd", "VFO C shift", rs) work.append(vfocshiftd) if not self.COLOR_LCD4: val = min(_mem.vfo.d.shiftd, len(LIST_SHIFT) - 1) rs = RadioSettingValueList(LIST_SHIFT, LIST_SHIFT[val]) vfodshiftd = RadioSetting("vfo.d.shiftd", "VFO D shift", rs) work.append(vfodshiftd) def convert_bytes_to_offset(bytes): real_offset = 0 for byte in bytes: real_offset = (real_offset * 10) + byte return chirp_common.format_freq(real_offset * 1000) def apply_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 1000 for i in range(5, -1, -1): obj.offset[i] = value % 10 value /= 10 if not self.MODEL == "GMRS-50X1": if self.COLOR_LCD: val1a = RadioSettingValueString(0, 10, convert_bytes_to_offset( _mem.vfo.a.offset)) vfoaoffset = RadioSetting("vfo.a.offset", "VFO A offset (0.000-999.999)", val1a) vfoaoffset.set_apply_callback(apply_offset, _mem.vfo.a) work.append(vfoaoffset) val1b = RadioSettingValueString(0, 10, convert_bytes_to_offset( _mem.vfo.b.offset)) vfoboffset = RadioSetting("vfo.b.offset", "VFO B offset (0.000-999.999)", val1b) vfoboffset.set_apply_callback(apply_offset, _mem.vfo.b) work.append(vfoboffset) val1c = RadioSettingValueString(0, 10, convert_bytes_to_offset( _mem.vfo.c.offset)) vfocoffset = RadioSetting("vfo.c.offset", "VFO C offset (0.000-999.999)", val1c) vfocoffset.set_apply_callback(apply_offset, _mem.vfo.c) work.append(vfocoffset) if not self.COLOR_LCD4: val1d = RadioSettingValueString(0, 10, convert_bytes_to_offset( _mem.vfo.d.offset)) vfodoffset = RadioSetting("vfo.d.offset", "VFO D offset (0.000-999.999)", val1d) vfodoffset.set_apply_callback(apply_offset, _mem.vfo.d) work.append(vfodoffset) else: val1a = RadioSettingValueString(0, 10, convert_bytes_to_offset( _mem.vfo.a.offset)) vfoaoffset = RadioSetting("vfo.a.offset", "VFO A offset (0.000-99.999)", val1a) vfoaoffset.set_apply_callback(apply_offset, _mem.vfo.a) work.append(vfoaoffset) val1b = RadioSettingValueString(0, 10, convert_bytes_to_offset( _mem.vfo.b.offset)) vfoboffset = RadioSetting("vfo.b.offset", "VFO B offset (0.000-99.999)", val1b) vfoboffset.set_apply_callback(apply_offset, _mem.vfo.b) work.append(vfoboffset) if not self.MODEL == "GMRS-50X1": val = min(_mem.vfo.a.power, len(LIST_TXP) - 1) rs = RadioSettingValueList(LIST_TXP, LIST_TXP[val]) vfoatxp = RadioSetting("vfo.a.power", "VFO A power", rs) work.append(vfoatxp) val = min(_mem.vfo.b.power, len(LIST_TXP) - 1) rs = RadioSettingValueList(LIST_TXP, LIST_TXP[val]) vfobtxp = RadioSetting("vfo.b.power", "VFO B power", rs) work.append(vfobtxp) if self.COLOR_LCD: val = min(_mem.vfo.c.power, len(LIST_TXP) - 1) rs = RadioSettingValueList(LIST_TXP, LIST_TXP[val]) vfoctxp = RadioSetting("vfo.c.power", "VFO C power", rs) work.append(vfoctxp) if not self.COLOR_LCD4: val = min(_mem.vfo.d.power, len(LIST_TXP) - 1) rs = RadioSettingValueList(LIST_TXP, LIST_TXP[val]) vfodtxp = RadioSetting("vfo.d.power", "VFO D power", rs) work.append(vfodtxp) if not self.MODEL == "GMRS-50X1": val = min(_mem.vfo.a.wide, len(LIST_WIDE) - 1) rs = RadioSettingValueList(LIST_WIDE, LIST_WIDE[val]) vfoawide = RadioSetting("vfo.a.wide", "VFO A bandwidth", rs) work.append(vfoawide) val = min(_mem.vfo.b.wide, len(LIST_WIDE) - 1) rs = RadioSettingValueList(LIST_WIDE, LIST_WIDE[val]) vfobwide = RadioSetting("vfo.b.wide", "VFO B bandwidth", rs) work.append(vfobwide) if self.COLOR_LCD: val = min(_mem.vfo.c.wide, len(LIST_WIDE) - 1) rs = RadioSettingValueList(LIST_WIDE, LIST_WIDE[val]) vfocwide = RadioSetting("vfo.c.wide", "VFO C bandwidth", rs) work.append(vfocwide) if not self.COLOR_LCD4: val = min(_mem.vfo.d.wide, len(LIST_WIDE) - 1) rs = RadioSettingValueList(LIST_WIDE, LIST_WIDE[val]) vfodwide = RadioSetting("vfo.d.wide", "VFO D bandwidth", rs) work.append(vfodwide) val = min(_mem.vfo.a.step, len(LIST_STEP) - 1) rs = RadioSettingValueList(LIST_STEP, LIST_STEP[val]) vfoastep = RadioSetting("vfo.a.step", "VFO A step", rs) work.append(vfoastep) val = min(_mem.vfo.b.step, len(LIST_STEP) - 1) rs = RadioSettingValueList(LIST_STEP, LIST_STEP[val]) vfobstep = RadioSetting("vfo.b.step", "VFO B step", rs) work.append(vfobstep) if self.COLOR_LCD: val = min(_mem.vfo.c.step, len(LIST_STEP) - 1) rs = RadioSettingValueList(LIST_STEP, LIST_STEP[val]) vfocstep = RadioSetting("vfo.c.step", "VFO C step", rs) work.append(vfocstep) if not self.COLOR_LCD4: val = min(_mem.vfo.d.step, len(LIST_STEP) - 1) rs = RadioSettingValueList(LIST_STEP, LIST_STEP[val]) vfodstep = RadioSetting("vfo.d.step", "VFO D step", rs) work.append(vfodstep) val = min(_mem.vfo.a.optsig, len(OPTSIG_LIST) - 1) rs = RadioSettingValueList(OPTSIG_LIST, OPTSIG_LIST[val]) vfoaoptsig = RadioSetting("vfo.a.optsig", "VFO A optional signal", rs) work.append(vfoaoptsig) val = min(_mem.vfo.b.optsig, len(OPTSIG_LIST) - 1) rs = RadioSettingValueList(OPTSIG_LIST, OPTSIG_LIST[val]) vfoboptsig = RadioSetting("vfo.b.optsig", "VFO B optional signal", rs) work.append(vfoboptsig) if self.COLOR_LCD: val = min(_mem.vfo.c.optsig, len(OPTSIG_LIST) - 1) rs = RadioSettingValueList(OPTSIG_LIST, OPTSIG_LIST[val]) vfocoptsig = RadioSetting("vfo.c.optsig", "VFO C optional signal", rs) work.append(vfocoptsig) if not self.COLOR_LCD4: val = min(_mem.vfo.d.optsig, len(OPTSIG_LIST) - 1) rs = RadioSettingValueList(OPTSIG_LIST, OPTSIG_LIST[val]) vfodoptsig = RadioSetting("vfo.d.optsig", "VFO D optional signal", rs) work.append(vfodoptsig) val = min(_mem.vfo.a.spmute, len(SPMUTE_LIST) - 1) rs = RadioSettingValueList(SPMUTE_LIST, SPMUTE_LIST[val]) vfoaspmute = RadioSetting("vfo.a.spmute", "VFO A speaker mute", rs) work.append(vfoaspmute) val = min(_mem.vfo.b.spmute, len(SPMUTE_LIST) - 1) rs = RadioSettingValueList(SPMUTE_LIST, SPMUTE_LIST[val]) vfobspmute = RadioSetting("vfo.b.spmute", "VFO B speaker mute", rs) work.append(vfobspmute) if self.COLOR_LCD: val = min(_mem.vfo.c.spmute, len(SPMUTE_LIST) - 1) rs = RadioSettingValueList(SPMUTE_LIST, SPMUTE_LIST[val]) vfocspmute = RadioSetting("vfo.c.spmute", "VFO C speaker mute", rs) work.append(vfocspmute) if not self.COLOR_LCD4: val = min(_mem.vfo.d.spmute, len(SPMUTE_LIST) - 1) rs = RadioSettingValueList(SPMUTE_LIST, SPMUTE_LIST[val]) vfodspmute = RadioSetting("vfo.d.spmute", "VFO D speaker mute", rs) work.append(vfodspmute) if not self.COLOR_LCD or \ (self.COLOR_LCD and not self.VENDOR == "BTECH"): rs = RadioSettingValueBoolean(_mem.vfo.a.scramble) vfoascr = RadioSetting("vfo.a.scramble", "VFO A scramble", rs) work.append(vfoascr) rs = RadioSettingValueBoolean(_mem.vfo.b.scramble) vfobscr = RadioSetting("vfo.b.scramble", "VFO B scramble", rs) work.append(vfobscr) if self.COLOR_LCD and not self.VENDOR == "BTECH": rs = RadioSettingValueBoolean(_mem.vfo.c.scramble) vfocscr = RadioSetting("vfo.c.scramble", "VFO C scramble", rs) work.append(vfocscr) rs = RadioSettingValueBoolean(_mem.vfo.d.scramble) vfodscr = RadioSetting("vfo.d.scramble", "VFO D scramble", rs) work.append(vfodscr) if not self.MODEL == "GMRS-50X1": val = min(_mem.vfo.a.scode, len(PTTIDCODE_LIST) - 1) rs = RadioSettingValueList(PTTIDCODE_LIST, PTTIDCODE_LIST[val]) vfoascode = RadioSetting("vfo.a.scode", "VFO A PTT-ID", rs) work.append(vfoascode) val = min(_mem.vfo.b.scode, len(PTTIDCODE_LIST) - 1) rs = RadioSettingValueList(PTTIDCODE_LIST, PTTIDCODE_LIST[val]) vfobscode = RadioSetting("vfo.b.scode", "VFO B PTT-ID", rs) work.append(vfobscode) if self.COLOR_LCD: val = min(_mem.vfo.c.scode, len(PTTIDCODE_LIST) - 1) rs = RadioSettingValueList(PTTIDCODE_LIST, PTTIDCODE_LIST[val]) vfocscode = RadioSetting("vfo.c.scode", "VFO C PTT-ID", rs) work.append(vfocscode) if not self.COLOR_LCD4: val = min(_mem.vfo.d.scode, len(PTTIDCODE_LIST) - 1) rs = RadioSettingValueList(PTTIDCODE_LIST, PTTIDCODE_LIST[val]) vfodscode = RadioSetting("vfo.d.scode", "VFO D PTT-ID", rs) work.append(vfodscode) if not self.MODEL == "GMRS-50X1": val = min(_mem.settings.pttid, len(PTTID_LIST) - 1) rs = RadioSettingValueList(PTTID_LIST, PTTID_LIST[val]) pttid = RadioSetting("settings.pttid", "PTT ID", rs) work.append(pttid) if not self.COLOR_LCD: # FM presets fm_presets = RadioSettingGroup("fm_presets", "FM Presets") top.append(fm_presets) def fm_validate(value): if value == 0: return chirp_common.format_freq(value) if not (87.5 <= value and value <= 108.0): # 87.5-108 MHz msg = ("FM-Preset-Frequency: " + "Must be between 87.5 and 108 MHz") raise InvalidValueError(msg) return value def apply_fm_preset_name(setting, obj): valstring = str(setting.value) for i in range(0, 6): if valstring[i] in VALID_CHARS: obj[i] = valstring[i] else: obj[i] = '0xff' def apply_fm_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 _presets = self._memobj.fm_radio_preset i = 1 for preset in _presets: line = RadioSetting("fm_presets_" + str(i), "Station name " + str(i), RadioSettingValueString(0, 6, _filter( preset.broadcast_station_name))) line.set_apply_callback(apply_fm_preset_name, preset.broadcast_station_name) val = RadioSettingValueFloat(0, 108, bfc.bcd_decode_freq( preset.freq)) fmfreq = RadioSetting("fm_presets_" + str(i) + "_freq", "Frequency " + str(i), val) val.set_validate_callback(fm_validate) fmfreq.set_apply_callback(apply_fm_freq, preset) fm_presets.append(line) fm_presets.append(fmfreq) i = i + 1 # DTMF-Setting dtmf_enc_settings = RadioSettingGroup("dtmf_enc_settings", "DTMF Encoding Settings") dtmf_dec_settings = RadioSettingGroup("dtmf_dec_settings", "DTMF Decoding Settings") top.append(dtmf_enc_settings) top.append(dtmf_dec_settings) txdisable = RadioSetting("dtmf_settings.txdisable", "TX-Disable", RadioSettingValueBoolean( _mem.dtmf_settings.txdisable)) dtmf_enc_settings.append(txdisable) rxdisable = RadioSetting("dtmf_settings.rxdisable", "RX-Disable", RadioSettingValueBoolean( _mem.dtmf_settings.rxdisable)) dtmf_enc_settings.append(rxdisable) if _mem.dtmf_settings.dtmfspeed_on > 0x0F: val = 0x03 else: val = _mem.dtmf_settings.dtmfspeed_on dtmfspeed_on = RadioSetting( "dtmf_settings.dtmfspeed_on", "DTMF Speed (On Time)", RadioSettingValueList(LIST_DTMF_SPEED, LIST_DTMF_SPEED[ val])) dtmf_enc_settings.append(dtmfspeed_on) if _mem.dtmf_settings.dtmfspeed_off > 0x0F: val = 0x03 else: val = _mem.dtmf_settings.dtmfspeed_off dtmfspeed_off = RadioSetting( "dtmf_settings.dtmfspeed_off", "DTMF Speed (Off Time)", RadioSettingValueList(LIST_DTMF_SPEED, LIST_DTMF_SPEED[ val])) dtmf_enc_settings.append(dtmfspeed_off) def memory2string(dmtf_mem): dtmf_string = "" for digit in dmtf_mem: if digit != 255: index = LIST_DTMF_VALUES.index(digit) dtmf_string = dtmf_string + LIST_DTMF_DIGITS[index] return dtmf_string def apply_dmtf_frame(setting, obj): LOG.debug("Setting DTMF-Code: " + str(setting.value)) val_string = str(setting.value) for i in range(0, 16): obj[i] = 255 i = 0 for current_char in val_string: current_char = current_char.upper() index = LIST_DTMF_DIGITS.index(current_char) obj[i] = LIST_DTMF_VALUES[index] i = i + 1 codes = self._memobj.dtmf_codes i = 1 for dtmfcode in codes: val = RadioSettingValueString(0, 16, memory2string( dtmfcode.code), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_code_" + str(i) + "_code", "DMTF Code " + str(i), val) line.set_apply_callback(apply_dmtf_frame, dtmfcode.code) dtmf_enc_settings.append(line) i = i + 1 line = RadioSetting("dtmf_settings.mastervice", "Master and Vice ID", RadioSettingValueBoolean( _mem.dtmf_settings.mastervice)) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.masterid), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.masterid", "Master Control ID ", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.masterid) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.minspection", "Master Inspection", RadioSettingValueBoolean( _mem.dtmf_settings.minspection)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.mmonitor", "Master Monitor", RadioSettingValueBoolean( _mem.dtmf_settings.mmonitor)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.mstun", "Master Stun", RadioSettingValueBoolean( _mem.dtmf_settings.mstun)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.mkill", "Master Kill", RadioSettingValueBoolean( _mem.dtmf_settings.mkill)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.mrevive", "Master Revive", RadioSettingValueBoolean( _mem.dtmf_settings.mrevive)) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.viceid), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.viceid", "Vice Control ID ", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.viceid) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.vinspection", "Vice Inspection", RadioSettingValueBoolean( _mem.dtmf_settings.vinspection)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.vmonitor", "Vice Monitor", RadioSettingValueBoolean( _mem.dtmf_settings.vmonitor)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.vstun", "Vice Stun", RadioSettingValueBoolean( _mem.dtmf_settings.vstun)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.vkill", "Vice Kill", RadioSettingValueBoolean( _mem.dtmf_settings.vkill)) dtmf_dec_settings.append(line) line = RadioSetting("dtmf_settings.vrevive", "Vice Revive", RadioSettingValueBoolean( _mem.dtmf_settings.vrevive)) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.inspection), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.inspection", "Inspection", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.inspection) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.alarmcode), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.alarmcode", "Alarm", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.alarmcode) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.kill), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.kill", "Kill", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.kill) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.monitor), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.monitor", "Monitor", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.monitor) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.stun), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.stun", "Stun", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.stun) dtmf_dec_settings.append(line) val = RadioSettingValueString(0, 16, memory2string( _mem.dtmf_settings.revive), False, CHARSET_DTMF_DIGITS) line = RadioSetting("dtmf_settings.revive", "Revive", val) line.set_apply_callback(apply_dmtf_frame, _mem.dtmf_settings.revive) dtmf_dec_settings.append(line) def apply_dmtf_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = LIST_DTMF_SPECIAL_DIGITS.index(val) val = LIST_DTMF_SPECIAL_VALUES[index] obj.set_value(val) if _mem.dtmf_settings.groupcode not in LIST_DTMF_SPECIAL_VALUES: val = 0x0B else: val = _mem.dtmf_settings.groupcode idx = LIST_DTMF_SPECIAL_VALUES.index(val) line = RadioSetting( "dtmf_settings.groupcode", "Group Code", RadioSettingValueList(LIST_DTMF_SPECIAL_DIGITS, LIST_DTMF_SPECIAL_DIGITS[idx])) line.set_apply_callback(apply_dmtf_listvalue, _mem.dtmf_settings.groupcode) dtmf_dec_settings.append(line) if _mem.dtmf_settings.spacecode not in LIST_DTMF_SPECIAL_VALUES: val = 0x0C else: val = _mem.dtmf_settings.spacecode idx = LIST_DTMF_SPECIAL_VALUES.index(val) line = RadioSetting( "dtmf_settings.spacecode", "Space Code", RadioSettingValueList(LIST_DTMF_SPECIAL_DIGITS, LIST_DTMF_SPECIAL_DIGITS[idx])) line.set_apply_callback(apply_dmtf_listvalue, _mem.dtmf_settings.spacecode) dtmf_dec_settings.append(line) if self.COLOR_LCD: if _mem.dtmf_settings.resettime > 0x63: val = 0x4F else: val = _mem.dtmf_settings.resettime line = RadioSetting( "dtmf_settings.resettime", "Reset time", RadioSettingValueList(LIST_5TONE_RESET_COLOR, LIST_5TONE_RESET_COLOR[ val])) dtmf_dec_settings.append(line) else: line = RadioSetting( "dtmf_settings.resettime", "Reset time", RadioSettingValueList(LIST_5TONE_RESET, LIST_5TONE_RESET[ _mem.dtmf_settings.resettime])) dtmf_dec_settings.append(line) if _mem.dtmf_settings.delayproctime > 0x27: val = 0x04 else: val = _mem.dtmf_settings.delayproctime line = RadioSetting( "dtmf_settings.delayproctime", "Delay processing time", RadioSettingValueList(LIST_DTMF_DELAY, LIST_DTMF_DELAY[ val])) dtmf_dec_settings.append(line) # 5 Tone Settings stds_5tone = RadioSettingGroup("stds_5tone", "Standards") codes_5tone = RadioSettingGroup("codes_5tone", "Codes") group_5tone = RadioSettingGroup("group_5tone", "5 Tone Settings") group_5tone.append(stds_5tone) group_5tone.append(codes_5tone) top.append(group_5tone) def apply_list_value(setting, obj): options = setting.value.get_options() obj.set_value(options.index(str(setting.value))) _5tone_standards = self._memobj._5tone_std_settings i = 0 for standard in _5tone_standards: std_5tone = RadioSettingGroup("std_5tone_" + str(i), LIST_5TONE_STANDARDS[i]) stds_5tone.append(std_5tone) period = standard.period if period == 255: LOG.debug("Period for " + LIST_5TONE_STANDARDS[i] + " is not yet configured. Setting to 70ms.") period = 5 if period <= len(LIST_5TONE_STANDARD_PERIODS): line = RadioSetting( "_5tone_std_settings_" + str(i) + "_period", "Period (ms)", RadioSettingValueList (LIST_5TONE_STANDARD_PERIODS, LIST_5TONE_STANDARD_PERIODS[period])) line.set_apply_callback(apply_list_value, standard.period) std_5tone.append(line) else: LOG.debug("Invalid value for 5tone period! Disabling.") group_tone = standard.group_tone if group_tone == 255: LOG.debug("Group-Tone for " + LIST_5TONE_STANDARDS[i] + " is not yet configured. Setting to A.") group_tone = 10 if group_tone <= len(LIST_5TONE_DIGITS): line = RadioSetting( "_5tone_std_settings_" + str(i) + "_grouptone", "Group Tone", RadioSettingValueList(LIST_5TONE_DIGITS, LIST_5TONE_DIGITS[ group_tone])) line.set_apply_callback(apply_list_value, standard.group_tone) std_5tone.append(line) else: LOG.debug("Invalid value for 5tone digit! Disabling.") repeat_tone = standard.repeat_tone if repeat_tone == 255: LOG.debug("Repeat-Tone for " + LIST_5TONE_STANDARDS[i] + " is not yet configured. Setting to E.") repeat_tone = 14 if repeat_tone <= len(LIST_5TONE_DIGITS): line = RadioSetting( "_5tone_std_settings_" + str(i) + "_repttone", "Repeat Tone", RadioSettingValueList(LIST_5TONE_DIGITS, LIST_5TONE_DIGITS[ repeat_tone])) line.set_apply_callback(apply_list_value, standard.repeat_tone) std_5tone.append(line) else: LOG.debug("Invalid value for 5tone digit! Disabling.") i = i + 1 def my_apply_5tonestdlist_value(setting, obj): if LIST_5TONE_STANDARDS.index(str(setting.value)) == 15: obj.set_value(0xFF) else: obj.set_value(LIST_5TONE_STANDARDS. index(str(setting.value))) def apply_5tone_frame(setting, obj): LOG.debug("Setting 5 Tone: " + str(setting.value)) valstring = str(setting.value) if len(valstring) == 0: for i in range(0, 5): obj[i] = 255 else: validFrame = True for i in range(0, 5): currentChar = valstring[i].upper() if currentChar in LIST_5TONE_DIGITS: obj[i] = LIST_5TONE_DIGITS.index(currentChar) else: validFrame = False LOG.debug("invalid char: " + str(currentChar)) if not validFrame: LOG.debug("setting whole frame to FF") for i in range(0, 5): obj[i] = 255 def validate_5tone_frame(value): if (len(str(value)) != 5) and (len(str(value)) != 0): msg = ("5 Tone must have 5 digits or 0 digits") raise InvalidValueError(msg) for digit in str(value): if digit.upper() not in LIST_5TONE_DIGITS: msg = (str(digit) + " is not a valid digit for 5tones") raise InvalidValueError(msg) return value def frame2string(frame): frameString = "" for digit in frame: if digit != 255: frameString = frameString + LIST_5TONE_DIGITS[digit] return frameString _5tone_codes = self._memobj._5tone_codes i = 1 for code in _5tone_codes: code_5tone = RadioSettingGroup("code_5tone_" + str(i), "5 Tone code " + str(i)) codes_5tone.append(code_5tone) if (code.standard == 255): currentVal = 15 else: currentVal = code.standard line = RadioSetting("_5tone_code_" + str(i) + "_std", " Standard", RadioSettingValueList(LIST_5TONE_STANDARDS, LIST_5TONE_STANDARDS[ currentVal])) line.set_apply_callback(my_apply_5tonestdlist_value, code.standard) code_5tone.append(line) val = RadioSettingValueString(0, 6, frame2string(code.frame1), False) line = RadioSetting("_5tone_code_" + str(i) + "_frame1", " Frame 1", val) val.set_validate_callback(validate_5tone_frame) line.set_apply_callback(apply_5tone_frame, code.frame1) code_5tone.append(line) val = RadioSettingValueString(0, 6, frame2string(code.frame2), False) line = RadioSetting("_5tone_code_" + str(i) + "_frame2", " Frame 2", val) val.set_validate_callback(validate_5tone_frame) line.set_apply_callback(apply_5tone_frame, code.frame2) code_5tone.append(line) val = RadioSettingValueString(0, 6, frame2string(code.frame3), False) line = RadioSetting("_5tone_code_" + str(i) + "_frame3", " Frame 3", val) val.set_validate_callback(validate_5tone_frame) line.set_apply_callback(apply_5tone_frame, code.frame3) code_5tone.append(line) i = i + 1 _5_tone_decode1 = RadioSetting( "_5tone_settings._5tone_decode_call_frame1", "5 Tone decode call Frame 1", RadioSettingValueBoolean( _mem._5tone_settings._5tone_decode_call_frame1)) group_5tone.append(_5_tone_decode1) _5_tone_decode2 = RadioSetting( "_5tone_settings._5tone_decode_call_frame2", "5 Tone decode call Frame 2", RadioSettingValueBoolean( _mem._5tone_settings._5tone_decode_call_frame2)) group_5tone.append(_5_tone_decode2) _5_tone_decode3 = RadioSetting( "_5tone_settings._5tone_decode_call_frame3", "5 Tone decode call Frame 3", RadioSettingValueBoolean( _mem._5tone_settings._5tone_decode_call_frame3)) group_5tone.append(_5_tone_decode3) _5_tone_decode_disp1 = RadioSetting( "_5tone_settings._5tone_decode_disp_frame1", "5 Tone decode disp Frame 1", RadioSettingValueBoolean( _mem._5tone_settings._5tone_decode_disp_frame1)) group_5tone.append(_5_tone_decode_disp1) _5_tone_decode_disp2 = RadioSetting( "_5tone_settings._5tone_decode_disp_frame2", "5 Tone decode disp Frame 2", RadioSettingValueBoolean( _mem._5tone_settings._5tone_decode_disp_frame2)) group_5tone.append(_5_tone_decode_disp2) _5_tone_decode_disp3 = RadioSetting( "_5tone_settings._5tone_decode_disp_frame3", "5 Tone decode disp Frame 3", RadioSettingValueBoolean( _mem._5tone_settings._5tone_decode_disp_frame3)) group_5tone.append(_5_tone_decode_disp3) decode_standard = _mem._5tone_settings.decode_standard if decode_standard == 255: decode_standard = 0 if decode_standard <= len(LIST_5TONE_STANDARDS_without_none): line = RadioSetting("_5tone_settings.decode_standard", "5 Tone-decode Standard", RadioSettingValueList( LIST_5TONE_STANDARDS_without_none, LIST_5TONE_STANDARDS_without_none[ decode_standard])) group_5tone.append(line) else: LOG.debug("Invalid decode std...") _5tone_delay1 = _mem._5tone_settings._5tone_delay1 if _5tone_delay1 == 255: _5tone_delay1 = 20 if _5tone_delay1 <= len(LIST_5TONE_DELAY): list = RadioSettingValueList(LIST_5TONE_DELAY, LIST_5TONE_DELAY[ _5tone_delay1]) line = RadioSetting("_5tone_settings._5tone_delay1", "5 Tone Delay Frame 1", list) group_5tone.append(line) else: LOG.debug( "Invalid value for 5tone delay (frame1) ! Disabling.") _5tone_delay2 = _mem._5tone_settings._5tone_delay2 if _5tone_delay2 == 255: _5tone_delay2 = 20 LOG.debug("5 Tone delay unconfigured! Resetting to 200ms.") if _5tone_delay2 <= len(LIST_5TONE_DELAY): list = RadioSettingValueList(LIST_5TONE_DELAY, LIST_5TONE_DELAY[ _5tone_delay2]) line = RadioSetting("_5tone_settings._5tone_delay2", "5 Tone Delay Frame 2", list) group_5tone.append(line) else: LOG.debug("Invalid value for 5tone delay (frame2)! Disabling.") _5tone_delay3 = _mem._5tone_settings._5tone_delay3 if _5tone_delay3 == 255: _5tone_delay3 = 20 LOG.debug("5 Tone delay unconfigured! Resetting to 200ms.") if _5tone_delay3 <= len(LIST_5TONE_DELAY): list = RadioSettingValueList(LIST_5TONE_DELAY, LIST_5TONE_DELAY[ _5tone_delay3]) line = RadioSetting("_5tone_settings._5tone_delay3", "5 Tone Delay Frame 3", list) group_5tone.append(line) else: LOG.debug("Invalid value for 5tone delay (frame3)! Disabling.") ext_length = _mem._5tone_settings._5tone_first_digit_ext_length if ext_length == 255: ext_length = 0 LOG.debug("1st Tone ext length unconfigured! Resetting to 0") if ext_length <= len(LIST_5TONE_DELAY): list = RadioSettingValueList( LIST_5TONE_DELAY, LIST_5TONE_DELAY[ ext_length]) line = RadioSetting( "_5tone_settings._5tone_first_digit_ext_length", "First digit extend length", list) group_5tone.append(line) else: LOG.debug("Invalid value for 5tone ext length! Disabling.") decode_reset_time = _mem._5tone_settings.decode_reset_time if decode_reset_time == 255: decode_reset_time = 59 LOG.debug("Decode reset time unconfigured. resetting.") if decode_reset_time <= len(LIST_5TONE_RESET): list = RadioSettingValueList( LIST_5TONE_RESET, LIST_5TONE_RESET[ decode_reset_time]) line = RadioSetting("_5tone_settings.decode_reset_time", "Decode reset time", list) group_5tone.append(line) else: LOG.debug("Invalid value decode reset time! Disabling.") # 2 Tone encode_2tone = RadioSettingGroup("encode_2tone", "2 Tone Encode") decode_2tone = RadioSettingGroup("decode_2tone", "2 Code Decode") top.append(encode_2tone) top.append(decode_2tone) duration_1st_tone = self._memobj._2tone.duration_1st_tone if duration_1st_tone == 255: LOG.debug("Duration of first 2 Tone digit is not yet " + "configured. Setting to 600ms") duration_1st_tone = 60 if duration_1st_tone <= len(LIST_5TONE_DELAY): val = RadioSettingValueList(LIST_5TONE_DELAY, LIST_5TONE_DELAY[ duration_1st_tone]) line = RadioSetting("_2tone.duration_1st_tone", "Duration 1st Tone", val) encode_2tone.append(line) duration_2nd_tone = self._memobj._2tone.duration_2nd_tone if duration_2nd_tone == 255: LOG.debug("Duration of second 2 Tone digit is not yet " + "configured. Setting to 600ms") duration_2nd_tone = 60 if duration_2nd_tone <= len(LIST_5TONE_DELAY): val = RadioSettingValueList(LIST_5TONE_DELAY, LIST_5TONE_DELAY[ duration_2nd_tone]) line = RadioSetting("_2tone.duration_2nd_tone", "Duration 2nd Tone", val) encode_2tone.append(line) duration_gap = self._memobj._2tone.duration_gap if duration_gap == 255: LOG.debug("Duration of gap is not yet " + "configured. Setting to 300ms") duration_gap = 30 if duration_gap <= len(LIST_5TONE_DELAY): line = RadioSetting("_2tone.duration_gap", "Duration of gap", RadioSettingValueList(LIST_5TONE_DELAY, LIST_5TONE_DELAY[ duration_gap])) encode_2tone.append(line) def _2tone_validate(value): if value == 0: return 65535 if value == 65535: return value if not (300 <= value and value <= 3000): msg = ("2 Tone Frequency: Must be between 300 and 3000 Hz") raise InvalidValueError(msg) return value def apply_2tone_freq(setting, obj): val = int(setting.value) if (val == 0) or (val == 65535): obj.set_value(65535) else: obj.set_value(val) i = 1 for code in self._memobj._2tone._2tone_encode: code_2tone = RadioSettingGroup("code_2tone_" + str(i), "Encode Code " + str(i)) encode_2tone.append(code_2tone) tmp = code.freq1 if tmp == 65535: tmp = 0 val1 = RadioSettingValueInteger(0, 65535, tmp) freq1 = RadioSetting("2tone_code_" + str(i) + "_freq1", "Frequency 1", val1) val1.set_validate_callback(_2tone_validate) freq1.set_apply_callback(apply_2tone_freq, code.freq1) code_2tone.append(freq1) tmp = code.freq2 if tmp == 65535: tmp = 0 val2 = RadioSettingValueInteger(0, 65535, tmp) freq2 = RadioSetting("2tone_code_" + str(i) + "_freq2", "Frequency 2", val2) val2.set_validate_callback(_2tone_validate) freq2.set_apply_callback(apply_2tone_freq, code.freq2) code_2tone.append(freq2) i = i + 1 decode_reset_time = _mem._2tone.reset_time if decode_reset_time == 255: decode_reset_time = 59 LOG.debug("Decode reset time unconfigured. resetting.") if decode_reset_time <= len(LIST_5TONE_RESET): list = RadioSettingValueList( LIST_5TONE_RESET, LIST_5TONE_RESET[ decode_reset_time]) line = RadioSetting("_2tone.reset_time", "Decode reset time", list) decode_2tone.append(line) else: LOG.debug("Invalid value decode reset time! Disabling.") def apply_2tone_freq_pair(setting, obj): val = int(setting.value) derived_val = 65535 frqname = str(setting._name[-5:]) derivedname = "derived_from_" + frqname if (val == 0): val = 65535 derived_val = 65535 else: derived_val = int(round(2304000.0/val)) obj[frqname].set_value(val) obj[derivedname].set_value(derived_val) LOG.debug("Apply " + frqname + ": " + str(val) + " | " + derivedname + ": " + str(derived_val)) i = 1 for decode_code in self._memobj._2tone._2tone_decode: _2tone_dec_code = RadioSettingGroup("code_2tone_" + str(i), "Decode Code " + str(i)) decode_2tone.append(_2tone_dec_code) j = 1 for dec in decode_code.decs: val = dec.dec if val == 255: LOG.debug("Dec for Code " + str(i) + " Dec " + str(j) + " is not yet configured. Setting to 0.") val = 0 if val <= len(LIST_2TONE_DEC): line = RadioSetting( "_2tone_dec_settings_" + str(i) + "_dec_" + str(j), "Dec " + str(j), RadioSettingValueList (LIST_2TONE_DEC, LIST_2TONE_DEC[val])) line.set_apply_callback(apply_list_value, dec.dec) _2tone_dec_code.append(line) else: LOG.debug("Invalid value for 2tone dec! Disabling.") val = dec.response if val == 255: LOG.debug("Response for Code " + str(i) + " Dec " + str(j) + " is not yet configured. Setting to 0.") val = 0 if val <= len(LIST_2TONE_RESPONSE): line = RadioSetting( "_2tone_dec_settings_" + str(i) + "_resp_" + str(j), "Response " + str(j), RadioSettingValueList (LIST_2TONE_RESPONSE, LIST_2TONE_RESPONSE[val])) line.set_apply_callback(apply_list_value, dec.response) _2tone_dec_code.append(line) else: LOG.debug( "Invalid value for 2tone response! Disabling.") val = dec.alert if val == 255: LOG.debug("Alert for Code " + str(i) + " Dec " + str(j) + " is not yet configured. Setting to 0.") val = 0 if val <= len(PTTIDCODE_LIST): line = RadioSetting( "_2tone_dec_settings_" + str(i) + "_alert_" + str(j), "Alert " + str(j), RadioSettingValueList (PTTIDCODE_LIST, PTTIDCODE_LIST[val])) line.set_apply_callback(apply_list_value, dec.alert) _2tone_dec_code.append(line) else: LOG.debug("Invalid value for 2tone alert! Disabling.") j = j + 1 freq = self._memobj._2tone.freqs[i-1] for char in ['A', 'B', 'C', 'D']: setting_name = "freq" + str(char) tmp = freq[setting_name] if tmp == 65535: tmp = 0 if tmp != 0: expected = int(round(2304000.0/int(tmp))) from_mem = freq["derived_from_" + setting_name] if expected != from_mem: LOG.error("Expected " + str(expected) + " but read " + str(from_mem) + ". Disabling 2Tone Decode Freqs!") break val = RadioSettingValueInteger(0, 65535, tmp) frq = RadioSetting("2tone_dec_" + str(i) + "_freq" + str(char), ("Decode Frequency " + str(char)), val) val.set_validate_callback(_2tone_validate) frq.set_apply_callback(apply_2tone_freq_pair, freq) _2tone_dec_code.append(frq) i = i + 1 return top def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "volume" and self.MODEL == "KT-WP12": setattr(obj, setting, int(element.value) - 1) elif setting == "volume" and self.MODEL == "WP-9900": setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == MEM_SIZE: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1:2, spmute:2, unknown2:2, optsig:2; u8 unknown3:3, scramble:1, unknown4:3, power:1; u8 unknown5:1, wide:1, unknown6:2, bcl:1, add:1, pttid:2; } memory[200]; #seekto 0x0E00; struct { u8 unusedE00:7, tdr:1; u8 unknown1; u8 sql; u8 unknown2[2]; u8 tot; u8 apo; // BTech radios use this as the Auto Power Off time // other radios use this as pre-Time Out Alert u8 unknown3; u8 abr; u8 unusedE09:7, beep:1; u8 unknown4[4]; u8 dtmfst; u8 unknown5[2]; u8 unusedE11:7, prisc:1; u8 prich; u8 screv; u8 unknown6[2]; u8 pttid; u8 pttlt; u8 unknown7; u8 emctp; u8 emcch; u8 ringt; u8 unknown8; u8 camdf; u8 cbmdf; u8 unusedE1F:7, sync:1; // BTech radios use this as the display sync setting // other radios use this as the auto keypad lock setting u8 ponmsg; u8 wtled; u8 rxled; u8 txled; u8 unknown9[5]; u8 anil; u8 reps; u8 repm; u8 tdrab; u8 unusedE2D:7, ste:1; u8 rpste; u8 rptdl; u8 mgain; u8 dtmfg; } settings; #seekto 0x0E80; struct { u8 unknown1; u8 vfomr; u8 unusedE82:7, keylock:1; u8 unknown2; u8 unknown3:4, vfomren:1, unknown4:1, reseten:1, menuen:1; u8 unknown5[11]; u8 dispab; u8 mrcha; u8 mrchb; u8 menu; } settings2; #seekto 0x0EC0; struct { char line1[6]; char line2[6]; } poweron_msg; struct settings_vfo { u8 freq[8]; u8 offset[6]; u8 unknown2[2]; ul16 rxtone; ul16 txtone; u8 scode; u8 spmute; u8 optsig; u8 unused1:7, scramble:1; u8 wide; u8 power; u8 shiftd; u8 step; u8 unknown3[4]; }; #seekto 0x0F00; struct { struct settings_vfo a; struct settings_vfo b; } vfo; #seekto 0x1000; struct { char name[6]; u8 unknown1[10]; } names[200]; #seekto 0x2400; struct { u8 period; // one out of LIST_5TONE_STANDARD_PERIODS u8 group_tone; u8 repeat_tone; u8 unused[13]; } _5tone_std_settings[15]; #seekto 0x2500; struct { u8 frame1[5]; u8 frame2[5]; u8 frame3[5]; u8 standard; // one out of LIST_5TONE_STANDARDS } _5tone_codes[15]; // #seekto 0x25F0; struct { u8 _5tone_delay1; // * 10ms u8 _5tone_delay2; // * 10ms u8 _5tone_delay3; // * 10ms u8 _5tone_first_digit_ext_length; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 decode_standard; u8 unknown5:5, _5tone_decode_call_frame3:1, _5tone_decode_call_frame2:1, _5tone_decode_call_frame1:1; u8 unknown6:5, _5tone_decode_disp_frame3:1, _5tone_decode_disp_frame2:1, _5tone_decode_disp_frame1:1; u8 decode_reset_time; // * 100 + 100ms } _5tone_settings; #seekto 0x2900; struct { u8 code[16]; // 0=x0A, A=0x0D, B=0x0E, C=0x0F, D=0x00, #=0x0C *=0x0B } dtmf_codes[15]; // #seekto 0x29F0; struct { u8 dtmfspeed_on; //list with 50..2000ms in steps of 10 u8 dtmfspeed_off; //list with 50..2000ms in steps of 10 u8 unknown0[14]; u8 inspection[16]; u8 monitor[16]; u8 alarmcode[16]; u8 stun[16]; u8 kill[16]; u8 revive[16]; u8 unknown1[16]; u8 unknown2[16]; u8 unknown3[16]; u8 unknown4[16]; u8 unknown5[16]; u8 unknown6[16]; u8 unknown7[16]; u8 masterid[16]; u8 viceid[16]; u8 unused01:7, mastervice:1; u8 unused02:3, mrevive:1, mkill:1, mstun:1, mmonitor:1, minspection:1; u8 unused03:3, vrevive:1, vkill:1, vstun:1, vmonitor:1, vinspection:1; u8 unused04:6, txdisable:1, rxdisable:1; u8 groupcode; u8 spacecode; u8 delayproctime; // * 100 + 100ms u8 resettime; // * 100 + 100ms } dtmf_settings; #seekto 0x2D00; struct { struct { ul16 freq1; u8 unused01[6]; ul16 freq2; u8 unused02[6]; } _2tone_encode[15]; u8 duration_1st_tone; // *10ms u8 duration_2nd_tone; // *10ms u8 duration_gap; // *10ms u8 unused03[13]; struct { struct { u8 dec; // one out of LIST_2TONE_DEC u8 response; // one out of LIST_2TONE_RESPONSE u8 alert; // 1-16 } decs[4]; u8 unused04[4]; } _2tone_decode[15]; u8 unused05[16]; struct { ul16 freqA; ul16 freqB; ul16 freqC; ul16 freqD; // unknown what those values mean, but they are // derived from configured frequencies ul16 derived_from_freqA; // 2304000/freqA ul16 derived_from_freqB; // 2304000/freqB ul16 derived_from_freqC; // 2304000/freqC ul16 derived_from_freqD; // 2304000/freqD }freqs[15]; u8 reset_time; // * 100 + 100ms - 100-8000ms } _2tone; #seekto 0x3000; struct { u8 freq[8]; char broadcast_station_name[6]; u8 unknown[2]; } fm_radio_preset[16]; #seekto 0x3C90; struct { u8 vhf_low[3]; u8 vhf_high[3]; u8 uhf_low[3]; u8 uhf_high[3]; } ranges; // the UV-2501+220 & KT8900R has different zones for storing ranges #seekto 0x3CD0; struct { u8 vhf_low[3]; u8 vhf_high[3]; u8 unknown1[4]; u8 unknown2[6]; u8 vhf2_low[3]; u8 vhf2_high[3]; u8 unknown3[4]; u8 unknown4[6]; u8 uhf_low[3]; u8 uhf_high[3]; } ranges220; #seekto 0x3F70; struct { char fp[6]; } fingerprint; """ class BTech(BTechMobileCommon): """BTECH's UV-5001 and alike radios""" BANDS = 2 COLOR_LCD = False NAME_LENGTH = 6 def set_options(self): """This is to read the options from the image and set it in the environment, for now just the limits of the freqs in the VHF/UHF ranges""" # setting the correct ranges for each radio type if self.MODEL in ["UV-2501+220", "KT8900R"]: # the model 2501+220 has a segment in 220 # and a different position in the memmap # also the QYT KT8900R ranges = self._memobj.ranges220 else: ranges = self._memobj.ranges # the normal dual bands vhf = _decode_ranges(ranges.vhf_low, ranges.vhf_high) uhf = _decode_ranges(ranges.uhf_low, ranges.uhf_high) # DEBUG LOG.info("Radio ranges: VHF %d to %d" % vhf) LOG.info("Radio ranges: UHF %d to %d" % uhf) # 220 MHz radios case if self.MODEL in ["UV-2501+220", "KT8900R"]: vhf2 = _decode_ranges(ranges.vhf2_low, ranges.vhf2_high) LOG.info("Radio ranges: VHF(220) %d to %d" % vhf2) self._220_range = vhf2 # set the class with the real data self._vhf_range = vhf self._uhf_range = uhf def process_mmap(self): """Process the mem map into the mem object""" # Get it self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # load specific parameters from the radio image self.set_options() # Declaring Aliases (Clones of the real radios) class JT2705M(chirp_common.Alias): VENDOR = "Jetstream" MODEL = "JT2705M" class JT6188Mini(chirp_common.Alias): VENDOR = "Juentai" MODEL = "JT-6188 Mini" class JT6188Plus(chirp_common.Alias): VENDOR = "Juentai" MODEL = "JT-6188 Plus" class SSGT890(chirp_common.Alias): VENDOR = "Sainsonic" MODEL = "GT-890" class ZastoneMP300(chirp_common.Alias): VENDOR = "Zastone" MODEL = "MP-300" # real radios @directory.register class UV2501(BTech): """Baofeng Tech UV2501""" MODEL = "UV-2501" _fileid = [UV2501G3_fp, UV2501G2_fp, UV2501pp2_fp, UV2501pp_fp] @directory.register class UV2501_220(BTech): """Baofeng Tech UV2501+220""" MODEL = "UV-2501+220" BANDS = 3 _magic = MSTRING_220 _fileid = [UV2501_220G3_fp, UV2501_220G2_fp, UV2501_220_fp, UV2501_220pp_fp] @directory.register class UV5001(BTech): """Baofeng Tech UV5001""" MODEL = "UV-5001" _fileid = [UV5001G3_fp, UV5001G22_fp, UV5001G2_fp, UV5001alpha_fp, UV5001pp_fp] _power_levels = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Low", watts=10)] @directory.register class MINI8900(BTech): """WACCOM MINI-8900""" VENDOR = "WACCOM" MODEL = "MINI-8900" _magic = MSTRING_MINI8900 _fileid = [MINI8900_fp] # Clones ALIASES = [JT6188Plus] @directory.register class KTUV980(BTech): """QYT KT-UV980""" VENDOR = "QYT" MODEL = "KT-UV980" _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_MINI8900 _fileid = [KTUV980_fp] # Clones ALIASES = [JT2705M] # Please note that there is a version of this radios that is a clone of the # Waccom Mini8900, maybe an early version? class OTGRadioV1(chirp_common.Alias): VENDOR = 'OTGSTUFF' MODEL = 'OTG Radio v1' @directory.register class KT9800(BTech): """QYT KT8900""" VENDOR = "QYT" MODEL = "KT8900" _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_KT8900 _fileid = [KT8900_fp, KT8900_fp1, KT8900_fp2, KT8900_fp3, KT8900_fp4, KT8900_fp5, KT8900_fp6, KT8900_fp7] # Clones ALIASES = [JT6188Mini, SSGT890, ZastoneMP300] @directory.register class KT9800R(BTech): """QYT KT8900R""" VENDOR = "QYT" MODEL = "KT8900R" BANDS = 3 _vhf_range = (136000000, 175000000) _220_range = (240000000, 271000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_KT8900R _fileid = [KT8900R_fp, KT8900R_fp1, KT8900R_fp2, KT8900R_fp3, KT8900R_fp4, KT8900R_fp5] @directory.register class LT588UV(BTech): """LUITON LT-588UV""" VENDOR = "LUITON" MODEL = "LT-588UV" _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_KT8900 _fileid = [LT588UV_fp, LT588UV_fp1] _power_levels = [chirp_common.PowerLevel("High", watts=60), chirp_common.PowerLevel("Low", watts=10)] COLOR_MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1:2, spmute:2, unknown2:2, optsig:2; u8 unknown3:3, scramble:1, unknown4:2, power:2; u8 unknown5:1, wide:1, unknown6:2, bcl:1, add:1, pttid:2; } memory[200]; #seekto 0x0E00; struct { u8 tmr; u8 unknown1; u8 sql; u8 unknown2; u8 mgain2; u8 tot; u8 apo; u8 unknown3; u8 abr; u8 unusedE09:7, beep:1; u8 unknown4[4]; u8 dtmfst; u8 unknown5[2]; u8 screv; u8 unknown6[2]; u8 pttid; u8 pttlt; u8 unknown7; u8 emctp; u8 emcch; u8 unusedE19:7, sigbp:1; u8 unknown8; u8 camdf; u8 cbmdf; u8 ccmdf; u8 cdmdf; u8 langua; // BTech Gen2 radios have removed the Language setting // use this as the VOX setting u8 sync; // BTech radios use this as the display sync // setting, other radios use this as the auto // keypad lock setting u8 mainfc; u8 mainbc; u8 menufc; u8 menubc; u8 stafc; u8 stabc; u8 sigfc; u8 sigbc; u8 rxfc; u8 txfc; u8 txdisp; u8 unknown9[5]; u8 anil; u8 reps; u8 repm; u8 tmrmr; u8 unusedE35:7, ste:1; u8 rpste; u8 rptdl; u8 dtmfg; u8 mgain; // used by db25-g for ponyey u8 skiptx; u8 scmode; u8 tmrtx; u8 earpho; } settings; #seekto 0x0E80; struct { u8 unknown1; u8 vfomr; u8 unusedE82:7, keylock:1; u8 unknown2; u8 unknown3:4, vfomren:1, unknown4:1, reseten:1, menuen:1; u8 unknown5[11]; u8 dispab; u8 unknown6[2]; u8 menu; u8 unknown7[7]; u8 vfomra; u8 vfomrb; u8 vfomrc; u8 vfomrd; u8 mrcha; u8 mrchb; u8 mrchc; u8 mrchd; } settings2; struct settings_vfo { u8 freq[8]; u8 offset[6]; u8 unknown2[2]; ul16 rxtone; ul16 txtone; u8 scode; u8 spmute; u8 optsig; u8 unused1:7, scramble:1; u8 wide; u8 power; u8 shiftd; u8 step; u8 unknown3[4]; }; #seekto 0x0F00; struct { struct settings_vfo a; struct settings_vfo b; struct settings_vfo c; struct settings_vfo d; } vfo; // #seekto 0x0F80; struct { char line1[8]; char line2[8]; char line3[8]; char line4[8]; char line5[8]; char line6[8]; char line7[8]; char line8[8]; } poweron_msg; #seekto 0x1000; struct { char name[8]; u8 unknown1[8]; } names[200]; #seekto 0x2400; struct { u8 period; // one out of LIST_5TONE_STANDARD_PERIODS u8 group_tone; u8 repeat_tone; u8 unused[13]; } _5tone_std_settings[15]; #seekto 0x2500; struct { u8 frame1[5]; u8 frame2[5]; u8 frame3[5]; u8 standard; // one out of LIST_5TONE_STANDARDS } _5tone_codes[15]; // #seekto 0x25F0; struct { u8 _5tone_delay1; // * 10ms u8 _5tone_delay2; // * 10ms u8 _5tone_delay3; // * 10ms u8 _5tone_first_digit_ext_length; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 decode_standard; u8 unknown5:5, _5tone_decode_call_frame3:1, _5tone_decode_call_frame2:1, _5tone_decode_call_frame1:1; u8 unknown6:5, _5tone_decode_disp_frame3:1, _5tone_decode_disp_frame2:1, _5tone_decode_disp_frame1:1; u8 decode_reset_time; // * 100 + 100ms } _5tone_settings; #seekto 0x2900; struct { u8 code[16]; // 0=x0A, A=0x0D, B=0x0E, C=0x0F, D=0x00, #=0x0C *=0x0B } dtmf_codes[15]; // #seekto 0x29F0; struct { u8 dtmfspeed_on; //list with 50..2000ms in steps of 10 u8 dtmfspeed_off; //list with 50..2000ms in steps of 10 u8 unknown0[14]; u8 inspection[16]; u8 monitor[16]; u8 alarmcode[16]; u8 stun[16]; u8 kill[16]; u8 revive[16]; u8 unknown1[16]; u8 unknown2[16]; u8 unknown3[16]; u8 unknown4[16]; u8 unknown5[16]; u8 unknown6[16]; u8 unknown7[16]; u8 masterid[16]; u8 viceid[16]; u8 unused01:7, mastervice:1; u8 unused02:3, mrevive:1, mkill:1, mstun:1, mmonitor:1, minspection:1; u8 unused03:3, vrevive:1, vkill:1, vstun:1, vmonitor:1, vinspection:1; u8 unused04:6, txdisable:1, rxdisable:1; u8 groupcode; u8 spacecode; u8 delayproctime; // * 100 + 100ms u8 resettime; // * 100 + 100ms } dtmf_settings; #seekto 0x2D00; struct { struct { ul16 freq1; u8 unused01[6]; ul16 freq2; u8 unused02[6]; } _2tone_encode[15]; u8 duration_1st_tone; // *10ms u8 duration_2nd_tone; // *10ms u8 duration_gap; // *10ms u8 unused03[13]; struct { struct { u8 dec; // one out of LIST_2TONE_DEC u8 response; // one out of LIST_2TONE_RESPONSE u8 alert; // 1-16 } decs[4]; u8 unused04[4]; } _2tone_decode[15]; u8 unused05[16]; struct { ul16 freqA; ul16 freqB; ul16 freqC; ul16 freqD; // unknown what those values mean, but they are // derived from configured frequencies ul16 derived_from_freqA; // 2304000/freqA ul16 derived_from_freqB; // 2304000/freqB ul16 derived_from_freqC; // 2304000/freqC ul16 derived_from_freqD; // 2304000/freqD }freqs[15]; u8 reset_time; // * 100 + 100ms - 100-8000ms } _2tone; #seekto 0x3D80; struct { u8 vhf_low[3]; u8 vhf_high[3]; u8 unknown1[4]; u8 unknown2[6]; u8 vhf2_low[3]; u8 vhf2_high[3]; u8 unknown3[4]; u8 unknown4[6]; u8 uhf_low[3]; u8 uhf_high[3]; u8 unknown5[4]; u8 unknown6[6]; u8 uhf2_low[3]; u8 uhf2_high[3]; } ranges; #seekto 0x3F70; struct { char fp[6]; } fingerprint; """ class BTechColor(BTechMobileCommon): """BTECH's Color LCD Mobile and alike radios""" COLOR_LCD = True NAME_LENGTH = 8 LIST_TMR = LIST_TMR16 def process_mmap(self): """Process the mem map into the mem object""" # Get it self._memobj = bitwise.parse(COLOR_MEM_FORMAT, self._mmap) # load specific parameters from the radio image self.set_options() def set_options(self): """This is to read the options from the image and set it in the environment, for now just the limits of the freqs in the VHF/UHF ranges""" # setting the correct ranges for each radio type ranges = self._memobj.ranges # the normal dual bands vhf = _decode_ranges(ranges.vhf_low, ranges.vhf_high) uhf = _decode_ranges(ranges.uhf_low, ranges.uhf_high) # DEBUG LOG.info("Radio ranges: VHF %d to %d" % vhf) LOG.info("Radio ranges: UHF %d to %d" % uhf) # the additional bands if self.MODEL in ["UV-25X4", "KT7900D"]: # 200 MHz band vhf2 = _decode_ranges(ranges.vhf2_low, ranges.vhf2_high) LOG.info("Radio ranges: VHF(220) %d to %d" % vhf2) self._220_range = vhf2 # 350 MHz band uhf2 = _decode_ranges(ranges.uhf2_low, ranges.uhf2_high) LOG.info("Radio ranges: UHF(350) %d to %d" % uhf2) self._350_range = uhf2 # set the class with the real data self._vhf_range = vhf self._uhf_range = uhf # Declaring Aliases (Clones of the real radios) class SKT8900D(chirp_common.Alias): VENDOR = "Surecom" MODEL = "S-KT8900D" class QB25(chirp_common.Alias): VENDOR = "Radioddity" MODEL = "QB25" # real radios @directory.register class UV25X2(BTechColor): """Baofeng Tech UV25X2""" MODEL = "UV-25X2" BANDS = 2 _vhf_range = (130000000, 180000000) _uhf_range = (400000000, 521000000) _magic = MSTRING_UV25X2 _fileid = [UV25X2_fp] @directory.register class UV25X2_G2(UV25X2): """Baofeng Tech UV25X2_G2""" MODEL = "UV-25X2_G2" _fileid = [UV25X2G2_fp] @directory.register class UV25X4(BTechColor): """Baofeng Tech UV25X4""" MODEL = "UV-25X4" BANDS = 4 _vhf_range = (130000000, 180000000) _220_range = (200000000, 271000000) _uhf_range = (400000000, 521000000) _350_range = (350000000, 391000000) _magic = MSTRING_UV25X4 _fileid = [UV25X4_fp] @directory.register class UV25X4_G2(UV25X4): """Baofeng Tech UV25X4_G2""" MODEL = "UV-25X4_G2" _fileid = [UV25X4G2_fp] @directory.register class UV50X2(BTechColor): """Baofeng Tech UV50X2""" MODEL = "UV-50X2" BANDS = 2 _vhf_range = (130000000, 180000000) _uhf_range = (400000000, 521000000) _magic = MSTRING_UV25X2 _fileid = [UV50X2_fp] _power_levels = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Low", watts=10)] @directory.register class UV50X2_G2(BTechColor): """Baofeng Tech UV50X2_G2""" MODEL = "UV-50X2_G2" BANDS = 2 _vhf_range = (130000000, 180000000) _uhf_range = (400000000, 521000000) _magic = MSTRING_UV25X2 _fileid = [UV50X2_fp] _power_levels = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Low", watts=10)] @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class KT7900D(BTechColor): """QYT KT7900D""" VENDOR = "QYT" MODEL = "KT7900D" BANDS = 4 LIST_TMR = LIST_TMR15 _vhf_range = (136000000, 175000000) _220_range = (200000000, 271000000) _uhf_range = (400000000, 481000000) _350_range = (350000000, 371000000) _magic = MSTRING_KT8900D _fileid = [KT7900D_fp, KT7900D_fp1, KT7900D_fp2, KT7900D_fp3, KT7900D_fp4, KT7900D_fp5, KT7900D_fp6, KT7900D_fp7, KT7900D_fp8, KT7900D_fp9, QB25_fp] # Clones ALIASES = [SKT8900D, QB25] @directory.register class KT8900D(BTechColor): """QYT KT8900D""" VENDOR = "QYT" MODEL = "KT8900D" BANDS = 2 LIST_TMR = LIST_TMR15 _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_KT8900D _fileid = [KT8900D_fp3, KT8900D_fp2, KT8900D_fp1, KT8900D_fp] # Clones ALIASES = [OTGRadioV1] @directory.register class KT5800(BTechColor): """QYT KT5800""" VENDOR = "QYT" MODEL = "KT5800" BANDS = 2 LIST_TMR = LIST_TMR15 _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_KT8900D _fileid = [KT5800_fp] @directory.register class KT980PLUS(BTechColor): """QYT KT980PLUS""" VENDOR = "QYT" MODEL = "KT980PLUS" BANDS = 2 LIST_TMR = LIST_TMR15 _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_KT8900D _fileid = [KT980PLUS_fp1, KT980PLUS_fp] _power_levels = [chirp_common.PowerLevel("High", watts=75), chirp_common.PowerLevel("Low", watts=55)] @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False @directory.register class DB25G(BTechColor): """Radioddity DB25-G""" VENDOR = "Radioddity" MODEL = "DB25-G" BANDS = 2 LIST_TMR = LIST_TMR15 _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 481000000) _magic = MSTRING_KT8900D _fileid = [DB25G_fp1, DB25G_fp] _gmrs = True _power_levels = [chirp_common.PowerLevel("High", watts=25), chirp_common.PowerLevel("Mid", watts=15), chirp_common.PowerLevel("Low", watts=5)] def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if mem.freq in GMRS_FREQS3: if mem.duplex and mem.offset != 5000000: msgs.append(chirp_common.ValidationWarning(_msg_offset)) if mem.duplex and mem.duplex != "+": msgs.append(chirp_common.ValidationWarning(_msg_offset)) return msgs def check_set_memory_immutable_policy(self, existing, new): existing.immutable = [] super().check_set_memory_immutable_policy(existing, new) @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False GMRS_MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1:2, spmute:2, unknown2:2, optsig:2; u8 unknown3:3, scramble:1, unknown4:2, power:2; u8 unknown5:1, wide:1, unknown6:2, bcl:1, add:1, pttid:2; } memory[256]; // #seekto 0x1000; struct { char name[7]; u8 unknown1[9]; } names[256]; #seekto 0x2400; struct { u8 period; // one out of LIST_5TONE_STANDARD_PERIODS u8 group_tone; u8 repeat_tone; u8 unused[13]; } _5tone_std_settings[15]; #seekto 0x2500; struct { u8 frame1[5]; u8 frame2[5]; u8 frame3[5]; u8 standard; // one out of LIST_5TONE_STANDARDS } _5tone_codes[15]; // #seekto 0x25F0; struct { u8 _5tone_delay1; // * 10ms u8 _5tone_delay2; // * 10ms u8 _5tone_delay3; // * 10ms u8 _5tone_first_digit_ext_length; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 decode_standard; u8 unknown5:5, _5tone_decode_call_frame3:1, _5tone_decode_call_frame2:1, _5tone_decode_call_frame1:1; u8 unknown6:5, _5tone_decode_disp_frame3:1, _5tone_decode_disp_frame2:1, _5tone_decode_disp_frame1:1; u8 decode_reset_time; // * 100 + 100ms } _5tone_settings; // #seekto 0x2900; struct { u8 code[16]; // 0=x0A, A=0x0D, B=0x0E, C=0x0F, D=0x00, #=0x0C *=0x0B } dtmf_codes[15]; #seekto 0x29F0; struct { u8 dtmfspeed_on; //list with 50..2000ms in steps of 10 u8 dtmfspeed_off; //list with 50..2000ms in steps of 10 u8 unknown0[14]; u8 inspection[16]; u8 monitor[16]; u8 alarmcode[16]; u8 stun[16]; u8 kill[16]; u8 revive[16]; u8 unknown1[16]; u8 unknown2[16]; u8 unknown3[16]; u8 unknown4[16]; u8 unknown5[16]; u8 unknown6[16]; u8 unknown7[16]; u8 masterid[16]; u8 viceid[16]; u8 unused01:7, mastervice:1; u8 unused02:3, mrevive:1, mkill:1, mstun:1, mmonitor:1, minspection:1; u8 unused03:3, vrevive:1, vkill:1, vstun:1, vmonitor:1, vinspection:1; u8 unused04:6, txdisable:1, rxdisable:1; u8 groupcode; u8 spacecode; u8 delayproctime; // * 100 + 100ms u8 resettime; // * 100 + 100ms } dtmf_settings; #seekto 0x2D00; struct { struct { ul16 freq1; u8 unused01[6]; ul16 freq2; u8 unused02[6]; } _2tone_encode[15]; u8 duration_1st_tone; // *10ms u8 duration_2nd_tone; // *10ms u8 duration_gap; // *10ms u8 unused03[13]; struct { struct { u8 dec; // one out of LIST_2TONE_DEC u8 response; // one out of LIST_2TONE_RESPONSE u8 alert; // 1-16 } decs[4]; u8 unused04[4]; } _2tone_decode[15]; u8 unused05[16]; struct { ul16 freqA; ul16 freqB; ul16 freqC; ul16 freqD; // unknown what those values mean, but they are // derived from configured frequencies ul16 derived_from_freqA; // 2304000/freqA ul16 derived_from_freqB; // 2304000/freqB ul16 derived_from_freqC; // 2304000/freqC ul16 derived_from_freqD; // 2304000/freqD }freqs[15]; u8 reset_time; // * 100 + 100ms - 100-8000ms } _2tone; #seekto 0x3000; struct { u8 freq[8]; char broadcast_station_name[6]; u8 unknown[2]; } fm_radio_preset[16]; """ GMRS_MEM_FORMAT_PT2 = """ #seekto 0x3280; struct { u8 unknown1; u8 vfomr; u8 unused3281:7, keylock:1; u8 unknown2; u8 unknown3:4, vfomren:1, unknown4:1, reseten:1, menuen:1; u8 unknown5[11]; u8 dispab; u8 unknown6[2]; u8 smenu; u8 unknown7[7]; u8 vfomra; u8 vfomrb; u8 vfomrc; u8 vfomrd; u8 mrcha; u8 mrchb; u8 mrchc; u8 mrchd; } settings2; struct settings_vfo { u8 freq[8]; u8 offset[6]; u8 unknown2[2]; ul16 rxtone; ul16 txtone; u8 scode; u8 spmute; u8 optsig; u8 unused1:7, scramble:1; u8 wide; u8 power; u8 shiftd; u8 step; u8 unknown3[4]; }; #seekto 0x3300; struct { struct settings_vfo a; struct settings_vfo b; struct settings_vfo c; struct settings_vfo d; } vfo; #seekto 0x33B0; struct { char line[16]; } static_msg; #seekto 0x3D80; struct { u8 vhf_low[3]; u8 vhf_high[3]; u8 unknown1[4]; u8 unknown2[6]; u8 vhf2_low[3]; u8 vhf2_high[3]; u8 unknown3[4]; u8 unknown4[6]; u8 uhf_low[3]; u8 uhf_high[3]; u8 unknown5[4]; u8 unknown6[6]; u8 uhf2_low[3]; u8 uhf2_high[3]; } ranges; #seekto 0x3F70; struct { char fp[6]; } fingerprint; """ GMRS_ORIG_MEM_FORMAT = """ #seekto 0x3200; struct { u8 tmr; u8 unknown1; u8 sql; u8 unknown2; u8 unused3204:7, autolk:1; u8 tot; u8 apo; u8 unknown3; u8 abr; u8 unused3209:7, beep:1; u8 unknown4[4]; u8 dtmfst; u8 unknown5[2]; u8 screv; u8 unknown6[2]; u8 pttid; u8 pttlt; u8 unknown7; u8 emctp; u8 emcch; u8 unusedE19:7, sigbp:1; u8 vox; u8 camdf; u8 cbmdf; u8 ccmdf; u8 cdmdf; u8 langua; u8 sync; u8 stfc; u8 mffc; u8 sfafc; u8 sfbfc; u8 sfcfc; u8 sfdfc; u8 subfc; u8 fmfc; u8 sigfc; u8 modfc; u8 menufc; u8 txfc; u8 txdisp; u8 unknown9[5]; u8 anil; u8 reps; u8 repm; u8 tmrmr; u8 unusedE37:7, ste:1; u8 rpste; u8 rptdl; u8 dtmfg; u8 mgain; u8 skiptx; u8 scmode; u8 tmrtx; u8 unknown10; u8 earpho; } settings; """ GMRS_V2_MEM_FORMAT = """ #seekto 0x3200; struct { u8 tmr; u8 unknown1; u8 sql; u8 unknown2; u8 unused3204:7, autolk:1; u8 tot; u8 apo; u8 unknown3; u8 abr; u8 unused3209:7, beep:1; u8 unknown4[4]; u8 dtmfst; u8 unknown5[2]; u8 screv; u8 unknown6[2]; u8 pttid; u8 pttlt; u8 unknown7; u8 emctp; u8 emcch; u8 unusedE19:7, sigbp:1; u8 unknown8; // vox u8 camdf; u8 cbmdf; u8 ccmdf; u8 cdmdf; u8 vox; // langua u8 sync; u8 stfc; u8 mffc; u8 sfafc; u8 sfbfc; u8 sfcfc; u8 sfdfc; u8 subfc; u8 fmfc; u8 sigfc; u8 modfc; u8 menufc; u8 txfc; u8 unknown9[5]; u8 anil; u8 reps; u8 repm; u8 tmrmr; u8 unusedE37:7, ste:1; u8 rpste; u8 rptdl; u8 dtmfg; u8 mgain; u8 skiptx; u8 scmode; u8 tmrtx; u8 unknown10[2]; u8 earpho; } settings; """ class BTechGMRS(BTechMobileCommon): """BTECH's GMRS Mobile""" COLOR_LCD = True COLOR_LCD2 = True NAME_LENGTH = 7 UPLOAD_MEM_SIZE = 0X3400 def process_mmap(self): """Process the mem map into the mem object""" # Get it mem_format = GMRS_MEM_FORMAT + GMRS_ORIG_MEM_FORMAT + \ GMRS_MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format, self._mmap) # load specific parameters from the radio image self.set_options() def set_options(self): """This is to read the options from the image and set it in the environment, for now just the limits of the freqs in the VHF/UHF ranges""" # setting the correct ranges for each radio type ranges = self._memobj.ranges # the normal dual bands vhf = _decode_ranges(ranges.vhf_low, ranges.vhf_high) uhf = _decode_ranges(ranges.uhf_low, ranges.uhf_high) # DEBUG LOG.info("Radio ranges: VHF %d to %d" % vhf) LOG.info("Radio ranges: UHF %d to %d" % uhf) # set the class with the real data self._vhf_range = vhf self._uhf_range = uhf # real radios @directory.register class GMRS50X1(BTechGMRS): """Baofeng Tech GMRS50X1""" MODEL = "GMRS-50X1" BANDS = 2 LIST_TMR = LIST_TMR16 _power_levels = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Mid", watts=10), chirp_common.PowerLevel("Low", watts=5)] _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 521000000) _upper = 255 _magic = MSTRING_GMRS50X1 _fileid = [GMRS50X1_fp1, GMRS50X1_fp] _gmrs = True def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if not (mem.number >= 1 and mem.number <= 30): if mem.duplex != "off": msgs.append(chirp_common.ValidationWarning(_msg_duplex)) return msgs def check_set_memory_immutable_policy(self, existing, new): if not (new.number >= 1 and new.number <= 30): existing.immutable = [] super().check_set_memory_immutable_policy(existing, new) @directory.register class GMRS50V2(BTechGMRS): """Baofeng Tech GMRS50V2""" MODEL = "GMRS-50V2" BANDS = 2 LIST_TMR = LIST_TMR16 _power_levels = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Mid", watts=10), chirp_common.PowerLevel("Low", watts=5)] _vhf_range = (136000000, 175000000) _uhf_range = (400000000, 521000000) _upper = 255 _magic = MSTRING_GMRS50X1 _fileid = [GMRS50X1_fp1, GMRS50X1_fp] _gmrs = True def process_mmap(self): """Process the mem map into the mem object""" # Get it mem_format = GMRS_MEM_FORMAT + GMRS_V2_MEM_FORMAT + \ GMRS_MEM_FORMAT_PT2 self._memobj = bitwise.parse(mem_format, self._mmap) # load specific parameters from the radio image self.set_options() def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if mem.freq not in GMRS_FREQS: if mem.duplex != "off": msgs.append(chirp_common.ValidationWarning(_msg_duplex)) elif mem.duplex: if mem.duplex and mem.offset != 5000000: msgs.append(chirp_common.ValidationWarning(_msg_offset)) return msgs def check_set_memory_immutable_policy(self, existing, new): existing.immutable = [] super().check_set_memory_immutable_policy(existing, new) @classmethod def match_model(cls, filedata, filename): # This model is only ever matched via metadata return False COLORHT_MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1:2, spmute:2, unknown2:2, optsig:2; u8 unknown3:3, scramble:1, unknown4:3, power:1; u8 unknown5:1, wide:1, unknown6:2, bcl:1, add:1, pttid:2; } memory[200]; #seekto 0x0E00; struct { u8 tmr; u8 unknownE01; u8 sql; u8 unknownE03[2]; u8 tot; u8 unusedE06:7, save:1; u8 unknownE07; u8 abr; u8 unusedE09:7, beep:1; u8 unknownE0A[4]; u8 unusedE0E:7, dsub:1; u8 unusedE0F:7, dtmfst:1; u8 screv; u8 unknownE11[3]; u8 pttid; u8 unknownE15; u8 pttlt; u8 unknownE17; u8 emctp; u8 emcch; u8 unusedE1A:7, sigbp:1; u8 unknownE1B; u8 camdf; u8 cbmdf; u8 ccmdf; u8 cdmdf; u8 langua; u8 voice; u8 vox; u8 voxt; u8 sync; // BTech radios use this as the display sync setting // other radios use this as the auto keypad lock setting u8 stfc; u8 mffc; u8 sfafc; u8 sfbfc; u8 sfcfc; u8 sfdfc; u8 subfc; u8 fmfc; u8 sigfc; u8 menufc; u8 txfc; u8 rxfc; u8 unknownE31[5]; u8 anil; u8 reps; u8 tmrmr; u8 unusedE39:7, ste:1; u8 rpste; u8 rptdl; u8 dtmfg; u8 tmrtx; } settings; #seekto 0x0E80; struct { u8 unknown1; u8 vfomr; u8 unusedE82:7, keylock:1; u8 unknown2; u8 unknown3:4, vfomren:1, unknown4:1, reseten:1, menuen:1; u8 unknown5[11]; u8 dispab; u8 unknown6[2]; u8 menu; u8 unknown7[7]; u8 vfomra; u8 vfomrb; u8 vfomrc; u8 vfomrd; u8 mrcha; u8 mrchb; u8 mrchc; u8 mrchd; } settings2; struct settings_vfo { u8 freq[8]; u8 offset[6]; u8 unknown2[2]; ul16 rxtone; ul16 txtone; u8 scode; u8 spmute; u8 optsig; u8 unused1:7, scramble:1; u8 wide; u8 power; u8 shiftd; u8 step; u8 unknown3[4]; }; #seekto 0x0F00; struct { struct settings_vfo a; struct settings_vfo b; struct settings_vfo c; struct settings_vfo d; } vfo; #seekto 0x0FE0; struct { char line[16]; } static_msg; #seekto 0x1000; struct { char name[8]; u8 unknown1[8]; } names[200]; #seekto 0x2400; struct { u8 period; // one out of LIST_5TONE_STANDARD_PERIODS u8 group_tone; u8 repeat_tone; u8 unused[13]; } _5tone_std_settings[15]; #seekto 0x2500; struct { u8 frame1[5]; u8 frame2[5]; u8 frame3[5]; u8 standard; // one out of LIST_5TONE_STANDARDS } _5tone_codes[15]; // #seekto 0x25F0; struct { u8 _5tone_delay1; // * 10ms u8 _5tone_delay2; // * 10ms u8 _5tone_delay3; // * 10ms u8 _5tone_first_digit_ext_length; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 decode_standard; u8 unknown5:5, _5tone_decode_call_frame3:1, _5tone_decode_call_frame2:1, _5tone_decode_call_frame1:1; u8 unknown6:5, _5tone_decode_disp_frame3:1, _5tone_decode_disp_frame2:1, _5tone_decode_disp_frame1:1; u8 decode_reset_time; // * 100 + 100ms } _5tone_settings; #seekto 0x2900; struct { u8 code[16]; // 0=x0A, A=0x0D, B=0x0E, C=0x0F, D=0x00, #=0x0C *=0x0B } dtmf_codes[15]; // #seekto 0x29F0; struct { u8 dtmfspeed_on; //list with 50..2000ms in steps of 10 u8 dtmfspeed_off; //list with 50..2000ms in steps of 10 u8 unknown0[14]; u8 inspection[16]; u8 monitor[16]; u8 alarmcode[16]; u8 stun[16]; u8 kill[16]; u8 revive[16]; u8 unknown1[16]; u8 unknown2[16]; u8 unknown3[16]; u8 unknown4[16]; u8 unknown5[16]; u8 unknown6[16]; u8 unknown7[16]; u8 masterid[16]; u8 viceid[16]; u8 unused01:7, mastervice:1; u8 unused02:3, mrevive:1, mkill:1, mstun:1, mmonitor:1, minspection:1; u8 unused03:3, vrevive:1, vkill:1, vstun:1, vmonitor:1, vinspection:1; u8 unused04:6, txdisable:1, rxdisable:1; u8 groupcode; u8 spacecode; u8 delayproctime; // * 100 + 100ms u8 resettime; // * 100 + 100ms } dtmf_settings; #seekto 0x2D00; struct { struct { ul16 freq1; u8 unused01[6]; ul16 freq2; u8 unused02[6]; } _2tone_encode[15]; u8 duration_1st_tone; // *10ms u8 duration_2nd_tone; // *10ms u8 duration_gap; // *10ms u8 unused03[13]; struct { struct { u8 dec; // one out of LIST_2TONE_DEC u8 response; // one out of LIST_2TONE_RESPONSE u8 alert; // 1-16 } decs[4]; u8 unused04[4]; } _2tone_decode[15]; u8 unused05[16]; struct { ul16 freqA; ul16 freqB; ul16 freqC; ul16 freqD; // unknown what those values mean, but they are // derived from configured frequencies ul16 derived_from_freqA; // 2304000/freqA ul16 derived_from_freqB; // 2304000/freqB ul16 derived_from_freqC; // 2304000/freqC ul16 derived_from_freqD; // 2304000/freqD }freqs[15]; u8 reset_time; // * 100 + 100ms - 100-8000ms } _2tone; #seekto 0x3D80; struct { u8 vhf_low[3]; u8 vhf_high[3]; u8 unknown1[4]; u8 unknown2[6]; u8 vhf2_low[3]; u8 vhf2_high[3]; u8 unknown3[4]; u8 unknown4[6]; u8 uhf_low[3]; u8 uhf_high[3]; u8 unknown5[4]; u8 unknown6[6]; u8 uhf2_low[3]; u8 uhf2_high[3]; } ranges; #seekto 0x3F70; struct { char fp[6]; } fingerprint; """ class QYTColorHT(BTechMobileCommon): """QTY's Color LCD Handheld and alike radios""" COLOR_LCD = True COLOR_LCD3 = True NAME_LENGTH = 8 LIST_TMR = LIST_TMR15 def process_mmap(self): """Process the mem map into the mem object""" # Get it self._memobj = bitwise.parse(COLORHT_MEM_FORMAT, self._mmap) # load specific parameters from the radio image self.set_options() def set_options(self): """This is to read the options from the image and set it in the environment, for now just the limits of the freqs in the VHF/UHF ranges""" # setting the correct ranges for each radio type ranges = self._memobj.ranges # the normal dual bands vhf = _decode_ranges(ranges.vhf_low, ranges.vhf_high) uhf = _decode_ranges(ranges.uhf_low, ranges.uhf_high) # DEBUG LOG.info("Radio ranges: VHF %d to %d" % vhf) LOG.info("Radio ranges: UHF %d to %d" % uhf) # the additional bands if self.MODEL in ["KT-8R"]: # 200 MHz band vhf2 = _decode_ranges(ranges.vhf2_low, ranges.vhf2_high) LOG.info("Radio ranges: VHF(220) %d to %d" % vhf2) self._220_range = vhf2 # 350 MHz band uhf2 = _decode_ranges(ranges.uhf2_low, ranges.uhf2_high) LOG.info("Radio ranges: UHF(350) %d to %d" % uhf2) self._350_range = uhf2 # set the class with the real data self._vhf_range = vhf self._uhf_range = uhf # real radios @directory.register class KT8R(QYTColorHT): """QYT KT8R""" VENDOR = "QYT" MODEL = "KT-8R" BANDS = 4 LIST_TMR = LIST_TMR16 _vhf_range = (136000000, 175000000) _220_range = (200000000, 261000000) _uhf_range = (400000000, 481000000) _350_range = (350000000, 391000000) _magic = MSTRING_KT8R _fileid = [KT8R_fp2, KT8R_fp1, KT8R_fp] _power_levels = [chirp_common.PowerLevel("High", watts=5), chirp_common.PowerLevel("Low", watts=1)] COLOR9900_MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1:2, spmute:2, unknown2:2, optsig:2; u8 unknown3:3, scramble:1, unknown4:2, power:2; u8 unknown5:1, wide:1, unknown6:2, bcl:1, add:1, pttid:2; } memory[200]; #seekto 0x0E00; struct { u8 tmr; u8 unknown1; u8 sql; u8 unknown2[2]; u8 tot; u8 volume; u8 unknown3; u8 abr; u8 unusedE09:7, beep:1; u8 unknown4[4]; u8 unusedE0E:7, dsub:1; u8 unusedE0F:7, dtmfst:1; u8 unknown_e10; u8 unknown_e11; u8 screv; u8 unknown_e13; u8 unknown_e14; u8 pttid; u8 pttlt; u8 unknown7; u8 emctp; u8 emcch; u8 unusedE1A:7, sigbp:1; u8 unknown8; u8 camdf; u8 cbmdf; u8 ccmdf; u8 language; u8 tmrtx; u8 vox; u8 voxt; u8 unusedE23:7, autolock:1; u8 asfc; u8 mainfc; u8 a_fc; u8 b_fc; u8 c_fc; u8 subfc; u8 battfc; u8 sigfc; u8 menufc; u8 txfc; u8 rxfc; u8 unknown_e2f; u8 unknown_e30; u8 unknown9[3]; u8 anil; u8 reps; u8 tmrmr; u8 unusedE37:7, ste:1; u8 rpste; u8 rptdl; u8 dtmfg; } settings; #seekto 0x0E80; struct { u8 unknown1; u8 vfomr; u8 unusedE82:7, keylock:1; u8 unknown2; u8 unknown3:4, vfomren:1, unknown4:1, reseten:1, menuen:1; u8 unknown5[11]; u8 dispab; u8 unknown6[2]; u8 menu; u8 unknown7[7]; u8 vfomra; u8 vfomrb; u8 vfomrc; u8 vfomrd; u8 mrcha; u8 mrchb; u8 mrchc; u8 mrchd; } settings2; struct settings_vfo { u8 freq[8]; u8 offset[6]; u8 unknown2[2]; ul16 rxtone; ul16 txtone; u8 scode; u8 spmute; u8 optsig; u8 unused1:7, scramble:1; u8 wide; u8 power; u8 shiftd; u8 step; u8 unknown3[4]; }; #seekto 0x0F00; struct { struct settings_vfo a; struct settings_vfo b; struct settings_vfo c; struct settings_vfo d; } vfo; // #seekto 0x0F80; struct { char line1[8]; char line2[8]; char line3[8]; char line4[8]; char line5[8]; char line6[8]; char line7[8]; char line8[8]; } poweron_msg; #seekto 0x0FE0; struct { char line[16]; } static_msg; #seekto 0x1000; struct { char name[7]; u8 unknown1[9]; } names[200]; #seekto 0x2400; struct { u8 period; // one out of LIST_5TONE_STANDARD_PERIODS u8 group_tone; u8 repeat_tone; u8 unused[13]; } _5tone_std_settings[15]; #seekto 0x2500; struct { u8 frame1[5]; u8 frame2[5]; u8 frame3[5]; u8 standard; // one out of LIST_5TONE_STANDARDS } _5tone_codes[15]; // #seekto 0x25F0; struct { u8 _5tone_delay1; // * 10ms u8 _5tone_delay2; // * 10ms u8 _5tone_delay3; // * 10ms u8 _5tone_first_digit_ext_length; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 decode_standard; u8 unknown5:5, _5tone_decode_call_frame3:1, _5tone_decode_call_frame2:1, _5tone_decode_call_frame1:1; u8 unknown6:5, _5tone_decode_disp_frame3:1, _5tone_decode_disp_frame2:1, _5tone_decode_disp_frame1:1; u8 decode_reset_time; // * 100 + 100ms } _5tone_settings; #seekto 0x2900; struct { u8 code[16]; // 0=x0A, A=0x0D, B=0x0E, C=0x0F, D=0x00, #=0x0C *=0x0B } dtmf_codes[15]; // #seekto 0x29F0; struct { u8 dtmfspeed_on; //list with 50..2000ms in steps of 10 // 9f0 u8 dtmfspeed_off; //list with 50..2000ms in steps of 10 // 9f1 u8 unknown0[14]; // 9f2-9ff u8 inspection[16]; // a00-a0f u8 monitor[16]; // a10-a1f u8 alarmcode[16]; // a20-a2f u8 stun[16]; // a30-a3f u8 kill[16]; // a40-a4f u8 revive[16]; // a50-a5f u8 unknown1[16]; // a60-a6f u8 unknown2[16]; // a70-a7f u8 unknown3[16]; // a80-a8f u8 unknown4[16]; // a90-a9f u8 unknown5[16]; // aa0-aaf u8 unknown6[16]; // ab0-abf u8 unknown7[16]; // ac0-acf u8 masterid[16]; // ad0-adf u8 viceid[16]; // ae0-aef u8 unused01:7, // af0 mastervice:1; u8 unused02:3, // af1 mrevive:1, mkill:1, mstun:1, mmonitor:1, minspection:1; u8 unused03:3, // af2 vrevive:1, vkill:1, vstun:1, vmonitor:1, vinspection:1; u8 unused04:6, // af3 txdisable:1, rxdisable:1; u8 groupcode; // af4 u8 spacecode; // af5 u8 delayproctime; // * 100 + 100ms // af6 u8 resettime; // * 100 + 100ms // af7 } dtmf_settings; #seekto 0x2D00; struct { struct { ul16 freq1; u8 unused01[6]; ul16 freq2; u8 unused02[6]; } _2tone_encode[15]; u8 duration_1st_tone; // *10ms u8 duration_2nd_tone; // *10ms u8 duration_gap; // *10ms u8 unused03[13]; struct { struct { u8 dec; // one out of LIST_2TONE_DEC u8 response; // one out of LIST_2TONE_RESPONSE u8 alert; // 1-16 } decs[4]; u8 unused04[4]; } _2tone_decode[15]; u8 unused05[16]; struct { ul16 freqA; ul16 freqB; ul16 freqC; ul16 freqD; // unknown what those values mean, but they are // derived from configured frequencies ul16 derived_from_freqA; // 2304000/freqA ul16 derived_from_freqB; // 2304000/freqB ul16 derived_from_freqC; // 2304000/freqC ul16 derived_from_freqD; // 2304000/freqD }freqs[15]; u8 reset_time; // * 100 + 100ms - 100-8000ms } _2tone; #seekto 0x3D80; struct { u8 vhf_low[3]; u8 vhf_high[3]; u8 unknown1[4]; u8 unknown2[6]; u8 vhf2_low[3]; u8 vhf2_high[3]; u8 unknown3[4]; u8 unknown4[6]; u8 uhf_low[3]; u8 uhf_high[3]; u8 unknown5[4]; u8 unknown6[6]; u8 uhf2_low[3]; u8 uhf2_high[3]; } ranges; #seekto 0x3F70; struct { char fp[6]; } fingerprint; """ COLOR20V2_MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1:2, spmute:2, unknown2:2, optsig:2; u8 unknown3:3, scramble:1, unknown4:2, power:2; u8 unknown5:1, wide:1, unknown6:2, bcl:1, add:1, pttid:2; } memory[200]; #seekto 0x0E00; struct { u8 tmr; u8 unknown1; u8 sql; u8 unknown2; u8 unusedE04:7, autolock:1; u8 tot; u8 apo; u8 unknown3; u8 abr; u8 unusedE09:7, beep:1; u8 unknown4[4]; u8 unusedE0E:7, dtmfst:1; u8 unknown5[2]; u8 screv; u8 unknown6[2]; u8 pttid; u8 pttlt; u8 unknown7; u8 emctp; u8 emcch; u8 unusedE19:7, sigbp:1; u8 unknown8; u8 camdf; u8 cbmdf; u8 ccmdf; u8 vox; u8 voxt; u8 sync; u8 asfc; u8 mainfc; u8 a_fc; u8 b_fc; u8 c_fc; u8 subfc; u8 battfc; u8 sigfc; u8 menufc; u8 txfc; u8 rxfc; u8 repsw; u8 unusedE2D:7, dsub:1; u8 unknown9[5]; u8 anil; u8 reps; u8 repm; u8 tmrmr; u8 unusedE37:7, ste:1; u8 rpste; u8 rptdl; u8 dtmfg; u8 mgain; u8 skiptx; u8 scmode; u8 tmrtx; u8 volume; u8 unknown_10; u8 unusedE41:7, save:1; } settings; #seekto 0x0E80; struct { u8 unknown1; u8 vfomr; u8 unusedE82:7, keylock:1; u8 unknown2; u8 unknown3:4, vfomren:1, unknown4:1, reseten:1, menuen:1; u8 unknown5[11]; u8 dispab; u8 unknown6[2]; u8 menu; u8 unknown7[7]; u8 vfomra; u8 vfomrb; u8 vfomrc; u8 vfomrd; u8 mrcha; u8 mrchb; u8 mrchc; u8 mrchd; } settings2; struct settings_vfo { u8 freq[8]; u8 offset[6]; u8 unknown2[2]; ul16 rxtone; ul16 txtone; u8 scode; u8 spmute; u8 optsig; u8 unused1:7, scramble:1; u8 wide; u8 power; u8 shiftd; u8 step; u8 unknown3[4]; }; #seekto 0x0F00; struct { struct settings_vfo a; struct settings_vfo b; struct settings_vfo c; struct settings_vfo d; } vfo; // #seekto 0x0F80; struct { char line1[8]; char line2[8]; char line3[8]; char line4[8]; char line5[8]; char line6[8]; char line7[8]; char line8[8]; } poweron_msg; #seekto 0x0FE0; struct { char line[16]; } static_msg; #seekto 0x1000; struct { char name[7]; u8 unknown1[9]; } names[200]; #seekto 0x2400; struct { u8 period; // one out of LIST_5TONE_STANDARD_PERIODS u8 group_tone; u8 repeat_tone; u8 unused[13]; } _5tone_std_settings[15]; #seekto 0x2500; struct { u8 frame1[5]; u8 frame2[5]; u8 frame3[5]; u8 standard; // one out of LIST_5TONE_STANDARDS } _5tone_codes[15]; // #seekto 0x25F0; struct { u8 _5tone_delay1; // * 10ms u8 _5tone_delay2; // * 10ms u8 _5tone_delay3; // * 10ms u8 _5tone_first_digit_ext_length; u8 unknown1; u8 unknown2; u8 unknown3; u8 unknown4; u8 decode_standard; u8 unknown5:5, _5tone_decode_call_frame3:1, _5tone_decode_call_frame2:1, _5tone_decode_call_frame1:1; u8 unknown6:5, _5tone_decode_disp_frame3:1, _5tone_decode_disp_frame2:1, _5tone_decode_disp_frame1:1; u8 decode_reset_time; // * 100 + 100ms } _5tone_settings; #seekto 0x2900; struct { u8 code[16]; // 0=x0A, A=0x0D, B=0x0E, C=0x0F, D=0x00, #=0x0C *=0x0B } dtmf_codes[15]; // #seekto 0x29F0; struct { u8 dtmfspeed_on; //list with 50..2000ms in steps of 10 // 9f0 u8 dtmfspeed_off; //list with 50..2000ms in steps of 10 // 9f1 u8 unknown0[14]; // 9f2-9ff u8 inspection[16]; // a00-a0f u8 monitor[16]; // a10-a1f u8 alarmcode[16]; // a20-a2f u8 stun[16]; // a30-a3f u8 kill[16]; // a40-a4f u8 revive[16]; // a50-a5f u8 unknown1[16]; // a60-a6f u8 unknown2[16]; // a70-a7f u8 unknown3[16]; // a80-a8f u8 unknown4[16]; // a90-a9f u8 unknown5[16]; // aa0-aaf u8 unknown6[16]; // ab0-abf u8 unknown7[16]; // ac0-acf u8 masterid[16]; // ad0-adf u8 viceid[16]; // ae0-aef u8 unused01:7, // af0 mastervice:1; u8 unused02:3, // af1 mrevive:1, mkill:1, mstun:1, mmonitor:1, minspection:1; u8 unused03:3, // af2 vrevive:1, vkill:1, vstun:1, vmonitor:1, vinspection:1; u8 unused04:6, // af3 txdisable:1, rxdisable:1; u8 groupcode; // af4 u8 spacecode; // af5 u8 delayproctime; // * 100 + 100ms // af6 u8 resettime; // * 100 + 100ms // af7 } dtmf_settings; #seekto 0x2D00; struct { struct { ul16 freq1; u8 unused01[6]; ul16 freq2; u8 unused02[6]; } _2tone_encode[15]; u8 duration_1st_tone; // *10ms u8 duration_2nd_tone; // *10ms u8 duration_gap; // *10ms u8 unused03[13]; struct { struct { u8 dec; // one out of LIST_2TONE_DEC u8 response; // one out of LIST_2TONE_RESPONSE u8 alert; // 1-16 } decs[4]; u8 unused04[4]; } _2tone_decode[15]; u8 unused05[16]; struct { ul16 freqA; ul16 freqB; ul16 freqC; ul16 freqD; // unknown what those values mean, but they are // derived from configured frequencies ul16 derived_from_freqA; // 2304000/freqA ul16 derived_from_freqB; // 2304000/freqB ul16 derived_from_freqC; // 2304000/freqC ul16 derived_from_freqD; // 2304000/freqD }freqs[15]; u8 reset_time; // * 100 + 100ms - 100-8000ms } _2tone; #seekto 0x3D80; struct { u8 vhf_low[3]; u8 vhf_high[3]; u8 unknown1[4]; u8 unknown2[6]; u8 vhf2_low[3]; u8 vhf2_high[3]; u8 unknown3[4]; u8 unknown4[6]; u8 uhf_low[3]; u8 uhf_high[3]; u8 unknown5[4]; u8 unknown6[6]; u8 uhf2_low[3]; u8 uhf2_high[3]; } ranges; #seekto 0x3F70; struct { char fp[6]; } fingerprint; """ class BTechColorWP(BTechMobileCommon): """BTECH's Color WP Mobile and alike radios""" COLOR_LCD = True COLOR_LCD4 = True NAME_LENGTH = 7 LIST_TMR = LIST_TMR7 def set_options(self): """This is to read the options from the image and set it in the environment, for now just the limits of the freqs in the VHF/UHF ranges""" # setting the correct ranges for each radio type ranges = self._memobj.ranges # the normal dual bands vhf = _decode_ranges(ranges.vhf_low, ranges.vhf_high) uhf = _decode_ranges(ranges.uhf_low, ranges.uhf_high) # DEBUG LOG.info("Radio ranges: VHF %d to %d" % vhf) LOG.info("Radio ranges: UHF %d to %d" % uhf) # set the class with the real data self._vhf_range = vhf self._uhf_range = uhf # real radios @directory.register class KTWP12(BTechColorWP): """QYT KT-WP12""" VENDOR = "QYT" MODEL = "KT-WP12" BANDS = 2 UPLOAD_MEM_SIZE = 0X3100 _power_levels = [chirp_common.PowerLevel("High", watts=25), chirp_common.PowerLevel("Low", watts=5)] _upper = 199 _magic = MSTRING_KTWP12 _fileid = [KTWP12_fp] _gmrs = False def process_mmap(self): """Process the mem map into the mem object""" # Get it self._memobj = bitwise.parse(COLOR9900_MEM_FORMAT, self._mmap) # load specific parameters from the radio image self.set_options() @directory.register class WP9900(BTechColorWP): """Anysecu WP-9900""" VENDOR = "Anysecu" MODEL = "WP-9900" BANDS = 2 UPLOAD_MEM_SIZE = 0X3100 _power_levels = [chirp_common.PowerLevel("High", watts=25), chirp_common.PowerLevel("Low", watts=5)] _upper = 199 _magic = MSTRING_KTWP12 _fileid = [WP9900_fp] _gmrs = False def process_mmap(self): """Process the mem map into the mem object""" # Get it self._memobj = bitwise.parse(COLOR9900_MEM_FORMAT, self._mmap) # load specific parameters from the radio image self.set_options() @directory.register class GMRS20V2(BTechColorWP): """Baofeng Tech GMRS-20V2""" MODEL = "GMRS-20V2" BANDS = 2 UPLOAD_MEM_SIZE = 0X3100 _power_levels = [chirp_common.PowerLevel("High", watts=20), chirp_common.PowerLevel("", watts=6), chirp_common.PowerLevel("Low", watts=5)] _upper = 199 _magic = MSTRING_GMRS20V2 _fileid = [GMRS20V2_fp2, GMRS20V2_fp1, GMRS20V2_fp] _gmrs = True def validate_memory(self, mem): msgs = super().validate_memory(mem) _msg_duplex = 'Duplex must be "off" for this frequency' _msg_offset = 'Only simplex or +5 MHz offset allowed on GMRS' if mem.freq not in GMRS_FREQS: if mem.duplex != "off": msgs.append(chirp_common.ValidationWarning(_msg_duplex)) elif mem.duplex: if mem.duplex and mem.offset != 5000000: msgs.append(chirp_common.ValidationWarning(_msg_offset)) return msgs def check_set_memory_immutable_policy(self, existing, new): existing.immutable = [] super().check_set_memory_immutable_policy(existing, new) def process_mmap(self): """Process the mem map into the mem object""" # Get it self._memobj = bitwise.parse(COLOR20V2_MEM_FORMAT, self._mmap) # load specific parameters from the radio image self.set_options() chirp-20240224/chirp/drivers/bj9900.py0000644000175000017500000003166014563632215016123 0ustar hibbyhibby# # Copyright 2015 Marco Filippi IZ3GME # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Baojie BJ-9900 management module""" from chirp import chirp_common, util, memmap, errors, directory, bitwise import struct import time import logging LOG = logging.getLogger(__name__) CMD_ACK = b'\x06' @directory.register class BJ9900Radio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Baojie BJ-9900""" VENDOR = "Baojie" MODEL = "BJ-9900" VARIANT = "" BAUD_RATE = 115200 NEEDS_COMPAT_SERIAL = False DUPLEX = ["", "-", "+", "split"] MODES = ["NFM", "FM"] TMODES = ["", "Tone", "TSQL", "DTCS", "Cross"] CROSS_MODES = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] STEPS = [5.0, 6.25, 10.0, 12.5, 25.0] VALID_BANDS = [(109000000, 136000000), (136000000, 174000000), (400000000, 470000000)] CHARSET = list(chirp_common.CHARSET_ALPHANUMERIC) CHARSET.remove(" ") POWER_LEVELS = [ chirp_common.PowerLevel("Low", watts=20.00), chirp_common.PowerLevel("High", watts=40.00)] _memsize = 0x18F1 # dat file format is # 2 char per byte hex string # on CR LF terminated lines of 96 char # plus an empty line at the end _datsize = (_memsize * 2) // 96 * 98 + 2 # block are read in same order as original sw even though they are not # in physical order _blocks = [ (0x400, 0x1BFF, 0x30), (0x300, 0x32F, 0x30), (0x380, 0x3AF, 0x30), (0x200, 0x22F, 0x30), (0x240, 0x26F, 0x30), (0x270, 0x2A0, 0x31), ] MEM_FORMAT = """ #seekto 0x%X; struct { u32 rxfreq; u16 is_rxdigtone:1, rxdtcs_pol:1, rxtone:14; u8 rxdtmf:4, spmute:4; u8 unknown1; u32 txfreq; u16 is_txdigtone:1, txdtcs_pol:1, txtone:14; u8 txdtmf:4, pttid:4; u8 power:1, wide:1, compandor:1, unknown3:5; u8 namelen; char name[7]; } memory[128]; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_upload = rp.pre_download = _( "1. Turn radio off.\n" "2. Remove front head.\n" "3. Connect data cable to radio, use the same connector where\n" " head was connected to, not the mic connector.\n" "4. Click OK.\n") rp.experimental = _( 'This is experimental support for BJ-9900 ' 'which is still under development.\n' 'Please ensure you have a good backup with OEM software.\n' 'Also please send in bug and enhancement requests!\n' 'You have been warned. Proceed at your own risk!') return rp def _read(self, addr, blocksize): # read a single block msg = struct.pack(">4sHH", b"READ", addr, blocksize) LOG.debug("sending " + util.hexprint(msg)) self.pipe.write(msg) block = self.pipe.read(blocksize) LOG.debug("received " + util.hexprint(block)) if len(block) != blocksize: raise errors.RadioError( ("Unable to read block at addr %04X expected" " %i got %i bytes") % (addr, blocksize, len(block))) return block def _clone_in(self): start = time.time() data = b"" status = chirp_common.Status() status.msg = _("Cloning from radio") status.max = self._memsize for addr_from, addr_to, blocksize in self._blocks: for addr in range(addr_from, addr_to, blocksize): data += self._read(addr, blocksize) status.cur = len(data) self.status_fn(status) LOG.info("Clone completed in %i seconds" % (time.time() - start)) # This driver will accept any amount of garbage, and fails tests # as a result. This assertion appears correct based on the file # data matching below. However, untested as of 2024-Feb. assert data[-2:] == b'\r\n', 'Unrecognized radio image' return memmap.MemoryMapBytes(data) def _write(self, addr, block): # write a single block msg = struct.pack(">4sHH", b"WRIE", addr, len(block)) + block LOG.debug("sending " + util.hexprint(msg)) self.pipe.write(msg) data = self.pipe.read(1) LOG.debug("received " + util.hexprint(data)) if data != CMD_ACK: raise errors.RadioError( "Radio refused to accept block 0x%04x" % addr) def _clone_out(self): start = time.time() status = chirp_common.Status() status.msg = _("Cloning to radio") status.max = self._memsize pos = 0 for addr_from, addr_to, blocksize in self._blocks: for addr in range(addr_from, addr_to, blocksize): self._write(addr, self._mmap[pos:(pos + blocksize)]) pos += blocksize status.cur = pos self.status_fn(status) LOG.info("Clone completed in %i seconds" % (time.time() - start)) def sync_in(self): try: self._mmap = self._clone_in() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: self._clone_out() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): if len(self._mmap) == self._datsize: self._mmap = memmap.MemoryMapBytes([ chr(int(self._mmap.get(i, 2), 16)) for i in range(0, self._datsize, 2) if self._mmap.get(i, 2) != b"\r\n" ]) try: self._memobj = bitwise.parse( self.MEM_FORMAT % self._memstart, self._mmap) except AttributeError: # main variant have no _memstart attribute return def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.has_dtcs_polarity = True rf.has_nostep_tuning = False rf.valid_modes = list(self.MODES) rf.valid_tmodes = list(self.TMODES) rf.valid_cross_modes = list(self.CROSS_MODES) rf.valid_duplexes = list(self.DUPLEX) rf.has_tuning_step = False rf.valid_tuning_steps = list(self.STEPS) rf.valid_bands = self.VALID_BANDS rf.valid_skips = [""] rf.valid_power_levels = self.POWER_LEVELS rf.valid_characters = "".join(self.CHARSET) rf.valid_name_length = 7 rf.memory_bounds = (1, 128) rf.can_odd_split = True rf.has_settings = False rf.has_cross = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_sub_devices = self.VARIANT == "" return rf def get_sub_devices(self): return [BJ9900RadioLeft(self._mmap), BJ9900RadioRight(self._mmap)] def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.fill_raw(b"\xff") _mem.namelen = 0 return _mem.rxfreq = mem.freq / 10 if mem.duplex == "split": _mem.txfreq = mem.offset // 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) // 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) // 10 else: _mem.txfreq = mem.freq // 10 _mem.namelen = len(mem.name) _mem.name = mem.name.ljust(7) rxmode = "" txmode = "" if mem.tmode == "Tone": txmode = "Tone" elif mem.tmode == "TSQL": rxmode = "Tone" txmode = "TSQL" elif mem.tmode == "DTCS": rxmode = "DTCSSQL" txmode = "DTCS" elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if rxmode == "": _mem.rxdtcs_pol = 1 _mem.is_rxdigtone = 1 _mem.rxtone = 0x3FFF elif rxmode == "Tone": _mem.rxdtcs_pol = 0 _mem.is_rxdigtone = 0 _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCSSQL": _mem.rxdtcs_pol = 1 if mem.dtcs_polarity[1] == "R" else 0 _mem.is_rxdigtone = 1 _mem.rxtone = mem.dtcs elif rxmode == "DTCS": _mem.rxdtcs_pol = 1 if mem.dtcs_polarity[1] == "R" else 0 _mem.is_rxdigtone = 1 _mem.rxtone = mem.rx_dtcs if txmode == "": _mem.txdtcs_pol = 1 _mem.is_txdigtone = 1 _mem.txtone = 0x3FFF elif txmode == "Tone": _mem.txdtcs_pol = 0 _mem.is_txdigtone = 0 _mem.txtone = int(mem.rtone * 10) elif txmode == "TSQL": _mem.txdtcs_pol = 0 _mem.is_txdigtone = 0 _mem.txtone = int(mem.ctone * 10) elif txmode == "DTCS": _mem.txdtcs_pol = 1 if mem.dtcs_polarity[0] == "R" else 0 _mem.is_txdigtone = 1 _mem.txtone = mem.dtcs if (mem.power): _mem.power = self.POWER_LEVELS.index(mem.power) _mem.wide = self.MODES.index(mem.mode) # not supported yet _mem.compandor = 0 _mem.pttid = 0 _mem.txdtmf = 0 _mem.rxdtmf = 0 _mem.spmute = 0 # set to mimic radio behaviour _mem.unknown3 = 0 def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw()[0] == 0xFF: mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if int(_mem.rxfreq) == int(_mem.txfreq) or _mem.txfreq == 0xFFFFFFFF: mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 mem.name = str(_mem.name)[:_mem.namelen] dtcs_pol = ["N", "N"] if _mem.rxtone == 0x3FFF: rxmode = "" elif _mem.is_rxdigtone == 0: # ctcss rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 else: # digital rxmode = "DTCS" mem.rx_dtcs = int(_mem.rxtone & 0x3FFF) if _mem.rxdtcs_pol == 1: dtcs_pol[1] = "R" if _mem.txtone == 0x3FFF: txmode = "" elif _mem.is_txdigtone == 0: # ctcss txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 else: # digital txmode = "DTCS" mem.dtcs = int(_mem.txtone & 0x3FFF) if _mem.txdtcs_pol == 1: dtcs_pol[0] = "R" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) mem.power = self.POWER_LEVELS[_mem.power] mem.mode = self.MODES[_mem.wide] return mem @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize or \ (len(filedata) == cls._datsize and filedata[-4:] == b"\r\n\r\n") class BJ9900RadioLeft(BJ9900Radio): """Baojie BJ-9900 Left VFO subdevice""" VARIANT = "Left" _memstart = 0x0 class BJ9900RadioRight(BJ9900Radio): """Baojie BJ-9900 Right VFO subdevice""" VARIANT = "Right" _memstart = 0xC00 chirp-20240224/chirp/drivers/ft857.py0000644000175000017500000014621714520142245016060 0ustar hibbyhibby# # Copyright 2012 Filippi Marco # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """FT857 - FT857/US management module""" from chirp.drivers import ft817 from chirp import chirp_common, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettings import logging from chirp.util import safe_charset_string LOG = logging.getLogger(__name__) @directory.register class FT857Radio(ft817.FT817Radio): """Yaesu FT-857/897""" MODEL = "FT-857/897" _model = "" TMODES = { 0x04: "Tone", 0x05: "TSQL", # 0x08 : "DTCS Enc", not supported in UI yet 0x0a: "DTCS", 0xff: "Cross", 0x00: "", } TMODES_REV = dict(list(zip(list(TMODES.values()), list(TMODES.keys())))) CROSS_MODES = { 0x01: "->Tone", 0x02: "->DTCS", 0x04: "Tone->", 0x05: "Tone->Tone", 0x06: "Tone->DTCS", 0x08: "DTCS->", 0x09: "DTCS->Tone", 0x0a: "DTCS->DTCS", } CROSS_MODES_REV = dict(list(zip(list(CROSS_MODES.values()), list(CROSS_MODES.keys())))) _memsize = 7341 # block 9 (140 Bytes long) is to be repeated 40 times # should be 42 times but this way I can use original 817 functions _block_lengths = [2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140, 38, 176] # warning ranges has to be in this exact order VALID_BANDS = [(100000, 33000000), (33000000, 56000000), (76000000, 108000000), (108000000, 137000000), (137000000, 164000000), (420000000, 470000000)] CHARSET = list(chirp_common.CHARSET_ASCII) for i in "\\{|}": CHARSET.remove(i) MEM_FORMAT = """ struct mem_struct{ u8 tag_on_off:1, tag_default:1, unknown1:3, mode:3; u8 duplex:2, is_duplex:1, is_cwdig_narrow:1, is_fm_narrow:1, freq_range:3; u8 skip:1, unknokwn1_1:1, ipo:1, att:1, unknown2:4; u8 ssb_step:2, am_step:3, fm_step:3; u8 unknown3:3, is_split_tone:1, tmode:4; u8 unknown4:2, tx_mode:3, tx_freq_range:3; u8 unknown5:1, unknown_toneflag:1, tone:6; u8 unknown6:1, unknown_rxtoneflag:1, rxtone:6; u8 unknown7:1, dcs:7; u8 unknown8:1, rxdcs:7; ul16 rit; u32 freq; u32 offset; u8 name[8]; }; #seekto 0x00; struct { u16 radioconfig; u8 mem_vfo:2, m_tune:1, home:1, pms_tune:1, qmb:1, mt_qmb:1, vfo_ab:1; u8 unknown; u8 fst:1, lock:1, nb:1, unknown1:2, disp:1, agc:2; u8 vox:1, unknown2:1, bk:1, kyr:1, cw_speed_unit:1, cw_key_rev:1, pwr_meter_mode:2; u8 vfo_b_freq_range:4, vfo_a_freq_range:4; u8 unknown3; u8 disp_mode:2, unknown4:2, disp_contrast:4; u8 unknown5:4, clar_dial_sel:2, beep_tone:2; u8 arts_beep:2, dial_step:1, arts_id:1, unknown6:1, pkt_rate:1, unknown7:2; u8 unknown8:2, lock_mode:2, unknown9:1, cw_pitch:3; u8 sql_rf_gain:1, ars_144:1, ars_430:1, cw_weight:5; u8 cw_delay; u8 cw_delay_hi:1, cw_sidetone:7; u8 unknown10:2, cw_speed:6; u8 disable_amfm_dial:1, vox_gain:7; u8 cat_rate:2, emergency:1, vox_delay:5; u8 dig_mode:3, mem_group:1, unknown11:1, apo_time:3; u8 dcs_inv:2, unknown12:1, tot_time:5; u8 mic_scan:1, ssb_mic:7; u8 cw_paddle:1, am_mic:7; u8 unknown13:1, fm_mic:7; u8 unknown14:1, dig_mic:7; u8 extended_menu:1, pkt1200:7; u8 unknown15:1, pkt9600:7; i16 dig_shift; i16 dig_disp; i8 r_lsb_car; i8 r_usb_car; i8 t_lsb_car; i8 t_usb_car; u8 unknown16:1, menu_item:7; u8 unknown17[5]; u8 unknown18:1, mtr_peak_hold:1, mic_sel:2, cat_lin_tun:2, unknown19:1, split_tone:1; u8 unknown20:1, beep_vol:7; u8 unknown21:1, dig_vox:7; u8 ext_menu:1, home_vfo:1, scan_mode:2, scan_resume:4; u8 cw_auto_mode:1, cw_training:2, cw_qsk:3, cw_bfo:2; u8 dsp_nr:4, dsp_bpf:2, dsp_mic_eq:2; u8 unknown22:3, dsp_lpf:5; u8 mtr_atx_sel:3, unknown23:1, dsp_hpf:4; u8 unknown24:2, disp_intensity:2, unknown25:1, disp_color:3; u8 unknown26:1, disp_color_vfo:1, disp_color_mtr:1, disp_color_mode:1, disp_color_memgrp:1, unknown27:1, disp_color_band:1, disp_color_arts:1; u8 unknown28:3, disp_color_fix:5; u8 unknown29:1, nb_level:7; u8 unknown30:1, proc_level:7; u8 unknown31:1, rf_power_hf:7; u8 unknown32:2, tuner_atas:3, mem_vfo_dial_mode:3; u8 pg_a; u8 pg_b; u8 pg_c; u8 pg_acc; u8 pg_p1; u8 pg_p2; u8 unknown33:3, xvtr_sel:2, unknown33_1:2, op_filter1:1; u8 unknown34:6, tx_if_filter:2; u8 unknown35:3, xvtr_a_negative:1, xvtr_b_negative:1, mtr_arx_sel:3; u8 beacon_time; u8 unknown36[2]; u8 dig_vox_enable:1, unknown37:2, scope_peakhold:1, scope_width:2, proc:1, unknown38:1; u8 unknown39:1, rf_power_6m:7; u8 unknown40:1, rf_power_vhf:7; u8 unknown41:1, rf_power_uhf:7; } settings; #seekto 0x54; struct mem_struct vfoa[16]; struct mem_struct vfob[16]; struct mem_struct home[4]; struct mem_struct qmb; struct mem_struct mtqmb; struct mem_struct mtune; #seekto 0x4a9; u8 visible[25]; ul16 pmsvisible; #seekto 0x4c4; u8 filled[25]; ul16 pmsfilled; #seekto 0x4df; struct mem_struct memory[200]; struct mem_struct pms[10]; #seekto 0x1bf3; u8 arts_idw[10]; u8 beacon_text1[40]; u8 beacon_text2[40]; u8 beacon_text3[40]; u32 xvtr_a_offset; u32 xvtr_b_offset; u8 op_filter1_name[4]; u8 op_filter2_name[4]; #seekto 0x1CAD; struct mem_struct sixtymeterchannels[5]; """ _CALLSIGN_CHARSET = [chr(x) for x in list(range(ord("0"), ord("9") + 1)) + list(range(ord("A"), ord("Z") + 1))] + [" ", "/"] _CALLSIGN_CHARSET_REV = dict(list(zip(_CALLSIGN_CHARSET, list(range(0, len(_CALLSIGN_CHARSET)))))) _BEACON_CHARSET = _CALLSIGN_CHARSET + ["+", "."] _BEACON_CHARSET_REV = dict(list(zip(_BEACON_CHARSET, list(range(0, len(_BEACON_CHARSET)))))) # WARNING Index are hard wired in memory management code !!! SPECIAL_MEMORIES = { "VFOa-1.8M": -37, "VFOa-3.5M": -36, "VFOa-5M": -35, "VFOa-7M": -34, "VFOa-10M": -33, "VFOa-14M": -32, "VFOa-18M": -31, "VFOa-21M": -30, "VFOa-24M": -29, "VFOa-28M": -28, "VFOa-50M": -27, "VFOa-FM": -26, "VFOa-AIR": -25, "VFOa-144": -24, "VFOa-430": -23, "VFOa-HF": -22, "VFOb-1.8M": -21, "VFOb-3.5M": -20, "VFOb-5M": -19, "VFOb-7M": -18, "VFOb-10M": -17, "VFOb-14M": -16, "VFOb-18M": -15, "VFOb-21M": -14, "VFOb-24M": -13, "VFOb-28M": -12, "VFOb-50M": -11, "VFOb-FM": -10, "VFOb-AIR": -9, "VFOb-144M": -8, "VFOb-430M": -7, "VFOb-HF": -6, "HOME HF": -5, "HOME 50M": -4, "HOME 144M": -3, "HOME 430M": -2, "QMB": -1, } FIRST_VFOB_INDEX = -6 LAST_VFOB_INDEX = -21 FIRST_VFOA_INDEX = -22 LAST_VFOA_INDEX = -37 SPECIAL_PMS = { "PMS-1L": -47, "PMS-1U": -46, "PMS-2L": -45, "PMS-2U": -44, "PMS-3L": -43, "PMS-3U": -42, "PMS-4L": -41, "PMS-4U": -40, "PMS-5L": -39, "PMS-5U": -38, } LAST_PMS_INDEX = -47 SPECIAL_MEMORIES.update(SPECIAL_PMS) SPECIAL_MEMORIES_REV = dict(list(zip(list(SPECIAL_MEMORIES.values()), list(SPECIAL_MEMORIES.keys())))) FILTERS = ["CFIL", "FIL1", "FIL2"] PROGRAMMABLEOPTIONS = [ "MFa:A/B", "MFa:A=B", "MFa:SPL", "MFb:MW", "MFb:SKIP/MCLR", "MFb:TAG", "MFc:STO", "MFc:RCL", "MFc:PROC", "MFd:RPT", "MFd:REV", "MFd:VOX", "MFe:TON/ENC", "MFe:TON/DEC", "MFe:TDCH", "MFf:ARTS", "MFf:SRCH", "MFf:PMS", "MFg:SCN", "MFg:PRI", "MFg:DW", "MFh:SCOP", "MFh:WID", "MFh:STEP", "MFi:MTR", "MFi:SWR", "MFi:DISP", "MFj:SPOT", "MFj:BK", "MFj:KYR", "MFk:TUNE", "MFk:DOWN", "MFk:UP", "MFl:NB", "MFl:AGC", "MFl:AGC SEL", "MFm:IPO", "MFm:ATT", "MFm:NAR", "MFn:CFIL", "MFn:FIL1", "MFn:FIL2", "MFo:PLY1", "MFo:PLY2", "MFo:PLY3", "MFp:DNR", "MFp:DNF", "MFp:DBF", "01:EXT MENU", "02:144MHz ARS", "03:430MHz ARS", "04:AM&FM DIAL", "05:AM MIC GAIN", "06:AM STEP", "07:APO TIME", "08:ARTS BEEP", "09:ARTS ID", "10:ARTS IDW", "11:BEACON TEXT", "12:BEACON TIME", "13:BEEP TONE", "14:BEEP VOL", "15:CAR LSB R", "16:CAR LSB T", "17:CAR USB R", "18:CAR USB T", "19:CAT RATE", "20:CAT/LIN/TUN", "21:CLAR DIAL SEL", "22:CW AUTO MODE", "23:CW BFO", "24:CW DELAY", "25:CW KEY REV", "26:CW PADDLE", "27:CW PITCH", "28:CW QSK", "29:CW SIDE TONE", "30:CW SPEED", "31:CW TRAINING", "32:CW WEIGHT", "33:DCS CODE", "34:DCS INV", "35:DIAL STEP", "36:DIG DISP", "37:DIG GAIN", "38:DIG MODE", "39:DIG SHIFT", "40:DIG VOX", "41:DISP COLOR", "42:DISP CONTRAST", "43:DISP INTENSITY", "44:DISP MODE", "45:DSP BPF WIDTH", "46:DSP HPF CUTOFF", "47:DSP LPF CUTOFF", "48:DSP MIC EQ", "49:DSP NR LEVEL", "50:EMERGENCY", "51:FM MIC GAIN", "52:FM STEP", "53:HOME->VFO", "54:LOCK MODE", "55:MEM GROUP", "56:MEM TAG", "57:MEM/VFO DIAL MODE", "58:MIC SCAN", "59:MIC SEL", "60:MTR ARX", "61:MTR ATX", "62:MTR PEAK HOLD", "63:NB LEVEL", "64:OP FILTER", "71:PKT 1200", "72:PKT 9600", "73:PKT RATE", "74:PROC LEVEL", "75:RF POWER SET", "76:RPT SHIFT", "77:SCAN MODE", "78:SCAN RESUME", "79:SPLIT TONE", "80:SQL/RF GAIN", "81:SSB MIC GAIN", "82:SSB STEP", "83:TONE FREQ", "84:TX TIME", "85:TUNER/ATAS", "86:TX IF FILTER", "87:VOX DELAY", "88:VOX GAIN", "89:XVTR A FREQ", "90:XVTR B FREQ", "91:XVTR SEL", "MONI", "Q.SPL", "TCALL", "ATC", "USER"] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to CAT/LINEAR jack.\n" "3. Press and hold in the [MODE <] and [MODE >] keys" " while\n" " turning the radio on (\"CLONE MODE\" will appear on the\n" " display).\n" "4. After clicking OK,\n" " press the [C](SEND) key to send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to ACC jack.\n" "3. Press and hold in the [MODE <] and [MODE >] keys" " while\n" " turning the radio on (\"CLONE MODE\" will appear on the\n" " display).\n" "4. Press the [A](RCV) key (\"receiving\" will appear on the" " LCD).\n") return rp def get_features(self): rf = ft817.FT817Radio.get_features(self) rf.has_cross = True rf.has_ctone = True rf.has_rx_dtcs = True rf.valid_tmodes = list(self.TMODES_REV.keys()) rf.valid_cross_modes = list(self.CROSS_MODES_REV.keys()) return rf def _get_duplex(self, mem, _mem): # radio set is_duplex only for + and - but not for split # at the same time it does not complain if we set it same way 817 does # (so no set_duplex here) mem.duplex = self.DUPLEX[_mem.duplex] def _get_tmode(self, mem, _mem): if not _mem.is_split_tone: mem.tmode = self.TMODES[int(_mem.tmode)] else: mem.tmode = "Cross" mem.cross_mode = self.CROSS_MODES[int(_mem.tmode)] if mem.tmode == "Tone": mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] elif mem.tmode == "TSQL": mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] elif mem.tmode == "DTCS Enc": # UI does not support it yet but # this code has already been tested mem.dtcs = mem.rx_dtcs = chirp_common.DTCS_CODES[_mem.dcs] elif mem.tmode == "DTCS": mem.dtcs = mem.rx_dtcs = chirp_common.DTCS_CODES[_mem.dcs] elif mem.tmode == "Cross": mem.ctone = chirp_common.TONES[_mem.rxtone] # don't want to fail for this try: mem.rtone = chirp_common.TONES[_mem.tone] except IndexError: mem.rtone = chirp_common.TONES[0] mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] mem.rx_dtcs = chirp_common.DTCS_CODES[_mem.rxdcs] def _set_tmode(self, mem, _mem): if mem.tmode != "Cross": _mem.is_split_tone = 0 _mem.tmode = self.TMODES_REV[mem.tmode] else: _mem.tmode = self.CROSS_MODES_REV[mem.cross_mode] _mem.is_split_tone = 1 if mem.tmode == "Tone": _mem.tone = _mem.rxtone = chirp_common.TONES.index(mem.rtone) elif mem.tmode == "TSQL": _mem.tone = _mem.rxtone = chirp_common.TONES.index(mem.ctone) elif mem.tmode == "DTCS Enc": # UI does not support it yet but # this code has already been tested _mem.dcs = _mem.rxdcs = chirp_common.DTCS_CODES.index(mem.dtcs) elif mem.tmode == "DTCS": _mem.dcs = _mem.rxdcs = chirp_common.DTCS_CODES.index(mem.rx_dtcs) elif mem.tmode == "Cross": _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.rxtone = chirp_common.TONES.index(mem.ctone) _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.rxdcs = chirp_common.DTCS_CODES.index(mem.rx_dtcs) # have to put this bit to 0 otherwise we get strange display in tone # frequency (menu 83). See bug #88 and #163 _mem.unknown_toneflag = 0 # dunno if there's the same problem here but to be safe ... _mem.unknown_rxtoneflag = 0 def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") cw = RadioSettingGroup("cw", "CW") packet = RadioSettingGroup("packet", "Digital & packet") panel = RadioSettingGroup("panel", "Panel settings") extended = RadioSettingGroup("extended", "Extended") panelcontr = RadioSettingGroup("panelcontr", "Panel controls") top = RadioSettings(basic, cw, packet, panelcontr, panel, extended) rs = RadioSetting("extended_menu", "Extended menu", RadioSettingValueBoolean(_settings.extended_menu)) extended.append(rs) rs = RadioSetting("ars_144", "144 MHz ARS", RadioSettingValueBoolean(_settings.ars_144)) basic.append(rs) rs = RadioSetting("ars_430", "430 MHz ARS", RadioSettingValueBoolean(_settings.ars_430)) basic.append(rs) options = ["enable", "disable"] rs = RadioSetting("disable_amfm_dial", "AM&FM Dial", RadioSettingValueList(options, options[ _settings.disable_amfm_dial ])) panel.append(rs) rs = RadioSetting("am_mic", "AM mic gain", RadioSettingValueInteger(0, 100, _settings.am_mic)) basic.append(rs) options = ["OFF", "1h", "2h", "3h", "4h", "5h", "6h"] rs = RadioSetting("apo_time", "APO time", RadioSettingValueList(options, options[_settings.apo_time])) basic.append(rs) options = ["OFF", "Range", "All"] rs = RadioSetting("arts_beep", "ARTS beep", RadioSettingValueList(options, options[_settings.arts_beep])) basic.append(rs) rs = RadioSetting("arts_id", "ARTS ID", RadioSettingValueBoolean(_settings.arts_id)) extended.append(rs) st = RadioSettingValueString(0, 10, safe_charset_string( self._memobj.arts_idw, self._CALLSIGN_CHARSET) ) st.set_charset(self._CALLSIGN_CHARSET) rs = RadioSetting("arts_idw", "ARTS IDW", st) extended.append(rs) st = RadioSettingValueString(0, 40, safe_charset_string( self._memobj.beacon_text1, self._BEACON_CHARSET) ) st.set_charset(self._BEACON_CHARSET) rs = RadioSetting("beacon_text1", "Beacon text1", st) extended.append(rs) st = RadioSettingValueString(0, 40, safe_charset_string( self._memobj.beacon_text2, self._BEACON_CHARSET) ) st.set_charset(self._BEACON_CHARSET) rs = RadioSetting("beacon_text2", "Beacon text2", st) extended.append(rs) st = RadioSettingValueString(0, 40, safe_charset_string( self._memobj.beacon_text3, self._BEACON_CHARSET) ) st.set_charset(self._BEACON_CHARSET) rs = RadioSetting("beacon_text3", "Beacon text3", st) extended.append(rs) options = ["OFF"] + ["%i sec" % i for i in range(1, 256)] rs = RadioSetting("beacon_time", "Beacon time", RadioSettingValueList(options, options[_settings.beacon_time]) ) extended.append(rs) options = ["440 Hz", "880 Hz", "1760 Hz"] rs = RadioSetting("beep_tone", "Beep tone", RadioSettingValueList(options, options[_settings.beep_tone])) panel.append(rs) rs = RadioSetting("beep_vol", "Beep volume", RadioSettingValueInteger(0, 100, _settings.beep_vol)) panel.append(rs) rs = RadioSetting("r_lsb_car", "LSB Rx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.r_lsb_car)) extended.append(rs) rs = RadioSetting("r_usb_car", "USB Rx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.r_usb_car)) extended.append(rs) rs = RadioSetting("t_lsb_car", "LSB Tx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.t_lsb_car)) extended.append(rs) rs = RadioSetting("t_usb_car", "USB Tx carrier point (*10 Hz)", RadioSettingValueInteger(-30, 30, _settings.t_usb_car)) extended.append(rs) options = ["4800", "9600", "38400"] rs = RadioSetting("cat_rate", "CAT rate", RadioSettingValueList(options, options[_settings.cat_rate])) basic.append(rs) options = ["CAT", "Linear", "Tuner"] rs = RadioSetting("cat_lin_tun", "CAT/LIN/TUN selection", RadioSettingValueList(options, options[_settings.cat_lin_tun]) ) extended.append(rs) options = ["MAIN", "VFO/MEM", "CLAR"] # TODO test the 3 options on non D radio # which have only SEL and MAIN rs = RadioSetting("clar_dial_sel", "Clarifier dial selection", RadioSettingValueList(options, options[ _settings.clar_dial_sel])) panel.append(rs) rs = RadioSetting("cw_auto_mode", "CW Automatic mode", RadioSettingValueBoolean(_settings.cw_auto_mode)) cw.append(rs) options = ["USB", "LSB", "AUTO"] rs = RadioSetting("cw_bfo", "CW BFO", RadioSettingValueList(options, options[_settings.cw_bfo])) cw.append(rs) options = ["FULL"] + ["%i ms" % (i * 10) for i in range(3, 301)] val = (_settings.cw_delay + _settings.cw_delay_hi * 256) - 2 rs = RadioSetting("cw_delay", "CW delay", RadioSettingValueList(options, options[val])) cw.append(rs) options = ["Normal", "Reverse"] rs = RadioSetting("cw_key_rev", "CW key reverse", RadioSettingValueList(options, options[_settings.cw_key_rev])) cw.append(rs) rs = RadioSetting("cw_paddle", "CW paddle", RadioSettingValueBoolean(_settings.cw_paddle)) cw.append(rs) options = ["%i Hz" % i for i in range(400, 801, 100)] rs = RadioSetting("cw_pitch", "CW pitch", RadioSettingValueList(options, options[_settings.cw_pitch])) cw.append(rs) options = ["%i ms" % i for i in range(5, 31, 5)] rs = RadioSetting("cw_qsk", "CW QSK", RadioSettingValueList(options, options[_settings.cw_qsk])) cw.append(rs) rs = RadioSetting("cw_sidetone", "CW sidetone volume", RadioSettingValueInteger(0, 100, _settings.cw_sidetone)) cw.append(rs) options = ["%i wpm" % i for i in range(4, 61)] rs = RadioSetting("cw_speed", "CW speed", RadioSettingValueList(options, options[_settings.cw_speed])) cw.append(rs) options = ["Numeric", "Alphabet", "AlphaNumeric"] rs = RadioSetting("cw_training", "CW training", RadioSettingValueList(options, options[_settings.cw_training]) ) cw.append(rs) options = ["1:%1.1f" % (i / 10) for i in range(25, 46, 1)] rs = RadioSetting("cw_weight", "CW weight", RadioSettingValueList(options, options[_settings.cw_weight])) cw.append(rs) options = ["Tn-Rn", "Tn-Riv", "Tiv-Rn", "Tiv-Riv"] rs = RadioSetting("dcs_inv", "DCS inv", RadioSettingValueList(options, options[_settings.dcs_inv])) extended.append(rs) options = ["Fine", "Coarse"] rs = RadioSetting("dial_step", "Dial step", RadioSettingValueList(options, options[_settings.dial_step])) panel.append(rs) rs = RadioSetting("dig_disp", "Dig disp (*10 Hz)", RadioSettingValueInteger(-300, 300, _settings.dig_disp)) packet.append(rs) rs = RadioSetting("dig_mic", "Dig gain", RadioSettingValueInteger(0, 100, _settings.dig_mic)) packet.append(rs) options = ["RTTYL", "RTTYU", "PSK31-L", "PSK31-U", "USER-L", "USER-U"] rs = RadioSetting("dig_mode", "Dig mode", RadioSettingValueList(options, options[_settings.dig_mode])) packet.append(rs) rs = RadioSetting("dig_shift", "Dig shift (*10 Hz)", RadioSettingValueInteger(-300, 300, _settings.dig_shift)) packet.append(rs) rs = RadioSetting("dig_vox", "Dig vox", RadioSettingValueInteger(0, 100, _settings.dig_vox)) packet.append(rs) options = ["ARTS", "BAND", "FIX", "MEMGRP", "MODE", "MTR", "VFO"] rs = RadioSetting("disp_color", "Display color mode", RadioSettingValueList(options, options[_settings.disp_color])) panel.append(rs) rs = RadioSetting("disp_color_arts", "Display color ARTS set", RadioSettingValueInteger(0, 1, _settings.disp_color_arts)) panel.append(rs) rs = RadioSetting("disp_color_band", "Display color band set", RadioSettingValueInteger(0, 1, _settings.disp_color_band)) panel.append(rs) rs = RadioSetting("disp_color_memgrp", "Display color memory group set", RadioSettingValueInteger(0, 1, _settings.disp_color_memgrp) ) panel.append(rs) rs = RadioSetting("disp_color_mode", "Display color mode set", RadioSettingValueInteger(0, 1, _settings.disp_color_mode)) panel.append(rs) rs = RadioSetting("disp_color_mtr", "Display color meter set", RadioSettingValueInteger(0, 1, _settings.disp_color_mtr)) panel.append(rs) rs = RadioSetting("disp_color_vfo", "Display color VFO set", RadioSettingValueInteger(0, 1, _settings.disp_color_vfo)) panel.append(rs) rs = RadioSetting("disp_color_fix", "Display color fix set", RadioSettingValueInteger(1, 32, _settings.disp_color_fix + 1 )) panel.append(rs) rs = RadioSetting("disp_contrast", "Contrast", RadioSettingValueInteger(3, 15, _settings.disp_contrast + 2) ) panel.append(rs) rs = RadioSetting("disp_intensity", "Intensity", RadioSettingValueInteger(1, 3, _settings.disp_intensity)) panel.append(rs) options = ["OFF", "Auto1", "Auto2", "ON"] rs = RadioSetting("disp_mode", "Display backlight mode", RadioSettingValueList(options, options[_settings.disp_mode])) panel.append(rs) options = ["60 Hz", "120 Hz", "240 Hz"] rs = RadioSetting("dsp_bpf", "Dsp band pass filter", RadioSettingValueList(options, options[_settings.dsp_bpf])) cw.append(rs) options = ["100 Hz", "160 Hz", "220 Hz", "280 Hz", "340 Hz", "400 Hz", "460 Hz", "520 Hz", "580 Hz", "640 Hz", "720 Hz", "760 Hz", "820 Hz", "880 Hz", "940 Hz", "1000 Hz"] rs = RadioSetting("dsp_hpf", "Dsp hi pass filter cut off", RadioSettingValueList(options, options[_settings.dsp_hpf])) basic.append(rs) options = ["1000 Hz", "1160 Hz", "1320 Hz", "1480 Hz", "1650 Hz", "1800 Hz", "1970 Hz", "2130 Hz", "2290 Hz", "2450 Hz", "2610 Hz", "2770 Hz", "2940 Hz", "3100 Hz", "3260 Hz", "3420 Hz", "3580 Hz", "3740 Hz", "3900 Hz", "4060 Hz", "4230 Hz", "4390 Hz", "4550 Hz", "4710 Hz", "4870 Hz", "5030 Hz", "5190 Hz", "5390 Hz", "5520 Hz", "5680 Hz", "5840 Hz", "6000 Hz"] rs = RadioSetting("dsp_lpf", "Dsp low pass filter cut off", RadioSettingValueList(options, options[_settings.dsp_lpf])) basic.append(rs) options = ["OFF", "LPF", "HPF", "BOTH"] rs = RadioSetting("dsp_mic_eq", "Dsp mic equalization", RadioSettingValueList(options, options[_settings.dsp_mic_eq])) basic.append(rs) rs = RadioSetting("dsp_nr", "DSP noise reduction level", RadioSettingValueInteger(1, 16, _settings.dsp_nr + 1)) basic.append(rs) # emergency only for US model rs = RadioSetting("fm_mic", "FM mic gain", RadioSettingValueInteger(0, 100, _settings.fm_mic)) basic.append(rs) rs = RadioSetting("home_vfo", "Enable HOME to VFO moving", RadioSettingValueBoolean(_settings.home_vfo)) panel.append(rs) options = ["Dial", "Freq", "Panel", "All"] rs = RadioSetting("lock_mode", "Lock mode", RadioSettingValueList(options, options[_settings.lock_mode])) panel.append(rs) rs = RadioSetting("mem_group", "Mem group", RadioSettingValueBoolean(_settings.mem_group)) basic.append(rs) options = ["CW SIDETONE", "CW SPEED", "MHz/MEM GRP", "MIC GAIN", "NB LEVEL", "RF POWER", "STEP"] rs = RadioSetting("mem_vfo_dial_mode", "Mem/VFO dial mode", RadioSettingValueList(options, options[ _settings.mem_vfo_dial_mode ])) panel.append(rs) rs = RadioSetting("mic_scan", "Mic scan", RadioSettingValueBoolean(_settings.mic_scan)) basic.append(rs) options = ["NOR", "RMT", "CAT"] rs = RadioSetting("mic_sel", "Mic selection", RadioSettingValueList(options, options[_settings.mic_sel])) extended.append(rs) options = ["SIG", "CTR", "VLT", "N/A", "FS", "OFF"] rs = RadioSetting("mtr_arx_sel", "Meter receive selection", RadioSettingValueList(options, options[_settings.mtr_arx_sel]) ) extended.append(rs) options = ["PWR", "ALC", "MOD", "SWR", "VLT", "N/A", "OFF"] rs = RadioSetting("mtr_atx_sel", "Meter transmit selection", RadioSettingValueList(options, options[_settings.mtr_atx_sel]) ) extended.append(rs) rs = RadioSetting("mtr_peak_hold", "Meter peak hold", RadioSettingValueBoolean(_settings.mtr_peak_hold)) extended.append(rs) rs = RadioSetting("nb_level", "Noise blanking level", RadioSettingValueInteger(0, 100, _settings.nb_level)) basic.append(rs) st = RadioSettingValueString(0, 4, safe_charset_string( self._memobj.op_filter1_name, self._CALLSIGN_CHARSET) ) st.set_charset(self._CALLSIGN_CHARSET) rs = RadioSetting("op_filter1_name", "Optional filter1 name", st) extended.append(rs) st = RadioSettingValueString(0, 4, safe_charset_string( self._memobj.op_filter2_name, self._CALLSIGN_CHARSET) ) st.set_charset(self._CALLSIGN_CHARSET) rs = RadioSetting("op_filter2_name", "Optional filter2 name", st) extended.append(rs) rs = RadioSetting("pg_a", "Programmable key MFq:A", RadioSettingValueList(self.PROGRAMMABLEOPTIONS, self.PROGRAMMABLEOPTIONS[ _settings.pg_a])) extended.append(rs) rs = RadioSetting("pg_b", "Programmable key MFq:B", RadioSettingValueList(self.PROGRAMMABLEOPTIONS, self.PROGRAMMABLEOPTIONS[ _settings.pg_b])) extended.append(rs) rs = RadioSetting("pg_c", "Programmable key MFq:C", RadioSettingValueList(self.PROGRAMMABLEOPTIONS, self.PROGRAMMABLEOPTIONS[ _settings.pg_c])) extended.append(rs) rs = RadioSetting("pg_acc", "Programmable mic key ACC", RadioSettingValueList(self.PROGRAMMABLEOPTIONS, self.PROGRAMMABLEOPTIONS[ _settings.pg_acc])) extended.append(rs) rs = RadioSetting("pg_p1", "Programmable mic key P1", RadioSettingValueList(self.PROGRAMMABLEOPTIONS, self.PROGRAMMABLEOPTIONS[ _settings.pg_p1])) extended.append(rs) rs = RadioSetting("pg_p2", "Programmable mic key P2", RadioSettingValueList(self.PROGRAMMABLEOPTIONS, self.PROGRAMMABLEOPTIONS[ _settings.pg_p2])) extended.append(rs) rs = RadioSetting("pkt1200", "Packet 1200 gain level", RadioSettingValueInteger(0, 100, _settings.pkt1200)) packet.append(rs) rs = RadioSetting("pkt9600", "Packet 9600 gain level", RadioSettingValueInteger(0, 100, _settings.pkt9600)) packet.append(rs) options = ["1200", "9600"] rs = RadioSetting("pkt_rate", "Packet rate", RadioSettingValueList(options, options[_settings.pkt_rate])) packet.append(rs) rs = RadioSetting("proc_level", "Proc level", RadioSettingValueInteger(0, 100, _settings.proc_level)) basic.append(rs) rs = RadioSetting("rf_power_hf", "Rf power set HF", RadioSettingValueInteger(5, 100, _settings.rf_power_hf)) basic.append(rs) rs = RadioSetting("rf_power_6m", "Rf power set 6m", RadioSettingValueInteger(5, 100, _settings.rf_power_6m)) basic.append(rs) rs = RadioSetting("rf_power_vhf", "Rf power set VHF", RadioSettingValueInteger(5, 50, _settings.rf_power_vhf)) basic.append(rs) rs = RadioSetting("rf_power_uhf", "Rf power set UHF", RadioSettingValueInteger(2, 20, _settings.rf_power_uhf)) basic.append(rs) options = ["TIME", "BUSY", "STOP"] rs = RadioSetting("scan_mode", "Scan mode", RadioSettingValueList(options, options[_settings.scan_mode])) basic.append(rs) rs = RadioSetting("scan_resume", "Scan resume", RadioSettingValueInteger(1, 10, _settings.scan_resume)) basic.append(rs) rs = RadioSetting("split_tone", "Split tone enable", RadioSettingValueBoolean(_settings.split_tone)) extended.append(rs) options = ["RF-Gain", "Squelch"] rs = RadioSetting("sql_rf_gain", "Squelch/RF-Gain", RadioSettingValueList(options, options[_settings.sql_rf_gain]) ) panel.append(rs) rs = RadioSetting("ssb_mic", "SSB Mic gain", RadioSettingValueInteger(0, 100, _settings.ssb_mic)) basic.append(rs) options = ["Off"] + ["%i" % i for i in range(1, 21)] rs = RadioSetting("tot_time", "Time-out timer", RadioSettingValueList(options, options[_settings.tot_time])) basic.append(rs) options = ["OFF", "ATAS(HF)", "ATAS(HF&50)", "ATAS(ALL)", "TUNER"] rs = RadioSetting("tuner_atas", "Tuner/ATAS device", RadioSettingValueList(options, options[_settings.tuner_atas])) extended.append(rs) rs = RadioSetting("tx_if_filter", "Transmit IF filter", RadioSettingValueList(self.FILTERS, self.FILTERS[ _settings.tx_if_filter])) basic.append(rs) rs = RadioSetting("vox_delay", "VOX delay (*100 ms)", RadioSettingValueInteger(1, 30, _settings.vox_delay)) basic.append(rs) rs = RadioSetting("vox_gain", "VOX Gain", RadioSettingValueInteger(1, 100, _settings.vox_gain)) basic.append(rs) rs = RadioSetting("xvtr_a", "Xvtr A displacement", RadioSettingValueInteger( -4294967295, 4294967295, self._memobj.xvtr_a_offset * (-1 if _settings.xvtr_a_negative else 1))) extended.append(rs) rs = RadioSetting("xvtr_b", "Xvtr B displacement", RadioSettingValueInteger( -4294967295, 4294967295, self._memobj.xvtr_b_offset * (-1 if _settings.xvtr_b_negative else 1))) extended.append(rs) options = ["OFF", "XVTR A", "XVTR B"] rs = RadioSetting("xvtr_sel", "Transverter function selection", RadioSettingValueList(options, options[_settings.xvtr_sel])) extended.append(rs) rs = RadioSetting("disp", "Display large", RadioSettingValueBoolean(_settings.disp)) panel.append(rs) rs = RadioSetting("nb", "Noise blanker", RadioSettingValueBoolean(_settings.nb)) panelcontr.append(rs) options = ["Auto", "Fast", "Slow", "Off"] rs = RadioSetting("agc", "AGC", RadioSettingValueList(options, options[_settings.agc])) panelcontr.append(rs) options = ["PWR", "ALC", "SWR", "MOD"] rs = RadioSetting("pwr_meter_mode", "Power meter mode", RadioSettingValueList(options, options[ _settings.pwr_meter_mode])) panelcontr.append(rs) rs = RadioSetting("vox", "Vox", RadioSettingValueBoolean(_settings.vox)) panelcontr.append(rs) rs = RadioSetting("bk", "Semi break-in", RadioSettingValueBoolean(_settings.bk)) cw.append(rs) rs = RadioSetting("kyr", "Keyer", RadioSettingValueBoolean(_settings.kyr)) cw.append(rs) options = ["enabled", "disabled"] rs = RadioSetting("fst", "Fast", RadioSettingValueList(options, options[_settings.fst] )) panelcontr.append(rs) options = ["enabled", "disabled"] rs = RadioSetting("lock", "Lock", RadioSettingValueList(options, options[_settings.lock])) panelcontr.append(rs) rs = RadioSetting("scope_peakhold", "Scope max hold", RadioSettingValueBoolean(_settings.scope_peakhold)) panelcontr.append(rs) options = ["21", "31", "127"] rs = RadioSetting("scope_width", "Scope width (channels)", RadioSettingValueList(options, options[_settings.scope_width]) ) panelcontr.append(rs) rs = RadioSetting("proc", "Speech processor", RadioSettingValueBoolean(_settings.proc)) panelcontr.append(rs) return top def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() try: LOG.debug("Setting %s(%s) <= %s" % (setting, getattr(obj, setting), element.value)) except AttributeError: LOG.debug("Setting %s <= %s" % (setting, element.value)) if setting == "arts_idw": self._memobj.arts_idw = \ [self._CALLSIGN_CHARSET_REV[x] for x in str(element.value)] elif setting in ["beacon_text1", "beacon_text2", "beacon_text3", "op_filter1_name", "op_filter2_name"]: setattr(self._memobj, setting, [self._BEACON_CHARSET_REV[x] for x in str(element.value)]) elif setting == "cw_delay": val = int(element.value) + 2 setattr(obj, "cw_delay_hi", val / 256) setattr(obj, setting, val & 0xff) elif setting == "dig_vox": val = int(element.value) setattr(obj, "dig_vox_enable", int(val > 0)) setattr(obj, setting, val) elif setting in ["disp_color_fix", "dsp_nr"]: setattr(obj, setting, int(element.value) - 1) elif setting == "disp_contrast": setattr(obj, setting, int(element.value) - 2) elif setting in ["xvtr_a", "xvtr_b"]: val = int(element.value) setattr(obj, setting + "_negative", int(val < 0)) setattr(self._memobj, setting + "_offset", abs(val)) else: setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @directory.register class FT857USRadio(FT857Radio): """Yaesu FT857/897 (US version)""" # seems that radios configured for 5 MHz operations send one packet more # than others so we have to distinguish sub models MODEL = "FT-857/897 (US)" _model = "" _US_model = True _memsize = 7481 # block 9 (140 Bytes long) is to be repeated 40 times # should be 42 times but this way I can use original 817 functions _block_lengths = [2, 82, 252, 196, 252, 196, 212, 55, 140, 140, 140, 38, 176, 140] SPECIAL_60M = { "M-601": -52, "M-602": -51, "M-603": -50, "M-604": -49, "M-605": -48, } LAST_SPECIAL60M_INDEX = -52 SPECIAL_MEMORIES = dict(FT857Radio.SPECIAL_MEMORIES) SPECIAL_MEMORIES.update(SPECIAL_60M) SPECIAL_MEMORIES_REV = dict(list(zip(list(SPECIAL_MEMORIES.values()), list(SPECIAL_MEMORIES.keys())))) # this is identical to the one in FT817ND_US_Radio but we inherit from 857 def _get_special_60m(self, number): mem = chirp_common.Memory() mem.number = self.SPECIAL_60M[number] mem.extd_number = number _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number] mem = self._get_memory(mem, _mem) mem.immutable = ["number", "rtone", "ctone", "extd_number", "name", "dtcs", "tmode", "cross_mode", "dtcs_polarity", "power", "duplex", "offset", "empty"] return mem # this is identical to the one in FT817ND_US_Radio but we inherit from 857 def _set_special_60m(self, mem): if mem.empty: # can't delete 60M memories! raise Exception("Sorry, 60M memory can't be deleted") cur_mem = self._get_special_60m(self.SPECIAL_MEMORIES_REV[mem.number]) for key in cur_mem.immutable: if cur_mem.__dict__[key] != mem.__dict__[key]: raise errors.RadioError("Editing field `%s' " % key + "is not supported on M-60x channels") if mem.mode not in ["USB", "LSB", "CW", "CWR", "NCW", "NCWR", "DIG"]: raise errors.RadioError("Mode {mode} is not valid " "in 60m channels".format(mode=mem.mode)) _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number] self._set_memory(mem, _mem) def get_memory(self, number): if number in self.SPECIAL_60M: return self._get_special_60m(number) elif isinstance(number, int) and number < 0 and ( self.SPECIAL_MEMORIES_REV[number] in list(self.SPECIAL_60M.keys())): # I can't stop delete operation from losing extd_number but # I know how to get it back return self._get_special_60m(self.SPECIAL_MEMORIES_REV[number]) else: return FT857Radio.get_memory(self, number) def set_memory(self, memory): if memory.number in list(self.SPECIAL_60M.values()): return self._set_special_60m(memory) else: return FT857Radio.set_memory(self, memory) def get_settings(self): top = FT857Radio.get_settings(self) basic = top[0] rs = RadioSetting("emergency", "Emergency", RadioSettingValueBoolean( self._memobj.settings.emergency)) basic.append(rs) return top chirp-20240224/chirp/drivers/ftm3200d.py0000644000175000017500000001504214443274461016443 0ustar hibbyhibby# Copyright 2010 Dan Smith # Copyright 2017 Wade Simmons # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import yaesu_clone, ft1d from chirp import chirp_common, directory, bitwise from chirp.settings import RadioSettings LOG = logging.getLogger(__name__) POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=30), chirp_common.PowerLevel("Hi", watts=65)] TMODES = ["", "Tone", "TSQL", "DTCS", "TSQL-R", None, None, "Pager", "Cross"] CROSS_MODES = [None, "DTCS->", "Tone->DTCS", "DTCS->Tone"] MODES = ["FM", "NFM"] STEPS = [0, 5, 6.25, 10, 12.5, 15, 20, 25, 50, 100] # 0 = auto RFSQUELCH = ["OFF", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8"] # Charset is subset of ASCII + some unknown chars \x80-\x86 VALID_CHARS = ["%i" % int(x) for x in range(0, 10)] + \ list(":>=After clicking OK, press the [REV(DW)] key\n" " to send image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to DATA terminal.\n" "3. Press and hold in the [MHz(SETUP)] key while turning the" " radio\n" " on (\"CLONE\" will appear on the display).\n" "4. Press the [MHz(SETUP)] key\n" " (\"-WAIT-\" will appear on the LCD).\n") return rp def process_mmap(self): mem_format = ft1d.MEM_FORMAT + MEM_FORMAT self._memobj = bitwise.parse(mem_format % self._mem_params, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.valid_modes = list(MODES) rf.valid_tmodes = [x for x in TMODES if x is not None] rf.valid_cross_modes = [x for x in CROSS_MODES if x is not None] rf.valid_duplexes = list(ft1d.DUPLEX) rf.valid_tuning_steps = list(STEPS) rf.valid_bands = [(136000000, 174000000)] # rf.valid_skips = SKIPS rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(VALID_CHARS) rf.valid_name_length = 8 rf.memory_bounds = (1, 199) rf.can_odd_split = True rf.has_ctone = False rf.has_bank = False rf.has_bank_names = False # disable until implemented rf.has_settings = False return rf def _decode_label(self, mem): # TODO preserve the unknown \x80-x86 chars? return str(mem.label).rstrip("\xFF").rstrip() def _encode_label(self, mem): label = mem.name.rstrip().encode('ascii', 'ignore') return self._add_ff_pad(label, 16) def _encode_charsetbits(self, mem): # TODO this is a setting to decide if the memory should be displayed # as a name or frequency. Should we expose this setting to the user # instead of autoselecting it (and losing their preference)? if mem.name.rstrip() == '': return 0x0000 return 0x0080 def _decode_power_level(self, mem): return POWER_LEVELS[mem.power - 1] def _encode_power_level(self, mem): if mem.power is None: return 1 else: return POWER_LEVELS.index(mem.power) + 1 def _decode_mode(self, mem): return MODES[mem.mode_alt] def _encode_mode(self, mem): return MODES.index(mem.mode) def _get_tmode(self, mem, _mem): if _mem.tone_mode > 8: tmode = "Cross" mem.cross_mode = CROSS_MODES[_mem.tone_mode - 8] else: tmode = TMODES[_mem.tone_mode] if tmode == "Pager": # TODO chirp_common does not allow 'Pager' # Expose as a different setting? mem.tmode = "" else: mem.tmode = tmode def _set_tmode(self, _mem, mem): if mem.tmode == "Cross": _mem.tone_mode = 8 + CROSS_MODES.index(mem.cross_mode) else: _mem.tone_mode = TMODES.index(mem.tmode) def _set_mode(self, _mem, mem): _mem.mode_alt = self._encode_mode(mem) def get_bank_model(self): return None def _debank(self, mem): return def _checksums(self): return [yaesu_clone.YaesuChecksum(0x064A, 0x06C8), yaesu_clone.YaesuChecksum(0x06CA, 0x0748), yaesu_clone.YaesuChecksum(0x074A, 0x07C8), yaesu_clone.YaesuChecksum(0x07CA, 0x0848), yaesu_clone.YaesuChecksum(0x0000, 0xFEC9)] def _get_settings(self): # TODO top = RadioSettings() return top @classmethod def _wipe_memory(cls, mem): mem.set_raw("\x00" * (mem.size() // 8)) def sync_out(self): # Need to give enough time for the radio to ACK after writes self.pipe.timeout = 1 return super(FTM3200Radio, self).sync_out() chirp-20240224/chirp/drivers/ftlx011.py0000644000175000017500000006121314466370044016403 0ustar hibbyhibby# Copyright 2019 Pavel Milanes, CO7WT # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import time from chirp import chirp_common, directory, memmap, errors, bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettings LOG = logging.getLogger(__name__) # SAMPLE MEM DUMP as sent from the radios # FTL-1011 # 0x000000 52 f0 16 90 04 08 38 c0 00 00 00 01 00 00 00 ff |R.....8.........| # 0x000010 20 f1 00 20 00 00 00 20 04 47 25 04 47 25 00 00 | .. ... .G%.G%..| # FTL-2011 # 0x000000: 50 90 21 40 04 80 fc 40 00 00 00 01 00 00 00 ff |P.!@...@........| # 0x000010: 20 f1 00 0b 00 00 00 0b 14 51 70 14 45 70 00 00 |.........Qp.Ep..| MEM_FORMAT = """ #seekto 0x000; u8 rid; // Radio Identification struct { u8 scan_time:4, // Scan timer per channel: 0-15 (5-80msec in 5msec steps) unknownA:4; bbcd if[2]; // Radio internal IF, depending on model (16.90, 21.40, 45.10, 47.90) u8 chcount; // how many channels are programmed u8 scan_resume:1, // Scan sesume: 0 = 0.5 seconds, 1 = Carrier priority_during_scan:1, // Priority during scan: 0 = enabled, 1 = disabled priority_speed:1, // Priority speed: 0 = slow, 1 = fast monitor:1, // Monitor: 0 = enabled, 1 = disabled off_hook:1, // Off hook: 0 = enabled, 1 = disabled home_channel:1, // Home Channel: 0 = Scan Start ch, 1 = Priority 1ch talk_back:1, // Talk Back: 0 = enabled, 1 = disabled tx_carrier_delay:1; // TX carrier delay: 1 = enabled, 0 = disabled u8 tot:4, // Time out timer: 16 values (0.0-7.5 in 0.5s step) tot_resume:2, // Time out timer resume: 3, 2, 1, 0 => 0s, 6s, 20s, 60s unknownB:2; u8 a_key:2, // A key function: resume: 0-3: Talkaround, High/Low, Call, Accessory unknownB:6; u8 pch1; // Priority channel 1 u8 pch2; // Priority channel 1 } settings; #seekto 0x010; struct { u8 notx:1, // 0 = Tx possible, 1 = Tx disabled empty:1, // 0 = channel enabled, 1 = channed empty tot:1, // 0 = tot disabled, 1 = tot enabled power:1, // 0 = high, 1 = low bclo_cw:1, // 0 = disabled, 1 = Busy Channel Lock out by carrier bclo_tone:1, // 0 = disabled, 1 = Busy Channel Lock out by tone (set rx tone) skip:1, // 0 = scan enabled, 1 = skip on scanning unknownA0:1; u8 chname; u8 rx_tone[2]; // empty value is \x00\x0B / disabled is \x00\x00 u8 unknown4; u8 unknown5; u8 tx_tone[2]; // empty value is \x00\x0B / disabled is \x00\x00 bbcd rx_freq[3]; // RX freq bbcd tx_freq[3]; // TX freq u8 unknownA[2]; } memory[24]; #seekto 0x0190; char filename[11]; #seekto 0x19C; u8 checksum; """ MEM_SIZE = 0x019C POWER_LEVELS = [chirp_common.PowerLevel("High", watts=50), chirp_common.PowerLevel("Low", watts=5)] DTCS_CODES = chirp_common.DTCS_CODES SKIP_VALUES = ["", "S"] LIST_BCL = ["OFF", "Carrier", "Tone"] LIST_SCAN_RESUME = ["0.5 seconds", "Carrier drop"] LIST_SCAN_TIME = ["%s ms" % x for x in range(5, 85, 5)] LIST_SCAN_P_SPEED = ["Slow", "Fast"] LIST_HOME_CHANNEL = ["Scan Start ch", "Priority 1ch"] LIST_TOT = ["Off"] + ["%.1f s" % (x/10.0) for x in range(5, 80, 5)] # 3, 2, 1, 0 => 0 s, 6 s, 20 s, 60 s LIST_TOT_RESUME = ["60 s", "20 s", "6 s", "0 s"] LIST_A_KEY = ["Talkaround", "High/Low", "Call", "Accessory"] LIST_PCH = [] # dynamic, as depends on channel list. # make a copy of the tones, is not funny to work with this directly TONES = list(chirp_common.TONES) # this old radios has not the full tone ranges in CST invalid_tones = ( 69.3, 159.8, 165.5, 171.3, 177.3, 183.5, 189.9, 196.6, 199.5, 206.5, 229.1, 245.1) # remove invalid tones for tone in invalid_tones: try: TONES.remove(tone) except: pass def _set_serial(radio): """Set the serial protocol settings""" radio.pipe.timeout = 10 radio.pipe.parity = "N" radio.pipe.baudrate = 9600 def _checksum(data): """the radio block checksum algorithm""" cs = 0 for byte in data: cs += ord(byte) return cs % 256 def _update_cs(radio): """Update the checksum on the mmap""" payload = str(radio.get_mmap())[:-1] cs = _checksum(payload) radio._mmap[MEM_SIZE - 1] = cs def _do_download(radio): """ The download function """ # Get the whole 413 bytes (0x019D) bytes one at a time with plenty of time # to get to the user's pace # set serial discipline _set_serial(radio) # UI progress status = chirp_common.Status() status.cur = 0 status.max = MEM_SIZE status.msg = " Press A to clone. " radio.status_fn(status) data = "" for i in range(0, MEM_SIZE): a = radio.pipe.read(1) if len(a) == 0: # error, no received data if len(data) != 0: # received some data, not the complete stream msg = "Just %02i bytes of the %02i received, try again." % \ (len(data), MEM_SIZE) else: # timeout, please retry msg = "No data received, try again." raise errors.RadioError(msg) data += a # UI Update status.cur = len(data) radio.status_fn(status) if len(data) != MEM_SIZE: msg = "Incomplete data, we need %02i but got %02i bytes." % \ (MEM_SIZE, len(data)) raise errors.RadioError(msg) if ord(data[-1]) != _checksum(data[:-1]): msg = "Bad checksum, please try again." raise errors.RadioError(msg) return data def _do_upload(radio): """The upload function""" # set serial discipline _set_serial(radio) # UI progress status = chirp_common.Status() # 10 seconds timeout status.cur = 0 status.max = 100 status.msg = " Quick, press MON on the radio to start. " radio.status_fn(status) for byte in range(0, 100): status.cur = byte radio.status_fn(status) time.sleep(0.1) # real upload if user don't cancel the timeout status.cur = 0 status.max = MEM_SIZE status.msg = " Cloning to radio... " radio.status_fn(status) # send data data = str(radio.get_mmap()) # this radio has a trick, the EEPROM is an ancient SPI one, so it needs # some time to write, so we send every byte and then allow # a 0.01 seg to complete the write from the MCU to the SPI EEPROM c = 0 for byte in data: radio.pipe.write(byte) time.sleep(0.01) # UI Update status.cur = c radio.status_fn(status) # counter c = c + 1 def _model_match(cls, data): """Use a experimental guess to determine if the radio you just downloaded or the img you opened is for this model""" # It's hard to tell when this radio is really this radio. # I use the first byte, that appears to be the ID and the IF settings radiod = [data[0], data[2:4]] return cls.finger == radiod def bcd_to_int(data): """Convert an array of bcdDataElement like \x12 into an int like 12""" value = 0 a = (data & 0xF0) >> 4 b = data & 0x0F value = (a * 10) + b return value def int_to_bcd(data): """Convert a int like 94 to 0x94""" data, lsb = divmod(data, 10) data, msb = divmod(data, 10) res = (msb << 4) + lsb return res class ftlx011(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Vertex FTL1011/2011/7011 4/8/12/24 channels""" VENDOR = "Vertex Standard" _memsize = MEM_SIZE _upper = 0 _range = [] finger = [] # two elements rid & IF @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This is a experimental driver, use it on your own risk.\n' '\n' 'This driver is just for the 4/12/24 channels variants of ' 'these radios, 99 channel variants are not supported yet.\n' '\n' 'The 99 channel versions appears to use another mem layout.\n' ) rp.pre_download = _( "Please follow this steps carefully:\n" "1 - Turn on your radio\n" "2 - Connect the interface cable to your radio.\n" "3 - Click the button on this window to start download\n" " (Radio will beep and led will flash)\n" "4 - Then press the \"A\" button in your radio to start" " cloning.\n" " (At the end radio will beep)\n") rp.pre_upload = _( "Please follow this steps carefully:\n" "1 - Turn on your radio\n" "2 - Connect the interface cable to your radio\n" "3 - Click the button on this window to start download\n" " (you may see another dialog, click ok)\n" "4 - Radio will beep and led will flash\n" "5 - You will get a 10 seconds timeout to press \"MON\" before\n" " data upload start\n" "6 - If all goes right radio will beep at end.\n" "After cloning remove the cable and power cycle your radio to\n" "get into normal mode.\n") return rp def get_features(self): """Return information about this radio's features""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.has_name = False rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = False rf.has_ctone = True rf.has_cross = True rf.valid_duplexes = ["", "-", "+", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->DTCS", "DTCS->", "->DTCS"] rf.valid_dtcs_codes = DTCS_CODES rf.valid_skips = SKIP_VALUES rf.valid_modes = ["FM"] rf.valid_power_levels = POWER_LEVELS # rf.valid_tuning_steps = [5.0] rf.valid_bands = [self._range] rf.memory_bounds = (1, self._upper) return rf def sync_in(self): """Do a download of the radio eeprom""" try: data = _do_download(self) except Exception as e: raise errors.RadioError("Failed to communicate with radio:\n %s" % e) # match model if _model_match(self, data) is False: raise errors.RadioError("Incorrect radio model") self._mmap = memmap.MemoryMap(data) self.process_mmap() # set the channel count from the radio eeprom self._upper = int(ord(data[4])) def sync_out(self): """Do an upload to the radio eeprom""" # update checksum _update_cs(self) # sanity check, match model data = str(self.get_mmap()) if len(data) != MEM_SIZE: raise errors.RadioError("Wrong radio image? Size miss match.") if _model_match(self, data) is False: raise errors.RadioError("Wrong image? Fingerprint miss match") try: _do_upload(self) except Exception as e: msg = "Failed to communicate with radio:\n%s" % e raise errors.RadioError(msg) def process_mmap(self): """Process the memory object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): """Return a raw representation of the memory object""" return repr(self._memobj.memory[number]) def _decode_tone(self, mem, rx=True): """Parse the tone data to decode from mem tones are encoded like this CTCS: mapped [0x80...0xa5] = [67.0...250.3] DTCS: mixed [0x88, 0x23] last is BCD and first is the 100 power - 88 It return: ((''|DTCS|Tone), Value (None|###), None)""" mode = "" tone = None # get the tone depending of rx or tx if rx: t = mem.rx_tone else: t = mem.tx_tone tMSB = t[0] tLSB = t[1] # no tone at all if (tMSB == 0 and tLSB < 128): return ('', None, None) # extract the tone info if tMSB == 0x00: # CTCS mode = "Tone" try: tone = TONES[tLSB - 128] except IndexError: LOG.debug("Error decoding a CTCS tone") pass else: # DTCS mode = "DTCS" try: tone = ((tMSB - 0x88) * 100) + bcd_to_int(tLSB) except IndexError: LOG.debug("Error decoding a DTCS tone") pass return (mode, tone, None) def _encode_tone(self, mem, mode, value, pol, rx=True): """Parse the tone data to encode from UI to mem CTCS: mapped [0x80...0xa5] = [67.0...250.3] DTCS: mixed [0x88, 0x23] last is BCD and first is the 100 power - 88 """ # array to pass tone = [0x00, 0x00] # which mod if mode == "DTCS": tone[0] = int(value / 100) + 0x88 tone[1] = int_to_bcd(value % 100) if mode == "Tone": # CTCS tone[1] = TONES.index(value) + 128 # set it if rx: mem.rx_tone = tone else: mem.tx_tone = tone def get_memory(self, number): """Extract a memory object from the memory map""" # Get a low-level memory object mapped to the image _mem = self._memobj.memory[number - 1] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # number mem.number = number # empty if bool(_mem.empty) is True: mem.empty = True return mem # rx freq mem.freq = int(_mem.rx_freq) * 1000 # power mem.power = POWER_LEVELS[int(_mem.power)] # checking if tx freq is disabled if bool(_mem.notx) is True: mem.duplex = "off" mem.offset = 0 else: tx = int(_mem.tx_freq) * 1000 if tx == mem.freq: mem.offset = 0 mem.duplex = "" else: mem.duplex = mem.freq > tx and "-" or "+" mem.offset = abs(tx - mem.freq) # skip mem.skip = SKIP_VALUES[_mem.skip] # tone data rxtone = txtone = None rxtone = self._decode_tone(_mem) txtone = self._decode_tone(_mem, False) chirp_common.split_tone_decode(mem, txtone, rxtone) # this radio has a primitive mode to show the channel number on a 7-segment # two digit LCD, we will use channel number # we will use a trick to show the numbers < 10 with a space not a zero in front chname = int_to_bcd(mem.number) if mem.number < 10: # convert to F# as BCD chname = mem.number + 240 _mem.chname = chname # Extra mem.extra = RadioSettingGroup("extra", "Extra") # bcl preparations: ["OFF", "Carrier", "Tone"] bcls = 0 if _mem.bclo_cw: bcls = 1 if _mem.bclo_tone: bcls = 2 bcl = RadioSetting("bclo", "Busy channel lockout", RadioSettingValueList(LIST_BCL, LIST_BCL[bcls])) mem.extra.append(bcl) # return mem return mem def set_memory(self, mem): """Store details about a high-level memory to the memory map This is called when a user edits a memory in the UI""" # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] # Empty memory _mem.empty = mem.empty if mem.empty: _mem.rx_freq = _mem.tx_freq = 0 return # freq rx _mem.rx_freq = mem.freq / 1000 # power, # default power level is high _mem.power = 0 if mem.power is None else POWER_LEVELS.index(mem.power) # freq tx if mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 1000 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 1000 elif mem.duplex == "off": _mem.notx = 1 _mem.tx_freq = _mem.rx_freq else: _mem.tx_freq = mem.freq / 1000 # scan add property _mem.skip = SKIP_VALUES.index(mem.skip) # tone data ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) # validate tone data from here if rxmode == "Tone" and rxtone in invalid_tones: msg = "The tone %s Hz is not valid for this radio" % rxtone raise errors.UnsupportedToneError(msg) if txmode == "Tone" and txtone in invalid_tones: msg = "The tone %s Hz is not valid for this radio" % txtone raise errors.UnsupportedToneError(msg) if rxmode == "DTCS" and rxtone not in DTCS_CODES: msg = "The digital tone %s is not valid for this radio" % rxtone raise errors.UnsupportedToneError(msg) if txmode == "DTCS" and txtone not in DTCS_CODES: msg = "The digital tone %s is not valid for this radio" % txtone raise errors.UnsupportedToneError(msg) self._encode_tone(_mem, rxmode, rxtone, rxpol) self._encode_tone(_mem, txmode, txtone, txpol, False) # this radio has a primitive mode to show the channel number on a 7-segment # two digit LCD, we will use channel number # we will use a trick to show the numbers < 10 with a space not a zero in front chname = int_to_bcd(mem.number) if mem.number < 10: # convert to F# as BCD chname = mem.number + 240 def _zero_settings(): _mem.bclo_cw = 0 _mem.bclo_tone = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse LOG.debug("Extra-Setting supplied. Setting them.") # Zero them all first so any not provided by model don't # stay set _zero_settings() for setting in mem.extra: if setting.get_name() == "bclo": sw = LIST_BCL.index(str(setting.value)) if sw == 0: # empty _zero_settings() if sw == 1: # carrier _mem.bclo_cw = 1 if sw == 2: # tone _mem.bclo_tone = 1 # activate the tone _mem.rx_tone = [0x00, 0x80] else: # reset extra settings _zero_settings() _mem.chname = chname return mem def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) # ## Basic Settings scanr = RadioSetting("scan_resume", "Scan resume by", RadioSettingValueList( LIST_SCAN_RESUME, LIST_SCAN_RESUME[_settings.scan_resume])) basic.append(scanr) scant = RadioSetting("scan_time", "Scan time per channel", RadioSettingValueList( LIST_SCAN_TIME, LIST_SCAN_TIME[_settings.scan_time])) basic.append(scant) LIST_PCH = ["%s" % x for x in range(1, _settings.chcount + 1)] pch1 = RadioSetting("pch1", "Priority channel 1", RadioSettingValueList( LIST_PCH, LIST_PCH[_settings.pch1])) basic.append(pch1) pch2 = RadioSetting("pch2", "Priority channel 2", RadioSettingValueList( LIST_PCH, LIST_PCH[_settings.pch2])) basic.append(pch2) scanp = RadioSetting("priority_during_scan", "Disable priority during scan", RadioSettingValueBoolean(_settings.priority_during_scan)) basic.append(scanp) scanps = RadioSetting("priority_speed", "Priority scan speed", RadioSettingValueList( LIST_SCAN_P_SPEED, LIST_SCAN_P_SPEED[_settings.priority_speed])) basic.append(scanps) oh = RadioSetting("off_hook", "Off Hook", # inverted RadioSettingValueBoolean(not _settings.off_hook)) basic.append(oh) tb = RadioSetting("talk_back", "Talk Back", # inverted RadioSettingValueBoolean(not _settings.talk_back)) basic.append(tb) tot = RadioSetting("tot", "Time out timer", RadioSettingValueList( LIST_TOT, LIST_TOT[_settings.tot])) basic.append(tot) totr = RadioSetting("tot_resume", "Time out timer resume guard", RadioSettingValueList( LIST_TOT_RESUME, LIST_TOT_RESUME[_settings.tot_resume])) basic.append(totr) ak = RadioSetting("a_key", "A Key function", RadioSettingValueList( LIST_A_KEY, LIST_A_KEY[_settings.a_key])) basic.append(ak) monitor = RadioSetting("monitor", "Monitor", # inverted RadioSettingValueBoolean(not _settings.monitor)) basic.append(monitor) homec = RadioSetting("home_channel", "Home Channel is", RadioSettingValueList( LIST_HOME_CHANNEL, LIST_HOME_CHANNEL[_settings.home_channel])) basic.append(homec) txd = RadioSetting("tx_carrier_delay", "Talk Back", RadioSettingValueBoolean(_settings.tx_carrier_delay)) basic.append(txd) return group def set_settings(self, uisettings): _settings = self._memobj.settings for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: name = element.get_name() value = element.value obj = getattr(_settings, name) if name in ["off_hook", "talk_back", "monitor"]: setattr(_settings, name, not value) else: setattr(_settings, name, value) LOG.debug("Setting %s: %s" % (name, value)) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == cls._memsize: match_size = True # testing the firmware fingerprint, this experimental try: match_model = _model_match(cls, filedata) except Exception: match_model = False return match_size and match_model @directory.register class ftl1011(ftlx011): """Vertex FTL-1011""" MODEL = "FTL-1011" _memsize = MEM_SIZE _upper = 4 _range = [44000000, 56000000] finger = ["\x52", "\x16\x90"] @directory.register class ftl2011(ftlx011): """Vertex FTL-2011""" MODEL = "FTL-2011" _memsize = MEM_SIZE _upper = 24 _range = [134000000, 174000000] finger = ["\x50", "\x21\x40"] @directory.register class ftl7011(ftlx011): """Vertex FTL-7011""" MODEL = "FTL-7011" _memsize = MEM_SIZE _upper = 24 _range = [400000000, 512000000] finger = ["\x54", "\x47\x90"] @directory.register class ftl8011(ftlx011): """Vertex FTL-8011""" MODEL = "FTL-8011" _memsize = MEM_SIZE _upper = 24 _range = [400000000, 512000000] finger = ["\x5c", "\x45\x10"] chirp-20240224/chirp/drivers/mml_jc8810.py0000644000175000017500000014332714566340166017000 0ustar hibbyhibby# Copyright 2023 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging import struct from chirp import ( bitwise, chirp_common, directory, errors, memmap, util, ) from chirp.settings import ( RadioSetting, RadioSettingGroup, RadioSettings, RadioSettingValueBoolean, RadioSettingValueInteger, RadioSettingValueList, RadioSettingValueString, ) LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { lbcd rxfreq[4]; // 0-3 lbcd txfreq[4]; // 4-7 ul16 rxtone; // 8-9 ul16 txtone; // A-B u8 unknown1:4, // C scode:4; // Signaling u8 unknown2:6, // D pttid:2; // PTT-ID u8 unknown3:6, // E txpower:2; // Power Level 0 = H, 1 = L, 2 = M u8 unknown4:1, // F narrow:1, // Bandwidth 0 = Wide, 1 = Narrow encrypt:2, // Encrypt bcl:1, // BCL scan:1, // Scan 0 = Skip, 1 = Scan unknown5:1, // learning:1; // Learning lbcd code[3]; // 0-2 Code u8 unknown6; // 3 char name[12]; // 4-F 12-character Alpha Tag } memory[%d]; #seekto 0x9000; struct { u8 unused:4, // 9000 sql:4; // Squelch Level u8 unused_9001:6, // 9001 save:2; // Battery Save u8 unused_9002:4, // 9002 vox:4; // VOX Level u8 unused_9003:4, // 9003 abr:4; // Auto BackLight u8 unused_9004:7, // 9004 tdr:1; // TDR u8 unused_9005:5, // 9005 tot:3; // Time-out Timer u8 unused_9006:7, // 9006 beep:1; // Beep u8 unused_9007:7, // 9007 voice:1; // Voice Prompt u8 unused_9008:7, // 9008 language:1; // Language u8 unused_9009:6, // 9009 dtmfst:2; // DTMF ST u8 unused_900a:6, // 900A screv:2; // Scan Mode u8 unused_900B:4, // 900B pttid:4; // PTT-ID u8 unused_900c:5, // 900C pttlt:3; // PTT Delay u8 unused_900d:6, // 900D mdfa:2; // Channel_A Display u8 unused_900e:6, // 900E mdfb:2; // Channel_B Display u8 unknown_900f; // 900F u8 unused_9010:4, // 9010 autolk:4; // Key Auto Lock u8 unused_9011:6, // 9011 almode:2; // Alarm Mode u8 unused_9012:7, // 9012 alarmsound:1; // Alarm Sound u8 unused_9013:6, // 9013 dualtx:2; // Dual TX u8 unused_9014:7, // 9014 ste:1; // Tail Noise Clear u8 unused_9015:4, // 9015 rpste:4; // RPT Noise Clear u8 unused_9016:4, // 9016 rptrl:4; // RPT Noise Delay u8 unused_9017:6, // 9017 roger:2; // Roger u8 unknown_9018; // 9018 u8 unused_9019:7, // 9019 fmradio:1; // FM Radio u8 unused_901a1:3, // 901A vfomrb:1, // WorkMode B unused_901a2:3, // vfomra:1; // WorkMode A u8 unused_901b:7, // 901B kblock:1; // KB Lock u8 unused_901c:7, // 901C ponmsg:1; // Power On Msg u8 unknown_901d; // 901D u8 unused_901e:6, // 901E tone:2; // Pilot u8 unknown_901f; // 901F u8 unused_9020:4, // 9020 voxd:4; // VOX Delay u8 unused_9021:4, // 9021 menuquit:4; // Menu Auto Quit u8 unused_9022:7, // 9022 tailcode:1; // Tail Code (RT-470L) u8 unknown_9023; // 9023 u8 unknown_9024; // 9024 u8 unknown_9025; // 9025 u8 unknown_9026; // 9026 u8 unknown_9027; // 9027 u8 unknown_9028; // 9028 u8 unused_9029:6, // 9029 qtsave:2; // QT Save Type u8 ani; // 902A ANI u8 skey2_sp; // 902B Skey2 Short u8 skey2_lp; // 902C Skey2 Long u8 skey3_sp; // 902D Skey3 Short u8 topkey_sp; // 902E Top Key (RT-470L) u8 unused_902f:6, // 902F rxendtail:2; // RX END TAIL (RT-470) // TAIL PHASE (A36plus) u8 skey3_lp; // 9030 Skey3 Long (RT-470L) // RX END TAIL (A36plus) } settings; #seekto 0xA006; struct { u8 unknown_A006; // A006 u8 unused_a007:5, // A007 dtmfon:3; // DTMF Speed (on time) u8 unused_a008:5, // A008 dtmfoff:3; // DTMF Speed (off time) } dtmf; #seekto 0xA020; struct { u8 code[5]; // 5-character DTMF Encoder Groups u8 unused[11]; } pttid[15]; #seekto 0xB000; struct { u8 code[3]; // 3-character ANI Code Groups } anicodes[60]; #seekto 0xB0C0; struct { char name[10]; // 10-character ANI Code Group Names u8 unused[6]; } aninames[%d]; """ MEM_FORMAT_A36PLUS = """ #seekto 0xB200; struct { char name[10]; // 10-character Custom CH Names (Talkpod A36plus) u8 unused[6]; } customnames[30]; """ CMD_ACK = b"\x06" DTCS = tuple(sorted(chirp_common.DTCS_CODES + (645,))) DTMF_CHARS = "0123456789 *#ABCD" TXPOWER_HIGH = 0x00 TXPOWER_LOW = 0x01 TXPOWER_MID = 0x02 ABR_LIST = ["On", "5 seconds", "10 seconds", "15 seconds", "20 seconds", "30 seconds", "1 minute", "2 minutes", "3 minutes"] ALMODE_LIST = ["Site", "Tone", "Code"] AUTOLK_LIST = ["Off"] + ABR_LIST[1:4] DTMFSPEED_LIST = ["50 ms", "100 ms", "200 ms", "300 ms", "500 ms"] DTMFST_LIST = ["Off", "KeyBoard Side Tone", "ANI Side Tone", "KB ST + ANI ST"] DUALTX_LIST = ["Off", "A", "B"] ENCRYPT_LIST = ["Off", "DCP1", "DCP2", "DCP3"] LANGUAGE_LIST = ["English", "Chinese"] MDF_LIST = ["Name", "Frequency", "Channel"] MENUQUIT_LIST = ["%s seconds" % x for x in range(5, 55, 5)] + ["60 seconds"] OFF1TO9_LIST = ["Off"] + ["%s" % x for x in range(1, 10)] PONMSG_LIST = ["Logo", "Voltage"] PTTID_LIST = ["Off", "BOT", "EOT", "Both"] PTTIDCODE_LIST = ["%s" % x for x in range(1, 16)] PTTLT_LIST = ["None", "100 ms"] + \ ["%s ms" % x for x in range(200, 1200, 200)] QTSAVE_LIST = ["All", "RX", "TX"] ROGER_LIST = ["OFF", "BEEP", "TONE1200"] RPSTE_LIST = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] SAVE_LIST = ["Off", "Normal", "Super", "Deep"] SCREV_LIST = ["Time (TO)", "Carrier (CO)", "Search (SE)"] TAILCODE_LIST = ["55 Hz", "62.5 Hz"] TAILPHASE_LIST = ["None", "120 Shift", "180 Shift", "240 Shift"] TONERXEND_LIST = ["Off", "MDC-1200"] TONE_LIST = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] TOT_LIST = ["Off", "30 seconds", "60 seconds", "120 seconds", "240 seconds", "480 seconds"] VOXD_LIST = ["%s seconds" % str(x / 10) for x in range(5, 21)] WORKMODE_LIST = ["VFO Mode", "Channel Mode"] ALL_SKEY_CHOICES = ["OFF", "FM Radio", "TX Power Level", "Scan", "Search", "Flashlight", "NOAA Weather", "Monitor", "PTT B", "SOS", "DTMF", "REVERSE", "REMOTE Scan"] ALL_SKEY_VALUES = [0xFF, 0x07, 0x0A, 0x1C, 0x1D, 0x08, 0x0C, 0x05, 0x01, 0x03, 0x2A, 0x2D, 0x23] def _enter_programming_mode(radio): serial = radio.pipe exito = False for i in range(0, 5): serial.write(radio._magic) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except Exception: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) try: serial.write(b"F") ident = serial.read(8) except Exception: raise errors.RadioError("Error communicating with radio") if ident not in radio._fingerprint: LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio returned unknown identification string") if radio.MODEL == "RT-470X": if ident in radio._fingerprint_pcb1: LOG.info("Radtel RT-470X - original pcb") radio.RT470X_ORIG = True elif ident in radio._fingerprint_pcb2: LOG.info("Radtel RT-470X - pcb2") radio.RT470X_ORIG = False def _exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"E") except Exception: raise errors.RadioError("Radio refused to exit programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'R', block_addr, block_size) expectedresponse = b"R" + cmd[1:] LOG.debug("Reading block %04x..." % (block_addr)) try: serial.write(cmd) response = serial.read(4 + block_size) if response[:4] != expectedresponse: raise Exception("Error reading block %04x." % (block_addr)) block_data = response[4:] except Exception: raise errors.RadioError("Failed to read block at %04x" % block_addr) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">cHb", b'W', block_addr, block_size) data = radio.get_mmap()[block_addr:block_addr + block_size] LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except Exception: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio._memsize for addr in range(0, radio._memsize, radio.BLOCK_SIZE): status.cur = addr + radio.BLOCK_SIZE radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, radio.BLOCK_SIZE_UP): status.cur = addr + radio.BLOCK_SIZE_UP radio.status_fn(status) _write_block(radio, addr, radio.BLOCK_SIZE_UP) _exit_programming_mode(radio) def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True class JC8810base(chirp_common.CloneModeRadio): """MML JC-8810""" VENDOR = "MML" MODEL = "JC-8810base" BAUD_RATE = 57600 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x40 BLOCK_SIZE_UP = 0x40 POWER_LEVELS = [chirp_common.PowerLevel("H", watts=10.00), chirp_common.PowerLevel("M", watts=8.00), chirp_common.PowerLevel("L", watts=4.00)] VALID_BANDS = [(108000000, 136000000), (136000000, 180000000), (200000000, 260000000), (330000000, 400000000), (400000000, 520000000)] _magic = b"PROGRAMJC81U" _fingerprint = [b"\x00\x00\x00\x26\x00\x20\xD8\x04", b"\x00\x00\x00\x42\x00\x20\xF0\x04", b"\x00\x00\x00\x4A\x00\x20\xF8\x04"] _ranges = [ (0x0000, 0x2000), (0x8000, 0x8040), (0x9000, 0x9040), (0xA000, 0xA140), (0xB000, 0xB300) ] _memsize = 0xB300 _upper = 256 _aninames = 30 _mem_params = (_upper, # number of channels _aninames, # number of aninames ) _valid_chars = chirp_common.CHARSET_ALPHANUMERIC + \ "`~!@#$%^&*()-=_+[]\\{}|;':\",./<>?" def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.valid_name_length = 12 rf.valid_characters = self._valid_chars rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_dtcs_codes = DTCS rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = [2.5, 5., 6.25, 8.33, 10., 12.5, 20., 25., 50.] rf.valid_bands = self.VALID_BANDS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT % self._mem_params, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_memory(self, number): """Get the mem representation from the radio image""" _mem = self._memobj.memory[number - 1] # Create a high-level memory object to return to the UI mem = chirp_common.Memory() # Memory number mem.number = number if _mem.get_raw()[:1] == b"\xFF": mem.empty = True return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # tx freq can be blank if _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": # TX freq not set mem.offset = 0 mem.duplex = "off" else: # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 for char in _mem.name: if str(char) == "\xFF": char = " " # may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() dtcs_pol = ["N", "N"] if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 elif _mem.txtone <= 0x0258: txmode = "DTCS" if _mem.txtone > 0x69: index = _mem.txtone - 0x6A dtcs_pol[0] = "R" else: index = _mem.txtone - 1 mem.dtcs = DTCS[index] else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 elif _mem.rxtone <= 0x0258: rxmode = "DTCS" if _mem.rxtone >= 0x6A: index = _mem.rxtone - 0x6A dtcs_pol[1] = "R" else: index = _mem.rxtone - 1 mem.rx_dtcs = DTCS[index] else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) if not _mem.scan: mem.skip = "S" _levels = self.POWER_LEVELS if self.MODEL in ["A36plus", "A36plus_8w", "UV-A37", "AR-730"]: if _mem.txpower == TXPOWER_HIGH: mem.power = _levels[0] elif _mem.txpower == TXPOWER_LOW: mem.power = _levels[1] else: LOG.error('%s: get_mem: unhandled power level: 0x%02x' % (mem.name, _mem.txpower)) else: if _mem.txpower == TXPOWER_HIGH: mem.power = _levels[0] elif _mem.txpower == TXPOWER_MID: mem.power = _levels[1] elif _mem.txpower == TXPOWER_LOW: mem.power = _levels[2] else: LOG.error('%s: get_mem: unhandled power level: 0x%02x' % (mem.name, _mem.txpower)) mem.mode = _mem.narrow and "NFM" or "FM" mem.extra = RadioSettingGroup("Extra", "extra") # BCL (Busy Channel Lockout) rs = RadioSettingValueBoolean(_mem.bcl) rset = RadioSetting("bcl", "BCL", rs) mem.extra.append(rset) # PTT-ID rs = RadioSettingValueList(PTTID_LIST, PTTID_LIST[_mem.pttid]) rset = RadioSetting("pttid", "PTT ID", rs) mem.extra.append(rset) # Signal (DTMF Encoder Group #) rs = RadioSettingValueList(PTTIDCODE_LIST, PTTIDCODE_LIST[_mem.scode]) rset = RadioSetting("scode", "PTT ID Code", rs) mem.extra.append(rset) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] if mem.empty: _mem.set_raw("\xff" * 32) return _mem.set_raw("\x00" * 16 + "\xFF" * 16) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": _mem.txfreq.fill_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _mem.name[i] = mem.name[i] except IndexError: _mem.name[i] = "\xFF" rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": rxmode = txmode = "DTCS" _mem.txtone = DTCS.index(mem.dtcs) + 1 _mem.rxtone = DTCS.index(mem.dtcs) + 1 elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) elif txmode == "DTCS": _mem.txtone = DTCS.index(mem.dtcs) + 1 else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCS": _mem.rxtone = DTCS.index(mem.rx_dtcs) + 1 else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 if txmode == "DTCS" and mem.dtcs_polarity[0] == "R": _mem.txtone += 0x69 if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R": _mem.rxtone += 0x69 _mem.scan = mem.skip != "S" _mem.narrow = mem.mode == "NFM" _levels = self.POWER_LEVELS if self.MODEL in ["A36plus", "A36plus_8w", "UV-A37", "AR-730"]: if mem.power is None: _mem.txpower = TXPOWER_HIGH elif mem.power == _levels[0]: _mem.txpower = TXPOWER_HIGH elif mem.power == _levels[1]: _mem.txpower = TXPOWER_LOW else: LOG.error('%s: set_mem: unhandled power level: %s' % (mem.name, mem.power)) else: if mem.power is None: _mem.txpower = TXPOWER_HIGH elif mem.power == _levels[0]: _mem.txpower = TXPOWER_HIGH elif mem.power == _levels[1]: _mem.txpower = TXPOWER_MID elif mem.power == _levels[2]: _mem.txpower = TXPOWER_LOW else: LOG.error('%s: set_mem: unhandled power level: %s' % (mem.name, mem.power)) for setting in mem.extra: if setting.get_name() == "scramble_type": setattr(_mem, setting.get_name(), int(setting.value) + 8) setattr(_mem, "scramble_type2", int(setting.value) + 8) else: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _dtmf = self._memobj.dtmf _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) # Menu 12: TOT rs = RadioSettingValueList(TOT_LIST, TOT_LIST[_settings.tot]) rset = RadioSetting("tot", "Time Out Timer", rs) basic.append(rset) # Menu 00: SQL rs = RadioSettingValueInteger(0, 9, _settings.sql) rset = RadioSetting("sql", "Squelch Level", rs) basic.append(rset) # Menu 13: VOX rs = RadioSettingValueList(OFF1TO9_LIST, OFF1TO9_LIST[_settings.vox]) rset = RadioSetting("vox", "VOX", rs) basic.append(rset) # Menu 39: VOX DELAY rs = RadioSettingValueList(VOXD_LIST, VOXD_LIST[_settings.voxd]) rset = RadioSetting("voxd", "VOX Delay", rs) basic.append(rset) # Menu 15: VOICE rs = RadioSettingValueBoolean(_settings.voice) rset = RadioSetting("voice", "Voice Prompts", rs) basic.append(rset) if self.MODEL not in ["A36plus", "A36plus_8w", "UV-A37", "AR-730"]: # Menu 17: LANGUAGE rs = RadioSettingValueList(LANGUAGE_LIST, LANGUAGE_LIST[_settings.language]) rset = RadioSetting("language", "Voice", rs) basic.append(rset) # Menu 23: ABR rs = RadioSettingValueList(ABR_LIST, ABR_LIST[_settings.abr]) rset = RadioSetting("abr", "Auto BackLight", rs) basic.append(rset) # Work Mode A rs = RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[_settings.vfomra]) rset = RadioSetting("vfomra", "Work Mode A", rs) basic.append(rset) # Work Mode B rs = RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[_settings.vfomrb]) rset = RadioSetting("vfomrb", "Work Mode B", rs) basic.append(rset) # Menu 19: SC-REV rs = RadioSettingValueList(SCREV_LIST, SCREV_LIST[_settings.screv]) rset = RadioSetting("screv", "Scan Resume Method", rs) basic.append(rset) # Menu 10: SAVE rs = RadioSettingValueList(SAVE_LIST, SAVE_LIST[_settings.save]) rset = RadioSetting("save", "Battery Save Mode", rs) basic.append(rset) # Menu 42: MDF-A rs = RadioSettingValueList(MDF_LIST, MDF_LIST[_settings.mdfa]) rset = RadioSetting("mdfa", "Memory Display Format A", rs) basic.append(rset) # Menu 43: MDF-B rs = RadioSettingValueList(MDF_LIST, MDF_LIST[_settings.mdfb]) rset = RadioSetting("mdfb", "Memory Display Format B", rs) basic.append(rset) # Menu 33: DTMFST (DTMF ST) rs = RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[_settings.dtmfst]) rset = RadioSetting("dtmfst", "DTMF Side Tone", rs) basic.append(rset) # Menu 37: PTT-LT rs = RadioSettingValueList(PTTLT_LIST, PTTLT_LIST[_settings.pttlt]) rset = RadioSetting("pttlt", "PTT Delay", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 60, _settings.ani + 1) rset = RadioSetting("ani", "ANI", rs) basic.append(rset) # Menu 20: PF2 def apply_skey2s_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = SKEY2S_CHOICES.index(val) val = SKEY2S_VALUES[index] obj.set_value(val) if self.MODEL in ["HI-8811", "RT-470L", "RT-470X", "RT-470"]: unwanted = [9, 10, 11, 12] elif self.MODEL in ["UV-A37", "AR-730"]: unwanted = [0, 5, 7, 9, 10, 11, 12] elif self.MODEL in ["A36plus", "A36plus_8w"]: unwanted = [0, 5, 7, 9, 10, 11] else: unwanted = [] SKEY2S_CHOICES = ALL_SKEY_CHOICES.copy() SKEY2S_VALUES = ALL_SKEY_VALUES.copy() for ele in sorted(unwanted, reverse=True): del SKEY2S_CHOICES[ele] del SKEY2S_VALUES[ele] if _settings.skey2_sp in SKEY2S_VALUES: idx = SKEY2S_VALUES.index(_settings.skey2_sp) else: idx = SKEY2S_VALUES.index(0x07) # default FM rs = RadioSettingValueList(SKEY2S_CHOICES, SKEY2S_CHOICES[idx]) rset = RadioSetting("skey2_sp", "PF2 Key (Short Press)", rs) rset.set_apply_callback(apply_skey2s_listvalue, _settings.skey2_sp) basic.append(rset) # Menu 21: PF2 LONG PRESS def apply_skey2l_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = SKEY2L_CHOICES.index(val) val = SKEY2L_VALUES[index] obj.set_value(val) if self.MODEL in ["HI-8811", "RT-470L", "RT-470X", "RT-470"]: unwanted = [8, 9, 10, 11, 12] elif self.MODEL in ["UV-A37", "AR-730"]: unwanted = [0, 5, 7, 8, 10, 11, 12] elif self.MODEL in ["A36plus", "A36plus_8w"]: unwanted = [0, 5, 7, 8, 11, 12] else: unwanted = [] SKEY2L_CHOICES = ALL_SKEY_CHOICES.copy() SKEY2L_VALUES = ALL_SKEY_VALUES.copy() for ele in sorted(unwanted, reverse=True): del SKEY2L_CHOICES[ele] del SKEY2L_VALUES[ele] if _settings.skey2_lp in SKEY2L_VALUES: idx = SKEY2L_VALUES.index(_settings.skey2_lp) else: idx = SKEY2L_VALUES.index(0x1D) # default Search rs = RadioSettingValueList(SKEY2L_CHOICES, SKEY2L_CHOICES[idx]) rset = RadioSetting("skey2_lp", "PF2 Key (Long Press)", rs) rset.set_apply_callback(apply_skey2l_listvalue, _settings.skey2_lp) basic.append(rset) # Menu 22: PF3 def apply_skey3s_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = SKEY3S_CHOICES.index(val) val = SKEY3S_VALUES[index] obj.set_value(val) if self.MODEL in ["HI-8811", "RT-470L", "RT-470X", "RT-470"]: unwanted = [8, 9, 10, 11, 12] elif self.MODEL in ["UV-A37", "AR-730"]: unwanted = [0, 5, 7, 8, 9, 10, 11, 12] elif self.MODEL in ["A36plus", "A36plus_8w"]: unwanted = [0, 5, 7, 8, 11] else: unwanted = [] SKEY3S_CHOICES = ALL_SKEY_CHOICES.copy() SKEY3S_VALUES = ALL_SKEY_VALUES.copy() for ele in sorted(unwanted, reverse=True): del SKEY3S_CHOICES[ele] del SKEY3S_VALUES[ele] if _settings.skey3_sp in SKEY3S_VALUES: idx = SKEY3S_VALUES.index(_settings.skey3_sp) else: idx = SKEY3S_VALUES.index(0x0C) # default NOAA rs = RadioSettingValueList(SKEY3S_CHOICES, SKEY3S_CHOICES[idx]) rset = RadioSetting("skey3_sp", "PF3 Key (Short Press)", rs) rset.set_apply_callback(apply_skey3s_listvalue, _settings.skey3_sp) basic.append(rset) if self.MODEL in ["HI-8811", "RT-470L", "RT-470X", "RT-470"]: # Menu 24: PF3 LONG PRESS (RT-470L) def apply_skey3l_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = SKEY3L_CHOICES.index(val) val = SKEY2L_VALUES[index] obj.set_value(val) if self.MODEL in ["HI-8811", "RT-470L", "RT-470X", "RT-470"]: unwanted = [8, 9, 10, 11, 12] else: unwanted = [] SKEY3L_CHOICES = ALL_SKEY_CHOICES.copy() SKEY3L_VALUES = ALL_SKEY_VALUES.copy() for ele in sorted(unwanted, reverse=True): del SKEY3L_CHOICES[ele] del SKEY3L_VALUES[ele] if _settings.skey3_lp in SKEY3L_VALUES: idx = SKEY3L_VALUES.index(_settings.skey3_lp) else: idx = SKEY3L_VALUES.index(0x1D) # default SEARCH rs = RadioSettingValueList(SKEY3L_CHOICES, SKEY3L_CHOICES[idx]) rset = RadioSetting("skey3_lp", "PF3 Key (Long Press)", rs) rset.set_apply_callback(apply_skey3l_listvalue, _settings.skey3_lp) basic.append(rset) # Menu 25: TOP KEY (RT-470L) def apply_skeytop_listvalue(setting, obj): LOG.debug("Setting value: " + str(setting.value) + " from list") val = str(setting.value) index = SKEYTOP_CHOICES.index(val) val = SKEYTOP_VALUES[index] obj.set_value(val) if self.MODEL in ["HI-8811", "RT-470L", "RT-470X", "RT-470"]: unwanted = [8, 9, 10, 11, 12] elif self.MODEL in ["UV-A37", "AR-730"]: unwanted = [0, 5, 7, 8, 9, 10, 11, 12] elif self.MODEL in ["A36plus", "A36plus_8w"]: unwanted = [0, 5, 7, 8, 11] else: unwanted = [] SKEYTOP_CHOICES = ALL_SKEY_CHOICES.copy() SKEYTOP_VALUES = ALL_SKEY_VALUES.copy() for ele in sorted(unwanted, reverse=True): del SKEYTOP_CHOICES[ele] del SKEYTOP_VALUES[ele] if _settings.topkey_sp in SKEYTOP_VALUES: idx = SKEYTOP_VALUES.index(_settings.topkey_sp) else: idx = SKEYTOP_VALUES.index(0x1D) # default SEARCH rs = RadioSettingValueList(SKEYTOP_CHOICES, SKEYTOP_CHOICES[idx]) rset = RadioSetting("topkey_sp", "Top Key (Short Press)", rs) rset.set_apply_callback(apply_skeytop_listvalue, _settings.topkey_sp) basic.append(rset) # Mneu 36: TONE rs = RadioSettingValueList(TONE_LIST, TONE_LIST[_settings.tone]) rset = RadioSetting("tone", "Tone-burst Frequency", rs) basic.append(rset) # Mneu 29: POWER ON MSG rs = RadioSettingValueList(PONMSG_LIST, PONMSG_LIST[_settings.ponmsg]) rset = RadioSetting("ponmsg", "Power On Message", rs) basic.append(rset) if self.MODEL in ["HI-8811", "RT-470L", "RT-470X"]: rs = RadioSettingValueList(TAILCODE_LIST, TAILCODE_LIST[_settings.tailcode]) rset = RadioSetting("tailcode", "Tail Code", rs) basic.append(rset) # Menu 46: STE rs = RadioSettingValueBoolean(_settings.ste) rset = RadioSetting("ste", "Squelch Tail Eliminate (HT to HT)", rs) basic.append(rset) # Menu 40: RP-STE rs = RadioSettingValueList(RPSTE_LIST, RPSTE_LIST[_settings.rpste]) rset = RadioSetting("rpste", "Squelch Tail Eliminate (repeater)", rs) basic.append(rset) # Menu 41: RPT-RL rs = RadioSettingValueList(RPSTE_LIST, RPSTE_LIST[_settings.rptrl]) rset = RadioSetting("rptrl", "STE Repeater Delay", rs) basic.append(rset) # Menu 38: MENU EXIT TIME rs = RadioSettingValueList(MENUQUIT_LIST, MENUQUIT_LIST[_settings.menuquit]) rset = RadioSetting("menuquit", "Menu Auto Quit", rs) basic.append(rset) # Menu 34: AUTOLOCK rs = RadioSettingValueList(AUTOLK_LIST, AUTOLK_LIST[_settings.autolk]) rset = RadioSetting("autolk", "Key Auto Lock", rs) basic.append(rset) # Menu 28: CDCSS SAVE MODE rs = RadioSettingValueList(QTSAVE_LIST, QTSAVE_LIST[_settings.qtsave]) rset = RadioSetting("qtsave", "QT Save Type", rs) basic.append(rset) # Menu 45: TX-A/B rs = RadioSettingValueList(DUALTX_LIST, DUALTX_LIST[_settings.dualtx]) rset = RadioSetting("dualtx", "Dual TX", rs) basic.append(rset) # Menu 47: AL-MODE rs = RadioSettingValueList(ALMODE_LIST, ALMODE_LIST[_settings.almode]) rset = RadioSetting("almode", "Alarm Mode", rs) basic.append(rset) # Menu 11: ROGER # ========== # Notice to developers: # The RT-470 v1.22 firmware expanded the ROGER menu with an additional # choice, 'TONE1200'. RT-470 radios with a firmware version prior to # v1.22 will not honor the ROGER menu's 'TONE1200' choice in CHIRP. # ========== rs = RadioSettingValueList(ROGER_LIST, ROGER_LIST[_settings.roger]) rset = RadioSetting("roger", "Roger", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.alarmsound) rset = RadioSetting("alarmsound", "Alarm Sound", rs) basic.append(rset) # Menu 44: TDR rs = RadioSettingValueBoolean(_settings.tdr) rset = RadioSetting("tdr", "TDR", rs) basic.append(rset) rs = RadioSettingValueBoolean(not _settings.fmradio) rset = RadioSetting("fmradio", "FM Radio", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.kblock) rset = RadioSetting("kblock", "KB Lock", rs) basic.append(rset) # Menu 16: BEEP PROMPT rs = RadioSettingValueBoolean(_settings.beep) rset = RadioSetting("beep", "Beep", rs) basic.append(rset) if self.MODEL not in ["A36plus", "A36plus_8w", "UV-A37", "AR-730"]: # Menu 48: RX END TAIL rs = RadioSettingValueList(TONERXEND_LIST, TONERXEND_LIST[_settings.rxendtail]) rset = RadioSetting("rxendtail", "Tone RX End", rs) basic.append(rset) dtmf = RadioSettingGroup("dtmf", "DTMF Settings") group.append(dtmf) def apply_code(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) rs = RadioSettingValueString(0, 5, _code, False) rs.set_charset(DTMF_CHARS) rset = RadioSetting("pttid/%i.code" % i, "PTT-ID Code %i" % (i + 1), rs) rset.set_apply_callback(apply_code, self._memobj.pttid[i], 5) dtmf.append(rset) rs = RadioSettingValueList(DTMFSPEED_LIST, DTMFSPEED_LIST[_dtmf.dtmfon]) rset = RadioSetting("dtmf.dtmfon", "DTMF Speed (on)", rs) dtmf.append(rset) rs = RadioSettingValueList(DTMFSPEED_LIST, DTMFSPEED_LIST[_dtmf.dtmfoff]) rset = RadioSetting("dtmf.dtmfoff", "DTMF Speed (off)", rs) dtmf.append(rset) rs = RadioSettingValueList(PTTID_LIST, PTTID_LIST[_settings.pttid]) rset = RadioSetting("pttid", "PTT ID", rs) dtmf.append(rset) ani = RadioSettingGroup("ani", "ANI Code List Settings") group.append(ani) def _filter(name): filtered = "" for char in str(name): if char in self._valid_chars: filtered += char else: filtered += " " return filtered end = 60 - self._aninames # end of immutable ANI names for i in range(0, end): _codeobj = self._memobj.anicodes[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) rs = RadioSettingValueString(0, 3, _code, False) rs.set_charset(DTMF_CHARS) rset = RadioSetting("anicodes/%i.code" % i, "ANI Code %i (NUM.%i)" % (i + 1, i + 1), rs) rset.set_apply_callback(apply_code, self._memobj.anicodes[i], 3) ani.append(rset) for i in range(end, 60): _codeobj = self._memobj.anicodes[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) rs = RadioSettingValueString(0, 3, _code, False) rs.set_charset(DTMF_CHARS) rset = RadioSetting("anicodes/%i.code" % (i), "ANI Code %i" % (i + 1), rs) rset.set_apply_callback(apply_code, self._memobj.anicodes[i], 3) ani.append(rset) _nameobj = self._memobj.aninames[i - end].name rs = RadioSettingValueString(0, 10, _filter(_nameobj)) rset = RadioSetting("aninames/%i.name" % (i - end), "ANI Code %i Name" % (i + 1), rs) ani.append(rset) if self.MODEL in ["A36plus", "A36plus_8w"]: custom = RadioSettingGroup("custom", "Custom Channel Names") group.append(custom) for i in range(0, 30): _nameobj = self._memobj.customnames[i].name rs = RadioSettingValueString(0, 10, _filter(_nameobj)) rset = RadioSetting("customnames/%i.name" % i, "Custom Name %i" % (i + 1), rs) custom.append(rset) if self.MODEL in ["A36plus", "A36plus_8w"]: # Menu 21: RX END TAIL rs = RadioSettingValueList(TONERXEND_LIST, TONERXEND_LIST[_settings.skey3_lp]) rset = RadioSetting("skey3_lp", "RX End Tail", rs) basic.append(rset) # Menu 23: TAIL PHASE rs = RadioSettingValueList(TAILPHASE_LIST, TAILPHASE_LIST[_settings.rxendtail]) rset = RadioSetting("rxendtail", "Tail Phase", rs) basic.append(rset) return group def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting == "ani": setattr(obj, setting, int(element.value) - 1) elif setting == "fmradio": setattr(obj, setting, not int(element.value)) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception as e: LOG.debug(element.get_name(), e) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class RT470Radio(JC8810base): """Radtel RT-470""" VENDOR = "Radtel" MODEL = "RT-470" # ========== # Notice to developers: # The RT-470 support in this driver is currently based upon... # - v1.25a firmware (original pcb) # - v2.11a firmware (pcb2) # ========== # original pcb _fingerprint_pcb1 = [b"\x00\x00\x00\x26\x00\x20\xD8\x04", b"\x00\x00\x00\x42\x00\x20\xF0\x04", b"\x00\x00\x00\x4A\x00\x20\xF8\x04", b"\x00\x00\x00\x3A\x00\x20\xE8\x04", # fw 1.25A ] # pcb 2 _fingerprint_pcb2 = [b"\x00\x00\x00\x2C\x00\x20\xD8\x04", # fw v2.11A ] _fingerprint = _fingerprint_pcb1 + _fingerprint_pcb2 VALID_BANDS = [(16000000, 100000000), (100000000, 136000000), (136000000, 200000000), (200000000, 300000000), (300000000, 400000000), (400000000, 560000000), (740000000, 1000000000), ] @directory.register class RT470LRadio(JC8810base): """Radtel RT-470L""" VENDOR = "Radtel" MODEL = "RT-470L" # ========== # Notice to developers: # The RT-470 support in this driver is currently based upon v1.17 firmware. # ========== _fingerprint = [b"\x00\x00\x00\xfe\x00\x20\xAC\x04", b"\x00\x00\x00\x20\x00\x20\xCC\x04", b"\x00\x00\x00\x20\x00\x20\x07\x00"] POWER_LEVELS = [chirp_common.PowerLevel("H", watts=5.00), chirp_common.PowerLevel("M", watts=4.00), chirp_common.PowerLevel("L", watts=2.00)] VALID_BANDS = [(108000000, 136000000), (136000000, 179000000), (220000000, 260000000), (330000000, 400000000), (400000000, 520000000)] @directory.register class RT470XRadio(RT470LRadio): """Radtel RT-470X""" VENDOR = "Radtel" MODEL = "RT-470X" # ========== # Notice to developers: # The RT-470X support in this driver is currently based upon... # - v1.18a firmware (original pcb) # - v2.13a firmware (pcb2) # ========== # original pcb _fingerprint_pcb1 = [b"\x00\x00\x00\x20\x00\x20\xCC\x04", ] # pcb 2 _fingerprint_pcb2 = [b"\x00\x00\x00\x2C\x00\x20\xD8\x04", # fw v2.10A b"\x00\x00\x00\x36\x00\x20\xDC\x04", # fw v2.13A ] _fingerprint = _fingerprint_pcb1 + _fingerprint_pcb2 RT470X_ORIG = False VALID_BANDS = [(100000000, 136000000), (136000000, 200000000), (200000000, 300000000), (300000000, 400000000), (400000000, 560000000)] @directory.register class HI8811Radio(RT470LRadio): """Hiroyasu HI-8811""" VENDOR = "Hiroyasu" MODEL = "HI-8811" # ========== # Notice to developers: # The HI-8811 support in this driver is currently based upon... # - v1.17 firmware (original pcb) # - v2.00 firmware (pcb2) # ========== # original pcb _fingerprint_pcb1 = [b"\x00\x00\x00\xfe\x00\x20\xAC\x04", b"\x00\x00\x00\x20\x00\x20\xCC\x04", # fw v1.17 b"\x00\x00\x00\x20\x00\x20\x07\x00", ] # pcb 2 _fingerprint_pcb2 = [b"\x00\x00\x00\x28\x00\x20\xD4\x04", # fw v2.00 b"\x00\x00\x00\x28\x00\x20\x07\x00", # fw v2.00 ] _fingerprint = _fingerprint_pcb1 + _fingerprint_pcb2 @directory.register class UVA37Radio(JC8810base): """Anysecu UV-A37""" VENDOR = "Anysecu" MODEL = "UV-A37" # ========== # Notice to developers: # The UV-A37 support in this driver is currently based upon v1.24 # firmware. # ========== POWER_LEVELS = [chirp_common.PowerLevel("H", watts=5.00), chirp_common.PowerLevel("L", watts=1.00)] VALID_BANDS = [(108000000, 136000000), (136000000, 174000000), (200000000, 260000000), (350000000, 390000000), (400000000, 520000000)] _magic = b"PROGRAMJC37U" _fingerprint = [b"\x00\x00\x00\xE4\x00\x20\x94\x04", b"\x00\x00\x00\xE8\x00\x20\x98\x04"] _ranges = [ (0x0000, 0x2000), (0x8000, 0x8040), (0x9000, 0x9040), (0xA000, 0xA140), (0xB000, 0xB440) ] _memsize = 0xB440 @directory.register class A36plusRadio(JC8810base): """Talkpod A36plus""" VENDOR = "Talkpod" MODEL = "A36plus" # ========== # Notice to developers: # The A36plus support in this driver is currently based upon v1.22 # firmware. # ========== POWER_LEVELS = [chirp_common.PowerLevel("H", watts=5.00), chirp_common.PowerLevel("L", watts=1.00)] VALID_BANDS = [(108000000, 136000000), (136000000, 180000000), (200000000, 260000000), (350000000, 400000000), (400000000, 520000000), ] _magic = b"PROGRAMJC37U" _fingerprint = [b"\x00\x00\x00\x42\x00\x20\xF0\x04", b"\x00\x00\x00\x5A\x00\x20\x08\x05", # fw 1.18 b"\x00\x00\x00\x9E\x00\x20\x0C\x05", # fw 1.22 b"\x00\x00\x00\xFA\x00\x20\x40\x05", # fw 1.4 ] _ranges = [ (0x0000, 0x4000), (0x8000, 0x8040), (0x9000, 0x9040), (0xA000, 0xA140), (0xB000, 0xB440) ] _memsize = 0xB440 _upper = 512 # fw 1.22 expands from 256 to 512 channels _aninames = 10 _mem_params = (_upper, # number of channels _aninames, # number of aninames ) def process_mmap(self): mem_format = MEM_FORMAT % self._mem_params + MEM_FORMAT_A36PLUS self._memobj = bitwise.parse(mem_format, self._mmap) @directory.register class A36plus8wRadio(A36plusRadio): """Talkpod A36plus8w""" VENDOR = "Talkpod" MODEL = "A36plus_8w" # ========== # Notice to developers: # The A36plus 8w support in this driver is currently based upon v1.4 # firmware. # ========== POWER_LEVELS = [chirp_common.PowerLevel("H", watts=8.00), chirp_common.PowerLevel("L", watts=1.00)] _fingerprint = [b"\x00\x00\x00\xFA\x00\x20\x40\x05", # fw 1.4 ] @directory.register class AR730Radio(UVA37Radio): """Abbree AR730""" VENDOR = "Abbree" MODEL = "AR-730" # ========== # Notice to developers: # The AR-730 support in this driver is currently based upon v1.24 # firmware. # ========== POWER_LEVELS = [chirp_common.PowerLevel("H", watts=5.00), chirp_common.PowerLevel("L", watts=1.00)] VALID_BANDS = [(108000000, 136000000), (136000000, 180000000), (200000000, 260000000), (350000000, 390000000), (400000000, 520000000)] chirp-20240224/chirp/drivers/ap510.py0000644000175000017500000007740614446523722016046 0ustar hibbyhibby# Copyright 2014 Tom Hayward # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct from time import sleep import logging from chirp import chirp_common, directory, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ InvalidValueError, RadioSettings LOG = logging.getLogger(__name__) def chunks(s, t): """ Yield chunks of s in sizes defined in t.""" i = 0 for n in t: yield s[i:i+n] i += n def encode_base100(v): return (v / 100 << 8) + (v % 100) def decode_base100(u16): return 100 * (u16 >> 8 & 0xff) + (u16 & 0xff) def drain(pipe): """Chew up any data waiting on @pipe""" for x in range(3): buf = pipe.read(4096) if not buf: return raise errors.RadioError('Your pipes are clogged.') def enter_setup(pipe): """Put AP510 in configuration mode.""" for x in range(30): if x % 2: pipe.write("@SETUP") else: pipe.write("\r\nSETUP\r\n") s = pipe.read(64) if s and "\r\nSETUP" in s: return True elif s and "SETUP" in s: return False raise errors.RadioError('Radio did not respond.') def download(radio): status = chirp_common.Status() drain(radio.pipe) status.msg = " Power on AP510 now, waiting " radio.status_fn(status) new = enter_setup(radio.pipe) status.cur = 1 status.max = 5 status.msg = "Downloading" radio.status_fn(status) if new: radio.pipe.write("\r\nDISP\r\n") else: radio.pipe.write("@DISP") buf = "" for status.cur in range(status.cur, status.max): buf += radio.pipe.read(1024) if buf.endswith("\r\n"): status.cur = status.max radio.status_fn(status) break radio.status_fn(status) else: raise errors.RadioError("Incomplete data received.") LOG.debug("%04i P7H", self._memobj[self.ATTR_MAP['smartbeacon']])) )) def set_smartbeacon(self, d): self._memobj[self.ATTR_MAP['smartbeacon']] = \ struct.pack(">7H", encode_base100(d['lowspeed']), encode_base100(d['slowrate']), encode_base100(d['highspeed']), encode_base100(d['fastrate']), encode_base100(d['turnslope']), encode_base100(d['turnangle']), encode_base100(d['turntime']), ) class AP510Memory20141215(AP510Memory): """Compatible with firmware version 20141215""" ATTR_MAP = dict(list(AP510Memory.ATTR_MAP.items()) + list({ 'tx_volume': '21', # 1-6 'rx_volume': '22', # 1-9 'tx_power': '23', # 1: 1 watt, 0: 0.5 watt 'tx_serial_ui_out': '24', 'path1': '25', 'path2': '26', 'path3': '27', # like "WIDE1 1" else "0" 'multiple': '28', 'auto_on': '29', }.items())) def get_multiple(self): return dict(zip( ( 'mice_message', # conveniently matches APRS spec Mic-E messages 'voltage', # voltage in comment 'temperature', # temperature in comment 'tfx', # not sure what the TF/X toggle does 'squelch', # squelch level 0-8 (0 = disabled) 'blueled', # 0: squelch LED on GPS lock # 1: light LED on GPS lock 'telemetry', # 1: enable 'telemetry_every', # two-digit int 'timeslot_enable', # 1: enable Is this implemented in firmware? 'timeslot', # int 00-59 'dcd', # 0: Blue LED displays squelch, # 1: Blue LED displays software DCD 'tf_card' # 0: KML, 1: WPL ), map(int, chunks(self._memobj[self.ATTR_MAP['multiple']], (1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1))) )) def set_multiple(self, d): self._memobj[self.ATTR_MAP['multiple']] = "%(mice_message)1d" \ "%(voltage)1d" \ "%(temperature)1d" \ "%(tfx)1d" \ "%(squelch)1d" \ "%(blueled)1d" \ "%(telemetry)1d" \ "%(telemetry_every)02d" \ "%(timeslot_enable)1d" \ "%(timeslot)02d" \ "%(dcd)1d" \ "%(tf_card)1d" % d def get_smartbeacon(self): # raw: 18=0100300060010240028005 # chunks: 18=010 0300 060 010 240 028 005 return dict(zip(( 'lowspeed', 'slowrate', 'highspeed', 'fastrate', 'turnslope', 'turnangle', 'turntime', ), map(int, chunks( self._memobj[self.ATTR_MAP['smartbeacon']], (3, 4, 3, 3, 3, 3, 3))) )) def set_smartbeacon(self, d): self._memobj[self.ATTR_MAP['smartbeacon']] = "%(lowspeed)03d" \ "%(slowrate)04d" \ "%(highspeed)03d" \ "%(fastrate)03d" \ "%(turnslope)03d" \ "%(turnangle)03d" \ "%(turntime)03d" % d PTT_DELAY = ['60 ms', '120 ms', '180 ms', '300 ms', '480 ms', '600 ms', '1000 ms'] OUTPUT = ['KISS', 'Waypoint out', 'UI out'] PATH = [ '(None)', 'WIDE1-1', 'WIDE1-1,WIDE2-1', 'WIDE1-1,WIDE2-2', 'TEMP1-1', 'TEMP1-1,WIDE 2-1', 'WIDE2-1', ] TABLE = r"/\#&0>AW^_acnsuvz" SYMBOL = "".join(map(chr, range(ord("!"), ord("~")+1))) BEACON = ['manual', 'auto', 'auto + manual', 'smart', 'smart + manual'] ALIAS = ['WIDE1-N', 'WIDE2-N', 'WIDE1-N + WIDE2-N'] CHARSET = "".join(map(chr, range(0, 256))) MICE_MESSAGE = ['Emergency', 'Priority', 'Special', 'Committed', 'Returning', 'In Service', 'En Route', 'Off Duty'] TF_CARD = ['WPL', 'KML'] POWER_LEVELS = [chirp_common.PowerLevel("0.5 watt", watts=0.50), chirp_common.PowerLevel("1 watt", watts=1.00)] RP_IMMUTABLE = ["number", "skip", "bank", "extd_number", "name", "rtone", "ctone", "dtcs", "tmode", "dtcs_polarity", "skip", "duplex", "offset", "mode", "tuning_step", "bank_index"] @directory.register class AP510Radio(chirp_common.CloneModeRadio): """Sainsonic AP510""" BAUD_RATE = 9600 VENDOR = "Sainsonic" MODEL = "AP510" _model = b"AVRT5" mem_upper_limit = 0 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.valid_modes = ["FM"] rf.valid_tmodes = [""] rf.valid_characters = "" rf.valid_duplexes = [""] rf.valid_name_length = 0 rf.valid_power_levels = POWER_LEVELS rf.valid_skips = [] rf.valid_tuning_steps = [] rf.has_bank = False rf.has_ctone = False rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_mode = False rf.has_name = False rf.has_offset = False rf.has_tuning_step = False rf.valid_bands = [(136000000, 174000000)] rf.memory_bounds = (0, 0) return rf def sync_in(self): try: data = download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) # _mmap isn't a Chirp MemoryMap, but since AP510Memory implements # get_packed(), the standard Chirp save feature works. if data.startswith('\r\n00=%s 20141215' % self._model): self._mmap = AP510Memory20141215(data) else: self._mmap = AP510Memory(data) def process_mmap(self): self._mmap.process_data() def sync_out(self): try: upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def load_mmap(self, filename): """Load the radio's memory map from @filename""" mapfile = open(filename, "rb") data = mapfile.read() if data.startswith('\r\n00=%s 20141215' % self._model): self._mmap = AP510Memory20141215(data) else: self._mmap = AP510Memory(data) mapfile.close() def get_raw_memory(self, number): return self._mmap.get_packed() def get_memory(self, number): if number != 0: raise errors.InvalidMemoryLocation("AP510 has only one slot") mem = chirp_common.Memory() mem.number = 0 mem.freq = float(self._mmap.freq) * 1000000 mem.name = "TX/RX" mem.mode = "FM" mem.offset = 0.0 try: mem.power = POWER_LEVELS[int(self._mmap.tx_power)] except NotImplementedError: mem.power = POWER_LEVELS[1] mem.immutable = RP_IMMUTABLE return mem def set_memory(self, mem): if mem.number != 0: raise errors.InvalidMemoryLocation("AP510 has only one slot") self._mmap.freq = "%8.4f" % (mem.freq / 1000000.0) if mem.power: try: self._mmap.tx_power = str(POWER_LEVELS.index(mem.power)) except NotImplementedError: pass def get_settings(self): china = RadioSettingGroup("china", "China Map Fix") smartbeacon = RadioSettingGroup("smartbeacon", "Smartbeacon") aprs = RadioSettingGroup("aprs", "APRS", china, smartbeacon) digipeat = RadioSettingGroup("digipeat", "Digipeat") system = RadioSettingGroup("system", "System") settings = RadioSettings(aprs, digipeat, system) aprs.append(RadioSetting("callsign", "Callsign", RadioSettingValueString(0, 6, self._mmap.callsign[:6]))) aprs.append(RadioSetting("ssid", "SSID", RadioSettingValueInteger( 0, 15, ord(self._mmap.callsign[6]) - 0x30))) pttdelay = PTT_DELAY[int(self._mmap.pttdelay) - 1] aprs.append(RadioSetting("pttdelay", "PTT Delay", RadioSettingValueList(PTT_DELAY, pttdelay))) output = OUTPUT[int(self._mmap.output) - 1] aprs.append(RadioSetting("output", "Output", RadioSettingValueList(OUTPUT, output))) aprs.append(RadioSetting("mice", "Mic-E", RadioSettingValueBoolean(strbool(self._mmap.mice)))) try: mice_msg = MICE_MESSAGE[int(self._mmap.multiple['mice_message'])] aprs.append(RadioSetting("mice_message", "Mic-E Message", RadioSettingValueList(MICE_MESSAGE, mice_msg))) except NotImplementedError: pass try: aprs.append(RadioSetting("path1", "Path 1", RadioSettingValueString(0, 6, self._mmap.path1[:6], autopad=True, charset=CHARSET))) ssid1 = ord(self._mmap.path1[6]) - 0x30 aprs.append(RadioSetting("ssid1", "SSID 1", RadioSettingValueInteger(0, 7, ssid1))) aprs.append(RadioSetting("path2", "Path 2", RadioSettingValueString(0, 6, self._mmap.path2[:6], autopad=True, charset=CHARSET))) ssid2 = ord(self._mmap.path2[6]) - 0x30 aprs.append(RadioSetting("ssid2", "SSID 2", RadioSettingValueInteger(0, 7, ssid2))) aprs.append(RadioSetting("path3", "Path 3", RadioSettingValueString(0, 6, self._mmap.path3[:6], autopad=True, charset=CHARSET))) ssid3 = ord(self._mmap.path3[6]) - 0x30 aprs.append(RadioSetting("ssid3", "SSID 3", RadioSettingValueInteger(0, 7, ssid3))) except NotImplementedError: aprs.append(RadioSetting("path", "Path", RadioSettingValueList(PATH, PATH[int(self._mmap.path)]))) aprs.append(RadioSetting("table", "Table or Overlay", RadioSettingValueList(TABLE, self._mmap.symbol[1]))) aprs.append(RadioSetting("symbol", "Symbol", RadioSettingValueList(SYMBOL, self._mmap.symbol[0]))) aprs.append(RadioSetting("beacon", "Beacon Mode", RadioSettingValueList(BEACON, BEACON[int(self._mmap.beacon) - 1]))) aprs.append(RadioSetting("rate", "Beacon Rate (seconds)", RadioSettingValueInteger(10, 9999, self._mmap.rate))) aprs.append(RadioSetting("comment", "Comment", RadioSettingValueString(0, 34, self._mmap.comment, autopad=False, charset=CHARSET))) try: voltage = self._mmap.multiple['voltage'] aprs.append(RadioSetting("voltage", "Voltage in comment", RadioSettingValueBoolean(voltage))) temperature = self._mmap.multiple['temperature'] aprs.append(RadioSetting("temperature", "Temperature in comment", RadioSettingValueBoolean(temperature))) except NotImplementedError: pass aprs.append(RadioSetting("status", "Status", RadioSettingValueString( 0, 34, self._mmap.status, autopad=False, charset=CHARSET))) try: telemetry = self._mmap.multiple['telemetry'] aprs.append(RadioSetting("telemetry", "Telemetry", RadioSettingValueBoolean(telemetry))) telemetry_every = self._mmap.multiple['telemetry_every'] aprs.append(RadioSetting("telemetry_every", "Telemetry every", RadioSettingValueInteger(1, 99, telemetry_every))) timeslot_enable = self._mmap.multiple['telemetry'] aprs.append(RadioSetting("timeslot_enable", "Timeslot", RadioSettingValueBoolean(timeslot_enable))) timeslot = self._mmap.multiple['timeslot'] aprs.append(RadioSetting("timeslot", "Timeslot (second of minute)", RadioSettingValueInteger(0, 59, timeslot))) except NotImplementedError: pass fields = [ ("chinamapfix", "China map fix", RadioSettingValueBoolean(strbool(self._mmap.chinamapfix[0]))), ("chinalat", "Lat", RadioSettingValueInteger( -45, 45, ord(self._mmap.chinamapfix[2]) - 80)), ("chinalon", "Lon", RadioSettingValueInteger( -45, 45, ord(self._mmap.chinamapfix[1]) - 80)), ] for field in fields: china.append(RadioSetting(*field)) try: # Sometimes when digipeat is disabled, alias is 0xFF alias = ALIAS[int(self._mmap.digipeat[1]) - 1] except ValueError: alias = ALIAS[0] fields = [ ("digipeat", "Digipeat", RadioSettingValueBoolean(strbool(self._mmap.digipeat[0]))), ("alias", "Digipeat Alias", RadioSettingValueList( ALIAS, alias)), ("virtualgps", "Static Position", RadioSettingValueBoolean(strbool(self._mmap.virtualgps[0]))), ("btext", "Static Position BTEXT", RadioSettingValueString( 0, 27, self._mmap.virtualgps[1:], autopad=False, charset=CHARSET)), ] for field in fields: digipeat.append(RadioSetting(*field)) sb = self._mmap.smartbeacon fields = [ ("lowspeed", "Low Speed"), ("highspeed", "High Speed"), ("slowrate", "Slow Rate (seconds)"), ("fastrate", "Fast Rate (seconds)"), ("turnslope", "Turn Slope"), ("turnangle", "Turn Angle"), ("turntime", "Turn Time (seconds)"), ] for field in fields: smartbeacon.append(RadioSetting( field[0], field[1], RadioSettingValueInteger(0, 9999, sb[field[0]]) )) system.append(RadioSetting("version", "Version (read-only)", RadioSettingValueString(0, 14, self._mmap.version))) system.append(RadioSetting("autooff", "Auto off (after 90 minutes)", RadioSettingValueBoolean(strbool(self._mmap.autooff)))) system.append(RadioSetting("beep", "Beep on transmit", RadioSettingValueBoolean(strbool(self._mmap.beep)))) system.append(RadioSetting("highaltitude", "High Altitude", RadioSettingValueBoolean( strbool(self._mmap.highaltitude)))) system.append(RadioSetting("busywait", "Wait for clear channel before transmit", RadioSettingValueBoolean( strbool(self._mmap.busywait)))) try: system.append(RadioSetting("tx_volume", "Transmit volume", RadioSettingValueList( map(str, range(1, 7)), self._mmap.tx_volume))) system.append(RadioSetting("rx_volume", "Receive volume", RadioSettingValueList( map(str, range(1, 10)), self._mmap.rx_volume))) system.append(RadioSetting("squelch", "Squelch", RadioSettingValueList( map(str, range(0, 9)), str(self._mmap.multiple['squelch'])))) system.append(RadioSetting("tx_serial_ui_out", "Tx serial UI out", RadioSettingValueBoolean( strbool(self._mmap.tx_serial_ui_out)))) system.append(RadioSetting("auto_on", "Auto-on with 5V input", RadioSettingValueBoolean( strbool(self._mmap.auto_on[0])))) system.append(RadioSetting( "auto_on_delay", "Auto-off delay after 5V lost (seconds)", RadioSettingValueInteger( 0, 9999, int(self._mmap.auto_on[1:])) )) system.append(RadioSetting("tfx", "TF/X", RadioSettingValueBoolean( self._mmap.multiple['tfx']))) system.append(RadioSetting("blueled", "Light blue LED on GPS lock", RadioSettingValueBoolean( self._mmap.multiple['blueled']))) system.append(RadioSetting("dcd", "Blue LED shows software DCD", RadioSettingValueBoolean( self._mmap.multiple['dcd']))) system.append(RadioSetting("tf_card", "TF card format", RadioSettingValueList( TF_CARD, TF_CARD[int(self._mmap.multiple['tf_card'])]))) except NotImplementedError: pass return settings def set_settings(self, settings): for setting in settings: if not isinstance(setting, RadioSetting): self.set_settings(setting) continue if not setting.changed(): continue try: name = setting.get_name() if name == "callsign": self.set_callsign(callsign=setting.value) elif name == "ssid": self.set_callsign(ssid=int(setting.value)) elif name == "pttdelay": self._mmap.pttdelay = PTT_DELAY.index( str(setting.value)) + 1 elif name == "output": self._mmap.output = OUTPUT.index(str(setting.value)) + 1 elif name in ('mice', 'autooff', 'beep', 'highaltitude', 'busywait', 'tx_serial_ui_out'): setattr(self._mmap, name, boolstr(setting.value)) elif name == "mice_message": multiple = self._mmap.multiple multiple['mice_message'] = MICE_MESSAGE.index( str(setting.value)) self._mmap.multiple = multiple elif name == "path": self._mmap.path = PATH.index(str(setting.value)) elif name == "path1": self._mmap.path1 = "%s%s" % ( setting.value, self._mmap.path1[6]) elif name == "ssid1": self._mmap.path1 = "%s%s" % ( self._mmap.path1[:6], setting.value) elif name == "path2": self._mmap.path2 = "%s%s" % ( setting.value, self._mmap.path2[6]) elif name == "ssid2": self._mmap.path2 = "%s%s" % ( self._mmap.path2[:6], setting.value) elif name == "path3": self._mmap.path3 = "%s%s" % ( setting.value, self._mmap.path3[6]) elif name == "ssid3": self._mmap.path3 = "%s%s" % ( self._mmap.path3[:6], setting.value) elif name == "table": self.set_symbol(table=setting.value) elif name == "symbol": self.set_symbol(symbol=setting.value) elif name == "beacon": self._mmap.beacon = BEACON.index(str(setting.value)) + 1 elif name == "rate": self._mmap.rate = "%04d" % setting.value elif name == "comment": self._mmap.comment = str(setting.value) elif name == "voltage": multiple = self._mmap.multiple multiple['voltage'] = int(setting.value) self._mmap.multiple = multiple elif name == "temperature": multiple = self._mmap.multiple multiple['temperature'] = int(setting.value) self._mmap.multiple = multiple elif name == "status": self._mmap.status = str(setting.value) elif name in ("telemetry", "telemetry_every", "timeslot_enable", "timeslot", "tfx", "blueled", "dcd"): multiple = self._mmap.multiple multiple[name] = int(setting.value) self._mmap.multiple = multiple elif name == "chinamapfix": self.set_chinamapfix(enable=setting.value) elif name == "chinalat": self.set_chinamapfix(lat=int(setting.value)) elif name == "chinalon": self.set_chinamapfix(lon=int(setting.value)) elif name == "digipeat": self.set_digipeat(enable=setting.value) elif name == "alias": self.set_digipeat( alias=str(ALIAS.index(str(setting.value)) + 1)) elif name == "virtualgps": self.set_virtualgps(enable=setting.value) elif name == "btext": self.set_virtualgps(btext=str(setting.value)) elif name == "lowspeed": self.set_smartbeacon(lowspeed=int(setting.value)) elif name == "highspeed": self.set_smartbeacon(highspeed=int(setting.value)) elif name == "slowrate": self.set_smartbeacon(slowrate=int(setting.value)) elif name == "fastrate": self.set_smartbeacon(fastrate=int(setting.value)) elif name == "turnslope": self.set_smartbeacon(turnslope=int(setting.value)) elif name == "turnangle": self.set_smartbeacon(turnangle=int(setting.value)) elif name == "turntime": self.set_smartbeacon(turntime=int(setting.value)) elif name in ("tx_volume", "rx_volume", "squelch"): setattr(self._mmap, name, "%1d" % setting.value) elif name == "auto_on": self._mmap.auto_on = "%s%05d" % ( bool(setting.value) and '1' or 'i', int(self._mmap.auto_on[1:])) elif name == "auto_on_delay": self._mmap.auto_on = "%s%05d" % ( self._mmap.auto_on[0], setting.value) elif name == "tf_card": multiple = self._mmap.multiple multiple['tf_card'] = TF_CARD.index(str(setting.value)) self._mmap.multiple = multiple except Exception: LOG.debug(setting.get_name()) raise def set_callsign(self, callsign=None, ssid=None): if callsign is None: callsign = self._mmap.callsign[:6] if ssid is None: ssid = ord(self._mmap.callsign[6]) - 0x30 self._mmap.callsign = str(callsign) + chr(ssid + 0x30) def set_symbol(self, table=None, symbol=None): if table is None: table = self._mmap.symbol[1] if symbol is None: symbol = self._mmap.symbol[0] self._mmap.symbol = str(symbol) + str(table) def set_chinamapfix(self, enable=None, lat=None, lon=None): if enable is None: enable = strbool(self._mmap.chinamapfix[0]) if lat is None: lat = ord(self._mmap.chinamapfix[2]) - 80 if lon is None: lon = ord(self._mmap.chinamapfix[1]) - 80 self._mmapchinamapfix = boolstr(enable) + chr(lon + 80) + chr(lat + 80) def set_digipeat(self, enable=None, alias=None): if enable is None: enable = strbool(self._mmap.digipeat[0]) if alias is None: alias = self._mmap.digipeat[1] self._mmap.digipeat = boolstr(enable) + alias def set_virtualgps(self, enable=None, btext=None): if enable is None: enable = strbool(self._mmap.virtualgps[0]) if btext is None: btext = self._mmap.virtualgps[1:] self._mmap.virtualgps = boolstr(enable) + btext def set_smartbeacon(self, **kwargs): sb = self._mmap.smartbeacon sb.update(kwargs) if sb['lowspeed'] > sb['highspeed']: raise InvalidValueError("Low speed must be less than high speed") if sb['slowrate'] < sb['fastrate']: raise InvalidValueError("Slow rate must be greater than fast rate") self._mmap.smartbeacon = sb @classmethod def match_model(cls, filedata, filename): return filedata.startswith(b'\r\n00=' + cls._model) chirp-20240224/chirp/drivers/gmrsuv1.py0000644000175000017500000010673414557410440016614 0ustar hibbyhibby# Copyright 2016: # * Jim Unroe KC9HI, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory from chirp import bitwise from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings, \ InvalidValueError LOG = logging.getLogger(__name__) # #### MAGICS ######################################################### # BTECH GMRS-V1 magic string MSTRING_GMRSV1 = b"\x50\x5F\x20\x15\x12\x15\x4D" # #### ID strings ##################################################### # BTECH GMRS-V1 GMRSV1_fp1 = b"US32411" # original GMRSV1_fp2 = b"US32416" # original GMRSV1_fp3 = b"US32418" # new rules GMRSV1_fp4 = b"US32412" # original DTMF_CHARS = "0123456789 *#ABCD" STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] LIST_AB = ["A", "B"] LIST_ALMOD = ["Off", "Site", "Tone", "Code"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_COLOR = ["Off", "Blue", "Orange", "Purple"] LIST_DTMFSPEED = ["%s ms" % x for x in range(50, 2010, 10)] LIST_DTMFST = ["Off", "DT-ST", "ANI-ST", "DT+ANI"] LIST_MODE = ["Channel", "Name", "Frequency"] LIST_OFF1TO9 = ["Off"] + list("123456789") LIST_OFF1TO10 = LIST_OFF1TO9 + ["10"] LIST_OFFAB = ["Off"] + LIST_AB LIST_RESUME = ["TO", "CO", "SE"] LIST_PONMSG = ["Full", "Message"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_SCODE = ["%s" % x for x in range(1, 16)] LIST_RPSTE = ["Off"] + ["%s" % x for x in range(1, 11)] LIST_RTONE = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] LIST_SAVE = ["Off", "1:1", "1:2", "1:3", "1:4"] LIST_SHIFTD = ["Off", "+", "-"] LIST_STEDELAY = ["Off"] + ["%s ms" % x for x in range(100, 1100, 100)] LIST_STEP = [str(x) for x in STEPS] LIST_TIMEOUT = ["%s sec" % x for x in range(15, 615, 15)] LIST_TXPOWER = ["High", "Low"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_WORKMODE = ["Frequency", "Channel"] GMRS_FREQS1 = [462562500, 462587500, 462612500, 462637500, 462662500, 462687500, 462712500] GMRS_FREQS2 = [467562500, 467587500, 467612500, 467637500, 467662500, 467687500, 467712500] GMRS_FREQS3 = [462550000, 462575000, 462600000, 462625000, 462650000, 462675000, 462700000, 462725000] GMRS_FREQS_ORIG = GMRS_FREQS1 + GMRS_FREQS3 * 2 GMRS_FREQS_2017 = GMRS_FREQS1 + GMRS_FREQS2 + GMRS_FREQS3 * 2 def model_match(cls, data): """Match the opened/downloaded image to the correct version""" rid = data[0x1EF0:0x1EF7] if rid in cls._fileid: return True return False @directory.register class GMRSV1(bfc.BaofengCommonHT): """BTech GMRS-V1""" VENDOR = "BTECH" MODEL = "GMRS-V1" NEEDS_COMPAT_SERIAL = False _fileid = [GMRSV1_fp4, GMRSV1_fp3, GMRSV1_fp2, GMRSV1_fp1, ] _is_orig = [GMRSV1_fp2, GMRSV1_fp1, GMRSV1_fp4, ] _magic = [MSTRING_GMRSV1, ] _magic_response_length = 8 _fw_ver_start = 0x1EF0 _recv_block_size = 0x40 _mem_size = 0x2000 _ack_block = True _ranges = [(0x0000, 0x0DF0), (0x0E00, 0x1800), (0x1EE0, 0x1EF0), (0x1F60, 0x1F70), (0x1F80, 0x1F90), (0x1FC0, 0x1FD0)] _send_block_size = 0x10 MODES = ["NFM", "FM"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" LENGTH_NAME = 7 SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=2.00)] VALID_BANDS = [(130000000, 180000000), (400000000, 521000000)] PTTID_LIST = LIST_PTTID SCODE_LIST = LIST_SCODE def get_features(self): """Get the radio's features""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = False rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_name_length = self.LENGTH_NAME rf.valid_duplexes = ["", "-", "+", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = self.SKIP_VALUES rf.valid_dtcs_codes = self.DTCS_CODES rf.memory_bounds = (0, 127) rf.valid_power_levels = self.POWER_LEVELS rf.valid_bands = self.VALID_BANDS rf.valid_tuning_steps = STEPS return rf MEM_FORMAT = """ // #seekto 0x0000; struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 unknown0:4, scode:4; u8 unknown1; u8 unknown2:7, lowpower:1; u8 unknown3:1, wide:1, unknown4:2, bcl:1, scan:1, pttid:2; } memory[128]; #seekto 0x0B00; struct { u8 code[5]; u8 unused[11]; } pttid[15]; #seekto 0x0C80; struct { u8 unknown222[5]; u8 unknown333[5]; u8 alarm[5]; u8 unknown1; u8 unknown555[5]; u8 unknown666[5]; u8 unknown777[5]; u8 unknown2; u8 unknown60606[5]; u8 unknown70707[5]; u8 code[5]; u8 unused1:6, aniid:2; u8 unknown[2]; u8 dtmfon; u8 dtmfoff; } ani; #seekto 0x0E20; struct { u8 unused01:4, squelch:4; u8 unused02; u8 unused03; u8 unused04:5, save:3; u8 unused05:4, vox:4; u8 unused06; u8 unused07:4, abr:4; u8 unused08:7, tdr:1; u8 unused09:7, beep:1; u8 unused10:2, timeout:6; u8 unused11[4]; u8 unused12:6, voice:2; u8 unused13; u8 unused14:6, dtmfst:2; u8 unused15; u8 unused16:6, screv:2; u8 unused17:6, pttid:2; u8 unused18:2, pttlt:6; u8 unused19:6, mdfa:2; u8 unused20:6, mdfb:2; u8 unused21; u8 unused22:7, sync:1; u8 unused23[4]; u8 unused24:6, wtled:2; u8 unused25:6, rxled:2; u8 unused26:6, txled:2; u8 unused27:6, almod:2; u8 unused28:7, dbptt:1; u8 unused29:6, tdrab:2; u8 unused30:7, ste:1; u8 unused31:4, rpste:4; u8 unused32:4, rptrl:4; u8 unused33:7, ponmsg:1; u8 unused34:7, roger:1; u8 unused35:6, rtone:2; u8 unused36; u8 unused37:6, rogerrx:2; u8 unused38; u8 displayab:1, unknown1:2, fmradio:1, alarm:1, unknown2:1, reset:1, menu:1; u8 unused39; u8 workmode; u8 keylock; u8 cht; } settings; #seekto 0x0E76; struct { u8 unused1:1, mrcha:7; u8 unused2:1, mrchb:7; } wmchannel; struct vfo { u8 unknown0[8]; u8 freq[8]; u8 unknown1; u8 offset[4]; u8 unknown2; ul16 rxtone; ul16 txtone; u8 unused1:7, band:1; u8 unknown3; u8 unused2:2, sftd:2, scode:4; u8 unknown4; u8 unused3:1, step:3, unused4:4; u8 txpower:1, widenarr:1, unknown5:4, txpower3:2; }; #seekto 0x0F00; struct { struct vfo a; struct vfo b; } vfo; #seekto 0x0F4E; u16 fm_presets; #seekto 0x1000; struct { char name[7]; u8 unknown1[9]; } names[128]; #seekto 0x1ED0; struct { char line1[7]; char line2[7]; } sixpoweron_msg; #seekto 0x1EE0; struct { char line1[7]; char line2[7]; } poweron_msg; #seekto 0x1EF0; struct { char line1[7]; char line2[7]; } firmware_msg; struct squelch { u8 sql0; u8 sql1; u8 sql2; u8 sql3; u8 sql4; u8 sql5; u8 sql6; u8 sql7; u8 sql8; u8 sql9; }; #seekto 0x1F60; struct { struct squelch vhf; u8 unknown1[6]; u8 unknown2[16]; struct squelch uhf; } squelch; """ @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('The BTech GMRS-V1 driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number if _mem.get_raw()[:1] == b"\xff": mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _nam.name: if str(char) == "\xFF": char = " " # The OEM software may have 0xFF mid-name mem.name += str(char) mem.name = mem.name.rstrip() dtcs_pol = ["N", "N"] if _mem.txtone in [0, 0xFFFF]: txmode = "" elif _mem.txtone >= 0x0258: txmode = "Tone" mem.rtone = int(_mem.txtone) / 10.0 elif _mem.txtone <= 0x0258: txmode = "DTCS" if _mem.txtone > 0x69: index = _mem.txtone - 0x6A dtcs_pol[0] = "R" else: index = _mem.txtone - 1 mem.dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: txtone is %04x" % _mem.txtone) if _mem.rxtone in [0, 0xFFFF]: rxmode = "" elif _mem.rxtone >= 0x0258: rxmode = "Tone" mem.ctone = int(_mem.rxtone) / 10.0 elif _mem.rxtone <= 0x0258: rxmode = "DTCS" if _mem.rxtone >= 0x6A: index = _mem.rxtone - 0x6A dtcs_pol[1] = "R" else: index = _mem.rxtone - 1 mem.rx_dtcs = self.DTCS_CODES[index] else: LOG.warn("Bug: rxtone is %04x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) mem.dtcs_polarity = "".join(dtcs_pol) if not _mem.scan: mem.skip = "S" levels = self.POWER_LEVELS try: mem.power = levels[_mem.lowpower] except IndexError: LOG.error("Radio reported invalid power level %s (in %s)" % (_mem.power, levels)) mem.power = levels[0] mem.mode = _mem.wide and "FM" or "NFM" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(self.PTTID_LIST, self.PTTID_LIST[_mem.pttid])) mem.extra.append(rs) rs = RadioSetting("scode", "S-CODE", RadioSettingValueList(self.SCODE_LIST, self.SCODE_LIST[_mem.scode])) mem.extra.append(rs) immutable = [] # Original GMRS-V1 models (pre-2017 GMRS rules) # line1 is a valid string, so safe to encode here if str(self._memobj.firmware_msg.line1).encode() in self._is_orig: if mem.freq in GMRS_FREQS_ORIG: if mem.number >= 0 and mem.number <= 22: GMRS_FREQ = GMRS_FREQS_ORIG[mem.number] mem.freq = GMRS_FREQ immutable = ["empty", "freq"] if mem.number >= 0 and mem.number <= 6: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 7 and mem.number <= 14: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 15 and mem.number <= 22: mem.duplex = '+' mem.offset = 5000000 immutable += ["duplex", "offset"] else: if mem.number > 22: mem.duplex = 'off' immutable = ["duplex", "offset"] # GMRS-V1 models supporting 2017 GMRS rules else: if mem.freq in GMRS_FREQS_2017: if mem.number >= 1 and mem.number <= 30: GMRS_FREQ = GMRS_FREQS_2017[mem.number - 1] mem.freq = GMRS_FREQ immutable = ["empty", "freq"] if mem.number >= 1 and mem.number <= 7: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 8 and mem.number <= 14: mem.duplex = '' mem.offset = 0 mem.mode = "NFM" mem.power = self.POWER_LEVELS[1] immutable += ["duplex", "offset", "mode", "power"] elif mem.number >= 15 and mem.number <= 22: mem.duplex = '' mem.offset = 0 immutable += ["duplex", "offset"] elif mem.number >= 23 and mem.number <= 30: mem.duplex = '+' mem.offset = 5000000 immutable += ["duplex", "offset"] else: if mem.number < 1 or mem.number > 30: mem.duplex = 'off' immutable = ["duplex", "offset"] mem.immutable = immutable return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _nam = self._memobj.names[mem.number] if mem.empty: _mem.set_raw("\xff" * 16) _nam.set_raw("\xff" * 16) return _mem.set_raw("\x00" * 16) _mem.rxfreq = mem.freq / 10 if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _namelength = self.get_features().valid_name_length for i in range(_namelength): try: _nam.name[i] = mem.name[i] except IndexError: _nam.name[i] = "\xFF" rxmode = txmode = "" if mem.tmode == "Tone": _mem.txtone = int(mem.rtone * 10) _mem.rxtone = 0 elif mem.tmode == "TSQL": _mem.txtone = int(mem.ctone * 10) _mem.rxtone = int(mem.ctone * 10) elif mem.tmode == "DTCS": rxmode = txmode = "DTCS" _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 _mem.rxtone = self.DTCS_CODES.index(mem.dtcs) + 1 elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "Tone": _mem.txtone = int(mem.rtone * 10) elif txmode == "DTCS": _mem.txtone = self.DTCS_CODES.index(mem.dtcs) + 1 else: _mem.txtone = 0 if rxmode == "Tone": _mem.rxtone = int(mem.ctone * 10) elif rxmode == "DTCS": _mem.rxtone = self.DTCS_CODES.index(mem.rx_dtcs) + 1 else: _mem.rxtone = 0 else: _mem.rxtone = 0 _mem.txtone = 0 if txmode == "DTCS" and mem.dtcs_polarity[0] == "R": _mem.txtone += 0x69 if rxmode == "DTCS" and mem.dtcs_polarity[1] == "R": _mem.rxtone += 0x69 _mem.scan = mem.skip != "S" _mem.wide = mem.mode == "FM" if mem.power: _mem.lowpower = self.POWER_LEVELS.index(mem.power) else: _mem.lowpower = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj basic = RadioSettingGroup("basic", "Basic Settings") advanced = RadioSettingGroup("advanced", "Advanced Settings") other = RadioSettingGroup("other", "Other Settings") work = RadioSettingGroup("work", "Work Mode Settings") fm_preset = RadioSettingGroup("fm_preset", "FM Preset") dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") service = RadioSettingGroup("service", "Service Settings") top = RadioSettings(basic, advanced, other, work, fm_preset, dtmfe, service) # Basic settings if _mem.settings.squelch > 0x09: val = 0x00 else: val = _mem.settings.squelch rs = RadioSetting("settings.squelch", "Squelch", RadioSettingValueList( LIST_OFF1TO9, LIST_OFF1TO9[val])) basic.append(rs) if _mem.settings.save > 0x04: val = 0x00 else: val = _mem.settings.save rs = RadioSetting("settings.save", "Battery Saver", RadioSettingValueList( LIST_SAVE, LIST_SAVE[val])) basic.append(rs) if _mem.settings.vox > 0x0A: val = 0x00 else: val = _mem.settings.vox rs = RadioSetting("settings.vox", "Vox", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) if _mem.settings.abr > 0x0A: val = 0x00 else: val = _mem.settings.abr rs = RadioSetting("settings.abr", "Backlight Timeout", RadioSettingValueList( LIST_OFF1TO10, LIST_OFF1TO10[val])) basic.append(rs) rs = RadioSetting("settings.tdr", "Dual Watch", RadioSettingValueBoolean(_mem.settings.tdr)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep", RadioSettingValueBoolean(_mem.settings.beep)) basic.append(rs) if _mem.settings.timeout > 0x27: val = 0x03 else: val = _mem.settings.timeout rs = RadioSetting("settings.timeout", "Timeout Timer", RadioSettingValueList( LIST_TIMEOUT, LIST_TIMEOUT[val])) basic.append(rs) if _mem.settings.voice > 0x02: val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( LIST_VOICE, LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("settings.dtmfst", "DTMF Sidetone", RadioSettingValueList(LIST_DTMFST, LIST_DTMFST[ _mem.settings.dtmfst])) basic.append(rs) if _mem.settings.screv > 0x02: val = 0x01 else: val = _mem.settings.screv rs = RadioSetting("settings.screv", "Scan Resume", RadioSettingValueList( LIST_RESUME, LIST_RESUME[val])) basic.append(rs) rs = RadioSetting("settings.pttid", "When to send PTT ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[ _mem.settings.pttid])) basic.append(rs) if _mem.settings.pttlt > 0x32: val = 0x05 else: val = _mem.settings.pttlt rs = RadioSetting("pttlt", "PTT ID Delay", RadioSettingValueInteger(0, 50, val)) basic.append(rs) rs = RadioSetting("settings.mdfa", "Display Mode (A)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfa])) basic.append(rs) rs = RadioSetting("settings.mdfb", "Display Mode (B)", RadioSettingValueList(LIST_MODE, LIST_MODE[ _mem.settings.mdfb])) basic.append(rs) rs = RadioSetting("settings.sync", "Sync A & B", RadioSettingValueBoolean(_mem.settings.sync)) basic.append(rs) rs = RadioSetting("settings.wtled", "Standby LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.wtled])) basic.append(rs) rs = RadioSetting("settings.rxled", "RX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.rxled])) basic.append(rs) rs = RadioSetting("settings.txled", "TX LED Color", RadioSettingValueList( LIST_COLOR, LIST_COLOR[_mem.settings.txled])) basic.append(rs) val = _mem.settings.almod rs = RadioSetting("settings.almod", "Alarm Mode", RadioSettingValueList( LIST_ALMOD, LIST_ALMOD[val])) basic.append(rs) rs = RadioSetting("settings.dbptt", "Double PTT", RadioSettingValueBoolean(_mem.settings.dbptt)) basic.append(rs) if _mem.settings.tdrab > 0x02: val = 0x00 else: val = _mem.settings.tdrab rs = RadioSetting("settings.tdrab", "Dual Watch TX Priority", RadioSettingValueList( LIST_OFFAB, LIST_OFFAB[val])) basic.append(rs) rs = RadioSetting("settings.ste", "Squelch Tail Eliminate (HT to HT)", RadioSettingValueBoolean(_mem.settings.ste)) basic.append(rs) if _mem.settings.rpste > 0x0A: val = 0x00 else: val = _mem.settings.rpste rs = RadioSetting("settings.rpste", "Squelch Tail Eliminate (repeater)", RadioSettingValueList( LIST_RPSTE, LIST_RPSTE[val])) basic.append(rs) if _mem.settings.rptrl > 0x0A: val = 0x00 else: val = _mem.settings.rptrl rs = RadioSetting("settings.rptrl", "STE Repeater Delay", RadioSettingValueList( LIST_STEDELAY, LIST_STEDELAY[val])) basic.append(rs) rs = RadioSetting("settings.ponmsg", "Power-On Message", RadioSettingValueList(LIST_PONMSG, LIST_PONMSG[ _mem.settings.ponmsg])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger Beep", RadioSettingValueBoolean(_mem.settings.roger)) basic.append(rs) rs = RadioSetting("settings.rtone", "Tone Burst Frequency", RadioSettingValueList(LIST_RTONE, LIST_RTONE[ _mem.settings.rtone])) basic.append(rs) rs = RadioSetting("settings.rogerrx", "Roger Beep (RX)", RadioSettingValueList( LIST_OFFAB, LIST_OFFAB[ _mem.settings.rogerrx])) basic.append(rs) # Advanced settings rs = RadioSetting("settings.reset", "RESET Menu", RadioSettingValueBoolean(_mem.settings.reset)) advanced.append(rs) rs = RadioSetting("settings.menu", "All Menus", RadioSettingValueBoolean(_mem.settings.menu)) advanced.append(rs) rs = RadioSetting("settings.fmradio", "Broadcast FM Radio", RadioSettingValueBoolean(_mem.settings.fmradio)) advanced.append(rs) rs = RadioSetting("settings.alarm", "Alarm Sound", RadioSettingValueBoolean(_mem.settings.alarm)) advanced.append(rs) # Other settings def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered _msg = _mem.firmware_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line1", "Firmware Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("firmware_msg.line2", "Firmware Message 2", val) other.append(rs) _msg = _mem.sixpoweron_msg val = RadioSettingValueString(0, 7, _filter(_msg.line1)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line1", "6+Power-On Message 1", val) other.append(rs) val = RadioSettingValueString(0, 7, _filter(_msg.line2)) val.set_mutable(False) rs = RadioSetting("sixpoweron_msg.line2", "6+Power-On Message 2", val) other.append(rs) _msg = _mem.poweron_msg rs = RadioSetting("poweron_msg.line1", "Power-On Message 1", RadioSettingValueString( 0, 7, _filter(_msg.line1))) other.append(rs) rs = RadioSetting("poweron_msg.line2", "Power-On Message 2", RadioSettingValueString( 0, 7, _filter(_msg.line2))) other.append(rs) # Work mode settings rs = RadioSetting("settings.displayab", "Display", RadioSettingValueList( LIST_AB, LIST_AB[_mem.settings.displayab])) work.append(rs) rs = RadioSetting("settings.workmode", "VFO/MR Mode", RadioSettingValueList( LIST_WORKMODE, LIST_WORKMODE[_mem.settings.workmode])) work.append(rs) rs = RadioSetting("settings.keylock", "Keypad Lock", RadioSettingValueBoolean(_mem.settings.keylock)) work.append(rs) rs = RadioSetting("wmchannel.mrcha", "MR A Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrcha)) work.append(rs) rs = RadioSetting("wmchannel.mrchb", "MR B Channel", RadioSettingValueInteger(0, 127, _mem.wmchannel.mrchb)) work.append(rs) def my_validate(value): value = chirp_common.parse_freq(value) msg = ("Can't be less than %i.0000") if value > 99000000 and value < 130 * 1000000: raise InvalidValueError(msg % (130)) msg = ("Can't be between %i.9975-%i.0000") if (179 + 1) * 1000000 <= value and value < 400 * 1000000: raise InvalidValueError(msg % (179, 400)) msg = ("Can't be greater than %i.9975") if value > 99000000 and value > (520 + 1) * 1000000: raise InvalidValueError(msg % (520)) return chirp_common.format_freq(value) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 val1a = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.a.freq)) val1a.set_validate_callback(my_validate) rs = RadioSetting("vfo.a.freq", "VFO A Frequency", val1a) rs.set_apply_callback(apply_freq, _mem.vfo.a) work.append(rs) val1b = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.b.freq)) val1b.set_validate_callback(my_validate) rs = RadioSetting("vfo.b.freq", "VFO B Frequency", val1b) rs.set_apply_callback(apply_freq, _mem.vfo.b) work.append(rs) rs = RadioSetting("vfo.a.step", "VFO A Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.a.step])) work.append(rs) rs = RadioSetting("vfo.b.step", "VFO B Tuning Step", RadioSettingValueList( LIST_STEP, LIST_STEP[_mem.vfo.b.step])) work.append(rs) # broadcast FM settings _fm_presets = self._memobj.fm_presets if _fm_presets <= 108.0 * 10 - 650: preset = _fm_presets / 10.0 + 65 elif _fm_presets >= 65.0 * 10 and _fm_presets <= 108.0 * 10: preset = _fm_presets / 10.0 else: preset = 76.0 rs = RadioSetting("fm_presets", "FM Preset(MHz)", RadioSettingValueFloat(65, 108.0, preset, 0.1, 1)) fm_preset.append(rs) # DTMF settings def apply_code(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code for i in range(0, 15): _codeobj = self._memobj.pttid[i].code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) pttid = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) pttid.set_apply_callback(apply_code, self._memobj.pttid[i], 5) dtmfe.append(pttid) if _mem.ani.dtmfon > 0xC3: val = 0x03 else: val = _mem.ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if _mem.ani.dtmfoff > 0xC3: val = 0x03 else: val = _mem.ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) _codeobj = self._memobj.ani.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.code", "ANI Code", val) rs.set_apply_callback(apply_code, self._memobj.ani, 5) dtmfe.append(rs) rs = RadioSetting("ani.aniid", "When to send ANI ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[_mem.ani.aniid])) dtmfe.append(rs) def apply_alarmcode(setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.alarm = code _codeobj = self._memobj.ani.alarm _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.alarm", "Alarm Code", val) rs.set_apply_callback(apply_alarmcode, self._memobj.ani, 5) dtmfe.append(rs) # Service settings for band in ["vhf", "uhf"]: for index in range(0, 10): key = "squelch.%s.sql%i" % (band, index) if band == "vhf": _obj = self._memobj.squelch.vhf elif band == "uhf": _obj = self._memobj.squelch.uhf val = RadioSettingValueInteger(0, 123, getattr(_obj, "sql%i" % ( index))) if index == 0: val.set_mutable(False) name = "%s Squelch %i" % (band.upper(), index) rs = RadioSetting(key, name, val) service.append(rs) return top @classmethod def match_model(cls, filedata, filename): match_size = False match_model = False # testing the file data size if len(filedata) == 0x2008: match_size = True # testing the firmware model fingerprint match_model = model_match(cls, filedata) if match_size and match_model: return True else: return False chirp-20240224/chirp/drivers/vx2.py0000644000175000017500000005636414446523722015737 0ustar hibbyhibby# Copyright 2013 Jens Jensen # based on modification of Dan Smith's and Rick Farina's original work # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, bitwise from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueList, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettings import re import logging LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x7F52; u8 checksum; #seekto 0x005A; u8 banksoff1; #seekto 0x00DA; u8 banksoff2; #seekto 0x0068; u16 prioritychan1; #seekto 0x00E8; u16 prioritychan2; #seekto 0x110; struct { u8 unk1; u8 unk2; u8 nfm_sql; u8 wfm_sql; u8 rfsql; u8 vfomode:1, cwid_en:1, scan_lamp:1, unk3:1, ars:1, beep:1, split:1, dtmfmode:1; u8 busyled:1, unk4:2, bclo:1, edgebeep:1, unk5:2, txsave:1; u8 unk6:2, smartsearch:1, unk7:1, artsinterval:1, unk8:1, hmrv:1, moni_tcall:1; u8 unk9:5, dcsrev:1, unk10:1, mwmode:1; u8 internet_mode:1, internet_key:1, wx_alert:1, unk11:2, att:1, unk12:2; u8 lamp; u8 dimmer; u8 rxsave; u8 resume; u8 chcounter; u8 openmsgmode; u8 openmsg[6]; u8 cwid[16]; u8 unk13[16]; u8 artsbeep; u8 bell; u8 apo; u8 tot; u8 lock; u8 mymenu; u8 unk14[4]; u8 emergmode; } settings; #seekto 0x0192; struct { u8 digits[16]; } dtmf[9]; #seekto 0x016A; struct { u16 in_use; } bank_used[20]; #seekto 0x0396; struct { u8 name[6]; } wxchannels[10]; #seekto 0x05C2; struct { u16 channels[100]; } banks[20]; #seekto 0x1562; struct { u8 even_pskip:1, even_skip:1, even_valid:1, even_masked:1, odd_pskip:1, odd_skip:1, odd_valid:1, odd_masked:1; } flags[500]; struct mem_struct { u8 unknown1:2, txnarrow:1, clk:1, unknown2:4; u8 mode:2, duplex:2, tune_step:4; bbcd freq[3]; u8 power:2, unknown3:4, tmode:2; u8 name[6]; bbcd offset[3]; u8 unknown4:2, tone:6; u8 unknown5:1, dcs:7; u8 unknown6; }; #seekto 0x17C2; struct mem_struct memory[1000]; struct { struct mem_struct lower; struct mem_struct upper; } pms[50]; #seekto 0x03D2; struct mem_struct home[12]; #seekto 0x04E2; struct mem_struct vfo[12]; """ VX2_DUPLEX = ["", "-", "+", "split"] # NFM handled specially in radio VX2_MODES = ["FM", "AM", "WFM", "Auto", "NFM"] VX2_TMODES = ["", "Tone", "TSQL", "DTCS"] VX2_STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0, 9.0] CHARSET = list("0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ " + "+-/\x00[](){}\x00\x00_" + ("\x00" * 13) + "*" + "\x00\x00,'|\x00\x00\x00\x00" + ("\x00" * 64)) DTMFCHARSET = list("0123456789ABCD*#") POWER_LEVELS = [chirp_common.PowerLevel("High", watts=1.50), chirp_common.PowerLevel("Low", watts=0.10)] class VX2BankModel(chirp_common.BankModel): """A VX-2 bank model""" def get_num_mappings(self): return len(self.get_mappings()) def get_mappings(self): banks = self._radio._memobj.banks bank_mappings = [] for index, _bank in enumerate(banks): bank = chirp_common.Bank(self, "%i" % index, "b%i" % (index + 1)) bank.index = index bank_mappings.append(bank) return bank_mappings def _get_channel_numbers_in_bank(self, bank): _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xFFFF: return set() _members = self._radio._memobj.banks[bank.index] return set([int(ch) + 1 for ch in _members.channels if ch != 0xFFFF]) def _update_bank_with_channel_numbers(self, bank, channels_in_bank): _members = self._radio._memobj.banks[bank.index] if len(channels_in_bank) > len(_members.channels): raise Exception("Too many entries in bank %d" % bank.index) empty = 0 for index, channel_number in enumerate(sorted(channels_in_bank)): _members.channels[index] = channel_number - 1 empty = index + 1 for index in range(empty, len(_members.channels)): _members.channels[index] = 0xFFFF def add_memory_to_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) channels_in_bank.add(memory.number) self._update_bank_with_channel_numbers(bank, channels_in_bank) _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0x0000 # also needed for unit to recognize banks? self._radio._memobj.banksoff1 = 0x00 self._radio._memobj.banksoff2 = 0x00 # todo: turn back off (0xFF) when all banks are empty? def remove_memory_from_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) try: channels_in_bank.remove(memory.number) except KeyError: raise Exception("Memory %i is not in bank %s. Cannot remove" % (memory.number, bank)) self._update_bank_with_channel_numbers(bank, channels_in_bank) if not channels_in_bank: _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0xFFFF def get_mapping_memories(self, bank): memories = [] for channel in self._get_channel_numbers_in_bank(bank): memories.append(self._radio.get_memory(channel)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in self._get_channel_numbers_in_bank(bank): banks.append(bank) return banks def _wipe_memory(mem): mem.set_raw("\x00" * (mem.size() // 8)) @directory.register class VX2Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu VX-2""" MODEL = "VX-2" _model = b"AH015" BAUD_RATE = 19200 _block_lengths = [10, 8, 32577] _memsize = 32595 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = True rf.has_settings = True rf.has_dtcs_polarity = False rf.valid_modes = list(set(VX2_MODES)) rf.valid_tmodes = list(VX2_TMODES) rf.valid_duplexes = list(VX2_DUPLEX) rf.valid_tuning_steps = list(VX2_STEPS) rf.valid_bands = [(500000, 999000000)] rf.valid_skips = ["", "S", "P"] rf.valid_power_levels = POWER_LEVELS rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 6 rf.memory_bounds = (1, 1000) rf.can_odd_split = True rf.has_ctone = False return rf def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x7F51)] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def get_memory(self, number): _mem = self._memobj.memory[number-1] _flag = self._memobj.flags[(number-1)/2] nibble = ((number-1) % 2) and "even" or "odd" used = _flag["%s_masked" % nibble] valid = _flag["%s_valid" % nibble] pskip = _flag["%s_pskip" % nibble] skip = _flag["%s_skip" % nibble] mem = chirp_common.Memory() mem.number = number if not used: mem.empty = True if not valid: mem.empty = True mem.power = POWER_LEVELS[0] return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = int(_mem.offset) * 1000 mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone] mem.tmode = VX2_TMODES[_mem.tmode] mem.duplex = VX2_DUPLEX[_mem.duplex] if mem.duplex == "split": mem.offset = chirp_common.fix_rounded_step(mem.offset) if _mem.txnarrow and _mem.mode == VX2_MODES.index("FM"): # narrow + FM mem.mode = "NFM" else: mem.mode = VX2_MODES[_mem.mode] mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs] mem.tuning_step = VX2_STEPS[_mem.tune_step] mem.skip = pskip and "P" or skip and "S" or "" mem.power = POWER_LEVELS[~_mem.power & 0x01] for i in _mem.name: if i == 0xFF: break mem.name += CHARSET[i & 0x7F] mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] _flag = self._memobj.flags[(mem.number-1)/2] nibble = ((mem.number-1) % 2) and "even" or "odd" used = _flag["%s_masked" % nibble] valid = _flag["%s_valid" % nibble] if not mem.empty and not valid: _wipe_memory(_mem) if mem.empty and valid and not used: _flag["%s_valid" % nibble] = False return _flag["%s_masked" % nibble] = not mem.empty if mem.empty: return _flag["%s_valid" % nibble] = True _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 1000 _mem.tone = chirp_common.TONES.index(mem.rtone) _mem.tmode = VX2_TMODES.index(mem.tmode) _mem.duplex = VX2_DUPLEX.index(mem.duplex) if mem.mode == "NFM": _mem.mode = VX2_MODES.index("FM") _mem.txnarrow = True else: _mem.mode = VX2_MODES.index(mem.mode) _mem.txnarrow = False _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tune_step = VX2_STEPS.index(mem.tuning_step) if mem.power == POWER_LEVELS[1]: # Low _mem.power = 0x00 else: # Default to High _mem.power = 0x03 _flag["%s_pskip" % nibble] = mem.skip == "P" _flag["%s_skip" % nibble] = mem.skip == "S" for i in range(0, 6): _mem.name[i] = CHARSET.index(mem.name.ljust(6)[i]) if mem.name.strip(): # empty name field, disable name display # leftmost bit of name chararr is: # 1 = display freq, 0 = display name _mem.name[0] |= 0x80 # for now, clear unknown fields for i in range(1, 7): setattr(_mem, "unknown%i" % i, 0) def validate_memory(self, mem): msgs = yaesu_clone.YaesuCloneModeRadio.validate_memory(self, mem) return msgs def get_bank_model(self): return VX2BankModel(self) def _decode_chars(self, inarr): LOG.debug("@_decode_chars, type: %s" % type(inarr)) LOG.debug(inarr) outstr = "" for i in inarr: if i == 0xFF: break outstr += CHARSET[i & 0x7F] return outstr.rstrip() def _encode_chars(self, instr, length=16): LOG.debug("@_encode_chars, type: %s" % type(instr)) LOG.debug(instr) outarr = [] instr = str(instr) for i in range(0, length): if i < len(instr): outarr.append(CHARSET.index(instr[i])) else: outarr.append(0xFF) return outarr def get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") dtmf = RadioSettingGroup("dtmf", "DTMF") arts = RadioSettingGroup("arts", "ARTS") top = RadioSettings(basic, arts, dtmf) options = ["off", "30m", "1h", "3h", "5h", "8h"] rs = RadioSetting( "apo", "APO time (hrs)", RadioSettingValueList(options, options[_settings.apo])) basic.append(rs) rs = RadioSetting( "ars", "Auto Repeater Shift", RadioSettingValueBoolean(_settings.ars)) basic.append(rs) rs = RadioSetting( "att", "Attenuation", RadioSettingValueBoolean(_settings.att)) basic.append(rs) rs = RadioSetting( "bclo", "Busy Channel Lockout", RadioSettingValueBoolean(_settings.bclo)) basic.append(rs) rs = RadioSetting( "beep", "Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) options = ["off", "1", "3", "5", "8", "cont"] rs = RadioSetting( "bell", "Bell", RadioSettingValueList(options, options[_settings.bell])) basic.append(rs) rs = RadioSetting( "busyled", "Busy LED", RadioSettingValueBoolean(_settings.busyled)) basic.append(rs) options = ["5", "10", "50", "100"] rs = RadioSetting( "chcounter", "Channel Counter (MHz)", RadioSettingValueList(options, options[_settings.chcounter])) basic.append(rs) rs = RadioSetting( "dcsrev", "DCS Reverse", RadioSettingValueBoolean(_settings.dcsrev)) basic.append(rs) options = list(map(str, list(range(0, 12+1)))) rs = RadioSetting( "dimmer", "Dimmer", RadioSettingValueList(options, options[_settings.dimmer])) basic.append(rs) rs = RadioSetting( "edgebeep", "Edge Beep", RadioSettingValueBoolean(_settings.edgebeep)) basic.append(rs) options = ["beep", "strobe", "bp+str", "beam", "bp+beam", "cw", "bp+cw"] rs = RadioSetting( "emergmode", "Emergency Mode", RadioSettingValueList(options, options[_settings.emergmode])) basic.append(rs) options = ["Home", "Reverse"] rs = RadioSetting( "hmrv", "HM/RV key", RadioSettingValueList(options, options[_settings.hmrv])) basic.append(rs) options = ["My Menu", "Internet"] rs = RadioSetting( "internet_key", "Internet key", RadioSettingValueList( options, options[_settings.internet_key])) basic.append(rs) options = ["1 APO", "2 AR BEP", "3 AR INT", "4 ARS", "5 ATT", "6 BCLO", "7 BEEP", "8 BELL", "9 BSYLED", "10 CH CNT", "11 CK SFT", "12 CW ID", "13 DC VLT", "14 DCS CD", "15 DCS RV", "16 DIMMER", "17 DTMF", "18 DTMF S", "19 EDG BP", "20 EMG S", "21 HLFDEV", "22 HM/RV", "23 INT MD", "24 LAMP", "25 LOCK", "26 M/T-CL", "27 MW MD", "28 NAME", "29 NM SET", "30 OPNMSG", "31 RESUME", "32 RF SQL", "33 RPT", "34 RX MD", "35 RXSAVE", "36 S SCH", "37 SCNLMP", "38 SHIFT", "39 SKIP", "40 SPLIT", "41 SQL", "42 SQL TYP", "43 STEP", "44 TN FRQ", "45 TOT", "46 TXSAVE", "47 VFO MD", "48 TR SQL (JAPAN)", "48 WX ALT"] rs = RadioSetting( "mymenu", "My Menu function", RadioSettingValueList(options, options[_settings.mymenu - 9])) basic.append(rs) options = ["wires", "link"] rs = RadioSetting( "internet_mode", "Internet mode", RadioSettingValueList( options, options[_settings.internet_mode])) basic.append(rs) options = ["key", "cont", "off"] rs = RadioSetting( "lamp", "Lamp mode", RadioSettingValueList(options, options[_settings.lamp])) basic.append(rs) options = ["key", "dial", "key+dial", "ptt", "key+ptt", "dial+ptt", "all"] rs = RadioSetting( "lock", "Lock mode", RadioSettingValueList(options, options[_settings.lock])) basic.append(rs) options = ["monitor", "tone call"] rs = RadioSetting( "moni_tcall", "MONI key", RadioSettingValueList(options, options[_settings.moni_tcall])) basic.append(rs) options = ["lower", "next"] rs = RadioSetting( "mwmode", "Memory write mode", RadioSettingValueList(options, options[_settings.mwmode])) basic.append(rs) options = list(map(str, list(range(0, 15+1)))) rs = RadioSetting( "nfm_sql", "NFM Sql", RadioSettingValueList(options, options[_settings.nfm_sql])) basic.append(rs) options = list(map(str, list(range(0, 8+1)))) rs = RadioSetting( "wfm_sql", "WFM Sql", RadioSettingValueList(options, options[_settings.wfm_sql])) basic.append(rs) options = ["off", "dc", "msg"] rs = RadioSetting( "openmsgmode", "Opening message", RadioSettingValueList(options, options[_settings.openmsgmode])) basic.append(rs) openmsg = RadioSettingValueString( 0, 6, self._decode_chars(_settings.openmsg.get_value())) openmsg.set_charset(CHARSET) rs = RadioSetting("openmsg", "Opening Message", openmsg) basic.append(rs) options = ["3s", "5s", "10s", "busy", "hold"] rs = RadioSetting( "resume", "Resume", RadioSettingValueList(options, options[_settings.resume])) basic.append(rs) options = ["off"] + list(map(str, list(range(1, 9+1)))) rs = RadioSetting( "rfsql", "RF Sql", RadioSettingValueList(options, options[_settings.rfsql])) basic.append(rs) options = ["off", "200ms", "300ms", "500ms", "1s", "2s"] rs = RadioSetting( "rxsave", "RX pwr save", RadioSettingValueList(options, options[_settings.rxsave])) basic.append(rs) options = ["single", "cont"] rs = RadioSetting( "smartsearch", "Smart search", RadioSettingValueList(options, options[_settings.smartsearch])) basic.append(rs) rs = RadioSetting( "scan_lamp", "Scan lamp", RadioSettingValueBoolean(_settings.scan_lamp)) basic.append(rs) rs = RadioSetting( "split", "Split", RadioSettingValueBoolean(_settings.split)) basic.append(rs) options = ["off", "1", "3", "5", "10"] rs = RadioSetting( "tot", "TOT (mins)", RadioSettingValueList(options, options[_settings.tot])) basic.append(rs) rs = RadioSetting( "txsave", "TX pwr save", RadioSettingValueBoolean(_settings.txsave)) basic.append(rs) options = ["all", "band"] rs = RadioSetting( "vfomode", "VFO mode", RadioSettingValueList(options, options[_settings.vfomode])) basic.append(rs) rs = RadioSetting( "wx_alert", "WX Alert", RadioSettingValueBoolean(_settings.wx_alert)) basic.append(rs) # todo: priority channel # todo: handle WX ch labels # arts settings (ar beep, ar int, cwid en, cwid field) options = ["15s", "25s"] rs = RadioSetting( "artsinterval", "ARTS Interval", RadioSettingValueList( options, options[_settings.artsinterval])) arts.append(rs) options = ["off", "in range", "always"] rs = RadioSetting( "artsbeep", "ARTS Beep", RadioSettingValueList(options, options[_settings.artsbeep])) arts.append(rs) rs = RadioSetting( "cwid_en", "CWID Enable", RadioSettingValueBoolean(_settings.cwid_en)) arts.append(rs) cwid = RadioSettingValueString( 0, 16, self._decode_chars(_settings.cwid.get_value())) cwid.set_charset(CHARSET) rs = RadioSetting("cwid", "CWID", cwid) arts.append(rs) # setup dtmf options = ["manual", "auto"] rs = RadioSetting( "dtmfmode", "DTMF mode", RadioSettingValueList(options, options[_settings.dtmfmode])) dtmf.append(rs) for i in range(0, 8+1): name = "dtmf" + str(i+1) dtmfsetting = self._memobj.dtmf[i] # dtmflen = getattr(_settings, objname + "_len") dtmfstr = "" for c in dtmfsetting.digits: if c < len(DTMFCHARSET): dtmfstr += DTMFCHARSET[c] LOG.debug(dtmfstr) dtmfentry = RadioSettingValueString(0, 16, dtmfstr) dtmfentry.set_charset(DTMFCHARSET + list(" ")) rs = RadioSetting(name, name.upper(), dtmfentry) dtmf.append(rs) return top def set_settings(self, uisettings): for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() _settings = self._memobj.settings if re.match(r'dtmf\d', setting): # set dtmf fields dtmfstr = str(element.value).strip() newval = [] for i in range(0, 16): if i < len(dtmfstr): newval.append(DTMFCHARSET.index(dtmfstr[i])) else: newval.append(0xFF) LOG.debug(newval) idx = int(setting[-1:]) - 1 _settings = self._memobj.dtmf[idx] _settings.digits = newval continue if setting == "prioritychan": # prioritychan is top-level member, fix 0 index element.value -= 1 _settings = self._memobj if setting == "mymenu": opts = element.value.get_options() optsidx = opts.index(element.value.get_value()) idx = optsidx + 9 setattr(_settings, "mymenu", idx) continue oldval = getattr(_settings, setting) newval = element.value if setting == "cwid": newval = self._encode_chars(newval) if setting == "openmsg": newval = self._encode_chars(newval, 6) LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise chirp-20240224/chirp/drivers/__init__.py0000644000175000017500000001653114566340175016751 0ustar hibbyhibbyfrom chirp.drivers import __init__ from chirp.drivers import bj9900 from chirp.drivers import anytone from chirp.drivers import anytone778uv from chirp.drivers import anytone_ht from chirp.drivers import anytone_iii from chirp.drivers import ap510 from chirp.drivers import baofeng_common from chirp.drivers import baofeng_uv3r from chirp.drivers import baofeng_wp970i from chirp.drivers import bjuv55 from chirp.drivers import boblov_x3plus from chirp.drivers import btech from chirp.drivers import fake from chirp.drivers import fd268 from chirp.drivers import ft1500m from chirp.drivers import ft1802 from chirp.drivers import ft1d from chirp.drivers import ft2900 from chirp.drivers import ft2d from chirp.drivers import ft4 from chirp.drivers import ft2800 from chirp.drivers import ft450d from chirp.drivers import ft50 from chirp.drivers import ft60 from chirp.drivers import ft70 from chirp.drivers import ft7100 from chirp.drivers import ft7800 from chirp.drivers import ft8100 from chirp.drivers import ft817 from chirp.drivers import ft818 from chirp.drivers import ft857 from chirp.drivers import ft90 from chirp.drivers import ftlx011 from chirp.drivers import ftm3200d from chirp.drivers import ftm350 from chirp.drivers import ftm7250d from chirp.drivers import ga510 from chirp.drivers import generic_csv from chirp.drivers import generic_tpe from chirp.drivers import gmrsuv1 from chirp.drivers import gmrsv2 from chirp.drivers import h777 from chirp.drivers import hf90 from chirp.drivers import bf_t1 from chirp.drivers import ic208 from chirp.drivers import hg_uv98 from chirp.drivers import hobbypcb from chirp.drivers import ic2300 from chirp.drivers import ic2100 from chirp.drivers import ic2200 from chirp.drivers import ic2720 from chirp.drivers import ic2730 from chirp.drivers import ic9x_icf from chirp.drivers import ic2820 from chirp.drivers import ic9x from chirp.drivers import ic9x_ll from chirp.drivers import ic9x_icf_ll from chirp.drivers import icf from chirp.drivers import icomciv from chirp.drivers import icp7 from chirp.drivers import ict8 from chirp.drivers import icq7 from chirp.drivers import ict70 from chirp.drivers import ict7h from chirp.drivers import icv80 from chirp.drivers import id31 from chirp.drivers import icv86 from chirp.drivers import icw32 from chirp.drivers import icx8x from chirp.drivers import icx90 from chirp.drivers import id5100 from chirp.drivers import id51 from chirp.drivers import id51plus from chirp.drivers import id880 from chirp.drivers import id800 from chirp.drivers import idrp from chirp.drivers import kg935g from chirp.drivers import iradio_uv_5118 from chirp.drivers import kenwood_hmk from chirp.drivers import kenwood_itm from chirp.drivers import kenwood_live from chirp.drivers import kguv8d from chirp.drivers import kguv980p from chirp.drivers import kguv8dplus from chirp.drivers import kguv8e from chirp.drivers import kguv920pa from chirp.drivers import kguv9dplus from chirp.drivers import leixen from chirp.drivers import kyd from chirp.drivers import kyd_IP620 from chirp.drivers import lt725uv from chirp.drivers import mursv1 from chirp.drivers import alinco from chirp.drivers import puxing from chirp.drivers import puxing_px888k from chirp.drivers import radioddity_r2 from chirp.drivers import radtel_t18 from chirp.drivers import retevis_rb15 from chirp.drivers import retevis_rb17p from chirp.drivers import retevis_rb28 from chirp.drivers import retevis_rt1 from chirp.drivers import retevis_rt21 from chirp.drivers import retevis_rt22 from chirp.drivers import retevis_rt23 from chirp.drivers import retevis_rt26 from chirp.drivers import retevis_rt76p from chirp.drivers import retevis_rt87 from chirp.drivers import retevis_rt98 from chirp.drivers import bf_t8 from chirp.drivers import rh5r_v2 from chirp.drivers import tdxone_tdq8a from chirp.drivers import template from chirp.drivers import tg_uv2p from chirp.drivers import th350 from chirp.drivers import th7800 from chirp.drivers import th9000 from chirp.drivers import th9800 from chirp.drivers import th_uv3r from chirp.drivers import th_uv3r25 from chirp.drivers import th_uv8000 from chirp.drivers import th_uv88 from chirp.drivers import th_uvf8d from chirp.drivers import thd72 from chirp.drivers import thd74 from chirp.drivers import thuv1f from chirp.drivers import tk270 from chirp.drivers import tk3140 from chirp.drivers import tk760 from chirp.drivers import tk760g from chirp.drivers import tk8102 from chirp.drivers import tk8160 from chirp.drivers import tk8180 from chirp.drivers import tmd710 from chirp.drivers import tmv71 from chirp.drivers import tmv71_ll from chirp.drivers import ts2000 from chirp.drivers import ts480 from chirp.drivers import ts590 from chirp.drivers import ts850 from chirp.drivers import uv5r from chirp.drivers import uv5x3 from chirp.drivers import uv6r from chirp.drivers import uvb5 from chirp.drivers import vgc from chirp.drivers import vx170 from chirp.drivers import vx2 from chirp.drivers import vx3 from chirp.drivers import vx5 from chirp.drivers import vx510 from chirp.drivers import vx6 from chirp.drivers import vx7 from chirp.drivers import vx8 from chirp.drivers import vxa700 from chirp.drivers import wouxun from chirp.drivers import wouxun_common from chirp.drivers import kenwood_d7 from chirp.drivers import yaesu_clone from chirp.drivers import tdh8 from chirp.drivers import radtel_rt490 from chirp.drivers import baofeng_uv17Pro from chirp.drivers import uvk5 from chirp.drivers import baofeng_uv17 from chirp.drivers import iradio_uv_5118plus from chirp.drivers import mml_jc8810 from chirp.drivers import uvk5_egzumer __all__ = ['__init__', 'bj9900', 'anytone', 'anytone778uv', 'anytone_ht', 'anytone_iii', 'ap510', 'baofeng_common', 'baofeng_uv3r', 'baofeng_wp970i', 'bjuv55', 'boblov_x3plus', 'btech', 'fake', 'fd268', 'ft1500m', 'ft1802', 'ft1d', 'ft2900', 'ft2d', 'ft4', 'ft2800', 'ft450d', 'ft50', 'ft60', 'ft70', 'ft7100', 'ft7800', 'ft8100', 'ft817', 'ft818', 'ft857', 'ft90', 'ftlx011', 'ftm3200d', 'ftm350', 'ftm7250d', 'ga510', 'generic_csv', 'generic_tpe', 'gmrsuv1', 'gmrsv2', 'h777', 'hf90', 'bf_t1', 'ic208', 'hg_uv98', 'hobbypcb', 'ic2300', 'ic2100', 'ic2200', 'ic2720', 'ic2730', 'ic9x_icf', 'ic2820', 'ic9x', 'ic9x_ll', 'ic9x_icf_ll', 'icf', 'icomciv', 'icp7', 'ict8', 'icq7', 'ict70', 'ict7h', 'icv80', 'id31', 'icv86', 'icw32', 'icx8x', 'icx90', 'id5100', 'id51', 'id51plus', 'id880', 'id800', 'idrp', 'kg935g', 'iradio_uv_5118', 'kenwood_hmk', 'kenwood_itm', 'kenwood_live', 'kguv8d', 'kguv980p', 'kguv8dplus', 'kguv8e', 'kguv920pa', 'kguv9dplus', 'leixen', 'kyd', 'kyd_IP620', 'lt725uv', 'mursv1', 'alinco', 'puxing', 'puxing_px888k', 'radioddity_r2', 'radtel_t18', 'retevis_rb15', 'retevis_rb17p', 'retevis_rb28', 'retevis_rt1', 'retevis_rt21', 'retevis_rt22', 'retevis_rt23', 'retevis_rt26', 'retevis_rt76p', 'retevis_rt87', 'retevis_rt98', 'bf_t8', 'rh5r_v2', 'tdxone_tdq8a', 'template', 'tg_uv2p', 'th350', 'th7800', 'th9000', 'th9800', 'th_uv3r', 'th_uv3r25', 'th_uv8000', 'th_uv88', 'th_uvf8d', 'thd72', 'thd74', 'thuv1f', 'tk270', 'tk3140', 'tk760', 'tk760g', 'tk8102', 'tk8160', 'tk8180', 'tmd710', 'tmv71', 'tmv71_ll', 'ts2000', 'ts480', 'ts590', 'ts850', 'uv5r', 'uv5x3', 'uv6r', 'uvb5', 'vgc', 'vx170', 'vx2', 'vx3', 'vx5', 'vx510', 'vx6', 'vx7', 'vx8', 'vxa700', 'wouxun', 'wouxun_common', 'kenwood_d7', 'yaesu_clone', 'tdh8', 'radtel_rt490', 'baofeng_uv17Pro', 'uvk5', 'baofeng_uv17', 'iradio_uv_5118plus', 'mml_jc8810', 'uvk5_egzumer'] chirp-20240224/chirp/drivers/vx6.py0000644000175000017500000007413114560403070015721 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import yaesu_clone from chirp import chirp_common, directory, bitwise from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings from chirp.settings import RadioSettingValueString, RadioSettingValueList from chirp.settings import RadioSettingValueBoolean import re LOG = logging.getLogger(__name__) # flags.{even|odd}_pskip: These are actually "preferential *scan* channels". # Is that what they mean on other radios as well? # memory { # step_changed: Channel step has been changed. Bit stays on even after # you switch back to default step. Don't know why you would # care # half_deviation: 2.5 kHz deviation # cpu_shifted: CPU freq has been shifted (to move a birdie out of channel) # power: 0-3: ["L1", "L2", "L3", "Hi"] # pager: Set if this is a paging memory # tmodes: 0-7: ["", "Tone", "TSQL", "DTCS", "Rv Tn", "D Code", # "T DCS", "D Tone"] # Rv Tn: Reverse CTCSS - mutes receiver on tone # The final 3 are for split: # D Code: DCS Encode only # T DCS: Encodes tone, decodes DCS code # D Tone: Encodes DCS code, decodes tone # } MEM_FORMAT = """ #seekto 0x010A; struct { u8 auto_power_off; u8 arts_beep; u8 bell; u8 beep_level; u8 arts_cwid_alpha[16]; u8 unk1[2]; u8 channel_counter_width; u8 lcd_dimmer; u8 last_dtmf; u8 unk2; u8 internet_code; u8 last_internet_dtmf; u8 unk3[3]; u8 emergency; u8 unk4[16]; u8 lamp; u8 lock; u8 unk5; u8 mic_gain; u8 unk6[2]; u8 on_timer; u8 open_message_mode; u8 open_message[6]; u8 unk7; u8 unk8:6, pager_answer_back:1, unk9:1; u8 pager_rx_tone1; u8 pager_rx_tone2; u8 pager_tx_tone1; u8 pager_tx_tone2; u8 password[4]; u8 ptt_delay; u8 rf_squelch; u8 rx_save; u8 resume; u8 unk10[5]; u8 tx_timeout; u8 wakeup; u8 vfo_mode:1, arts_cwid:1, scan_lamp:1, ts_speed:1, unk11:1, beep:1, unk12:1, dtmf_autodial:1; u8 busy_led:1, tone_search_mute:1, int_autodial:1, bclo:1, edge_beep:1, unk13:1, dmr_wrt:1, tx_saver:1; u8 unk14:2, smart_search:1, unk15:3, home_rev:1, moni_tcall:1; u8 unk16:3, arts_interval:1, unk17:3, memory_method:1; u8 unk18:2, internet_mode:1, wx_alert:1, unk19:1, att:1, unk20:2; } settings; #seekto 0x018A; struct { u16 in_use; } bank_used[24]; #seekto 0x01D8; u8 clock_shift; #seekto 0x0214; u16 banksoff1; #seekto 0x0248; u8 lastsetting1; #seekto 0x0294; u16 banksoff2; #seekto 0x0248; u8 lastsetting2; #seekto 0x02CA; struct { u8 memory[16]; } dtmf[10]; #seekto 0x03CA; struct { u8 memory[8]; u8 empty_ff[8]; } internet_dtmf[64]; #seekto 0x097A; struct { u8 name[6]; } bank_names[24]; #seekto 0x0C0A; struct { u16 channels[100]; } banks[24]; #seekto 0x1ECA; struct { u8 even_pskip:1, even_skip:1, even_valid:1, even_masked:1, odd_pskip:1, odd_skip:1, odd_valid:1, odd_masked:1; } flags[500]; #seekto 0x21CA; struct { u8 unknown11:1, step_changed:1, half_deviation:1, cpu_shifted:1, unknown12:4; u8 mode:2, duplex:2, tune_step:4; bbcd freq[3]; u8 power:2, unknown2:2, pager:1, tmode:3; u8 name[6]; bbcd offset[3]; u8 tone; u8 dcs; u8 unknown5; } memory[999]; """ DUPLEX = ["", "-", "+", "split"] MODES = ["FM", "AM", "WFM", "FM"] # last is auto TMODES = ["", "Tone", "TSQL", "DTCS", "TSQL-R", # This is "RV TN" as Yaesu calls it "DTCS->", "Tone->DTCS", "DTCS->Tone"] DTMFCHARSET = list("0123456789ABCD*#-") STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 50.0, 100.0, 9.0, 200.0, 5.0] # last is auto, 9.0k and 200.0k are unadvertised CHARSET = ["%i" % int(x) for x in range(10)] + \ [chr(x) for x in range(ord("A"), ord("Z")+1)] + \ list(" +-/?[]u_" + ("\x00" * 9) + "$%%\x00*#.|=\\o@") + \ list("\x00" * 100) PASS_CHARSET = list("0123456789ABCDEF") POWER_LEVELS = [chirp_common.PowerLevel("Hi", watts=5.00), chirp_common.PowerLevel("L3", watts=2.50), chirp_common.PowerLevel("L2", watts=1.00), chirp_common.PowerLevel("L1", watts=0.30)] POWER_LEVELS_220 = [chirp_common.PowerLevel("Hi", watts=1.50), chirp_common.PowerLevel("L3", watts=1.00), chirp_common.PowerLevel("L2", watts=0.50), chirp_common.PowerLevel("L1", watts=0.20)] class VX6Bank(chirp_common.NamedBank): """A VX6 Bank""" def get_name(self): _bank = self._model._radio._memobj.bank_names[self.index] name = "" for i in _bank.name: if i == 0xFF: break name += CHARSET[i & 0x7F] return name.rstrip() def set_name(self, name): name = name.upper() _bank = self._model._radio._memobj.bank_names[self.index] _bank.name = [CHARSET.index(x) for x in name.ljust(6)[:6]] class VX6BankModel(chirp_common.BankModel): """A VX-6 bank model""" def get_num_mappings(self): return len(self.get_mappings()) def get_mappings(self): banks = self._radio._memobj.banks bank_mappings = [] for index, _bank in enumerate(banks): bank = VX6Bank(self, "%i" % index, "b%i" % (index + 1)) bank.index = index bank_mappings.append(bank) return bank_mappings def _get_channel_numbers_in_bank(self, bank): _bank_used = self._radio._memobj.bank_used[bank.index] if _bank_used.in_use == 0xFFFF: return set() _members = self._radio._memobj.banks[bank.index] return set([int(ch) + 1 for ch in _members.channels if ch != 0xFFFF]) def _update_bank_with_channel_numbers(self, bank, channels_in_bank): _members = self._radio._memobj.banks[bank.index] if len(channels_in_bank) > len(_members.channels): raise Exception("Too many entries in bank %d" % bank.index) empty = 0 for index, channel_number in enumerate(sorted(channels_in_bank)): _members.channels[index] = channel_number - 1 empty = index + 1 for index in range(empty, len(_members.channels)): _members.channels[index] = 0xFFFF def add_memory_to_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) channels_in_bank.add(memory.number) self._update_bank_with_channel_numbers(bank, channels_in_bank) _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0x0000 # enable # also needed for unit to recognize any banks? self._radio._memobj.banksoff1 = 0x0000 self._radio._memobj.banksoff2 = 0x0000 # TODO: turn back off (0xFFFF) when all banks are empty? def remove_memory_from_mapping(self, memory, bank): channels_in_bank = self._get_channel_numbers_in_bank(bank) try: channels_in_bank.remove(memory.number) except KeyError: raise Exception("Memory %i is not in bank %s. Cannot remove" % (memory.number, bank)) self._update_bank_with_channel_numbers(bank, channels_in_bank) if not channels_in_bank: _bank_used = self._radio._memobj.bank_used[bank.index] _bank_used.in_use = 0xFFFF # disable bank def get_mapping_memories(self, bank): memories = [] for channel in self._get_channel_numbers_in_bank(bank): memories.append(self._radio.get_memory(channel)) return memories def get_memory_mappings(self, memory): banks = [] for bank in self.get_mappings(): if memory.number in self._get_channel_numbers_in_bank(bank): banks.append(bank) return banks @directory.register class VX6Radio(yaesu_clone.YaesuCloneModeRadio): """Yaesu VX-6""" BAUD_RATE = 19200 VENDOR = "Yaesu" MODEL = "VX-6" _model = b"AH021" _memsize = 32587 _block_lengths = [10, 32577] _block_size = 16 _APO = ("OFF", "30 min", "1 hour", "3 hour", "5 hour", "8 hour") _ARTSBEEP = ("Off", "In Range", "Always") _ARTS_INT = ("15 S", "25 S") _BELL = ("OFF", "1", "3", "5", "8", "Continuous") _BEEP_LEVEL = ["%i" % int(x) for x in range(1, 10)] _CH_CNT = ("5 MHz", "10 MHz", "50 MHz", "100 MHz") _DIM_LEVEL = ["%i" % int(x) for x in range(0, 13)] _EMERGENCY = ("Beep", "Strobe", "Bp+Str", "Beam", "Bp+Bem", "CW", "Bp+CW", "CWT") _HOME_REV = ("HOME", "REV") _INT_CD = ["%i" % int(x) for x in range(0, 10)] + \ [chr(x) for x in range(ord("A"), ord("F")+1)] _INT_MD = ("SRG: Sister Radio Group", "FRG: Friendly Radio Group") _LAMP = ("Key", "Continuous", "Off") _LOCK = ("Key", "Dial", "Key+Dial", "PTT", "Key+PTT", "Dial+PTT", "All") _MAN_AUTO = ("Manual", "Auto") _MEM_W_MD = ("Lower", "Next") _MONI_TCALL = ("MONI", "T-CALL") _NUM_1_9 = ["%i" % int(x) for x in range(1, 10)] _NUM_0_9 = ["%i" % int(x) for x in range(10)] _NUM_0_63 = ["%i" % int(x) for x in range(64)] _NUM_1_50 = ["%i" % int(x) for x in range(1, 51)] _ON_TIMER = ["OFF"] + \ ["%02d:%02d" % (t / 60, t % 60) for t in range(10, 1450, 10)] _OPEN_MSG = ("Off", "DC Voltage", "Message") _PTT_DELAY = ("OFF", "20 ms", "50 ms", "100 ms", "200 ms") _RF_SQL = ("OFF", "S1", "S2", "S3", "S4", "S5", "S6", "S7", "S8", "S9", "S9+") _RX_SAVE = ("OFF", "200 ms", "300 ms", "500 ms", "1 s", "2 s") _RESUME = ("3 SEC", "5 SEC", "10 SEC", "BUSY", "HOLD") _SMART_SEARCH = ("SINGLE", "CONT") _TOT = ("OFF", "1MIN", "3MIN", "5MIN", "10MIN") _TS_SPEED = ("FAST", "SLOW") _VFO_MODE = ("ALL", "BAND") _WAKEUP = ("OFF", "5S", "10S", "20S", "30S", "EAI") @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [F/W] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. After clicking OK, press the [BAND] key to send" " image.\n") rp.pre_upload = _( "1. Turn radio off.\n" "2. Connect cable to MIC/SP jack.\n" "3. Press and hold in the [F/W] key while turning the radio on\n" " (\"CLONE\" will appear on the display).\n" "4. Press the [V/M] key (\"-WAIT-\" will appear on the LCD).\n") return rp def _checksums(self): return [yaesu_clone.YaesuChecksum(0x0000, 0x7F49)] def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = True rf.has_bank_names = True rf.has_dtcs_polarity = False rf.valid_modes = ["FM", "WFM", "AM", "NFM"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "TSQL-R", "Cross"] rf.valid_cross_modes = [x for x in TMODES if '->' in x] rf.valid_duplexes = DUPLEX rf.valid_tuning_steps = STEPS rf.valid_power_levels = POWER_LEVELS rf.memory_bounds = (1, 999) rf.valid_bands = [(500000, 998990000)] rf.valid_characters = "".join(CHARSET) rf.valid_name_length = 6 rf.can_odd_split = True rf.has_ctone = False rf.has_settings = True return rf def get_raw_memory(self, number): return repr(self._memobj.memory[number-1]) + \ repr(self._memobj.flags[(number-1)/2]) def get_memory(self, number): _mem = self._memobj.memory[number-1] _flg = self._memobj.flags[(number-1)/2] nibble = ((number-1) % 2) and "even" or "odd" used = _flg["%s_masked" % nibble] valid = _flg["%s_valid" % nibble] pskip = _flg["%s_pskip" % nibble] skip = _flg["%s_skip" % nibble] mem = chirp_common.Memory() mem.number = number if not used: mem.empty = True if not valid: mem.empty = True mem.power = POWER_LEVELS[0] return mem mem.freq = chirp_common.fix_rounded_step(int(_mem.freq) * 1000) mem.offset = chirp_common.fix_rounded_step(int(_mem.offset) * 1000) mem.rtone = mem.ctone = chirp_common.TONES[_mem.tone & 0x3f] tmode = TMODES[_mem.tmode] if '->' in tmode: mem.tmode = 'Cross' mem.cross_mode = tmode else: mem.tmode = tmode mem.duplex = DUPLEX[_mem.duplex] mem.mode = MODES[_mem.mode] if mem.mode == "FM" and _mem.half_deviation: mem.mode = "NFM" mem.dtcs = chirp_common.DTCS_CODES[_mem.dcs & 0x7f] mem.tuning_step = STEPS[_mem.tune_step] mem.skip = pskip and "P" or skip and "S" or "" if mem.freq > 220000000 and mem.freq < 225000000: mem.power = POWER_LEVELS_220[3 - _mem.power] else: mem.power = POWER_LEVELS[3 - _mem.power] for i in _mem.name: if i == 0xFF: break mem.name += CHARSET[i & 0x7F] mem.name = mem.name.rstrip() return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number-1] _flag = self._memobj.flags[(mem.number-1)/2] nibble = ((mem.number-1) % 2) and "even" or "odd" used = _flag["%s_masked" % nibble] valid = _flag["%s_valid" % nibble] # initialize new channel to safe defaults if not mem.empty and not valid: _flag["%s_valid" % nibble] = True _mem.unknown11 = 0 _mem.step_changed = 0 _mem.cpu_shifted = 0 _mem.unknown12 = 0 _mem.unknown2 = 0 _mem.pager = 0 _mem.unknown5 = 0 if mem.empty and valid and not used: _flag["%s_valid" % nibble] = False return _flag["%s_masked" % nibble] = not mem.empty if mem.empty: return _mem.freq = mem.freq / 1000 _mem.offset = mem.offset / 1000 _mem.tone = chirp_common.TONES.index(mem.rtone) if mem.tmode == 'Cross': _mem.tmode = TMODES.index(mem.cross_mode) else: _mem.tmode = TMODES.index(mem.tmode) _mem.duplex = DUPLEX.index(mem.duplex) if mem.mode == "NFM": _mem.mode = MODES.index("FM") _mem.half_deviation = 1 else: _mem.mode = MODES.index(mem.mode) _mem.half_deviation = 0 _mem.dcs = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tune_step = STEPS.index(mem.tuning_step) if mem.power: _mem.power = 3 - self._resolve_power(mem) else: _mem.power = 0 _flag["%s_pskip" % nibble] = mem.skip == "P" _flag["%s_skip" % nibble] = mem.skip == "S" _mem.name = [0xFF] * 6 for i in range(0, 6): _mem.name[i] = CHARSET.index(mem.name.ljust(6)[i]) if mem.name.strip(): _mem.name[0] |= 0x80 def _resolve_power(self, mem): # Since we have two sets of power levels, we may need to match the # one in mem.power by name instead of absolute power to handle things # like editing a 2m channel to a 220 MHz frequency, etc. by_name = [str(x) for x in POWER_LEVELS] index = by_name.index(str(mem.power)) LOG.debug('Resolving power %r by name to index %i' % ( mem.power, index)) return index def validate_memory(self, mem): # Override memory validation with by-name power level matching, # since we do not expose those power levels in our RadioFeatures. if mem.power and mem.power not in POWER_LEVELS: mem = mem.dupe() mem.power = POWER_LEVELS[self._resolve_power(mem)] return super().validate_memory(mem) def get_bank_model(self): return VX6BankModel(self) def _decode_chars(self, inarr): outstr = "" for i in inarr: if i == 0xFF: break outchar = CHARSET[i & 0x7F] if outchar != "\x00": outstr += outchar return outstr.rstrip() def _encode_chars(self, instr, length=16): outarr = [] instr = str(instr) for i in range(length): if i < len(instr): outarr.append(CHARSET.index(instr[i])) else: outarr.append(0xFF) return outarr def _get_settings(self): _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic") arts = RadioSettingGroup("arts", "ARTS") dtmf = RadioSettingGroup("dtmf", "DTMF") wires = RadioSettingGroup("wires", "WIRES") misc = RadioSettingGroup("misc", "Misc") top = RadioSettings(basic, arts, dtmf, wires, misc) # BASIC val = RadioSettingValueList( self._APO, self._APO[_settings.auto_power_off]) rs = RadioSetting("auto_power_off", "Auto Power Off", val) basic.append(rs) val = RadioSettingValueList( self._BEEP_LEVEL, self._BEEP_LEVEL[_settings.beep_level]) rs = RadioSetting("beep_level", "Beep Level", val) basic.append(rs) val = RadioSettingValueList( self._DIM_LEVEL, self._DIM_LEVEL[_settings.lcd_dimmer]) rs = RadioSetting("lcd_dimmer", "Dimmer Level", val) basic.append(rs) val = RadioSettingValueList( self._LAMP, self._LAMP[_settings.lamp]) rs = RadioSetting("lamp", "Keypad Lamp", val) basic.append(rs) val = RadioSettingValueList( self._LOCK, self._LOCK[_settings.lock]) rs = RadioSetting("lock", "Lock", val) basic.append(rs) val = RadioSettingValueList( self._NUM_1_9, self._NUM_1_9[_settings.mic_gain]) rs = RadioSetting("mic_gain", "Mic Gain", val) basic.append(rs) val = RadioSettingValueList( self._OPEN_MSG, self._OPEN_MSG[_settings.open_message_mode]) rs = RadioSetting("open_message_mode", "Open Message Mode", val) basic.append(rs) val = RadioSettingValueString(0, 6, self._decode_chars( _settings.open_message)) val.set_charset(CHARSET) rs = RadioSetting("open_message", "Opening Message", val) basic.append(rs) passstr = "" for c in _settings.password: if c < len(PASS_CHARSET): passstr += PASS_CHARSET[c] val = RadioSettingValueString(0, 4, passstr) val.set_charset(PASS_CHARSET) rs = RadioSetting("password", "Password", val) basic.append(rs) val = RadioSettingValueList( self._RESUME, self._RESUME[_settings.resume]) rs = RadioSetting("resume", "Scan Resume", val) basic.append(rs) val = RadioSettingValueList( self._MONI_TCALL, self._MONI_TCALL[_settings.moni_tcall]) rs = RadioSetting("moni_tcall", "MONI/T-CALL switch", val) basic.append(rs) rs = RadioSetting("scan_lamp", "Scan Lamp", RadioSettingValueBoolean(_settings.scan_lamp)) basic.append(rs) rs = RadioSetting("beep", "Keypad Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) rs = RadioSetting("busy_led", "Busy LED", RadioSettingValueBoolean(_settings.busy_led)) basic.append(rs) rs = RadioSetting("bclo", "Busy Channel Lock-Out", RadioSettingValueBoolean(_settings.bclo)) basic.append(rs) rs = RadioSetting("wx_alert", "WX Alert", RadioSettingValueBoolean(_settings.wx_alert)) basic.append(rs) rs = RadioSetting("att", "Attenuator", RadioSettingValueBoolean(_settings.att)) basic.append(rs) # ARTS val = RadioSettingValueList( self._ARTS_INT, self._ARTS_INT[_settings.arts_interval]) rs = RadioSetting("arts_interval", "ARTS Interval", val) arts.append(rs) val = RadioSettingValueList( self._ARTSBEEP, self._ARTSBEEP[_settings.arts_beep]) rs = RadioSetting("arts_beep", "ARTS Beep", val) arts.append(rs) rs = RadioSetting("arts_cwid", "ARTS Send CWID", RadioSettingValueBoolean(_settings.arts_cwid)) arts.append(rs) val = RadioSettingValueString(0, 16, self._decode_chars( _settings.arts_cwid_alpha)) val.set_charset(CHARSET) rs = RadioSetting("arts_cwid_alpha", "ARTS CW ID", val) arts.append(rs) # DTMF val = RadioSettingValueList( self._MAN_AUTO, self._MAN_AUTO[_settings.dtmf_autodial]) rs = RadioSetting("dtmf_autodial", "DTMF Autodial", val) dtmf.append(rs) val = RadioSettingValueList( self._NUM_0_9, self._NUM_0_9[_settings.last_dtmf]) rs = RadioSetting("last_dtmf", "Last DTMF Memory Set", val) dtmf.append(rs) for i in range(10): name = "dtmf_" + str(i) dtmfsetting = self._memobj.dtmf[i] dtmfstr = "" for c in dtmfsetting.memory: if c < len(DTMFCHARSET): dtmfstr += DTMFCHARSET[c] dtmfentry = RadioSettingValueString(0, 16, dtmfstr) rs = RadioSetting(name, name.upper(), dtmfentry) dtmf.append(rs) # WIRES val = RadioSettingValueList( self._INT_CD, self._INT_CD[_settings.internet_code]) rs = RadioSetting("internet_code", "Internet Code", val) wires.append(rs) val = RadioSettingValueList( self._INT_MD, self._INT_MD[_settings.internet_mode]) rs = RadioSetting("internet_mode", "Internet Link Connection mode", val) wires.append(rs) val = RadioSettingValueList( self._MAN_AUTO, self._MAN_AUTO[_settings.int_autodial]) rs = RadioSetting("int_autodial", "Internet Autodial", val) wires.append(rs) val = RadioSettingValueList( self._NUM_0_63, self._NUM_0_63[_settings.last_internet_dtmf]) rs = RadioSetting("last_internet_dtmf", "Last Internet DTMF Memory Set", val) wires.append(rs) for i in range(64): name = "wires_dtmf_" + str(i) dtmfsetting = self._memobj.internet_dtmf[i] dtmfstr = "" for c in dtmfsetting.memory: if c < len(DTMFCHARSET): dtmfstr += DTMFCHARSET[c] dtmfentry = RadioSettingValueString(0, 8, dtmfstr) rs = RadioSetting(name, name.upper(), dtmfentry) wires.append(rs) # MISC val = RadioSettingValueList( self._BELL, self._BELL[_settings.bell]) rs = RadioSetting("bell", "CTCSS/DCS Bell", val) misc.append(rs) val = RadioSettingValueList( self._CH_CNT, self._CH_CNT[_settings.channel_counter_width]) rs = RadioSetting("channel_counter_width", "Channel Counter Search Width", val) misc.append(rs) val = RadioSettingValueList( self._EMERGENCY, self._EMERGENCY[_settings.emergency]) rs = RadioSetting("emergency", "Emergency alarm", val) misc.append(rs) val = RadioSettingValueList( self._ON_TIMER, self._ON_TIMER[_settings.on_timer]) rs = RadioSetting("on_timer", "On Timer", val) misc.append(rs) rs = RadioSetting("pager_answer_back", "Pager Answer Back", RadioSettingValueBoolean( _settings.pager_answer_back)) misc.append(rs) val = RadioSettingValueList( self._NUM_1_50, self._NUM_1_50[_settings.pager_rx_tone1]) rs = RadioSetting("pager_rx_tone1", "Pager RX Tone 1", val) misc.append(rs) val = RadioSettingValueList( self._NUM_1_50, self._NUM_1_50[_settings.pager_rx_tone2]) rs = RadioSetting("pager_rx_tone2", "Pager RX Tone 2", val) misc.append(rs) val = RadioSettingValueList( self._NUM_1_50, self._NUM_1_50[_settings.pager_tx_tone1]) rs = RadioSetting("pager_tx_tone1", "Pager TX Tone 1", val) misc.append(rs) val = RadioSettingValueList( self._NUM_1_50, self._NUM_1_50[_settings.pager_tx_tone2]) rs = RadioSetting("pager_tx_tone2", "Pager TX Tone 2", val) misc.append(rs) val = RadioSettingValueList( self._PTT_DELAY, self._PTT_DELAY[_settings.ptt_delay]) rs = RadioSetting("ptt_delay", "PTT Delay", val) misc.append(rs) val = RadioSettingValueList( self._RF_SQL, self._RF_SQL[_settings.rf_squelch]) rs = RadioSetting("rf_squelch", "RF Squelch", val) misc.append(rs) val = RadioSettingValueList( self._RX_SAVE, self._RX_SAVE[_settings.rx_save]) rs = RadioSetting("rx_save", "RX Save", val) misc.append(rs) val = RadioSettingValueList( self._TOT, self._TOT[_settings.tx_timeout]) rs = RadioSetting("tx_timeout", "TOT", val) misc.append(rs) val = RadioSettingValueList( self._WAKEUP, self._WAKEUP[_settings.wakeup]) rs = RadioSetting("wakeup", "Wakeup", val) misc.append(rs) rs = RadioSetting("edge_beep", "Band-Edge Beep", RadioSettingValueBoolean(_settings.edge_beep)) misc.append(rs) val = RadioSettingValueList( self._VFO_MODE, self._VFO_MODE[_settings.vfo_mode]) rs = RadioSetting("vfo_mode", "VFO Band Edge Limiting", val) misc.append(rs) rs = RadioSetting("tone_search_mute", "Tone Search Mute", RadioSettingValueBoolean(_settings.tone_search_mute)) misc.append(rs) val = RadioSettingValueList( self._TS_SPEED, self._TS_SPEED[_settings.ts_speed]) rs = RadioSetting("ts_speed", "Tone Search Speed", val) misc.append(rs) rs = RadioSetting("dmr_wrt", "Direct Memory Recall Overwrite", RadioSettingValueBoolean(_settings.dmr_wrt)) misc.append(rs) rs = RadioSetting("tx_saver", "TX Battery Saver", RadioSettingValueBoolean(_settings.tx_saver)) misc.append(rs) val = RadioSettingValueList( self._SMART_SEARCH, self._SMART_SEARCH[_settings.smart_search]) rs = RadioSetting("smart_search", "Smart Search", val) misc.append(rs) val = RadioSettingValueList( self._HOME_REV, self._HOME_REV[_settings.home_rev]) rs = RadioSetting("home_rev", "HM/RV(EMG)R/H key", val) misc.append(rs) val = RadioSettingValueList( self._MEM_W_MD, self._MEM_W_MD[_settings.memory_method]) rs = RadioSetting("memory_method", "Memory Write Method", val) misc.append(rs) return top def get_settings(self): try: return self._get_settings() except: import traceback print(traceback.format_exc()) return None def set_settings(self, uisettings): for element in uisettings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() _settings = self._memobj.settings if re.match(r'internet_dtmf_\d', setting): # set dtmf fields dtmfstr = str(element.value).strip() newval = [] for i in range(0, 8): if i < len(dtmfstr): newval.append(DTMFCHARSET.index(dtmfstr[i])) else: newval.append(0xFF) idx = int(setting[-1:]) _settings = self._memobj.internet_dtmf[idx] _settings.memory = newval continue elif re.match(r'dtmf_\d', setting): # set dtmf fields dtmfstr = str(element.value).strip() newval = [] for i in range(0, 16): if i < len(dtmfstr): newval.append(DTMFCHARSET.index(dtmfstr[i])) else: newval.append(0xFF) idx = int(setting[-1:]) _settings = self._memobj.dtmf[idx] _settings.memory = newval continue oldval = getattr(_settings, setting) newval = element.value if setting == "arts_cwid_alpha": newval = self._encode_chars(newval) elif setting == "open_message": newval = self._encode_chars(newval, 6) elif setting == "password": newval = self._encode_chars(newval, 4) setattr(_settings, setting, newval) except Exception: raise chirp-20240224/chirp/drivers/retevis_rt98.py0000644000175000017500000014513414540610211017542 0ustar hibbyhibby# Copyright 2021 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp import errors from chirp import memmap from chirp import util from chirp.settings import RadioSettingGroup, RadioSetting, RadioSettings, \ RadioSettingValueList, RadioSettingValueString, RadioSettingValueBoolean, \ RadioSettingValueInteger LOG = logging.getLogger(__name__) # # Chirp Driver for Retevis RT98 models: RT98V (136-174 MHz) # RT98U (400-490 MHz) # RT98W (66-88 MHz) # # # # Global Parameters # TONES = [62.5] + list(chirp_common.TONES) TMODES = ['', 'Tone', 'DTCS'] DUPLEXES = ['', '+', '-'] TXPOWER_LOW = 0x00 TXPOWER_MED = 0x01 TXPOWER_HIGH = 0x02 DUPLEX_NOSPLIT = 0x00 DUPLEX_POSSPLIT = 0x01 DUPLEX_NEGSPLIT = 0x02 CHANNEL_WIDTH_12d5kHz = 0x00 CHANNEL_WIDTH_20kHz = 0x01 CHANNEL_WIDTH_25kHz = 0x02 TUNING_STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 30.0, 50.0] POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5), chirp_common.PowerLevel("Mid", watts=10), chirp_common.PowerLevel("High", watts=15)] PMR_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=0.5), ] FREENET_POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1), ] PMR_FREQS = [446006250, 446018750, 446031250, 446043750, 446056250, 446068750, 446081250, 446093750, 446106250, 446118750, 446131250, 446143750, 446156250, 446168750, 446181250, 446193750] FREENET_FREQS = [149025000, 149037500, 149050000, 149087500, 149100000, 149112500] CROSS_MODES = ["Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] LIST_STEP = [str(x) for x in TUNING_STEPS] LIST_TIMEOUT = ["Off"] + ["%s min" % x for x in range(1, 31)] LIST_APO = ["Off", "30 min", "1 hr", "2 hrs"] LIST_SQUELCH = ["Off"] + ["Level %s" % x for x in range(1, 10)] LIST_DISPLAY_MODE = ["Channel", "Frequency", "Name"] LIST_AOP = ["Manual", "Auto"] LIST_STE_TYPE = ["Off", "Silent", "120 Degree", "180 Degree", "240 Degree"] LIST_STE_FREQ = ["Off", "55.2 Hz", "259.2 Hz"] LIST_VFOMR = ["MR", "VFO"] LIST_SCAN = ["TO", "CO", "SE"] LIST_PRIORITY_CH = ["Off", "Priority Channel 1", "Priority Channel 2", "Priority Channel 1 + Priority Channel 2"] LIST_REVERT_CH = ["Selected", "Selected + TalkBack", "Priority Channel 1", "Priority Channel 2", "Last Called", "Last Used", "Priority Channel 1 + TalkBack", "Priority Channel 2 + TalkBack"] LIST_TIME50 = ["0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "0.7", "0.8", "0.9", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "1.6", "1.7", "1.8", "1.9", "2.0", "2.1", "3.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8", "2.9", "3.0", "3.1", "3.2", "3.3", "3.4", "3.5", "3.6", "3.7", "3.8", "3.9", "4.0", "4.1", "4.2", "4.3", "4.4", "4.5", "4.6", "4.7", "4.8", "4.9", "5.0"] LIST_TIME46 = LIST_TIME50[4:] LIST_RT98V_MODES = ["FreeNet", "COM", "COMII"] LIST_RT98U_MODES = ["PMR", "COM", "COMII"] LIST_RT98W_MODES = ["", "", "", "", "", "", "COM"] LIST_RT98V_FREQS = ["Rx(149 - 149.2 MHz) Tx(149 - 149.2 MHz)", "Rx(136 - 174 MHz) Tx(136 - 174 MHz)", "Rx(147 - 174 MHz) Tx(147 - 174 MHz)"] LIST_RT98U_FREQS = ["Rx(446 - 446.2 MHz) Tx(446 - 446.2 MHz)", "Rx(400 - 470 MHz) Tx(400 - 470 MHz)", "Rx(450 - 470 MHz) Tx(450 - 470 MHz)"] LIST_RT98W_FREQS = ["", "", "", "", "", "", "Rx(66 - 88 MHz) Tx(66 - 88 MHz)"] # RT98 memory map # section: 1 Channel Bank # description of channel bank (199 channels , range 1-199) # Each 32 Byte (0x20 hex) record: # bytes:bit type description # --------------------------------------------------------------------------- # 4 bbcd freq[4] receive frequency in packed binary coded # decimal # 4 bbcd offset[4] transceive offset in packed binary coded # decimal (note: +/- direction set by # 'duplex' field) # 1 u8 unknown0 # 1 u8 # :1 reverse:1 reverse flag, 0=off, 1=on (reverses # transmit and receive frequencies) # :1 txoff:1 transmitt off flag, 0=transmit, 1=do not # transmit # :2 power:2 transmit power setting, value range 0-2, # 0=low, 1=middle, 2=high # :2 duplex:2 duplex settings, 0=simplex, 1=plus (+) # offset, 2=minus(-) offset (see offset field) # :2 channel_width:2 channel spacing, 0=12.5kHz, 1=20kHz, 2=25kHz # 1 u8 # :2 unknown1:2 # :1 talkaround:1 talkaround flag, 0=off, 1=on # (bypasses repeater) # :1 squelch_mode:1 squelch mode flag, 0=carrier, 1=ctcss/dcs # :1 rxdcsextra:1 use with rxcode for index of rx DCS to use # :1 rxinv:1 inverse DCS rx polarity flag, 0=N, 1=I # :1 txdcsextra:1 use with txcode for index of tx DCS to use # :1 txinv:1 inverse DCS tx polarity flag, 0=N, 1=I # 1 u8 # :4 unknown2:4 # :2 rxtmode:2 rx tone mode, value range 0-2, 0=none, # 1=CTCSS, 2=DCS (ctcss tone in field rxtone) # :2 txtmode:2 tx tone mode, value range 0-2, 0=none, # 1=CTCSS, 3=DCS (ctcss tone in field txtone) # 1 u8 # :2 unknown3:2 # :6 txtone:6 tx ctcss tone, menu index # 1 u8 # :2 unknown4:2 # :6 rxtone:6 rx ctcss tone, menu index # 1 u8 txcode ?, not used for ctcss # 1 u8 rxcode ?, not used for ctcss # 1 u8 # :6 unknown5:6 # :1 busychannellockout:1 busy channel lockout flag, 0=off, 1=enabled # :1 unknown6:1 # 6 char name[6] 6 byte char string for channel name # 9 u8 unknown7[9] # MEM_FORMAT = """ // #seekto 0x0000; struct { bbcd freq[4]; bbcd offset[4]; u8 unknown0; u8 reverse:1, tx_off:1, txpower:2, duplex:2, channel_width:2; u8 unknown1:2, talkaround:1, squelch_mode:1, rxdcsextra:1, rxinv:1, txdcsextra:1, txinv:1; u8 unknown2:4, rxtmode:2, txtmode:2; u8 unknown3:2, txtone:6; u8 unknown4:2, rxtone:6; u8 txcode; u8 rxcode; u8 unknown5:6, busychannellockout:1, unknown6:1; char name[6]; u8 unknown7[9]; } memory[199]; """ # RT98 memory map # section: 2 and 3 Channel Set/Skip Flags # # Channel Set (starts 0x3240) : Channel Set bit is value 0 if a memory # location in the channel bank is active. # Channel Skip (starts 0x3260): Channel Skip bit is value 0 if a memory # location in the channel bank is active. # # Both flag maps are a total 24 bytes in length, aligned on 32 byte records. # bit = 0 channel not set/skip, 1 is channel set/no skip # # to index a channel: # cbyte = channel / 8 ; # cbit = channel % 8 ; # setflag = csetflag[cbyte].c[cbit] ; # skipflag = cskipflag[cbyte].c[cbit] ; # # channel range is 1-199, range is 32 bytes (last 7 unknown) # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x3240; struct { bit c[8]; } csetflag[32]; // #seekto 0x3260; struct { bit c[8]; } cskipflag[32]; """ # RT98 memory map # section: 4 Startup Label # # bytes:bit type description # --------------------------------------------------------------------------- # 6 char start_label[6] label displayed at startup (usually # your call sign) # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x3300; struct { char startname[6]; } slabel; """ # RT98 memory map # section: 5, 6 and 7 Radio Options # used to set a number of radio options # # description of function setup options, starting at 0x3310 (settings3) # # bytes:bit type description # --------------------------------------------------------------------------- # 1 u8 # :6 unknown:6 # :2 bandlimit_3310:2 frequency ranges, range 0-2, # 0=freenet(vhf) or pmr(uhf), 1=com, 2=comii # rt98v - 00 FreeNet Rx(149 - 149.2 MHz) Tx(149 - 149.2 MHz) # 01 COM Rx(136 - 174 MHz) Tx(136 - 174 MHz) # 02 COMII Rx(147 - 174 MHz) Tx(147 - 174 MHz) # rt98u - 00 PMR Rx(446 - 446.2 MHz) Tx(446 - 446.2 MHz) # 01 COM Rx(400 - 470 MHz) Tx(400 - 470 MHz) # 02 COMII Rx(450 - 470 MHz) Tx(450 - 470 MHz) # 1 u8 ch_number; channel number, range 1-199 # 1 u8 # :7 unknown_3312:7 # :1 vfomr:1 vfo/mr mode, range 0-1, 0=mr, 1=vfo # only S/N:1907*********** # # description of function setup options, starting at 0x3340 (settings) # # bytes:bit type description # --------------------------------------------------------------------------- # 1 u8 # :4 unknown_3340:4 # :4 tuning_step:4 tuning step, menu index value from 0-8 # 2.5, 5, 6.25, 10, 12.5, 20, 25, 30, 50 # 1 u8 # :7 unknown_3341:7 # :1 beep:1 beep mode, range 0-1, 0=off, 1=on # 1 u8 # :3 unknown_3342:3 # :5 timeout_timer:5 timeout timer, range off (no timeout), # 1-30 minutes # 1 u8 # :6 unknown_3343:6 # :2 auto_power_off:2 auto power off, range 0-3, off, 30min, # 1hr, 2hr # 1 u8 # :4 unknown_3344:4 # :4 squelch:4 squelch level, range off, 1-9 # 1 u8 # :3 unknown_3345:3 # :5 volume:5 volume level, range 1-30 (no zero) # 1 u8 # :6 unknown_3346:6 # :2 scan_revive:2 scan revive method, range 0-2, 0=to, # 1=co, 2=se # only S/N:1907*********** # 1 u8 unknown_3347 # 1 u8 0x3348 [12] # :6 unknown_3348:6 # :2 display_mode display mode, range 0-2, 0=channel, # 1=frequency, 2=name # 1 u8 # :7 unknown_3349:7 # :1 auto_power_on:1 auto power on, range 0-1, 0=manual, # 1=auto # 1 u8 # :3 unknown_334A:3 # :5 mic_gain:5 mic gain, range 1-30 (no zero) # 1 u8 # :5 unknown_334C:5 # :3 ste_type:3 ste type, range 0-4, 0=off, 1=silent, # 2=120degree, 3=180degree, 4=240degree # 1 u8 # :7 unknown_334D:7 # :1 ste_frequency:1 ste frequency, range 0-2, 0=off, # 1=55.2Hz, 2=259.2Hz # 1 u8 # :2 unknown_0x334E:2 # :1 forbid_setting:1 forbid setting(optional function), # range 0-1, 0=disabled, 1=enabled # :1 forbid_initialize:1 forbid initialize operate, range 0-1, # 0=enabled, 1=disabled (inverted) # :1 save_chan_param:1 save channel parameters, range 0-1, # 0=disabled, 1=enabled # :1 forbid_chan_menu:1 forbid channel menu, range 0-1, # 0=disabled, 1=enabled # :1 sql_key_function:1 sql key function, range 0-1, # 0=squelch off momentary, 1=squelch off # :1 unknown:1 # # description of function setup options, starting at 0x3380 (settings2) # # bytes:bit type description # --------------------------------------------------------------------------- # 1 u8 # :7 unknown_3380:7 # :1 scan_mode:1 scan mode, range 0-1, 0=off, 1=on # 1 u8 # :6 unknown_3381:6 # :2 priority_ch:2 priority channel, range 0-3, 0=off, # 1=priority channel 1, # 2=priority channel 2, # 3=priority channel 1 + priority channel 2 # 1 u8 priority_ch1 priority channel 1 number, range 1-199 # 1 u8 priority_ch2 priority channel 2 number, range 1-199 # 1 u8 # :4 unknown_3384:4 # :4 revert_ch:4 revert channel, range 0-3, 0=selected, # 1=selected + talkback, 2=last called, # 3=last used # 1 u8 look_back_time_a look back time a, range 0-45 # 1 u8 look_back_time_b look back time b, range 0-45 # 1 u8 dropout_delay_time dropout delay time, range 0-49 # 1 u8 dwell_time dwell time, range 0-49 # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x3310; struct { u8 bandlimit; u8 ch_number; u8 unknown_3312:7, vfomr:1; } settings3; """ MEM_FORMAT = MEM_FORMAT + """ #seekto 0x3340; struct { u8 unknown_3340:4, tuning_step:4; u8 unknown_3341:7, beep:1; u8 unknown_3342:3, timeout_timer:5; u8 unknown_3343:6, auto_power_off:2; u8 unknown_3344:4, squelch:4; u8 unknown_3345:3, volume:5; u8 unknown_3346:6, scan_resume:2; u8 unknown_3347; u8 unknown_3348:6, display_mode:2; u8 unknown_3349:7, auto_power_on:1; u8 unknown_334A:3, mic_gain:5; u8 unknown_334B; u8 unknown_334C:5, ste_type:3; u8 unknown_334D:6, ste_frequency:2; u8 unknown_334E:1, forbid_setting:1, unknown1:1, forbid_initialize:1, save_chan_param:1, forbid_chan_menu:1, sql_key_function:1, unknown2:1; } settings; """ MEM_FORMAT = MEM_FORMAT + """ #seekto 0x3380; struct { u8 unknown_3380:7, scan_mode:1; u8 unknown_3381:6, priority_ch:2; u8 priority_ch1; u8 priority_ch2; u8 unknown_3384:4, revert_ch:4; u8 look_back_time_a; u8 look_back_time_b; u8 dropout_delay_time; u8 dwell_time; } settings2; """ # RT98 memory map # section: 8 Embedded Messages # # bytes:bit type description # --------------------------------------------------------------------------- # 6 char radio_type[5] radio type, vhf=rt98v, uhf=rt98u # 2 u8 unknown1[2] # 4 char mcu_version[4] mcu version, [x.xx] # 2 u8 unknown2[2] # 1 u8 mode rt98u mode: 0=pmr, 1=com, 2=comii # rt98v mode: 0=freenet, 1=com, 2=comii # 1 u8 unknown3 # 10 u8 unused1[10] # 4 u8 unknown4[4] # 3 u8 unused2[3] # 16 u8 unknown5[16] # 10 char date_mfg[16] date manufactured, [yyyy-mm-dd] # MEM_FORMAT = MEM_FORMAT + """ #seekto 0x3D00; struct { char radio_type[7]; char mcu_version[4]; u8 unknown2[2]; u8 mode; u8 unknown3; u8 unused1[10]; u8 unknown4[4]; u8 unused2[3]; u8 unknown5[16]; char date_mfg[10]; } embedded_msg; """ # Format for the version messages returned by the radio VER_FORMAT = ''' u8 hdr; char model[7]; u8 bandlimit; char version[6]; u8 ack; ''' # Radio supports upper case and symbols CHARSET_ASCII_PLUS = chirp_common.CHARSET_UPPER_NUMERIC + '- ' # Band limits as defined by the band byte in ver_response, defined in Hz, for # VHF and UHF, used for RX and TX. RT98V_BAND_LIMITS = {0x00: [(149000000, 149200000)], 0x01: [(136000000, 174000000)], 0x02: [(147000000, 174000000)]} RT98U_BAND_LIMITS = {0x00: [(446000000, 446200000)], 0x01: [(400000000, 470000000)], 0x02: [(450000000, 470000000)]} RT98W_BAND_LIMITS = {0x00: [(66000000, 88000000)], 0x01: [(66000000, 88000000)], 0x02: [(66000000, 88000000)], 0x03: [(66000000, 88000000)], 0x04: [(66000000, 88000000)], 0x05: [(66000000, 88000000)], 0x06: [(66000000, 88000000)]} # Get band limits from a band limit value def get_band_limits_Hz(radio_type, limit_value): if str(radio_type).rstrip("\00") in ["RT98U", "AT-779U"]: if limit_value not in RT98U_BAND_LIMITS: limit_value = 0x01 LOG.warning('Unknown band limit value 0x%02x, default to 0x01') bandlimitfrequencies = RT98U_BAND_LIMITS[limit_value] elif str(radio_type).rstrip("\00") in ["RT98V", "AT-779V"]: if limit_value not in RT98V_BAND_LIMITS: limit_value = 0x01 LOG.warning('Unknown band limit value 0x%02x, default to 0x01') bandlimitfrequencies = RT98V_BAND_LIMITS[limit_value] elif str(radio_type).rstrip("\00") in ["RT98W", "AT-779W"]: if limit_value not in RT98W_BAND_LIMITS: limit_value = 0x06 LOG.warning('Unknown band limit value 0x%02x, default to 0x06') bandlimitfrequencies = RT98W_BAND_LIMITS[limit_value] return bandlimitfrequencies def _echo_write(radio, data): try: radio.pipe.write(data) radio.pipe.read(len(data)) except Exception as e: LOG.error("Error writing to radio: %s" % e) raise errors.RadioError("Unable to write to radio") def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def _read(radio, length): try: data = radio.pipe.read(length) except Exception as e: _finish(radio) LOG.error("Error reading from radio: %s" % e) raise errors.RadioError("Unable to read from radio") if len(data) != length: _finish(radio) LOG.error("Short read from radio (%i, expected %i)" % (len(data), length)) LOG.debug(util.hexprint(data)) raise errors.RadioError("Short read from radio") return data # strip trailing 0x00 to convert a string returned by bitwise.parse into a # python string def cstring_to_py_string(cstring): return "".join(c for c in cstring if c != '\x00') # Check the radio version reported to see if it's one we support, # returns bool version supported, and the band index def check_ver(ver_response, allowed_types): ''' Check the returned radio version is one we approve of ''' LOG.debug('ver_response = ') LOG.debug(util.hexprint(ver_response)) resp = bitwise.parse(VER_FORMAT, ver_response) verok = False if resp.hdr == 0x49 and resp.ack == 0x06: model, version = [cstring_to_py_string(bitwise.get_string(s)).strip() for s in (resp.model, resp.version)] LOG.debug('radio model: \'%s\' version: \'%s\'' % (model, version)) LOG.debug('allowed_types = %s' % allowed_types) if model in allowed_types: LOG.debug('model in allowed_types') if version in allowed_types[model]: LOG.debug('version in allowed_types[model]') verok = True else: _finish(radio) raise errors.RadioError('Failed to parse version response') return verok, str(resp.model), int(resp.bandlimit) def _ident(radio): radio.pipe.timeout = 1 _echo_write(radio, b"PROGRAM") response = radio.pipe.read(3) if response != b"QX\06": _finish(radio) LOG.debug("Response was :\n%s" % util.hexprint(response)) raise errors.RadioError("Radio did not respond. Check connection.") _echo_write(radio, b"\x02") ver_response = radio.pipe.read(16) LOG.debug(util.hexprint(ver_response)) verok, model, bandlimit = check_ver(ver_response, radio.ALLOWED_RADIO_TYPES) if not verok: _finish(radio) raise errors.RadioError( 'Radio version not in allowed list for %s-%s: %s' % (radio.VENDOR, radio.MODEL, util.hexprint(ver_response))) return model, bandlimit def _send(radio, cmd, addr, length, data=None): frame = struct.pack(">cHb", cmd, addr, length) if data: frame += data frame += bytes([_checksum(frame[1:])]) frame += b"\x06" _echo_write(radio, frame) LOG.debug("Sent:\n%s" % util.hexprint(frame)) if data: result = radio.pipe.read(1) if result != b"\x06": _finish(radio) LOG.debug("Ack was: %s" % repr(result)) raise errors.RadioError("Radio did not accept block at %04x" % addr) return result = _read(radio, length + 6) LOG.debug("Got:\n%s" % util.hexprint(result)) header = result[:4] data = result[4:-2] ack = result[-1:] if ack != b"\x06": _finish(radio) LOG.debug("Ack was: %s" % repr(ack)) raise errors.RadioError("Radio NAK'd block at %04x" % addr) _cmd, _addr, _length = struct.unpack(">cHb", header) if _addr != addr or _length != _length: _finish(radio) LOG.debug("Expected/Received:") LOG.debug(" Length: %02x/%02x" % (length, _length)) LOG.debug(" Addr: %04x/%04x" % (addr, _addr)) raise errors.RadioError("Radio send unexpected block") cs = _checksum(result[1:-2]) if cs != result[-2]: _finish(radio) LOG.debug("Calculated: %02x" % cs) LOG.debug("Actual: %02x" % result[-2]) raise errors.RadioError("Block at 0x%04x failed checksum" % addr) return data def _finish(radio): endframe = b"\x45\x4E\x44" _echo_write(radio, endframe) result = radio.pipe.read(1) if result != b"\x06": LOG.error("Got:\n%s" % util.hexprint(result)) raise errors.RadioError("Radio did not finish cleanly") def do_download(radio): _ident(radio) _memobj = None data = b"" for addr in range(0, radio._memsize, 0x10): block = _send(radio, b'R', addr, 0x10) data += block status = chirp_common.Status() status.cur = len(data) status.max = radio._memsize status.msg = "Downloading from radio" radio.status_fn(status) _finish(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): model, bandlimit = _ident(radio) _embedded = radio._memobj.embedded_msg if model != str(_embedded.radio_type): LOG.warning('radio and image model types differ') LOG.warning('model type (radio): %s' % str(model)) LOG.warning('model type (image): %s' % str(_embedded.radio_type)) _finish(radio) msg = ("The upload was stopped because the radio type " "of the image (%s) does not match that " "of the radio (%s).") raise errors.RadioError(msg % (str(_embedded.radio_type), str(model))) if bandlimit != int(_embedded.mode): if str(_embedded.radio_type).rstrip("\00") in ["RT98U", "AT-779U"]: image_band_limits = LIST_RT98U_FREQS[int(_embedded.mode)] if str(_embedded.radio_type).rstrip("\00") in ["RT98V", "AT-779V"]: image_band_limits = LIST_RT98V_FREQS[int(_embedded.mode)] if str(_embedded.radio_type).rstrip("\00") in ["RT98W", "AT-779W"]: image_band_limits = LIST_RT98W_FREQS[int(_embedded.mode)] if str(model).rstrip("\00") in ["RT98U", "AT-779U"]: radio_band_limits = LIST_RT98U_FREQS[int(bandlimit)] if str(model).rstrip("\00") in ["RT98V", "AT-779V"]: radio_band_limits = LIST_RT98V_FREQS[int(bandlimit)] if str(model).rstrip("\00") in ["RT98W", "AT-779W"]: radio_band_limits = LIST_RT98W_FREQS[int(bandlimit)] LOG.warning('radio and image band limits differ') LOG.warning('image band limits: %s' % image_band_limits) LOG.warning('radio band limits: %s' % radio_band_limits) _finish(radio) msg = ("The upload was stopped because the band limits " "of the image (%s) does not match that " "of the radio (%s).") raise errors.RadioError(msg % (image_band_limits, radio_band_limits)) try: for start, end in radio._ranges: for addr in range(start, end, 0x10): block = radio._mmap[addr:addr+0x10] _send(radio, b'W', addr, len(block), block) status = chirp_common.Status() status.cur = addr status.max = end status.msg = "Uploading to Radio" radio.status_fn(status) _finish(radio) except errors.RadioError: raise except Exception as e: _finish(radio) raise errors.RadioError('Failed to upload to radio: %s' % e) # # The base class, extended for use with other models # class Rt98BaseRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Retevis RT98 Base""" VENDOR = "Retevis" MODEL = "RT98 Base" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False _memsize = 0x3E00 _ranges = [(0x0000, 0x3310), (0x3320, 0x3390)] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("The Retevis RT98 driver is an beta version." "Proceed with Caution and backup your data") return rp def get_features(self): class FakeEmbedded(object): mode = 0 radio_type = 'RT98U' if self._memobj: _embedded = self._memobj.embedded_msg else: # If we have no memory object, take defaults for unit # test, make_supported, etc _embedded = FakeEmbedded() rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.can_odd_split = True rf.has_name = True if _embedded.mode == 0: # PMR or FreeNet rf.has_offset = False else: rf.has_offset = True rf.has_ctone = True rf.has_cross = True rf.has_tuning_step = False rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.valid_skips = ["", "S"] rf.memory_bounds = (1, 199) rf.valid_name_length = 6 if _embedded.mode == 0: # PMR or FreeNet rf.valid_duplexes = ['', 'off'] else: rf.valid_duplexes = DUPLEXES + ['split', 'off'] rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "- " rf.valid_modes = ['FM', 'NFM'] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = CROSS_MODES if _embedded.mode == 0: # PMR or FreeNet if str(_embedded.radio_type).rstrip("\00") == "RT98U": rf.valid_power_levels = PMR_POWER_LEVELS if str(_embedded.radio_type).rstrip("\00") == "RT98V": rf.valid_power_levels = FREENET_POWER_LEVELS else: rf.valid_power_levels = POWER_LEVELS rf.valid_tones = TONES rf.valid_dtcs_codes = chirp_common.ALL_DTCS_CODES try: rf.valid_bands = get_band_limits_Hz( str(_embedded.radio_type), int(_embedded.mode)) except TypeError: # If we're asked without memory loaded, assume the most permissive rf.valid_bands = get_band_limits_Hz(str(_embedded.radio_type), 1) except Exception as e: LOG.error('Failed to get band limits for RT98: %s' % e) rf.valid_bands = get_band_limits_Hz(str(_embedded.radio_type), 1) rf.valid_tuning_steps = TUNING_STEPS return rf # Do a download of the radio from the serial port def sync_in(self): self._mmap = do_download(self) self.process_mmap() # Do an upload of the radio to the serial port def sync_out(self): do_upload(self) def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) # Return a raw representation of the memory object, which # is very helpful for development def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def _get_dcs_index(self, _mem, which): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) return (int(extra) << 8) | int(base) def _set_dcs_index(self, _mem, which, index): base = getattr(_mem, '%scode' % which) extra = getattr(_mem, '%sdcsextra' % which) base.set_value(index & 0xFF) extra.set_value(index >> 8) # Extract a high-level memory object from the low-level memory map # This is called to populate a memory in the UI def get_memory(self, number): _embedded = self._memobj.embedded_msg # Get a low-level memory object mapped to the image _mem = self._memobj.memory[number - 1] # get flag info cbyte = (number - 1) / 8 cbit = 7 - ((number - 1) % 8) setflag = self._memobj.csetflag[cbyte].c[cbit] skipflag = self._memobj.cskipflag[cbyte].c[cbit] mem = chirp_common.Memory() mem.number = number # Set the memory number # We'll consider any blank (i.e. 0 MHz frequency) to be empty if _mem.freq == 0: mem.empty = True return mem if setflag == 0: mem.empty = True return mem if _mem.get_raw()[0] == b"\xFF": mem.empty = True return mem # set the name mem.name = str(_mem.name).rstrip() # Set the alpha tag # Convert your low-level frequency and offset to Hertz mem.freq = int(_mem.freq) * 10 mem.offset = int(_mem.offset) * 10 # Set the duplex flags if _mem.tx_off: # handle tx off mem.duplex = 'off' elif _mem.duplex == DUPLEX_POSSPLIT: mem.duplex = '+' elif _mem.duplex == DUPLEX_NEGSPLIT: mem.duplex = '-' elif _mem.duplex == DUPLEX_NOSPLIT: mem.duplex = '' elif _mem.duplex == DUPLEX_ODDSPLIT: mem.duplex = 'split' else: LOG.error('%s: get_mem: unhandled duplex: %02x' % (mem.name, _mem.duplex)) # Set the channel width if _mem.channel_width == CHANNEL_WIDTH_12d5kHz: mem.mode = 'NFM' elif _embedded.mode == 0: # PMR or FreeNet LOG.info('PMR and FreeNet channels must be Channel Width 12.5 kHz') mem.mode = 'NFM' elif _mem.channel_width == CHANNEL_WIDTH_25kHz: mem.mode = 'FM' elif _mem.channel_width == CHANNEL_WIDTH_20kHz: LOG.info( '%s: get_mem: promoting 20 kHz channel width to 25 kHz' % mem.name) mem.mode = 'FM' else: LOG.error('%s: get_mem: unhandled channel width: 0x%02x' % (mem.name, _mem.channel_width)) # set the power level if _embedded.mode == 0: # PMR or FreeNet if str(_embedded.radio_type).rstrip("\00") == "RT98U": LOG.info('using PMR power levels') _levels = PMR_POWER_LEVELS if str(_embedded.radio_type).rstrip("\00") == "RT98V": LOG.info('using FreeNet power levels') _levels = FREENET_POWER_LEVELS else: # COM or COMII LOG.info('using general power levels') _levels = POWER_LEVELS if _mem.txpower == TXPOWER_LOW: mem.power = _levels[0] elif _embedded.mode == 0: # PMR or FreeNet LOG.info('FreeNet or PMR channel is not set to TX Power Low') LOG.info('Setting channel to TX Power Low') mem.power = _levels[0] elif _mem.txpower == TXPOWER_MED: mem.power = _levels[1] elif _mem.txpower == TXPOWER_HIGH: mem.power = _levels[2] else: LOG.error('%s: get_mem: unhandled power level: 0x%02x' % (mem.name, _mem.txpower)) # CTCSS Tones and DTCS Codes rxtone = txtone = None rxmode = TMODES[_mem.rxtmode] txmode = TMODES[_mem.txtmode] if rxmode == "Tone": rxtone = TONES[_mem.rxtone] elif rxmode == "DTCS": rxtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index( _mem, 'rx')] if txmode == "Tone": txtone = TONES[_mem.txtone] elif txmode == "DTCS": txtone = chirp_common.ALL_DTCS_CODES[self._get_dcs_index( _mem, 'tx')] rxpol = _mem.rxinv and "R" or "N" txpol = _mem.txinv and "R" or "N" chirp_common.split_tone_decode(mem, (txmode, txtone, txpol), (rxmode, rxtone, rxpol)) # Check if this memory is in the scan enabled list mem.skip = "S" if skipflag == 0 else "" # Extra mem.extra = RadioSettingGroup("extra", "Extra") rs = RadioSettingValueBoolean(bool(_mem.busychannellockout)) rset = RadioSetting("busychannellockout", "Busy channel lockout", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(bool(_mem.reverse)) rset = RadioSetting("reverse", "Reverse", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(bool(_mem.talkaround)) rset = RadioSetting("talkaround", "Talk around", rs) mem.extra.append(rset) rs = RadioSettingValueBoolean(bool(_mem.squelch_mode)) rset = RadioSetting("squelch_mode", "Squelch mode", rs) mem.extra.append(rset) return mem # Store details about a high-level memory to the memory map # This is called when a user edits a memory in the UI def set_memory(self, mem): _embedded = self._memobj.embedded_msg # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number - 1] cbyte = (mem.number - 1) / 8 cbit = 7 - ((mem.number - 1) % 8) if mem.empty: self._memobj.csetflag[cbyte].c[cbit] = 0 self._memobj.cskipflag[cbyte].c[cbit] = 0 _mem.set_raw("\xff" * 32) return _mem.set_raw("\x00" * 32) # FreeNet and PMR radio types if _embedded.mode == 0: # PMR or FreeNet mem.mode = 'NFM' mem.offset = 0 # FreeNet if str(_embedded.radio_type).rstrip("\00") == "RT98V": if mem.number >= 1 and mem.number <= 6: FREENET_FREQ = FREENET_FREQS[mem.number - 1] mem.freq = FREENET_FREQ else: _mem.tx_off = 1 mem.duplex = 'off' # PMR if str(_embedded.radio_type).rstrip("\00") == "RT98U": if mem.number >= 1 and mem.number <= 16: PMR_FREQ = PMR_FREQS[mem.number - 1] mem.freq = PMR_FREQ else: _mem.tx_off = 1 mem.duplex = 'off' # set the occupied bitfield self._memobj.csetflag[cbyte].c[cbit] = 1 # set the scan add bitfield self._memobj.cskipflag[cbyte].c[cbit] = 0 if (mem.skip == "S") else 1 _mem.freq = mem.freq / 10 # Convert to low-level frequency _mem.offset = mem.offset / 10 # Convert to low-level frequency # Store the alpha tag _mem.name = mem.name.ljust(6)[:6] # Store the alpha tag # Set duplex bitfields _mem.tx_off = 0 if mem.duplex == 'off': # handle tx off _mem.tx_off = 1 elif mem.duplex == '+': _mem.duplex = DUPLEX_POSSPLIT elif mem.duplex == '-': _mem.duplex = DUPLEX_NEGSPLIT elif mem.duplex == '': _mem.duplex = DUPLEX_NOSPLIT elif mem.duplex == 'split': diff = mem.offset - mem.freq _mem.duplex = DUPLEXES.index("-") \ if diff < 0 else DUPLEXES.index("+") _mem.offset = abs(diff) / 10 else: LOG.error('%s: set_mem: unhandled duplex: %s' % (mem.name, mem.duplex)) # Set the channel width - remember we promote 20 kHz channels to FM # on import, so don't handle them here if mem.mode == 'FM': _mem.channel_width = CHANNEL_WIDTH_25kHz elif mem.mode == 'NFM': _mem.channel_width = CHANNEL_WIDTH_12d5kHz else: LOG.error('%s: set_mem: unhandled mode: %s' % ( mem.name, mem.mode)) # CTCSS Tones and DTCS Codes ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = chirp_common.split_tone_encode(mem) _mem.txtmode = TMODES.index(txmode) _mem.rxtmode = TMODES.index(rxmode) if txmode == "Tone": _mem.txtone = TONES.index(txtone) elif txmode == "DTCS": self._set_dcs_index(_mem, 'tx', chirp_common.ALL_DTCS_CODES.index(txtone)) _mem.squelch_mode = False if rxmode == "Tone": _mem.rxtone = TONES.index(rxtone) _mem.squelch_mode = True elif rxmode == "DTCS": self._set_dcs_index(_mem, 'rx', chirp_common.ALL_DTCS_CODES.index(rxtone)) _mem.squelch_mode = True _mem.txinv = txpol == "R" _mem.rxinv = rxpol == "R" # set the power level if _embedded.mode == 0: # PMR or FreeNet if str(_embedded.radio_type).rstrip("\00") == "RT98U": LOG.info('using PMR power levels') _levels = PMR_POWER_LEVELS if str(_embedded.radio_type).rstrip("\00") == "RT98V": LOG.info('using FreeNet power levels') _levels = FREENET_POWER_LEVELS else: # COM or COMII LOG.info('using general power levels') _levels = POWER_LEVELS if mem.power is None: _mem.txpower = TXPOWER_HIGH elif mem.power == _levels[0]: _mem.txpower = TXPOWER_LOW elif _embedded.mode == 0: # PMR or FreeNet LOG.info('FreeNet or PMR channel is not set to TX Power Low') LOG.info('Setting channel to TX Power Low') _mem.txpower = TXPOWER_LOW elif mem.power == _levels[1]: _mem.txpower = TXPOWER_MED elif mem.power == _levels[2]: _mem.txpower = TXPOWER_HIGH else: LOG.error('%s: set_mem: unhandled power level: %s' % (mem.name, mem.power)) # extra settings for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def _get_settings(self): _embedded = self._memobj.embedded_msg _settings = self._memobj.settings _settings2 = self._memobj.settings2 _settings3 = self._memobj.settings3 _slabel = self._memobj.slabel function = RadioSettingGroup("function", "Function Setup") group = RadioSettings(function) # Function Setup # MODE SET rs = RadioSettingValueList(LIST_DISPLAY_MODE, LIST_DISPLAY_MODE[_settings.display_mode]) rset = RadioSetting("display_mode", "Display Mode", rs) function.append(rset) if "AT-779" in str(_embedded.radio_type): rs = RadioSettingValueList(LIST_VFOMR, LIST_VFOMR[_settings3.vfomr]) rset = RadioSetting("settings3.vfomr", "VFO/MR", rs) function.append(rset) rs = RadioSettingValueInteger(1, 199, _settings3.ch_number + 1) rset = RadioSetting("settings3.ch_number", "Channel Number", rs) function.append(rset) # DISPLAY SET def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered val = RadioSettingValueString(0, 6, _filter(_slabel.startname)) rs = RadioSetting("slabel.startname", "Startup Label", val) function.append(rs) # VOL SET rs = RadioSettingValueBoolean(bool(_settings.beep)) rset = RadioSetting("beep", "Beep Prompt", rs) function.append(rset) rs = RadioSettingValueInteger(1, 30, _settings.volume) rset = RadioSetting("volume", "Volume Level", rs) function.append(rset) rs = RadioSettingValueInteger(1, 16, _settings.mic_gain) rset = RadioSetting("mic_gain", "Mic Gain", rs) function.append(rset) # ON/OFF SET rs = RadioSettingValueList(LIST_APO, LIST_APO[_settings.auto_power_off]) rset = RadioSetting("auto_power_off", "Auto Power Off", rs) function.append(rset) rs = RadioSettingValueList(LIST_AOP, LIST_AOP[_settings.auto_power_on]) rset = RadioSetting("auto_power_on", "Power On Method", rs) function.append(rset) # STE SET rs = RadioSettingValueList(LIST_STE_FREQ, LIST_STE_FREQ[_settings.ste_frequency]) rset = RadioSetting("ste_frequency", "STE Frequency", rs) function.append(rset) rs = RadioSettingValueList(LIST_STE_TYPE, LIST_STE_TYPE[_settings.ste_type]) rset = RadioSetting("ste_type", "STE Type", rs) function.append(rset) # FUNCTION SET rs = RadioSettingValueList(LIST_STEP, LIST_STEP[_settings.tuning_step]) rset = RadioSetting("tuning_step", "Tuning Step", rs) function.append(rset) rs = RadioSettingValueList(LIST_SQUELCH, LIST_SQUELCH[_settings.squelch]) rset = RadioSetting("squelch", "Squelch Level", rs) function.append(rset) if "AT-779" in str(_embedded.radio_type): rs = RadioSettingValueList(LIST_SCAN, LIST_SCAN[_settings.scan_resume]) rset = RadioSetting("scan_resume", "Frequency Scan", rs) function.append(rset) rs = RadioSettingValueBoolean(bool(_settings.sql_key_function)) rset = RadioSetting("sql_key_function", "SQL Key Function", rs) function.append(rset) rs = RadioSettingValueList(LIST_TIMEOUT, LIST_TIMEOUT[_settings.timeout_timer]) rset = RadioSetting("timeout_timer", "Timeout Timer", rs) function.append(rset) # uncategorized rs = RadioSettingValueBoolean(bool(_settings.save_chan_param)) rset = RadioSetting("save_chan_param", "Save Channel Parameters", rs) function.append(rset) rs = RadioSettingValueBoolean(bool(_settings.forbid_chan_menu)) rset = RadioSetting("forbid_chan_menu", "Forbid Channel Menu", rs) function.append(rset) rs = RadioSettingValueBoolean(bool(not _settings.forbid_initialize)) rset = RadioSetting("forbid_initialize", "Forbid Initialize", rs) function.append(rset) rs = RadioSettingValueBoolean(bool(_settings.forbid_setting)) rset = RadioSetting("forbid_setting", "Forbid Setting", rs) function.append(rset) # Information Of Scanning Channel scanning = RadioSettingGroup("scanning", "Scanning Setup") group.append(scanning) rs = RadioSettingValueBoolean(bool(_settings2.scan_mode)) rset = RadioSetting("settings2.scan_mode", "Scan Mode", rs) scanning.append(rset) rs = RadioSettingValueList(LIST_PRIORITY_CH, LIST_PRIORITY_CH[_settings2.priority_ch]) rset = RadioSetting("settings2.priority_ch", "Priority Channel", rs) scanning.append(rset) rs = RadioSettingValueInteger(1, 199, _settings2.priority_ch1 + 1) rset = RadioSetting("settings2.priority_ch1", "Priority Channel 1", rs) scanning.append(rset) rs = RadioSettingValueInteger(1, 199, _settings2.priority_ch2 + 1) rset = RadioSetting("settings2.priority_ch2", "Priority Channel 2", rs) scanning.append(rset) rs = RadioSettingValueList(LIST_REVERT_CH, LIST_REVERT_CH[_settings2.revert_ch]) rset = RadioSetting("settings2.revert_ch", "Revert Channel", rs) scanning.append(rset) rs = RadioSettingValueList(LIST_TIME46, LIST_TIME46[_settings2.look_back_time_a]) rset = RadioSetting("settings2.look_back_time_a", "Look Back Time A", rs) scanning.append(rset) rs = RadioSettingValueList(LIST_TIME46, LIST_TIME46[_settings2.look_back_time_b]) rset = RadioSetting("settings2.look_back_time_b", "Look Back Time B", rs) scanning.append(rset) rs = RadioSettingValueList(LIST_TIME50, LIST_TIME50[_settings2.dropout_delay_time]) rset = RadioSetting("settings2.dropout_delay_time", "Dropout Delay Time", rs) scanning.append(rset) rs = RadioSettingValueList(LIST_TIME50, LIST_TIME50[_settings2.dwell_time]) rset = RadioSetting("settings2.dwell_time", "Dwell Time", rs) scanning.append(rset) # Embedded Message embedded = RadioSettingGroup("embedded", "Embedded Message") group.append(embedded) rs = RadioSettingValueString(0, 7, _filter(_embedded.radio_type)) rs.set_mutable(False) rset = RadioSetting("embedded_msg.radio_type", "Radio Type", rs) embedded.append(rset) if str(_embedded.radio_type).rstrip("\00") in ["RT98V", "AT-779V"]: options = LIST_RT98V_MODES elif str(_embedded.radio_type).rstrip("\00") in ["RT98W", "AT-779W"]: options = LIST_RT98W_MODES else: options = LIST_RT98U_MODES rs = RadioSettingValueList(options, options[_embedded.mode]) rs.set_mutable(False) rset = RadioSetting("embedded_msg.mode", "Mode", rs) embedded.append(rset) # frequency if str(_embedded.radio_type).rstrip("\00") in ["RT98V", "AT-779V"]: options = LIST_RT98V_FREQS elif str(_embedded.radio_type).rstrip("\00") in ["RT98W", "AT-779W"]: options = LIST_RT98W_FREQS else: options = LIST_RT98U_FREQS rs = RadioSettingValueList(options, options[_settings3.bandlimit]) rs.set_mutable(False) rset = RadioSetting("settings3.bandlimit", "Frequency", rs) embedded.append(rset) rs = RadioSettingValueString(0, 10, _filter(_embedded.date_mfg)) rs.set_mutable(False) rset = RadioSetting("embedded_msg.date_mfg", "Production Date", rs) embedded.append(rset) rs = RadioSettingValueString(0, 4, _filter(_embedded.mcu_version)) rs.set_mutable(False) rset = RadioSetting("embedded_msg.mcu_version", "MCU Version", rs) embedded.append(rset) return group def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("failed to parse settings") traceback.print_exc() return None def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("using apply callback") element.run_apply_callback() elif setting == "ch_number": setattr(obj, setting, int(element.value) - 1) elif setting == "forbid_initialize": setattr(obj, setting, not int(element.value)) elif setting == "priority_ch1": setattr(obj, setting, int(element.value) - 1) elif setting == "priority_ch2": setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class Rt98Radio(Rt98BaseRadio): """Retevis RT98""" VENDOR = "Retevis" MODEL = "RT98" # Allowed radio types is a dict keyed by model of a list of version # strings ALLOWED_RADIO_TYPES = {'RT98V': ['V100'], 'RT98U': ['V100'], 'RT98W': ['V100'], 'AT-779V': ['V100'], 'AT-779U': ['V100'], 'AT-779W': ['V100'], } chirp-20240224/chirp/drivers/kg935g.py0000644000175000017500000023060214561124165016212 0ustar hibbyhibby# Wouxun KG-935G Driver # Updated to support the KG-935G Plus # Updated to support the KG-UV8H # melvin.terechenok@gmail.com # Copyright 2019 Pavel Milanes CO7WT # # Based on the work of Krystian Struzik # who figured out the crypt used and made possible the # Wuoxun KG-UV8D Plus driver, in which this work is based. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun KG-935G radio management module""" import struct import time import logging from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettingValueFloat, RadioSettingValueMap, RadioSettings, \ InvalidValueError LOG = logging.getLogger(__name__) CMD_ID = 128 # \x80 CMD_END = 129 # \x81 CMD_RD = 130 # \82 CMD_WR = 131 # \83 MEM_VALID = 158 # set up map of addresses to upload to known memory locations only # Add new regions as new settings are discovered # 1st entry is start address in hex # 2nd entry is write size (number of bytes to transfer in decimal (64-MAX)) # 3rd entry is write count # so 0x00, 64, 512 = start at 0x00 and write 64*512 bytes = 0 - 32768 # NOTE : It looks like the radio MUST have write # sizes in values of 1,2,4,8,16,32 or 64 bytes if using # a write count value of > 1. # OTHERWISE - it appears the radio gets out of sync # and the memory write is messed up # for that section config_map_935G = ( # map address, write size, write count # (0x00, 64, 512), #- Use for full upload testing (0x44, 32, 1), # Freq Limits (0x440, 8, 1), # Area Message (0x480, 8, 5), # Scan Groups (0x500, 8, 15), # Call Codes (0x580, 8, 15), # Call Names (0x600, 8, 5), # FM Presets (0x800, 64, 2), # settings (0x880, 16, 1), # VFO A (0x8C0, 16, 1), # VFO B (0x900, 64, 250), # Channel Memory 0-999 (0x4780, 32, 375), # Memory Names 0-999 (0x7670, 8, 125), # Ch Valid bytes 0-999 ) AB_LIST = ["A", "B"] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] STEP_LIST = [str(x) for x in STEPS] ROGER_LIST = ["Off", "Begin", "End", "Both"] TIMEOUT_LIST = ["Off"] + [str(x) + "s" for x in range(15, 901, 15)] VOX_LIST = ["Off"] + ["%s" % x for x in range(1, 10)] BANDWIDTH_LIST = ["Narrow", "Wide"] VOICE_LIST = ["Off", "On"] LANGUAGE_LIST = ["Chinese", "English", "Traditional Chinese"] SCANMODE_LIST = ["TO", "CO", "SE"] PFKEYLONG_LIST = ["undef", "FRQ2-PTT", "Selec Call", "Scan", "Flashlight", "Alarm", "SOS", "FM Radio", "Moni", "Strobe", "Weather", "Tlk A", "Reverse", "CTC Scan", "DCS Scan", "BRT"] PFKEYSHORT_LIST = ["undef", "Scan", "Flashlight", "Alarm", "SOS", "FM Radio", "Moni", "Strobe", "Weather", "Tlk A", "Reverse", "CTC Scan", "DCS Scan", "BRT"] PFKEYLONG_LIST_UV8H = ["Selec Call", "Sub Freq Tx"] PFKEYSHORT_LIST_UV8H = ["undef", "Scan", "Lamp", "Alarm", "SOS", "Radio"] PFKEYLONG_LIST_935GPLUS = ["undef", "FRQ2-PTT", "Selec Call", "Favorite", "Bright+", "Scan", "Flashlight", "Alarm", "SOS", "FM Radio", "Moni", "Strobe", "Weather", "Tlk A", "Reverse", "CTC Scan", "DCS Scan", "Backlight"] PFKEYSHORT_LIST_935GPLUS = ["undef", "Favorite", "Bright+", "Scan", "Flashlight", "Alarm", "SOS", "FM Radio", "Moni", "Strobe", "Weather", "Tlk A", "Reverse", "CTC Scan", "DCS Scan", "Backlight"] WORKMODE_LIST = ["VFO", "Ch.Number.", "Ch.Freq.", "Ch.Name"] WORKMODE_LIST_935GPLUS = ["FREQ", "Ch.Number.", "Ch.Freq.", "Ch.Name"] BACKLIGHT_LIST = ["Always On"] + [str(x) + "s" for x in range(1, 21)] + \ ["Always Off"] OFFSET_LIST = ["Off", "Plus Shift", "Minus Shift"] PONMSG_LIST = ["MSG - Bitmap", "Battery Volts"] SPMUTE_LIST = ["QT", "QT+DTMF", "QT*DTMF"] DTMFST_LIST = ["OFF", "DTMF", "ANI", "DTMF+ANI"] DTMF_TIMES = [('%dms' % dtmf, (dtmf // 10)) for dtmf in range(50, 501, 10)] ALERTS = [1750, 2100, 1000, 1450] ALERTS_LIST = [str(x) for x in ALERTS] PTTID_LIST = ["BOT", "EOT", "Both"] LIST_10 = ["Off"] + ["%s" % x for x in range(1, 11)] SCANGRP_LIST = ["All"] + ["%s" % x for x in range(1, 11)] SCQT_LIST = ["Decoder", "Encoder", "All"] SMUTESET_LIST = ["Off", "Tx", "Rx", "Tx+Rx"] POWER_LIST = ["Lo", "Mid", "Hi"] HOLD_TIMES = ["Off"] + ["%s" % x for x in range(100, 5001, 100)] RPTMODE_LIST = ["Radio", "Repeater"] RPTTYPE_MAP = [("X-DIRPT", 1), ("X-TWRPT", 2)] CALLGROUP_LIST = [str(x) for x in range(1, 21)] THEME_LIST = ["White-1", "White-2", "Black-1", "Black-2"] THEME_LIST_935GPLUS = ["White-1", "White-2", "Black-1", "Black-2", "Cool", "Rain", "NotARubi", "Sky", "BTWR", "Candy"] DSPBRTSBY_LIST = ["OFF", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"] DSPBRTACT_MAP = [("1", 1), ("2", 2), ("3", 3), ("4", 4), ("5", 5), ("6", 6), ("7", 7), ("8", 8), ("9", 9), ("10", 10)] TONESCANSAVELIST = ["Rx", "Tx", "Tx/Rx"] PTTDELAY_TIMES = [('%dms' % pttdelay, (pttdelay // 100)) for pttdelay in range(100, 3001, 100)] SCRAMBLE_LIST = ["OFF"] + [str(x) for x in range(1, 9)] ONOFF_LIST = ["OFF", "ON"] # MRT - Map CTCSS Tones - Value in mem is hex value of # (ctcss tone * 10) + 0x8000 # MRT - 0x8000 is for CTCSS tones # MRT - Map DCS Tones - Value in mem is hex representation of # DCS Tone# in Octal + either 0x4000 or 0x6000 for polarity # MRT - 0x4000 is for DCS n tones # MRT - 0x6000 is for DCS i tones TONE_MAP = [('Off', 0x0000)] + \ [('%.1f' % tone, int(0x8000 + tone * 10)) for tone in chirp_common.TONES] + \ [('D%03dn' % tone, int(0x4000 + int(str(tone), 8))) for tone in chirp_common.DTCS_CODES] + \ [('D%03di' % tone, int(0x6000 + int(str(tone), 8))) for tone in chirp_common.DTCS_CODES] BATT_DISP_LIST = ["Icon", "Voltage", "Percent"] WX_TYPE = ["Weather", "Icon-Only", "Tone", "Flash", "Tone-Flash"] # memory slot 0 is not used, start at 1 (so need 1000 slots, not 999) # structure elements whose name starts with x are currently unidentified _MEM_FORMAT_935G = """ #seekto 0x0044; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } uhf_limits; #seekto 0x0054; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } vhf_limits; #seekto 0x0400; struct { char oem1[8]; char unknown[2]; u8 unknown2[10]; u8 unknown3[10]; u8 unknown4[8]; char oem2[10]; u8 version[6]; char date[8]; u8 unknown5[2]; char model[8]; } oem_info; #seekto 0x0480; struct { u16 Group_lower1; u16 Group_upper1; u16 Group_lower2; u16 Group_upper2; u16 Group_lower3; u16 Group_upper3; u16 Group_lower4; u16 Group_upper4; u16 Group_lower5; u16 Group_upper5; u16 Group_lower6; u16 Group_upper6; u16 Group_lower7; u16 Group_upper7; u16 Group_lower8; u16 Group_upper8; u16 Group_lower9; u16 Group_upper9; u16 Group_lower10; u16 Group_upper10; } scan_groups; #seekto 0x0500; struct { u8 cid[6]; } call_ids[20]; #seekto 0x0580; struct { char call_name1[6]; char call_name2[6]; char call_name3[6]; char call_name4[6]; char call_name5[6]; char call_name6[6]; char call_name7[6]; char call_name8[6]; char call_name9[6]; char call_name10[6]; char call_name11[6]; char call_name12[6]; char call_name13[6]; char call_name14[6]; char call_name15[6]; char call_name16[6]; char call_name17[6]; char call_name18[6]; char call_name19[6]; char call_name20[6]; } call_names; #seekto 0x0600; struct { u16 FM_radio1; u16 FM_radio2; u16 FM_radio3; u16 FM_radio4; u16 FM_radio5; u16 FM_radio6; u16 FM_radio7; u16 FM_radio8; u16 FM_radio9; u16 FM_radio10; u16 FM_radio11; u16 FM_radio12; u16 FM_radio13; u16 FM_radio14; u16 FM_radio15; u16 FM_radio16; u16 FM_radio17; u16 FM_radio18; u16 FM_radio19; u16 FM_radio20; u16 unknown_pad_x0640[235]; u8 unknown07fe; u8 unknown07ff; u8 ponmsg; char dispstr[15]; u8 unknown0810; u8 unknown0811; u8 unknown0812; u8 unknown0813; u8 unknown0814; u8 voice; u8 timeout; u8 toalarm; u8 channel_menu; u8 power_save; u8 autolock; u8 keylock; u8 beep; u8 stopwatch; u8 vox; u8 scan_rev; u8 backlight; u8 roger_beep; char mode_sw_pwd[6]; char reset_pwd[6]; u16 pri_ch; u8 ani_sw; u8 ptt_delay; u8 ani_code[6]; u8 dtmf_st; u8 BCL_A; u8 BCL_B; u8 ptt_id; u8 prich_sw; u8 unknown083d; u8 unknown083e; u8 unknown083f; u8 alert; u8 pf1_shrt; u8 pf1_long; u8 pf2_shrt; u8 pf2_long; u8 unknown0845; u8 work_mode_a; u8 work_mode_b; u8 dtmf_tx_time; u8 dtmf_interval; u8 main_band; u16 work_ch_a; u16 work_ch_b; u8 unknown084f; u8 unknown0850; u8 unknown0851; u8 unknown0852; u8 unknown0853; u8 unknown0854; u8 unknown0855; u8 unknown0856; u8 unknown0857; u8 unknown0858; u8 unknown0859; u8 unknown085a; u8 unknown085b; u8 unknown085c; u8 unknown085d; u8 unknown085e; u8 unknown085f; u8 unknown0860; u8 TDR_single_mode; u8 ring_time; u8 ScnGrpA_Act; u8 ScnGrpB_Act; u8 unknown0865; u8 rpt_tone; u8 unknown0867; u8 scan_det; u8 ToneScnSave; u8 unknown086a; u8 smuteset; u8 cur_call_grp; u8 DspBrtAct; u8 DspBrtSby; u8 unknown086f; u8 theme; u8 wxalert; u8 VFO_repeater_a; u8 VFO_repeater_b; u8 unknown0874; u8 unknown0875; u8 unknown0876; u8 unknown0877; u8 unknown0878; u8 unknown0879; u8 unknown087a; u8 unknown087b; u8 unknown087c; u8 unknown087d; u8 unknown087e; u8 unknown087f; } settings; #seekto 0x0880; struct { u32 rxfreq; u32 unknown0; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:1, unknown5:2, unknown4:1, cmpndr:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfoa; #seekto 0x08c0; struct { u32 rxfreq; u32 unknown0; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:1, unknown5:2, unknown4:1, cmpndr:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfob; #seekto 0x0900; struct { u32 rxfreq; u32 txfreq; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:2, scan_add:1, unknown4:1, compander:1, mute_mode:2, iswide:1; u8 unknown5; u8 unknown6; } memory[1000]; #seekto 0x4780; struct { u8 name[8]; u8 unknown[4]; } names[1000]; #seekto 0x7670; u8 valid[1000]; """ _MEM_FORMAT_935GPLUS = """ #seekto 0x0044; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } uhf_limits; #seekto 0x0054; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } vhf_limits; #seekto 0x0400; struct { char oem1[8]; char unknown[2]; u8 unknown2[10]; u8 unknown3[10]; u8 unknown4[8]; char oem2[10]; u8 version[6]; char date[8]; u8 unknown5[2]; char model[8]; } oem_info; #seekto 0x0480; struct { u16 Group_lower1; u16 Group_upper1; u16 Group_lower2; u16 Group_upper2; u16 Group_lower3; u16 Group_upper3; u16 Group_lower4; u16 Group_upper4; u16 Group_lower5; u16 Group_upper5; u16 Group_lower6; u16 Group_upper6; u16 Group_lower7; u16 Group_upper7; u16 Group_lower8; u16 Group_upper8; u16 Group_lower9; u16 Group_upper9; u16 Group_lower10; u16 Group_upper10; } scan_groups; #seekto 0x0500; struct { u8 cid[6]; } call_ids[20]; #seekto 0x0580; struct { char call_name1[6]; char call_name2[6]; char call_name3[6]; char call_name4[6]; char call_name5[6]; char call_name6[6]; char call_name7[6]; char call_name8[6]; char call_name9[6]; char call_name10[6]; char call_name11[6]; char call_name12[6]; char call_name13[6]; char call_name14[6]; char call_name15[6]; char call_name16[6]; char call_name17[6]; char call_name18[6]; char call_name19[6]; char call_name20[6]; } call_names; #seekto 0x0600; struct { u16 FM_radio1; u16 FM_radio2; u16 FM_radio3; u16 FM_radio4; u16 FM_radio5; u16 FM_radio6; u16 FM_radio7; u16 FM_radio8; u16 FM_radio9; u16 FM_radio10; u16 FM_radio11; u16 FM_radio12; u16 FM_radio13; u16 FM_radio14; u16 FM_radio15; u16 FM_radio16; u16 FM_radio17; u16 FM_radio18; u16 FM_radio19; u16 FM_radio20; u16 unknown_pad_x0640[235]; u8 unknown07fe; u8 unknown07ff; u8 ponmsg; char dispstr[15]; u8 unknown0810; u8 unknown0811; u8 unknown0812; u8 unknown0813; u8 unknown0814; u8 voice; u8 timeout; u8 toalarm; u8 channel_menu; u8 power_save; u8 autolock; u8 keylock; u8 beep; u8 stopwatch; u8 vox; u8 scan_rev; u8 backlight; u8 roger_beep; char mode_sw_pwd[6]; char reset_pwd[6]; u16 pri_ch; u8 ani_sw; u8 ptt_delay; u8 ani_code[6]; u8 dtmf_st; u8 BCL_A; u8 BCL_B; u8 ptt_id; u8 prich_sw; u8 unknown083d; u8 unknown083e; u8 unknown083f; u8 alert; u8 pf1_shrt; u8 pf1_long; u8 pf2_shrt; u8 pf2_long; u8 unknown0845; u8 work_mode_a; u8 work_mode_b; u8 dtmf_tx_time; u8 dtmf_interval; u8 main_band; u16 work_ch_a; u16 work_ch_b; u8 unknown084f; u8 unknown0850; u8 unknown0851; u8 unknown0852; u8 unknown0853; u8 unknown0854; u8 unknown0855; u8 unknown0856; u8 unknown0857; u8 unknown0858; u8 unknown0859; u8 unknown085a; u8 unknown085b; u8 unknown085c; u8 unknown085d; u8 unknown085e; u8 unknown085f; u8 unknown0860; u8 TDR_single_mode; u8 ring_time; u8 ScnGrpA_Act; u8 ScnGrpB_Act; u8 unknown0865; u8 rpt_tone; u8 unknown0867; u8 scan_det; u8 ToneScnSave; u8 unknown086a; u8 smuteset; u8 cur_call_grp; u8 DspBrtAct; u8 DspBrtSby; u8 unknown086f; u8 theme; u8 batt_ind; u8 wxalert; u8 wxalert_type; u8 VFO_repeater_a; u8 VFO_repeater_b; u8 sim_rec; u8 unknown0877; u8 unknown0878; u8 unknown0879; u8 unknown087a; u8 unknown087b; u8 unknown087c; u8 unknown087d; u8 unknown087e; u8 unknown087f; } settings; #seekto 0x0880; struct { u32 rxfreq; u32 unknown0; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:1, unknown5:2, unknown4:1, cmpndr:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfoa; #seekto 0x08c0; struct { u32 rxfreq; u32 unknown0; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:1, unknown5:2, unknown4:1, cmpndr:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfob; #seekto 0x0900; struct { u32 rxfreq; u32 txfreq; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:2, scan_add:1, unknown4:1, compander:1, mute_mode:2, iswide:1; u8 unknown5; u8 unknown6; } memory[1000]; #seekto 0x4780; struct { u8 name[8]; u8 unknown[4]; } names[1000]; #seekto 0x7670; u8 valid[1000]; """ _MEM_FORMAT_UV8H = """ #seekto 0x0044; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } uhf_limits; #seekto 0x0054; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } vhf_limits; #seekto 0x0400; struct { char oem1[8]; char unknown[2]; u8 unknown2[10]; u8 unknown3[10]; u8 unknown4[8]; char oem2[10]; u8 version[6]; char date[8]; u8 unknown5[2]; char model[8]; } oem_info; #seekto 0x0480; struct { u16 Group_lower1; u16 Group_upper1; u16 Group_lower2; u16 Group_upper2; u16 Group_lower3; u16 Group_upper3; u16 Group_lower4; u16 Group_upper4; u16 Group_lower5; u16 Group_upper5; u16 Group_lower6; u16 Group_upper6; u16 Group_lower7; u16 Group_upper7; u16 Group_lower8; u16 Group_upper8; u16 Group_lower9; u16 Group_upper9; u16 Group_lower10; u16 Group_upper10; } scan_groups; #seekto 0x0500; struct { u8 cid[6]; } call_ids[20]; #seekto 0x0580; struct { char call_name1[6]; char call_name2[6]; char call_name3[6]; char call_name4[6]; char call_name5[6]; char call_name6[6]; char call_name7[6]; char call_name8[6]; char call_name9[6]; char call_name10[6]; char call_name11[6]; char call_name12[6]; char call_name13[6]; char call_name14[6]; char call_name15[6]; char call_name16[6]; char call_name17[6]; char call_name18[6]; char call_name19[6]; char call_name20[6]; } call_names; #seekto 0x0600; struct { u16 FM_radio1; u16 FM_radio2; u16 FM_radio3; u16 FM_radio4; u16 FM_radio5; u16 FM_radio6; u16 FM_radio7; u16 FM_radio8; u16 FM_radio9; u16 FM_radio10; u16 FM_radio11; u16 FM_radio12; u16 FM_radio13; u16 FM_radio14; u16 FM_radio15; u16 FM_radio16; u16 FM_radio17; u16 FM_radio18; u16 FM_radio19; u16 FM_radio20; u16 unknown_pad_x0640[235]; u8 unknown07fe; u8 unknown07ff; u8 ponmsg; char dispstr[15]; u8 unknown0810; u8 unknown0811; u8 unknown0812; u8 unknown0813; u8 unknown0814; u8 voice; u8 timeout; u8 toalarm; u8 channel_menu; u8 power_save; u8 autolock; u8 keylock; u8 beep; u8 stopwatch; u8 vox; u8 scan_rev; u8 backlight; u8 roger_beep; char mode_sw_pwd[6]; char reset_pwd[6]; u16 pri_ch; u8 ani_sw; u8 ptt_delay; u8 ani_code[6]; u8 dtmf_st; u8 BCL_A; u8 BCL_B; u8 ptt_id; u8 prich_sw; u8 rpttype; u8 rptspk; u8 rptptt; u8 alert; u8 pf1_long; u8 pf1_shrt; u8 unk845; u8 work_mode_a; u8 work_mode_b; u8 dtmf_tx_time; u8 dtmf_interval; u8 unk4a; u16 work_ch_a; u16 work_ch_b; u8 unk4d; u8 main_band; u8 unknown084f; u8 unknown0850; u8 unknown0851; u8 unknown0852; u8 unknown0853; u8 unknown0854; u8 rptmode; u8 language; u8 unknown0857; u8 unknown0858; u8 unknown0859; u8 unknown085a; u8 unknown085b; u8 unknown085c; u8 unknown085d; u8 unknown085e; u8 TDR_single_mode; u8 ring_time; u8 ScnGrpA_Act; u8 ScnGrpB_Act; u8 unk863; u8 rpt_tone; u8 rpt_hold; u8 scan_det; u8 ToneScnSave; u8 unk868; u8 smuteset; u8 cur_call_grp; u8 DspBrtAct; u8 unknown086c; u8 theme; u8 wxalert; u8 unknown086f; u8 unknown0870; u8 unk871; u8 unk872; u8 unk873; u8 unknown0874; u8 unknown0875; u8 unknown0876; u8 unknown0877; u8 unknown0878; u8 unknown0879; u8 unknown087a; u8 unknown087b; u8 unknown087c; u8 unknown087d; u8 unknown087e; u8 unknown087f; } settings; #seekto 0x0880; struct { u32 rxfreq; u32 offset; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:1, ofst_dir:2, unknown4:1, cmpndr:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfoa; #seekto 0x08c0; struct { u32 rxfreq; u32 offset; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:1, ofst_dir:2, unknown4:1, cmpndr:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfob; #seekto 0x0900; struct { u32 rxfreq; u32 txfreq; u16 rxtone; u16 txtone; u8 scrambler:4, power:4; u8 unknown3:2, scan_add:1, unknown4:1, compander:1, mute_mode:2, iswide:1; u8 unknown5; u8 unknown6; } memory[1000]; #seekto 0x4780; struct { u8 name[8]; u8 unknown[4]; } names[1000]; #seekto 0x7670; u8 valid[1000]; """ # Support for the Wouxun KG-935G radio # Serial coms are at 19200 baud # The data is passed in variable length records # Record structure: # Offset Usage # 0 start of record (\x7c) # 1 Command (\x80 Identify \x81 End/Reboot \x82 Read \x83 Write) # 2 direction (\xff PC-> Radio, \x00 Radio -> PC) # 3 length of payload (excluding header/checksum) (n) # 4 payload (n bytes) # 4+n+1 checksum - byte sum (% 256) of bytes 1 -> 4+n # # Memory Read Records: # the payload is 3 bytes, first 2 are offset (big endian), # 3rd is number of bytes to read # Memory Write Records: # the maximum payload size (from the Wouxun software) seems to be 66 bytes # (2 bytes location + 64 bytes data). # MRT 1.2 correct spelling of Wouxon def str2callid(val): """ Convert caller id strings from callid2str. """ ascii2bin = "0123456789" s = str(val).strip() LOG.debug("val = %s" % val) LOG.debug("s = %s" % s) if len(s) < 3 or len(s) > 6: raise InvalidValueError( "Caller ID must be at least 3 and no more than 6 digits") if s[0] == '0': raise InvalidValueError( "First digit of a Caller ID cannot be a zero '0'") blk = bytearray() for c in s: if c not in ascii2bin: raise InvalidValueError( "Caller ID must be all digits 0x%x" % c) b = ascii2bin.index(c) blk.append(b) if len(blk) < 6: blk.append(0x0F) # EOL a short ID if len(blk) < 6: for i in range(0, (6 - len(blk))): blk.append(0xf0) LOG.debug("blk = %s" % blk) return blk @directory.register class KG935GRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-935G""" VENDOR = "Wouxun" MODEL = "KG-935G" _model = b"KG-UV8D-B" BAUD_RATE = 19200 # MRT - Added Medium Power level for 935G support POWER_LEVELS = [chirp_common.PowerLevel("L", watts=0.5), chirp_common.PowerLevel("M", watts=4.5), chirp_common.PowerLevel("H", watts=5.5)] NEEDS_COMPAT_SERIAL = False _record_start = 0x7C def _checksum(self, data): cs = 0 for byte in data: cs += byte return cs % 256 def _write_record(self, cmd, payload=b''): _packet = struct.pack('BBBB', self._record_start, cmd, 0xFF, len(payload)) checksum = bytes([self._checksum(_packet[1:] + payload)]) _packet += self.encrypt(payload + checksum) LOG.debug("Sent:\n%s" % util.hexprint(_packet)) self.pipe.write(_packet) def _read_record(self): # read 4 chars for the header _header = self.pipe.read(4) if len(_header) != 4: raise errors.RadioError('Radio did not respond') _length = struct.unpack('xxxB', _header)[0] _packet = self.pipe.read(_length) _rcs_xor = _packet[-1] _packet = self.decrypt(_packet) _cs = self._checksum(_header[1:]) _cs += self._checksum(_packet) _cs %= 256 _rcs = self.strxor(self.pipe.read(1)[0], _rcs_xor)[0] LOG.debug("_cs =%x", _cs) LOG.debug("_rcs=%x", _rcs) return (_rcs != _cs, _packet) def decrypt(self, data): result = b'' for i in range(len(data)-1, 0, -1): result += self.strxor(data[i], data[i - 1]) result += self.strxor(data[0], 0x57) return result[::-1] def encrypt(self, data): result = self.strxor(0x57, data[0]) for i in range(1, len(data), 1): result += self.strxor(result[i - 1], data[i]) return result def strxor(self, xora, xorb): return bytes([xora ^ xorb]) # Identify the radio # # A Gotcha: the first identify packet returns a bad checksum, subsequent # attempts return the correct checksum... (well it does on my radio!) # # The ID record returned by the radio also includes the # current frequency range # as 4 bytes big-endian in 10 Hz increments # # Offset # 0:10 Model, zero padded (Looks for 'KG-UV8D-B') def _identify(self): """Do the identification dance""" for _i in range(0, 10): self._write_record(CMD_ID) _chksum_err, _resp = self._read_record() LOG.debug("Got:\n%s" % util.hexprint(_resp)) if _chksum_err: LOG.error("Checksum error: retrying ident...") time.sleep(0.100) continue LOG.debug("Model %s" % util.hexprint(_resp[0:9])) if _resp[0:9] == self._model: return if len(_resp) == 0: raise Exception("Radio not responding") else: raise Exception("Unable to identify radio") def _finish(self): self._write_record(CMD_END) def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT_935G, self._mmap) def sync_in(self): try: self._mmap = self._download() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): self._upload() # TODO: Load all memory. # It would be smarter to only load the active areas and none of # the padding/unused areas. Padding still need to be investigated. def _download(self): """Talk to a Wouxun KG-935G and do a download""" try: self._identify() return self._do_download(0, 32768, 64) except errors.RadioError: raise except Exception as e: LOG.exception('Unknown error during download process') raise errors.RadioError("Failed to communicate with radio: %s" % e) def _do_download(self, start, end, blocksize): # allocate & fill memory image = b"" for i in range(start, end, blocksize): req = struct.pack('>HB', i, blocksize) self._write_record(CMD_RD, req) cs_error, resp = self._read_record() if cs_error: LOG.debug(util.hexprint(resp)) raise Exception("Checksum error on read") # LOG.debug("Got:\n%s" % util.hexprint(resp)) image += resp[2:] if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning from radio" self.status_fn(status) self._finish() return memmap.MemoryMapBytes(image) def _upload(self): """Talk to a Wouxun KG-935G and do a upload""" try: self._identify() self._do_upload() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) return def _do_upload(self): cfgmap = config_map_935G for start, blocksize, count in cfgmap: end = start + (blocksize * count) LOG.debug("start = " + str(start)) LOG.debug("end = " + str(end)) LOG.debug("blksize = " + str(blocksize)) for addr in range(start, end, blocksize): ptr = addr LOG.debug("ptr = " + str(ptr)) req = struct.pack('>H', addr) chunk = self.get_mmap()[ptr:ptr + blocksize] self._write_record(CMD_WR, req + chunk) LOG.debug(util.hexprint(req + chunk)) cserr, ack = self._read_record() LOG.debug(util.hexprint(ack)) j = struct.unpack('>H', ack)[0] if cserr or j != ptr: raise Exception("Radio did not ack block %i" % ptr) ptr += blocksize if self.status_fn: status = chirp_common.Status() status.cur = ptr status.max = 0x8000 status.msg = "Cloning to radio" self.status_fn(status) self._finish() def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] # MRT - Open up channel memory freq range to support # RxFreq limit expansion rf.valid_bands = [(30000000, 299999990), # supports 2m (300000000, 999999990)] # supports 70cm rf.valid_characters = chirp_common.CHARSET_ASCII rf.memory_bounds = (1, 999) # 999 memories rf.valid_tuning_steps = STEPS return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is experimental. USE AT YOUR OWN RISK\n' '\n' 'Please save a copy of the image from your radio with Chirp ' 'before modifying any values.\n' '\n' 'Please keep a copy of your memories with the original Wouxon' 'CPS software if you treasure them, this driver is new and' 'may contain bugs.\n' ) return rp def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _get_tone(self, _mem, mem): # MRT - corrected the Polarity decoding to match 935G implementation # use 0x2000 bit mask for R # MRT - 0x2000 appears to be the bit mask for Inverted DCS tones # MRT - n DCS Tone will be 0x4xxx values - i DCS Tones will # be 0x6xxx values. # MRT - Chirp Uses N for n DCS Tones and R for i DCS Tones def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x2000) and "R" or "N" return code, pol # MRT - Modified the function below to bitwise AND with 0x4000 # to check for 935G DCS Tone decoding # MRT 0x4000 appears to be the bit mask for DCS tones tpol = False # MRT Beta 1.1 - Fix the txtone compare to 0x4000 - was rxtone. if _mem.txtone != 0xFFFF and (_mem.txtone & 0x4000) == 0x4000: tcode, tpol = _get_dcs(_mem.txtone) mem.dtcs = tcode txmode = "DTCS" elif _mem.txtone != 0xFFFF and _mem.txtone != 0x0: mem.rtone = (_mem.txtone & 0x7fff) / 10.0 txmode = "Tone" else: txmode = "" # MRT - Modified the function below to bitwise AND with 0x4000 # to check for 935G DCS Tone decoding rpol = False if _mem.rxtone != 0xFFFF and (_mem.rxtone & 0x4000) == 0x4000: rcode, rpol = _get_dcs(_mem.rxtone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rxtone != 0xFFFF and _mem.rxtone != 0x0: mem.ctone = (_mem.rxtone & 0x7fff) / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number _valid = self._memobj.valid[mem.number] if _valid != MEM_VALID: mem.empty = True return mem else: mem.empty = False mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _nam.name: if char != 0: mem.name += chr(char) mem.name = mem.name.rstrip() self._get_tone(_mem, mem) mem.skip = "" if bool(_mem.scan_add) else "S" _mem.power = _mem.power & 0x3 if _mem.power > 2: _mem.power = 2 mem.power = self.POWER_LEVELS[_mem.power] mem.mode = _mem.iswide and "FM" or "NFM" return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): # MRT Change from + 0x2800 to bitwise OR with 0x4000 to # set the bit for DCS val = int("%i" % code, 8) | 0x4000 if pol == "R": # MRT Change to 0x2000 from 0x8000 to set the bit for # i/R polarity val += 0x2000 return val rx_mode = tx_mode = None rxtone = txtone = 0x0000 if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None txtone = int(mem.rtone * 10) + 0x8000 elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) + 0x8000 elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) + 0x8000 if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) + 0x8000 _mem.rxtone = rxtone _mem.txtone = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.txtone, rx_mode, _mem.rxtone)) def set_memory(self, mem): number = mem.number _mem = self._memobj.memory[number] _nam = self._memobj.names[number] if mem.empty: _mem.set_raw("\x00" * (_mem.size() // 8)) self._memobj.valid[number] = 0 self._memobj.names[number].set_raw("\x00" * (_nam.size() // 8)) return _mem.rxfreq = int(mem.freq / 10) if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = int(mem.offset / 10) elif mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "+": _mem.txfreq = int(mem.freq / 10) + int(mem.offset / 10) elif mem.duplex == "-": _mem.txfreq = int(mem.freq / 10) - int(mem.offset / 10) else: _mem.txfreq = int(mem.freq / 10) _mem.scan_add = int(mem.skip != "S") _mem.iswide = int(mem.mode == "FM") # set the tone self._set_tone(mem, _mem) # MRT set the scrambler and compander to off by default # MRT This changes them in the channel memory _mem.scrambler = 0 _mem.compander = 0 # set the power _mem.power = _mem.power & 0x3 if mem.power: if _mem.power > 2: _mem.power = 2 _mem.power = self.POWER_LEVELS.index(mem.power) else: _mem.power = True # MRT set to mute mode to QT (not QT+DTMF or QT*DTMF) by default # MRT This changes them in the channel memory _mem.mute_mode = 0 # MRT it is unknown what impact these values have # MRT This changes them in the channel memory to match what # Wouxun CPS shows when creating a channel # MRT It is likely that these are just left as is and not # written to by CPS - bit remnants of 0xFF in the unused memory # _mem.unknown1 = 0 # MRT Set to 3 to TO MATCH CPS VALUES _mem.unknown3 = 3 # MRT Set to 1 to TO MATCH CPS VALUES _mem.unknown4 = 1 # MRT set unknown5 to 1 and unknown6 to 0 _mem.unknown5 = 1 _mem.unknown6 = 255 for i in range(0, len(_nam.name)): if i < len(mem.name) and mem.name[i]: _nam.name[i] = ord(mem.name[i]) else: _nam.name[i] = 0x0 self._memobj.valid[mem.number] = MEM_VALID def _get_settings(self): _settings = self._memobj.settings _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob _scan = self._memobj.scan_groups _callname = self._memobj.call_names if self.MODEL == "KG-935G": themelist = THEME_LIST vfoa_grp_label = "VFO A Settings" vfob_grp_label = "VFO B Settings" workmodelist = WORKMODE_LIST pfkeyshort = PFKEYSHORT_LIST pfkeylong = PFKEYLONG_LIST dispmesg = "Display Message - Interface Display Edit" areamsglabel = "Model / Bottom Banner" vfo_area = "VFO " ani_msg = "ANI-ID Switch (ANI-SW)" pttdly_msg = "PTT-DLY" idtx_msg = "PTT-ID" elif self.MODEL == "KG-UV8H": themelist = THEME_LIST vfoa_grp_label = "VFO A Settings" vfob_grp_label = "VFO B Settings" workmodelist = WORKMODE_LIST pfkeyshort = PFKEYSHORT_LIST_UV8H pfkeylong = PFKEYLONG_LIST_UV8H dispmesg = "Display Message - Interface Display Edit" areamsglabel = "Model / Bottom Banner" vfo_area = "VFO " ani_msg = "ANI-ID Switch (ANI-SW)" pttdly_msg = "PTT-DLY" idtx_msg = "PTT-ID" elif self.MODEL == "KG-935G Plus": themelist = THEME_LIST_935GPLUS vfoa_grp_label = "Freq Mode A Settings" vfob_grp_label = "Freq Mode B Settings" workmodelist = WORKMODE_LIST_935GPLUS pfkeyshort = PFKEYSHORT_LIST_935GPLUS pfkeylong = PFKEYLONG_LIST_935GPLUS dispmesg = "Top Message" areamsglabel = "Area Message" vfo_area = "Area " ani_msg = "Send ANI-ID on Tx(ANI-SW)" pttdly_msg = "ID Delay" idtx_msg = "ID Transmit Setting" cfg_grp = RadioSettingGroup("cfg_grp", "Config Settings") vfoa_grp = RadioSettingGroup("vfoa_grp", vfoa_grp_label) vfob_grp = RadioSettingGroup("vfob_grp", vfob_grp_label) key_grp = RadioSettingGroup("key_grp", "Key Settings") fmradio_grp = RadioSettingGroup("fmradio_grp", "FM Broadcast Memory") lmt_grp = RadioSettingGroup("lmt_grp", "Frequency Limits") oem_grp = RadioSettingGroup("oem_grp", "OEM Info") scan_grp = RadioSettingGroup("scan_grp", "Scan Group") call_grp = RadioSettingGroup("call_grp", "Call Settings") group = RadioSettings(cfg_grp, vfoa_grp, vfob_grp, fmradio_grp, key_grp, scan_grp, call_grp, lmt_grp, oem_grp) # Call Settings rs = RadioSetting("cur_call_grp", "Current Call Group", RadioSettingValueList(CALLGROUP_LIST, CALLGROUP_LIST[_settings. cur_call_grp])) call_grp.append(rs) def apply_callid(setting, obj): c = str2callid(setting.value) obj.cid = c callchars = "0123456789" for i in range(1, 21): _msg = "" _msg1 = str(getattr(_callname, 'call_name%i' % i)).split('\0')[0] # MRT - Handle default factory values of 0xFF or # non-ascii values in Call Name memory for char in _msg1: if char < chr(0x20) or char > chr(0x7E): _msg += "" else: _msg += str(char) val = RadioSettingValueString(0, 6, _msg) val.set_mutable(True) rs = RadioSetting("call_names.call_name%i" % i, "Call Name %i" % i, val) call_grp.append(rs) x = i - 1 callid = self._memobj.call_ids[x] c_id = RadioSettingValueString(0, 6, self.callid2str(callid.cid), False) rs = RadioSetting("call_ids[%i].cid" % x, "Call Code %i" % i, c_id) rs.set_apply_callback(apply_callid, callid) call_grp.append(rs) # Configuration Settings # rs = RadioSetting("DspBrtAct", "Display Brightness ACTIVE", RadioSettingValueMap(DSPBRTACT_MAP, _settings.DspBrtAct)) cfg_grp.append(rs) if self.MODEL != "KG-UV8H": rs = RadioSetting("DspBrtSby", "Display Brightness STANDBY", RadioSettingValueList( DSPBRTSBY_LIST, DSPBRTSBY_LIST[ _settings.DspBrtSby])) cfg_grp.append(rs) rs = RadioSetting("wxalert", "Weather Alert", RadioSettingValueBoolean(_settings.wxalert)) cfg_grp.append(rs) if self.MODEL == "KG-935G Plus": rs = RadioSetting("wxalert_type", "Weather Alert Notification", RadioSettingValueList(WX_TYPE, WX_TYPE[_settings. wxalert_type])) cfg_grp.append(rs) rs = RadioSetting("power_save", "Battery Saver", RadioSettingValueBoolean(_settings.power_save)) cfg_grp.append(rs) rs = RadioSetting("theme", "Theme", RadioSettingValueList( themelist, themelist[_settings.theme])) cfg_grp.append(rs) rs = RadioSetting("backlight", "Backlight Active Time", RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings. backlight])) cfg_grp.append(rs) rs = RadioSetting("scan_rev", "Scan Mode", RadioSettingValueList(SCANMODE_LIST, SCANMODE_LIST[_settings. scan_rev])) cfg_grp.append(rs) rs = RadioSetting("prich_sw", "Priority Channel Scan", RadioSettingValueBoolean(_settings.prich_sw)) cfg_grp.append(rs) rs = RadioSetting("pri_ch", "Priority Channel - Can not be empty Channel", RadioSettingValueInteger(1, 999, _settings.pri_ch)) cfg_grp.append(rs) rs = RadioSetting("scan_det", "Scan Mode Tone Detect", RadioSettingValueBoolean(_settings.scan_det)) cfg_grp.append(rs) rs = RadioSetting("ToneScnSave", "Tone Scan Save", RadioSettingValueList(TONESCANSAVELIST, TONESCANSAVELIST[_settings. ToneScnSave])) cfg_grp.append(rs) rs = RadioSetting("roger_beep", "Roger Beep", RadioSettingValueList(ROGER_LIST, ROGER_LIST[_settings. roger_beep])) cfg_grp.append(rs) rs = RadioSetting("timeout", "Timeout Timer (TOT)", RadioSettingValueList( TIMEOUT_LIST, TIMEOUT_LIST[_settings.timeout])) cfg_grp.append(rs) rs = RadioSetting("toalarm", "Timeout Alarm (TOA)", RadioSettingValueInteger(0, 10, _settings.toalarm)) cfg_grp.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueList(LIST_10, LIST_10[_settings.vox])) cfg_grp.append(rs) rs = RadioSetting("voice", "Voice Guide", RadioSettingValueBoolean(_settings.voice)) cfg_grp.append(rs) rs = RadioSetting("beep", "Keypad Beep", RadioSettingValueBoolean(_settings.beep)) cfg_grp.append(rs) rs = RadioSetting("BCL_A", "Busy Channel Lock-out A", RadioSettingValueBoolean(_settings.BCL_A)) cfg_grp.append(rs) rs = RadioSetting("BCL_B", "Busy Channel Lock-out B", RadioSettingValueBoolean(_settings.BCL_B)) cfg_grp.append(rs) rs = RadioSetting("smuteset", "Secondary Area Mute (SMUTESET)", RadioSettingValueList(SMUTESET_LIST, SMUTESET_LIST[_settings. smuteset])) cfg_grp.append(rs) rs = RadioSetting("ani_sw", ani_msg, RadioSettingValueBoolean(_settings.ani_sw)) cfg_grp.append(rs) rs = RadioSetting("dtmf_st", "DTMF Sidetone (SIDETONE)", RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[_settings. dtmf_st])) cfg_grp.append(rs) rs = RadioSetting("alert", "Alert Tone", RadioSettingValueList(ALERTS_LIST, ALERTS_LIST[_settings.alert])) cfg_grp.append(rs) rs = RadioSetting("ptt_delay", pttdly_msg, RadioSettingValueMap(PTTDELAY_TIMES, _settings.ptt_delay)) cfg_grp.append(rs) rs = RadioSetting("ptt_id", idtx_msg, RadioSettingValueList(PTTID_LIST, PTTID_LIST[_settings.ptt_id])) cfg_grp.append(rs) rs = RadioSetting("ring_time", "Ring Time", RadioSettingValueList(LIST_10, LIST_10[_settings.ring_time])) cfg_grp.append(rs) if self.MODEL == "KG-UV8H": rs = RadioSetting("language", "Language", RadioSettingValueList( LANGUAGE_LIST, LANGUAGE_LIST[_settings.language])) cfg_grp.append(rs) rs = RadioSetting("rptmode", "Radio Work Mode", RadioSettingValueList( RPTMODE_LIST, RPTMODE_LIST[_settings.rptmode])) cfg_grp.append(rs) rs = RadioSetting("rpttype", "Repeater Type", RadioSettingValueMap(RPTTYPE_MAP, _settings.rpttype)) cfg_grp.append(rs) rs = RadioSetting("rptspk", "Repeater Speaker", RadioSettingValueBoolean(_settings.rptspk)) cfg_grp.append(rs) rs = RadioSetting("rptptt", "Repeater PTT", RadioSettingValueBoolean(_settings.rptptt)) cfg_grp.append(rs) rs = RadioSetting("rpt_hold", "RPT Hold Time", RadioSettingValueList( HOLD_TIMES, HOLD_TIMES[_settings.rpt_hold])) cfg_grp.append(rs) rs = RadioSetting("rpt_tone", "Repeater Tone", RadioSettingValueBoolean(_settings.rpt_tone)) cfg_grp.append(rs) rs = RadioSetting("stopwatch", "Timer / Stopwatch", RadioSettingValueBoolean(_settings.stopwatch)) cfg_grp.append(rs) rs = RadioSetting("autolock", "Autolock", RadioSettingValueBoolean(_settings.autolock)) cfg_grp.append(rs) rs = RadioSetting("keylock", "Keypad Lock", RadioSettingValueBoolean(_settings.keylock)) cfg_grp.append(rs) rs = RadioSetting("ponmsg", "Poweron message", RadioSettingValueList( PONMSG_LIST, PONMSG_LIST[_settings.ponmsg])) cfg_grp.append(rs) rs = RadioSetting("dtmf_tx_time", "DTMF Transmit Time", RadioSettingValueMap(DTMF_TIMES, _settings.dtmf_tx_time)) cfg_grp.append(rs) rs = RadioSetting("dtmf_interval", "DTMF Interval Time", RadioSettingValueMap(DTMF_TIMES, _settings.dtmf_interval)) cfg_grp.append(rs) if self.MODEL == "KG-935G Plus": rs = RadioSetting("batt_ind", "Battery Indicator", RadioSettingValueList( BATT_DISP_LIST, BATT_DISP_LIST[_settings.batt_ind])) cfg_grp.append(rs) rs = RadioSetting("sim_rec", "Simultaneous Receive", RadioSettingValueBoolean(_settings.sim_rec)) cfg_grp.append(rs) rs = RadioSetting("channel_menu", "Menu available in channel mode", RadioSettingValueBoolean(_settings.channel_menu)) cfg_grp.append(rs) pswdchars = "0123456789" _msg = str(_settings.mode_sw_pwd).split("\0")[0] val = RadioSettingValueString(0, 6, _msg, False) val.set_mutable(True) val.set_charset(pswdchars) rs = RadioSetting("mode_sw_pwd", "Mode SW Pwd", val) cfg_grp.append(rs) _msg = str(_settings.reset_pwd).split("\0")[0] val = RadioSettingValueString(0, 6, _msg, False) val.set_charset(pswdchars) val.set_mutable(True) rs = RadioSetting("reset_pwd", "Reset Pwd", val) cfg_grp.append(rs) # Key Settings # _msg = str(_settings.dispstr).split("\0")[0] val = RadioSettingValueString(0, 15, _msg) val.set_mutable(True) rs = RadioSetting("dispstr", dispmesg, val) key_grp.append(rs) def apply_ani_id(setting, obj): c = str2callid(setting.value) obj.ani_code = c cid = self._memobj.settings my_callid = RadioSettingValueString(3, 6, self.callid2str(cid.ani_code), False) rs = RadioSetting("ani_code", "ANI Edit", my_callid) rs.set_apply_callback(apply_ani_id, cid) key_grp.append(rs) rs = RadioSetting("pf1_shrt", "PF1 SHORT Key function", RadioSettingValueList( pfkeyshort, pfkeyshort[_settings.pf1_shrt])) key_grp.append(rs) rs = RadioSetting("pf1_long", "PF1 LONG Key function", RadioSettingValueList( pfkeylong, pfkeylong[_settings.pf1_long])) key_grp.append(rs) if self.MODEL != "KG-UV8H": rs = RadioSetting("pf2_shrt", "PF2 SHORT Key function", RadioSettingValueList( pfkeyshort, pfkeyshort[_settings.pf2_shrt])) key_grp.append(rs) rs = RadioSetting("pf2_long", "PF2 LONG Key function", RadioSettingValueList( pfkeylong, pfkeylong[_settings.pf2_long])) key_grp.append(rs) # SCAN GROUP settings rs = RadioSetting("ScnGrpA_Act", "Scan Group A Active", RadioSettingValueList(SCANGRP_LIST, SCANGRP_LIST[_settings. ScnGrpA_Act])) scan_grp.append(rs) rs = RadioSetting("ScnGrpB_Act", "Scan Group B Active", RadioSettingValueList(SCANGRP_LIST, SCANGRP_LIST[_settings. ScnGrpB_Act])) scan_grp.append(rs) for i in range(1, 11): val = getattr(self._memobj.scan_groups, 'Group_lower%i' % i) rs = RadioSetting("scan_groups.Group_lower%i" % i, "Scan Group %i Lower" % i, RadioSettingValueInteger(1, 999, val)) scan_grp.append(rs) val = getattr(self._memobj.scan_groups, 'Group_upper%i' % i) rs = RadioSetting("scan_groups.Group_upper%i" % i, "Scan Group %i Upper" % i, RadioSettingValueInteger(1, 999, val)) scan_grp.append(rs) # VFO A Settings # rs = RadioSetting("work_mode_a", vfo_area + "A Workmode", RadioSettingValueList(workmodelist, workmodelist[_settings. work_mode_a])) vfoa_grp.append(rs) rs = RadioSetting("work_ch_a", vfo_area + "A Work Channel", RadioSettingValueInteger(1, 999, _settings.work_ch_a)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.rxfreq", vfo_area + "A Rx Frequency (MHz)", RadioSettingValueFloat( 30.00000, 999.999999, (_vfoa.rxfreq / 100000.0), 0.000001, 6)) vfoa_grp.append(rs) if self.MODEL == "KG-UV8H": rs = RadioSetting("vfoa.offset", vfo_area + "A Offset (MHz)", RadioSettingValueFloat( 0.00000, 599.999999, (_vfoa.offset / 100000.0), 0.000001, 6)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.rxtone", vfo_area + "A Rx tone", RadioSettingValueMap( TONE_MAP, _vfoa.rxtone)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.txtone", vfo_area + "A Tx tone", RadioSettingValueMap( TONE_MAP, _vfoa.txtone)) vfoa_grp.append(rs) # MRT - AND power with 0x03 to display only the lower 2 bits for # power level and to clear the upper bits # MRT - any bits set in the upper 2 bits will cause radio to show # invalid values for power level and a display glitch # MRT - when PTT is pushed _vfoa.power = _vfoa.power & 0x3 if _vfoa.power > 2: _vfoa.power = 2 rs = RadioSetting("vfoa.power", vfo_area + "A Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfoa.power])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.iswide", vfo_area + "A Wide/Narrow", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfoa.iswide])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.mute_mode", vfo_area + "A Mute (SP Mute)", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfoa.mute_mode])) vfoa_grp.append(rs) if self.MODEL == "KG-UV8H": rs = RadioSetting("vfoa.ofst_dir", vfo_area + "A Shift Dir", RadioSettingValueList( OFFSET_LIST, OFFSET_LIST[_vfoa.ofst_dir])) vfoa_grp.append(rs) else: rs = RadioSetting("VFO_repeater_a", vfo_area + "A Repeater", RadioSettingValueBoolean( _settings.VFO_repeater_a)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.scrambler", vfo_area + "A Descramble", RadioSettingValueList( SCRAMBLE_LIST, SCRAMBLE_LIST[_vfoa.scrambler])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.cmpndr", vfo_area + "A Compander", RadioSettingValueList( ONOFF_LIST, ONOFF_LIST[_vfoa.cmpndr])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.step", vfo_area + "A Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfoa.step])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.squelch", vfo_area + "A Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfoa.squelch])) vfoa_grp.append(rs) # VFO B Settings rs = RadioSetting("work_mode_b", vfo_area + "B Workmode", RadioSettingValueList(workmodelist, workmodelist[_settings. work_mode_b])) vfob_grp.append(rs) rs = RadioSetting("work_ch_b", vfo_area + "B Work Channel", RadioSettingValueInteger(1, 999, _settings.work_ch_b)) vfob_grp.append(rs) rs = RadioSetting("vfob.rxfreq", vfo_area + "B Rx Frequency (MHz)", RadioSettingValueFloat( 30.000000, 999.999999, (_vfob.rxfreq / 100000.0), 0.000001, 6)) vfob_grp.append(rs) if self.MODEL == "KG-UV8H": rs = RadioSetting("vfob.offset", vfo_area + "B Offset (MHz)", RadioSettingValueFloat( 0.00000, 599.999999, (_vfob.offset / 100000.0), 0.000001, 6)) vfob_grp.append(rs) rs = RadioSetting("vfob.rxtone", vfo_area + "B Rx tone", RadioSettingValueMap( TONE_MAP, _vfob.rxtone)) vfob_grp.append(rs) rs = RadioSetting("vfob.txtone", vfo_area + "B Tx tone", RadioSettingValueMap( TONE_MAP, _vfob.txtone)) vfob_grp.append(rs) # MRT - AND power with 0x03 to display only the lower 2 bits for # power level and to clear the upper bits # MRT - any bits set in the upper 2 bits will cause radio to show # invalid values for power level and a display glitch # MRT - when PTT is pushed _vfob.power = _vfob.power & 0x3 if _vfob.power > 2: _vfob.power = 2 rs = RadioSetting("vfob.power", vfo_area + "B Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfob.power])) vfob_grp.append(rs) rs = RadioSetting("vfob.iswide", vfo_area + "B Wide/Narrow", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfob.iswide])) vfob_grp.append(rs) rs = RadioSetting("vfob.mute_mode", vfo_area + "B Mute (SP Mute)", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfob.mute_mode])) vfob_grp.append(rs) if self.MODEL == "KG-UV8H": rs = RadioSetting("vfob.ofst_dir", vfo_area + "B Shift Dir", RadioSettingValueList( OFFSET_LIST, OFFSET_LIST[_vfob.ofst_dir])) vfob_grp.append(rs) else: rs = RadioSetting("VFO_repeater_b", vfo_area + "B Repeater", RadioSettingValueBoolean( _settings.VFO_repeater_b)) vfob_grp.append(rs) rs = RadioSetting("vfob.scrambler", vfo_area + "B Descramble", RadioSettingValueList( SCRAMBLE_LIST, SCRAMBLE_LIST[_vfob.scrambler])) vfob_grp.append(rs) rs = RadioSetting("vfob.cmpndr", vfo_area + "B Compander", RadioSettingValueList( ONOFF_LIST, ONOFF_LIST[_vfob.cmpndr])) vfob_grp.append(rs) rs = RadioSetting("vfob.step", vfo_area + "B Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfob.step])) vfob_grp.append(rs) rs = RadioSetting("vfob.squelch", vfo_area + "B Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfob.squelch])) vfob_grp.append(rs) # FM RADIO PRESETS # memory stores raw integer value like 760 # radio will divide 760 by 10 and interpret correctly at 76.0 MHz for i in range(1, 21): val = getattr(_settings, 'FM_radio%i' % i) rs = RadioSetting("FM_radio%i" % i, "FM Preset %i" % i, RadioSettingValueFloat(76.0, 108.0, val / 10, 0.1, 1)) fmradio_grp.append(rs) # Freq Limits settings rs = RadioSetting("vhf_limits.rx_start", "VHF RX Lower Limit (MHz)", RadioSettingValueFloat( 30.000000, 299.999999, (self._memobj.vhf_limits.rx_start / 100000.0), 0.000001, 6)) lmt_grp.append(rs) rs = RadioSetting("vhf_limits.rx_stop", "VHF RX Upper Limit (MHz)", RadioSettingValueFloat( 30.000000, 299.999999, (self._memobj.vhf_limits.rx_stop / 100000.0), 0.000001, 6)) lmt_grp.append(rs) rs = RadioSetting("vhf_limits.tx_start", "VHF TX Lower Limit (MHz)", RadioSettingValueFloat( 30.000000, 299.999999, (self._memobj.vhf_limits.tx_start / 100000.0), 0.000001, 6)) lmt_grp.append(rs) rs = RadioSetting("vhf_limits.tx_stop", "VHF TX Upper Limit (MHz)", RadioSettingValueFloat( 30.000000, 299.999999, (self._memobj.vhf_limits.tx_stop / 100000.0), 0.000001, 6)) lmt_grp.append(rs) # MRT - TX Limits do not appear to change radio's ability # to transmit on other freqs. # MRT - Appears that the radio firmware prevent Tx # on anything other than a valid GMRS Freq rs = RadioSetting("uhf_limits.rx_start", "UHF RX Lower Limit (MHz)", RadioSettingValueFloat( 300.000000, 999.999999, (self._memobj.uhf_limits.rx_start / 100000.0), 0.000001, 6)) lmt_grp.append(rs) rs = RadioSetting("uhf_limits.rx_stop", "UHF RX Upper Limit (MHz)", RadioSettingValueFloat( 300.000000, 999.999999, (self._memobj.uhf_limits.rx_stop / 100000.0), 0.000001, 6)) lmt_grp.append(rs) rs = RadioSetting("uhf_limits.tx_start", "UHF TX Lower Limit (MHz)", RadioSettingValueFloat( 300.000000, 999.999999, (self._memobj.uhf_limits.tx_start / 100000.0), 0.000001, 6)) lmt_grp.append(rs) rs = RadioSetting("uhf_limits.tx_stop", "UHF TX Upper Limit (MHz)", RadioSettingValueFloat( 300.000000, 999.999999, (self._memobj.uhf_limits.tx_stop / 100000.0), 0.000001, 6)) lmt_grp.append(rs) # OEM info def _decode(lst): _str = ''.join([chr(int(c)) for c in lst if chr(int(c)) in chirp_common.CHARSET_ASCII]) return _str def do_nothing(setting, obj): return _str = _decode(self._memobj.oem_info.model) val = RadioSettingValueString(0, 8, _str) val.set_mutable(True) rs = RadioSetting("oem_info.model", areamsglabel, val) if self.MODEL == "KG-935G": oem_grp.append(rs) else: key_grp.append(rs) _str = _decode(self._memobj.oem_info.oem1) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.oem1", "OEM String 1", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.oem2) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.oem2", "Firmware Version ??", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.date) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.date", "OEM Date", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) return group def get_settings(self): try: return self._get_settings() except: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: if "[" in bit and "]" in bit: bit, index = bit.split("[", 1) index, junk = index.split("]", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) if self._is_freq(element): # setattr(obj, setting, int(element.value / 10)) # MRT rescale freq values to match radio # expected values setattr(obj, setting, int(element.values()[0]._current * 100000.0)) elif self._is_fmradio(element): # MRT rescale FM Radio values to match radio # expected values setattr(obj, setting, int(element.values()[0]._current * 10.0)) else: setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _is_freq(self, element): return ("rxfreq" in element.get_name() or "txoffset" in element.get_name() or "rx_start" in element.get_name() or "rx_stop" in element.get_name() or "tx_start" in element.get_name() or "tx_stop" in element.get_name()) def _is_fmradio(self, element): return "FM_radio" in element.get_name() def callid2str(self, cid): """Caller ID per MDC-1200 spec? Must be 3-6 digits (100 - 999999). One digit (binary) per byte, terminated with '0xc' """ bin2ascii = "0123456789" cidstr = "" for i in range(0, 6): b = cid[i].get_value() # Handle fluky firmware 0x0a is sometimes used instead of 0x00 if b == 0x0a: b = 0x00 if b == 0xc or b == 0xf: # the cid EOL break if b > 0xa: raise InvalidValueError( "Caller ID code has illegal byte 0x%x" % b) cidstr += bin2ascii[b] return cidstr @directory.register class KG935GPlusRadio(KG935GRadio): """Wouxun KG-935G Plus""" VENDOR = "Wouxun" MODEL = "KG-935G Plus" NEEDS_COMPAT_SERIAL = False def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT_935GPLUS, self._mmap) @directory.register class KGUV8HRadio(KG935GRadio): """Wouxun KG-UV8H""" VENDOR = "Wouxun" MODEL = "KG-UV8H" NEEDS_COMPAT_SERIAL = False def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT_UV8H, self._mmap) chirp-20240224/chirp/drivers/ts480.py0000644000175000017500000012105214456716614016072 0ustar hibbyhibby# Copyright 2019 Rick DeWitt # Implementing Kenwood TS-480 as Clone Mode # March 2021: Implementing true Split mode support per issue #8297 # March 6, 2021: PL tone download fix for issue #8877 # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ #seekto 0x0000; struct { // 20 bytes per chan u32 rxfreq; u32 txfreq; u8 xmode; // param stored as CAT value u8 tmode; u8 rtone; u8 ctone; u8 split:4, skip:4; u8 step; char name[8]; } ch_mem[110]; // 100 normal + 10 P-type struct { // 5 bytes each u32 asfreq; u8 asmode:4, // param stored as CAT value (0 -9) asdata:2, asnu:2; } asf[32]; struct { // 10 x 5 4-byte frequencies u32 ssfreq; } ssf[50]; struct { u8 ag; u8 an; u32 fa; u32 fb; u8 mf; u8 mg; u8 pc; u8 rg; u8 ty; } settings; struct { // Menu A/B settings char ex000; u8 ex003; // These params stored as nibbles u8 ex007; u8 ex008; u8 ex009; u8 ex010; u8 ex011; u8 ex012; u8 ex013; u8 ex014; u8 ex021; u8 ex022; u8 ex048; u8 ex049; u8 ex050; u8 ex051; u8 ex052; } exset[2]; char mdl_name[9]; // appended model name, first 9 chars """ MEMSIZE = 0x0b1d # img file size STIMEOUT = 0.6 BAUD = 0 # Initial baud rate MEMSEL = 0 # Default Menu A BEEPVOL = 5 # Default beep level W8S = 0.01 # short wait, secs W8L = 0.05 # long wait TS480_DUPLEX = ["", "split"] TS480_SKIP = ["", "S"] # start at 0:LSB TS480_MODES = ["LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "FSK-R"] EX_MODES = ["FSK-R", "CW-R"] TS480_TONES = list(chirp_common.TONES) TS480_TONES.append(1750.0) TS480_BANDS = [(50000, 24999999), # VFO Rx range. TX has lockouts (25000000, 59999999)] TS480_TUNE_STEPS = [0.5, 1.0, 2.5, 5.0, 6.25, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] RADIO_IDS = { # From kenwood_live.py; used to report wrong radio "ID019;": "TS-2000", "ID009;": "TS-850", "ID020:": "TS-480", "ID021;": "TS-590S", "ID023;": "TS-590SG" } def command(ser, cmd, rsplen, w8t=0.01, exts=""): """Send @cmd to radio via @ser""" # cmd is output string without ; terminator # rsplen is expected response char count, including terminator # If rsplen = 0 then do not read after write start = time.time() stx = cmd # preserve cmd for response check stx = stx + exts + ";" # append arguments ser.write(stx) LOG.debug("PC->RADIO [%s]" % stx) ts = time.time() # implement the wait after command while (time.time() - ts) < w8t: ix = 0 # NOP result = "" if rsplen > 0: # read response result = ser.read(rsplen) LOG.debug("RADIO->PC [%s]" % result) result = result[:-1] # remove terminator return result.strip() def _connect_radio(radio): """Determine baud rate and verify radio on-line""" global BAUD # Allows modification bauds = [9600, 115200, 57600, 38400, 19200, 4800] if BAUD > 0: bauds.insert(0, BAUD) # Make the detected one first # Flush the input buffer radio.pipe.timeout = 0.005 junk = radio.pipe.read(256) radio.pipe.timeout = STIMEOUT for bd in bauds: radio.pipe.baudrate = bd BAUD = bd radio.pipe.write(";") radio.pipe.write(";") resp = radio.pipe.read(16) radio.pipe.write("ID;") resp = radio.pipe.read(16) if resp.find(radio.ID) >= 0: # Good comms resp = command(radio.pipe, "AI0", 0, W8L) return elif resp in RADIO_IDS.keys(): msg = "Radio reported as model %s, not %s!" % \ (RADIO_IDS[resp], radio.MODEL) raise errors.RadioError(msg) raise errors.RadioError("No response from radio") def read_str(radio, trm=";"): """ Read chars until terminator """ stq = "" ctq = "" while ctq != trm: ctq = radio.pipe.read(1) stq += ctq LOG.debug(" + [%s]" % stq) return stq[:-1] # Return without trm def _read_mem(radio): """Get the memory map""" global BEEPVOL # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._upper + 10 # 10 P chans status.msg = "Reading Channel Memory..." radio.status_fn(status) result0 = command(radio.pipe, "EX0120000", 12, W8S) BEEPVOL = int(result0[6:12]) result0 = command(radio.pipe, "EX01200000", 0, W8L) # Silence beeps data = "" mrlen = 41 # Expected fixed return string length for chn in range(0, (radio._upper + 11)): # Loop stops at +10 # Request this mem chn r0ch = 999 r1ch = r0ch # return results can come back out of order while (r0ch != chn): # simplex result0 = command(radio.pipe, "MR0%03i" % chn, mrlen, W8S) result0 += read_str(radio) r0ch = int(result0[3:6]) while (r1ch != chn): # split result1 = command(radio.pipe, "MR1%03i" % chn, mrlen, W8S) result1 += read_str(radio) r1ch = int(result1[3:6]) data += radio._parse_mem_spec(result0, result1) # UI Update status.cur = chn status.msg = "Reading Channel Memory..." radio.status_fn(status) if len(data) == 0: # To satisfy run_tests raise errors.RadioError('No data received.') return data def _make_dat(sx, nb): """ Split the string sx into nb binary bytes """ vx = int(sx) dx = "" if nb > 3: dx += chr((vx >> 24) & 0xFF) if nb > 2: dx += chr((vx >> 16) & 0xFF) if nb > 1: dx += chr((vx >> 8) & 0xFF) dx += chr(vx & 0xFF) return dx def _sets_asf(stx): """ Process AS0 auto-mode setting """ asm = _make_dat(stx[0:11], 4) # 11-bit freq a1 = int(stx[11]) # 4-bit mode a2 = 0 # not used in TS-480 asm += chr((a1 << 4) | (a2 << 2)) return asm def my_val_list(setting, opts, obj, atrb, fix=0, ndx=-1): """Callback:from ValueList. Set the integer index.""" # This function is here to be available to get_mem and get_set # fix is optional additive offset to the list index # ndx is optional obj[ndx] array index value = opts.index(str(setting.value)) value += fix if ndx >= 0: # indexed obj setattr(obj[ndx], atrb, value) else: setattr(obj, atrb, value) return def _read_settings(radio): """ Continue filling memory map""" global MEMSEL # setc: the list of CAT commands for downloaded settings # Block parameters first. In the exact order of MEM_FORMAT setc = radio.SETC setc.extend(radio.EX) # Menu A EX params setc.extend(radio.EX) # Menu B status = chirp_common.Status() status.cur = 0 status.max = 32 + 50 + 8 + 17 + 17 status.msg = "Reading Settings..." radio.status_fn(status) setts = "" nc = 0 for cmc in setc: skipme = False argx = "" # Extended arguments if cmc == "AS0": skipme = True # flag to disable further processing for ix in range(32): # 32 AS params result0 = command(radio.pipe, cmc, 19, W8S, "%02i" % ix) xc = len(cmc) + 2 result0 = result0[xc:] setts += _sets_asf(result0) nc += 1 status.cur = nc radio.status_fn(status) elif cmc == "SS": skipme = True for ix in range(10): # 10 chans for nx in range(5): # 5 spots result0 = command(radio.pipe, cmc, 16, W8S, "%1i%1i" % (ix, nx)) setts += _make_dat(result0[4:], 4) nc += 1 status.cur = nc radio.status_fn(status) elif (cmc == "MF0") or (cmc == "MF1"): result0 = command(radio.pipe, cmc, 0, W8S) skipme = True # cmd only, no response else: # issue the cmc cmd as-is with argx if str(cmc).startswith("EX"): argx = "0000" result0 = command(radio.pipe, cmc, 0, W8S, argx) result0 = read_str(radio) # various length responses # strip the cmd echo xc = len(cmc) result0 = result0[xc:] # Cmd has been sent, process the result if (cmc == "FA") or (cmc == "FB"): # Response is 11-bit frq skipme = True setts += _make_dat(result0, 4) # 11-bit freq elif (cmc == "MF0") or (cmc == "MF1"): # No stored response skipme = True elif (cmc == "TY"): # remove upper 2 digits result0 = result0[2:] # Generic single byte processing if not skipme: setts += chr(int(result0)) if cmc == "MF": # Save the initial Menu selection MEMSEL = int(result0) nc += 1 status.cur = nc radio.status_fn(status) setts += radio.MODEL.ljust(9) # Now set the initial menu selection back result0 = command(radio.pipe, "MF", 0, W8L, "%1i" % MEMSEL) # And the original Beep Volume result0 = command(radio.pipe, "EX0120000%i" % BEEPVOL, 0, W8L) return setts def _write_mem(radio): """ Send MW commands for each channel """ global BEEPVOL # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio._upper status.msg = "Writing Channel Memory" radio.status_fn(status) result0 = command(radio.pipe, "EX0120000", 12, W8S) BEEPVOL = int(result0[6:12]) result0 = command(radio.pipe, "EX01200000", 0, W8L) # Silence beeps for chn in range(0, (radio._upper + 1)): _mem = radio._memobj.ch_mem[chn] cmx = "MW0%03i" % chn if _mem.rxfreq == 0: # Empty, deleted stm = cmx + "0" * 35 result0 = command(radio.pipe, stm, 0, W8L) else: stm = cmx + radio._make_base_spec(_mem, _mem.rxfreq) result0 = command(radio.pipe, stm, 0, W8L) # No response if _mem.split: # SPLIT mode cmx = "MW1%03i" % chn stm = cmx + radio._make_base_spec(_mem, _mem.txfreq) result0 = command(radio.pipe, stm, 0, W8L) status.cur = chn radio.status_fn(status) return def _write_sets(radio): """ Send settings and Menu a/b """ status = chirp_common.Status() status.cur = 0 status.max = 124 # Total to send status.msg = "Writing Settings" radio.status_fn(status) # Define mem struct shortcuts _sets = radio._memobj.settings _asf = radio._memobj.asf _ssf = radio._memobj.ssf _mex = radio._memobj.exset snx = 0 # Settings status counter stlen = 0 # No response count # Send 32 AS for ix in range(32): scm = "AS0%02i%011i%1i%1i" % (ix, _asf[ix].asfreq, _asf[ix].asmode, _asf[ix].asdata) result0 = command(radio.pipe, scm, stlen, W8S) snx += 1 status.cur = snx radio.status_fn(status) # Send 50 SS for ix in range(10): for kx in range(5): nx = ix * 5 + kx scm = "SS%1i%1i%011i" % (ix, kx, _ssf[nx].ssfreq) result0 = command(radio.pipe, scm, stlen, W8S) snx += 1 status.cur = snx radio.status_fn(status) # Send 8 thingies scm = "AG0%03i" % _sets.ag result0 = command(radio.pipe, scm, stlen, W8S) scm = "AN%1i" % _sets.an result0 = command(radio.pipe, scm, stlen, W8S) scm = "FA%011i" % _sets.fa result0 = command(radio.pipe, scm, stlen, W8S) scm = "FB%011i" % _sets.fb result0 = command(radio.pipe, scm, stlen, W8S) scm = "MG%03i" % _sets.mg result0 = command(radio.pipe, scm, stlen, W8S) scm = "PC%03i" % _sets.pc result0 = command(radio.pipe, scm, stlen, W8S) scm = "RG%03i" % _sets.rg result0 = command(radio.pipe, scm, stlen, W8S) # TY cmd is firmware read-only scm = "MF0" # Select menu A/B result0 = command(radio.pipe, scm, stlen, W8S) snx += 8 status.cur = snx radio.status_fn(status) # Send 17 Menu A EX setc = radio.EX # list of EX cmds for ix in range(2): for cmx in setc: if str(cmx)[0:2] == "MF": scm = cmx else: # The EX cmds scm = "%s0000%i" % (cmx, getattr(_mex[ix], cmx.lower())) result0 = command(radio.pipe, scm, stlen, W8S) snx += 1 status.cur = snx radio.status_fn(status) # Now set the initial menu selection back result0 = command(radio.pipe, "MF", 0, W8L, "%1i" % _sets.mf) # And the original Beep Volume result0 = command(radio.pipe, "EX0120000%i" % BEEPVOL, 0, W8L) return @directory.register class TS480_CRadio(chirp_common.CloneModeRadio): """ Kenwood TS-480 simulated clone mode """ VENDOR = "Kenwood" MODEL = "TS-480_CloneMode" ID = "ID020;" # Settings read/write cmd sequence list SETC = ["AS0", "SS", "AG0", "AN", "FA", "FB", "MF", "MG", "PC", "RG", "TY", "MF0"] # This is the TS-590SG MENU A/B read_settings parameter tuple list # The order is mandatory; to match the Mem_Format sequence EX = ["EX000", "EX003", "EX007", "EX008", "EX009", "EX010", "EX011", "EX012", "EX013", "EX014", "EX021", "EX022", "EX048", "EX049", "EX050", "EX051", "EX052", "MF1"] # EX menu settings label dictionary. Key is the EX number EX_LBL = {0: " Display brightness", 3: " Tuning control adj rate (Hz)", 12: " Beep volume", 13: " Sidetone volume", 14: " Message playback volume", 7: " Temporary MR Chan freq allowed", 8: " Program Scan slowdown", 9: " Program Scan slowdown range (Hz)", 10: " Program Scan hold", 11: " Scan Resume method", 21: " TX Power fine adjust", 22: " Timeout timer (Secs)", 48: " Panel PF-A function", 49: " MIC PF1 function", 50: " MIC PF2 function", 51: " MIC PF3 function", 52: " MIC PF4 function"} _upper = 99 def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = True rf.has_bank = False rf.has_ctone = True rf.has_dtcs = False rf.has_dtcs_polarity = False rf.has_name = True rf.has_settings = True rf.has_offset = True rf.has_mode = True rf.has_tuning_step = True rf.has_nostep_tuning = True # Radio accepts any entered freq rf.has_cross = False rf.has_comment = False rf.memory_bounds = (0, self._upper) rf.valid_bands = TS480_BANDS rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "*+-/" rf.valid_duplexes = TS480_DUPLEX rf.valid_modes = [x for x in TS480_MODES if x in chirp_common.MODES] rf.valid_skips = TS480_SKIP rf.valid_tuning_steps = TS480_TUNE_STEPS rf.valid_tmodes = ["", "Tone", "TSQL"] rf.valid_name_length = 8 # 8 character channel names return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.info = _( "P-VFO channels 100-109 are considered Settings.\n" "Only a subset of the over 130 available radio settings\n" "are supported in this release.\n") rp.pre_download = _( "Follow these instructions to download the radio memory:\n" "1 - Connect your interface cable\n" "2 - Radio > Download from radio: Don't adjust any settings\n" "on the radio head!\n" "3 - Disconnect your interface cable\n") rp.pre_upload = _( "Follow these instructions to upload the radio memory:\n" "1 - Connect your interface cable\n" "2 - Radio > Upload to radio: Don't adjust any settings\n" "on the radio head!\n" "3 - Disconnect your interface cable\n") return rp def sync_in(self): """Download from radio""" try: _connect_radio(self) data = _read_mem(self) data += _read_settings(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMap(data) self.process_mmap() return def sync_out(self): """Upload to radio""" try: _connect_radio(self) _write_mem(self) _write_sets(self) except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') return def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) return def get_memory(self, number): """Convert raw channel data (_mem) into UI columns (mem)""" mem = chirp_common.Memory() _mem = self._memobj.ch_mem[number] mem.number = number # --- Correct old img file loads with +/- offsets --- if (_mem.txfreq != 0) and (_mem.rxfreq != _mem.txfreq): _mem.split = 1 mnx = "" for char in _mem.name: mnx += chr(int(char)) mem.name = mnx.strip() mem.name = mem.name.upper() if _mem.rxfreq == 0: mem.empty = True return mem mem.empty = False mem.freq = int(_mem.rxfreq) mem.duplex = TS480_DUPLEX[0] # None by default mem.offset = 0 if _mem.split: # NO +/- Offsets, just split mem.duplex = TS480_DUPLEX[1] mem.offset = _mem.txfreq elif _mem.txfreq == 0: # leave offset alone, or run_tests will bomb mem.duplex = TS480_DUPLEX[0] mx = _mem.xmode - 1 # CAT modes start at 1 if _mem.xmode == 9: # except there is no xmode 9 mx = 7 mem.mode = TS480_MODES[mx] mem.tmode = "" mem.cross_mode = "Tone->Tone" mem.ctone = TS480_TONES[_mem.ctone] mem.rtone = TS480_TONES[_mem.rtone] if _mem.tmode == 1: mem.tmode = "Tone" elif _mem.tmode == 2: mem.tmode = "TSQL" elif _mem.tmode == 3: mem.tmode = "Cross" mem.skip = TS480_SKIP[_mem.skip] # Tuning step depends on mode options = [0.5, 1.0, 2.5, 5.0, 10.0] # SSB/CS/FSK if _mem.xmode == 4 or _mem.xmode == 5: # AM/FM options = TS480_TUNE_STEPS[3:] mem.tuning_step = options[_mem.step] return mem def set_memory(self, mem): """Convert UI column data (mem) into MEM_FORMAT memory (_mem)""" _mem = self._memobj.ch_mem[mem.number] if mem.empty: _mem.rxfreq = 0 _mem.txfreq = 0 _mem.split = 0 _mem.xmode = 0 _mem.step = 0 _mem.tmode = 0 _mem.rtone = 0 _mem.ctone = 0 _mem.skip = 0 _mem.name = " " return if mem.number > self._upper: # Specials: No Name changes ix = 0 # LOG.warning("Special Chan set_mem @ %i" % mem.number) else: nx = len(mem.name) for ix in range(8): if ix < nx: _mem.name[ix] = mem.name[ix].upper() else: _mem.name[ix] = " " # assignment needs 8 chrs _mem.rxfreq = mem.freq _mem.txfreq = 0 _mem.split = 0 if mem.duplex == "": _mem.txfreq = _mem.rxfreq elif mem.duplex == "split": _mem.split = 1 _mem.txfreq = mem.offset ix = TS480_MODES.index(mem.mode) _mem.xmode = ix + 1 # stored as CAT values, LSB= 1 if ix == 7: # FSK-R _mem.xmode = 9 # There is no CAT 8 _mem.tmode = 0 _mem.rtone = TS480_TONES.index(mem.rtone) _mem.ctone = TS480_TONES.index(mem.ctone) if mem.tmode == "Tone": _mem.tmode = 1 if mem.tmode == "TSQL": _mem.tmode = 2 _mem.skip = 0 if mem.skip == "S": _mem.skip = 1 options = [0.5, 1.0, 2.5, 5.0, 10.0] # SSB/CS/FSK steps if _mem.xmode == 4 or _mem.xmode == 5: # AM/FM options = TS480_TUNE_STEPS[3:] try: _mem.step = options.index(mem.tuning_step) except ValueError: _mem.step = options[0] return def validate_memory(self, mem): msgs = super().validate_memory(mem) if mem.mode in ('AM', 'FM'): if mem.tuning_step not in TS480_TUNE_STEPS[3:]: msgs.append(chirp_common.ValidationError( 'Tuning step %s must be in list %s for %s' % ( mem.tuning_step, ','.join(str(x) for x in TS480_TUNE_STEPS[3:]), mem.mode))) return msgs def _parse_mem_spec(self, spec0, spec1): """ Extract ascii memory parameters; build data string """ # spec0 is Rx freq string, spec1 is Tx # pad string so indexes match Kenwood docs spec0 = "x" + spec0 # match CAT document 1-based description ix = len(spec0) # _pxx variables are STRINGS _p1 = spec0[3] # P1 Tx/Rx Specification _p3 = spec0[5:7] # P3 Memory Channel _p4 = spec0[7:18] # P4 Rx Frequency _p5 = spec0[18] # P5 Mode _p6 = spec0[19] # P6 Chan Lockout (Skip) _p7 = spec0[20] # P7 Tone Mode _p8 = spec0[21:23] # P8 Tone Frequency Index _p9 = spec0[23:25] # P9 CTCSS Frequency Index _p14 = spec0[39:41] # P14 Step Size _p16 = spec0[41:50] # P16 Max 8-Char Name if assigned spec1 = "x" + spec1 _p4s = spec1[7:18] # P4s: Tx freq _split = 0 if _p4 != _p4s: _split = 16 # upper byte bit 0 set datm = "" # Fill in MEM_FORMAT sequence datm += _make_dat(_p4, 4) # rxreq: u32, 4 bytes/chars datm += _make_dat(_p4s, 4) # tx freq datm += chr(int(_p5)) # xmode: 0-9 datm += chr(int(_p7)) # Tmode: 0-3 datm += chr(int(_p8)) # rtone: 00-41 datm += chr(int(_p9)) # ctone: 00-41 datm += chr(int(_p6) + _split) # split 0/1 & skip: 0/1 datm += chr(int(_p14)) # step: 0-9 v1 = len(_p16) for ix in range(8): if ix < v1: datm += _p16[ix] else: datm += " " return datm def _make_base_spec(self, mem, freq): """ Generate memory channel parameter string """ spec = "%011i%1i%1i%1i%02i%02i00000000000000%02i0%s" \ % (freq, mem.xmode, mem.skip, mem.tmode, mem.rtone, mem.ctone, mem.step, mem.name) return spec.strip() def get_settings(self): """Translate the MEM_FORMAT structs into settings in the UI""" # Define mem struct write-back shortcuts _sets = self._memobj.settings _asf = self._memobj.asf _ssf = self._memobj.ssf _mex = self._memobj.exset _chm = self._memobj.ch_mem basic = RadioSettingGroup("basic", "Basic Settings") pvfo = RadioSettingGroup("pvfo", "VFO Band Edges") mena = RadioSettingGroup("mena", "Menu A") menb = RadioSettingGroup("menb", "Menu B") amode = RadioSettingGroup("amode", "Auto Mode") ssc = RadioSettingGroup("ssc", "Slow Scan") group = RadioSettings(basic, pvfo, mena, menb, amode, ssc) mhz1 = 1000000. # Callback functions def _my_readonly(setting, obj, atrb): """NOP callback, prevents writing the setting""" vx = 0 return def my_adjraw(setting, obj, atrb, fix=0, ndx=-1): """Callback for Integer add or subtract fix from value.""" vx = int(str(setting.value)) value = vx + int(fix) if value < 0: value = 0 if ndx < 0: setattr(obj, atrb, value) else: setattr(obj[ndx], atrb, value) return def my_mhz_val(setting, obj, atrb, ndx=-1): """ Callback to set freq back to Hz """ vx = float(str(setting.value)) vx = int(vx * mhz1) if ndx < 0: setattr(obj, atrb, vx) else: setattr(obj[ndx], atrb, vx) return def my_bool(setting, obj, atrb, ndx=-1): """ Callback to properly set boolean """ # set_settings is not setting [indexed] booleans??? vx = 0 if str(setting.value) == "True": vx = 1 if ndx < 0: setattr(obj, atrb, vx) else: setattr(obj[ndx], atrb, vx) return def my_asf_mode(setting, obj, nx=0): """ Callback to extract mode and create asmode, asdata """ v1 = TS480_MODES.index(str(setting.value)) v2 = 0 # asdata vx = v1 + 1 # stored as CAT values, same as xmode if v1 == 7: vx = 9 if v1 > 7: # a Data mode v2 = 1 if v1 == 8: vx = 1 # LSB elif v1 == 9: vx = 2 # USB elif v1 == 10: vx = 4 # FM setattr(obj[nx], "asdata", v2) setattr(obj[nx], "asmode", vx) return def my_fnctns(setting, obj, ndx, atrb): """ Filter only valid key function assignments """ vx = int(str(setting.value)) if vx > 79: vx = 99 # Off setattr(obj[ndx], atrb, vx) return def my_labels(kx): lbl = "%03i:" % kx # SG EX number lbl += self.EX_LBL[kx] # and the label to match return lbl # ===== BASIC GROUP ===== options = ["TS-480HX (200W)", "TS-480SAT (100W + AT)", "Japanese 50W type", "Japanese 20W type"] nx = _sets.ty & 7 # Can have 'reserved' upper 2 digits rx = RadioSettingValueString(14, 22, options[nx]) rset = RadioSetting("settings.ty", "FirmwareVersion", rx) rset.set_apply_callback(_my_readonly, _sets, "ty") basic.append(rset) rx = RadioSettingValueInteger(0, 255, _sets.ag) rset = RadioSetting("settings.ag", "AF Gain", rx) # rset.set_apply_callback(my_adjraw, _sets, "ag", -1) basic.append(rset) rx = RadioSettingValueInteger(0, 100, _sets.rg) rset = RadioSetting("settings.rg", "RF Gain", rx) # rset.set_apply_callback(my_adjraw, _sets, "rg", -1) basic.append(rset) options = ["ANT1", "ANT2"] # CAUTION: an has value of 1 or 2 rx = RadioSettingValueList(options, options[_sets.an - 1]) rset = RadioSetting("settings.an", "Antenna Selected", rx) # Add 1 to the changed value. S/b 1/2 rset.set_apply_callback(my_val_list, options, _sets, "an", 1) basic.append(rset) rx = RadioSettingValueInteger(0, 100, _sets.mg) rset = RadioSetting("settings.mg", "Microphone gain", rx) basic.append(rset) nx = 5 # Coarse step if bool(_mex[0].ex021): # Power Fine enabled in menu A nx = 1 vx = _sets.pc # Trap invalid values from run_tests.py if vx < 5: vx = 5 options = [200, 100, 50, 20] # subject to firmware rx = RadioSettingValueInteger(5, options[_sets.ty & 7], vx, nx) sx = "TX Output power (Watts)" rset = RadioSetting("settings.pc", sx, rx) basic.append(rset) val = _sets.fa / mhz1 # valid range is for receiver rx = RadioSettingValueFloat(0.05, 60.0, val, 0.001, 3) sx = "VFO-A Frequency (MHz)" rset = RadioSetting("settings.fa", sx, rx) rset.set_apply_callback(my_mhz_val, _sets, "fa") basic.append(rset) val = _sets.fb / mhz1 rx = RadioSettingValueFloat(0.05, 60.0, val, 0.001, 3) sx = "VFO-B Frequency (MHz)" rset = RadioSetting("settings.fb", sx, rx) rset.set_apply_callback(my_mhz_val, _sets, "fb") basic.append(rset) options = ["Menu A", "Menu B"] rx = RadioSettingValueList(options, options[_sets.mf]) sx = "Menu Selected" rset = RadioSetting("settings.mf", sx, rx) rset.set_apply_callback(my_val_list, options, _sets, "mf") basic.append(rset) # ==== VFO Edges Group ================ for mx in range(100, 110): val = _chm[mx].rxfreq / mhz1 if val < 1.8: # Many operators never use this val = 1.8 # So default is 0.0 rx = RadioSettingValueFloat(1.8, 54.0, val, 0.001, 3) sx = "VFO-Band %i lower limit (MHz)" % (mx - 100) rset = RadioSetting("ch_mem.rxfreq/%d" % mx, sx, rx) rset.set_apply_callback(my_mhz_val, _chm, "rxfreq", mx) pvfo.append(rset) val = _chm[mx].txfreq / mhz1 if val < 1.8: val = 54.0 rx = RadioSettingValueFloat(1.8, 54.0, val, 0.001, 3) sx = " VFO-Band %i upper limit (MHz)" % (mx - 100) rset = RadioSetting("ch_mem.txfreq/%d" % mx, sx, rx) rset.set_apply_callback(my_mhz_val, _chm, "txfreq", mx) pvfo.append(rset) kx = _chm[mx].xmode options = ["None", "LSB", "USB", "CW", "FM", "AM", "FSK", "CW-R", "N/A", "FSK-R"] rx = RadioSettingValueList(options, options[kx]) sx = " VFO-Band %i Tx/Rx Mode" % (mx - 100) rset = RadioSetting("ch_mem.xmode/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _chm, "xmode", 0, mx) pvfo.append(rset) # ==== Menu A/B Group ================= for mx in range(2): # A/B index sx = my_labels(0) rx = RadioSettingValueInteger(0, 4, _mex[mx].ex000) rset = RadioSetting("exset.ex000", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 9, _mex[mx].ex012) sx = my_labels(12) rset = RadioSetting("exset.ex012", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) sx = my_labels(13) rx = RadioSettingValueInteger(0, 9, _mex[mx].ex013) rset = RadioSetting("exset.ex013", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) sx = my_labels(14) rx = RadioSettingValueInteger(0, 9, _mex[mx].ex014) rset = RadioSetting("exset.ex014", sx, rx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["250", "500", "1000"] rx = RadioSettingValueList(options, options[_mex[mx].ex003]) sx = my_labels(3) rset = RadioSetting("exset.ex003/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex003", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex007)) sx = my_labels(7) rset = RadioSetting("exset.ex007/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex007", mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex008)) sx = my_labels(8) rset = RadioSetting("exset.ex008/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex008", mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["100", "200", "300", "400", "500"] rx = RadioSettingValueList(options, options[_mex[mx].ex009]) sx = my_labels(9) rset = RadioSetting("exset.ex009/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex009", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex010)) sx = my_labels(10) rset = RadioSetting("exset.ex010/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex010", mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["TO", "CO"] rx = RadioSettingValueList(options, options[_mex[mx].ex011]) sx = my_labels(11) rset = RadioSetting("exset.ex011/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex011", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueBoolean(bool(_mex[mx].ex021)) sx = my_labels(21) rset = RadioSetting("exset.ex021/%d" % mx, sx, rx) rset.set_apply_callback(my_bool, _mex, "ex021", mx) if mx == 0: mena.append(rset) else: menb.append(rset) options = ["Off", "3", "5", "10", "20", "30"] rx = RadioSettingValueList(options, options[_mex[mx].ex022]) sx = my_labels(22) rset = RadioSetting("exset.ex022/%d" % mx, sx, rx) rset.set_apply_callback(my_val_list, options, _mex, "ex022", 0, mx) if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 99, _mex[mx].ex048) sx = my_labels(48) rset = RadioSetting("exset.ex048/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex048") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 99, _mex[mx].ex049) sx = my_labels(49) rset = RadioSetting("exset.ex049/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex049") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 99, _mex[mx].ex050) sx = my_labels(50) rset = RadioSetting("exset.ex050/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex050") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 99, _mex[mx].ex051) sx = my_labels(51) rset = RadioSetting("exset.ex051/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex051") if mx == 0: mena.append(rset) else: menb.append(rset) rx = RadioSettingValueInteger(0, 99, _mex[mx].ex052) sx = my_labels(52) rset = RadioSetting("exset.ex052/%d" % mx, sx, rx) rset.set_apply_callback(my_fnctns, _mex, mx, "ex052") if mx == 0: mena.append(rset) else: menb.append(rset) # End of for mx loop # ==== Auto Scan Params (amode) ============== for ix in range(32): val = _asf[ix].asfreq / mhz1 rx = RadioSettingValueFloat(0.03, 60.0, val, 0.001, 3) rset = RadioSetting("asf.asfreq/%d" % ix, "Scan %02i Freq (MHz)" % ix, rx) rset.set_apply_callback(my_mhz_val, _asf, "asfreq", ix) amode.append(rset) mx = _asf[ix].asmode - 1 # Same logic as xmode if _asf[ix].asmode == 9: mx = 7 rx = RadioSettingValueList(TS480_MODES, TS480_MODES[mx]) rset = RadioSetting("asf.asmode/%d" % ix, " Mode", rx) rset.set_apply_callback(my_asf_mode, _asf, ix) amode.append(rset) # ==== Slow Scan Settings === for ix in range(10): # Chans for nx in range(5): # spots px = ((ix * 5) + nx) val = _ssf[px].ssfreq / mhz1 stx = " - - - Slot %02i Freq (MHz)" % nx if nx == 0: stx = "Slow Scan %02i, Slot 0 Freq (MHz" % ix rx = RadioSettingValueFloat(0, 54.0, val, 0.001, 3) rset = RadioSetting("ssf.ssfreq/%d" % px, stx, rx) rset.set_apply_callback(my_mhz_val, _ssf, "ssfreq", px) ssc.append(rset) return group # END get_settings() def set_settings(self, settings): _settings = self._memobj.settings _mem = self._memobj for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise return @classmethod def match_model(cls, fdata, fyle): """ Included to prevent 'File > New' error """ # Test the file data size if len(fdata) == MEMSIZE: return True else: return False chirp-20240224/chirp/drivers/baofeng_uv3r.py0000644000175000017500000005225314522657251017571 0ustar hibbyhibby# Copyright 2011 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Baofeng UV3r radio management module""" import time import logging from chirp.drivers.wouxun_common import do_download, do_upload from chirp import util, chirp_common, bitwise, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) def _uv3r_prep(radio): radio.pipe.write(b"\x05PROGRAM") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio did not ACK first command") radio.pipe.write(b"\x02") ident = radio.pipe.read(8) if len(ident) != 8: LOG.debug(util.hexprint(ident)) raise errors.RadioError("Radio did not send identification") radio.pipe.write(b"\x06") if radio.pipe.read(1) != b"\x06": raise errors.RadioError("Radio did not ACK ident") def uv3r_prep(radio): """Do the UV3R identification dance""" for _i in range(0, 10): try: return _uv3r_prep(radio) except errors.RadioError: time.sleep(1) raise e def uv3r_download(radio): """Talk to a UV3R and do a download""" try: uv3r_prep(radio) return do_download(radio, 0x0000, 0x0E40, 0x0010) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def uv3r_upload(radio): """Talk to a UV3R and do an upload""" try: uv3r_prep(radio) return do_upload(radio, 0x0000, 0x0E40, 0x0010) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) UV3R_MEM_FORMAT = """ #seekto 0x0010; struct { lbcd rx_freq[4]; u8 rxtone; lbcd offset[4]; u8 txtone; u8 ishighpower:1, iswide:1, dtcsinvt:1, unknown1:1, dtcsinvr:1, unknown2:1, duplex:2; u8 unknown; lbcd tx_freq[4]; } tx_memory[99]; #seekto 0x0780; struct { lbcd lower_vhf[2]; lbcd upper_vhf[2]; lbcd lower_uhf[2]; lbcd upper_uhf[2]; } limits; struct vfosettings { lbcd freq[4]; u8 rxtone; u8 unknown1; lbcd offset[3]; u8 txtone; u8 power:1, bandwidth:1, unknown2:4, duplex:2; u8 step; u8 unknown3[4]; }; #seekto 0x0790; struct { struct vfosettings uhf; struct vfosettings vhf; } vfo; #seekto 0x07C2; struct { u8 squelch; u8 vox; u8 timeout; u8 save:1, unknown_1:1, dw:1, ste:1, beep:1, unknown_2:1, bclo:1, ch_flag:1; u8 backlight:2, relaym:1, scanm:1, pri:1, unknown_3:3; u8 unknown_4[3]; u8 pri_ch; } settings; #seekto 0x07E0; u16 fm_presets[16]; #seekto 0x0810; struct { lbcd rx_freq[4]; u8 rxtone; lbcd offset[4]; u8 txtone; u8 ishighpower:1, iswide:1, dtcsinvt:1, unknown1:1, dtcsinvr:1, unknown2:1, duplex:2; u8 unknown; lbcd tx_freq[4]; } rx_memory[99]; #seekto 0x1008; struct { u8 unknown[8]; u8 name[6]; u8 pad[2]; } names[128]; """ STEPS = [5.0, 6.25, 10.0, 12.5, 20.0, 25.0] STEP_LIST = [str(x) for x in STEPS] BACKLIGHT_LIST = ["Off", "Key", "Continuous"] TIMEOUT_LIST = ["Off"] + ["%s sec" % x for x in range(30, 210, 30)] SCANM_LIST = ["TO", "CO"] PRI_CH_LIST = ["Off"] + ["%s" % x for x in range(1, 100)] CH_FLAG_LIST = ["Freq Mode", "Channel Mode"] POWER_LIST = ["Low", "High"] BANDWIDTH_LIST = ["Narrow", "Wide"] DUPLEX_LIST = ["Off", "-", "+"] STE_LIST = ["On", "Off"] UV3R_DUPLEX = ["", "-", "+", ""] UV3R_POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] UV3R_DTCS_POL = ["NN", "NR", "RN", "RR"] @directory.register class UV3RRadio(chirp_common.CloneModeRadio): """Baofeng UV-3R""" VENDOR = "Baofeng" MODEL = "UV-3R" NEEDS_COMPAT_SERIAL = False def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = UV3R_POWER_LEVELS rf.valid_bands = [(136000000, 235000000), (400000000, 529000000)] rf.valid_skips = [] rf.valid_duplexes = ["", "-", "+", "split"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS"] rf.valid_tuning_steps = STEPS rf.has_ctone = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.has_name = False rf.can_odd_split = True rf.memory_bounds = (1, 99) return rf def sync_in(self): self._mmap = uv3r_download(self) self.process_mmap() def sync_out(self): uv3r_upload(self) def process_mmap(self): self._memobj = bitwise.parse(UV3R_MEM_FORMAT, self._mmap) def get_memory(self, number): _mem = self._memobj.rx_memory[number - 1] mem = chirp_common.Memory() mem.number = number if _mem.get_raw(asbytes=False)[0] == "\xff": mem.empty = True return mem mem.freq = int(_mem.rx_freq) * 10 mem.offset = int(_mem.offset) * 10 mem.duplex = UV3R_DUPLEX[_mem.duplex] if mem.offset > 60000000: if mem.duplex == "+": mem.offset = mem.freq + mem.offset elif mem.duplex == "-": mem.offset = mem.freq - mem.offset mem.duplex = "split" mem.power = UV3R_POWER_LEVELS[1 - _mem.ishighpower] if not _mem.iswide: mem.mode = "NFM" dtcspol = (int(_mem.dtcsinvt) << 1) + _mem.dtcsinvr mem.dtcs_polarity = UV3R_DTCS_POL[dtcspol] if _mem.txtone in [0, 0xFF]: txmode = "" elif _mem.txtone < 0x33: mem.rtone = chirp_common.TONES[_mem.txtone - 1] txmode = "Tone" elif _mem.txtone >= 0x33: tcode = chirp_common.DTCS_CODES[_mem.txtone - 0x33] mem.dtcs = tcode txmode = "DTCS" else: LOG.warn("Bug: tx_mode is %02x" % _mem.txtone) if _mem.rxtone in [0, 0xFF]: rxmode = "" elif _mem.rxtone < 0x33: mem.ctone = chirp_common.TONES[_mem.rxtone - 1] rxmode = "Tone" elif _mem.rxtone >= 0x33: rcode = chirp_common.DTCS_CODES[_mem.rxtone - 0x33] mem.dtcs = rcode rxmode = "DTCS" else: LOG.warn("Bug: rx_mode is %02x" % _mem.rxtone) if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS": mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) return mem def _set_tone(self, _mem, which, value, mode): if mode == "Tone": val = chirp_common.TONES.index(value) + 1 elif mode == "DTCS": val = chirp_common.DTCS_CODES.index(value) + 0x33 elif mode == "": val = 0 else: raise errors.RadioError("Internal error: tmode %s" % mode) setattr(_mem, which, val) def _set_memory(self, mem, _mem): if mem.empty: _mem.set_raw("\xff" * 16) return _mem.rx_freq = mem.freq / 10 if mem.duplex == "split": diff = mem.freq - mem.offset _mem.offset = abs(diff) / 10 _mem.duplex = UV3R_DUPLEX.index(diff < 0 and "+" or "-") for i in range(0, 4): _mem.tx_freq[i].set_raw("\xFF") else: _mem.offset = mem.offset / 10 _mem.duplex = UV3R_DUPLEX.index(mem.duplex) _mem.tx_freq = (mem.freq + mem.offset) / 10 _mem.ishighpower = mem.power == UV3R_POWER_LEVELS[0] _mem.iswide = mem.mode == "FM" _mem.dtcsinvt = mem.dtcs_polarity[0] == "R" _mem.dtcsinvr = mem.dtcs_polarity[1] == "R" rxtone = txtone = 0 rxmode = txmode = "" if mem.tmode == "DTCS": rxmode = txmode = "DTCS" rxtone = txtone = mem.dtcs elif mem.tmode and mem.tmode != "Cross": rxtone = txtone = mem.tmode == "Tone" and mem.rtone or mem.ctone txmode = "Tone" rxmode = mem.tmode == "TSQL" and "Tone" or "" elif mem.tmode == "Cross": txmode, rxmode = mem.cross_mode.split("->", 1) if txmode == "DTCS": txtone = mem.dtcs elif txmode == "Tone": txtone = mem.rtone if rxmode == "DTCS": rxtone = mem.dtcs elif rxmode == "Tone": rxtone = mem.ctone self._set_tone(_mem, "txtone", txtone, txmode) self._set_tone(_mem, "rxtone", rxtone, rxmode) def set_memory(self, mem): _tmem = self._memobj.tx_memory[mem.number - 1] _rmem = self._memobj.rx_memory[mem.number - 1] self._set_memory(mem, _tmem) self._set_memory(mem, _rmem) def get_settings(self): _settings = self._memobj.settings _vfo = self._memobj.vfo basic = RadioSettingGroup("basic", "Basic Settings") group = RadioSettings(basic) rs = RadioSetting("squelch", "Squelch Level", RadioSettingValueInteger(0, 9, _settings.squelch)) basic.append(rs) rs = RadioSetting("backlight", "LCD Back Light", RadioSettingValueList( BACKLIGHT_LIST, BACKLIGHT_LIST[_settings.backlight])) basic.append(rs) rs = RadioSetting("beep", "Keypad Beep", RadioSettingValueBoolean(_settings.beep)) basic.append(rs) rs = RadioSetting("vox", "VOX Level (0=OFF)", RadioSettingValueInteger(0, 9, _settings.vox)) basic.append(rs) rs = RadioSetting("dw", "Dual Watch", RadioSettingValueBoolean(_settings.dw)) basic.append(rs) rs = RadioSetting("ste", "Squelch Tail Eliminate", RadioSettingValueList( STE_LIST, STE_LIST[_settings.ste])) basic.append(rs) rs = RadioSetting("save", "Battery Saver", RadioSettingValueBoolean(_settings.save)) basic.append(rs) rs = RadioSetting("timeout", "Time Out Timer", RadioSettingValueList( TIMEOUT_LIST, TIMEOUT_LIST[_settings.timeout])) basic.append(rs) rs = RadioSetting("scanm", "Scan Mode", RadioSettingValueList( SCANM_LIST, SCANM_LIST[_settings.scanm])) basic.append(rs) rs = RadioSetting("relaym", "Repeater Sound Response", RadioSettingValueBoolean(_settings.relaym)) basic.append(rs) rs = RadioSetting("bclo", "Busy Channel Lock Out", RadioSettingValueBoolean(_settings.bclo)) basic.append(rs) rs = RadioSetting("pri", "Priority Channel Scanning", RadioSettingValueBoolean(_settings.pri)) basic.append(rs) rs = RadioSetting("pri_ch", "Priority Channel", RadioSettingValueList( PRI_CH_LIST, PRI_CH_LIST[_settings.pri_ch])) basic.append(rs) rs = RadioSetting("ch_flag", "Display Mode", RadioSettingValueList( CH_FLAG_LIST, CH_FLAG_LIST[_settings.ch_flag])) basic.append(rs) _limit = int(self._memobj.limits.lower_vhf) / 10 if _limit < 115 or _limit > 239: _limit = 144 rs = RadioSetting("limits.lower_vhf", "VHF Lower Limit (115-239 MHz)", RadioSettingValueInteger(115, 235, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.lower_vhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) _limit = int(self._memobj.limits.upper_vhf) / 10 if _limit < 115 or _limit > 239: _limit = 146 rs = RadioSetting("limits.upper_vhf", "VHF Upper Limit (115-239 MHz)", RadioSettingValueInteger(115, 235, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.upper_vhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) _limit = int(self._memobj.limits.lower_uhf) / 10 if _limit < 200 or _limit > 529: _limit = 420 rs = RadioSetting("limits.lower_uhf", "UHF Lower Limit (200-529 MHz)", RadioSettingValueInteger(200, 529, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.lower_uhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) _limit = int(self._memobj.limits.upper_uhf) / 10 if _limit < 200 or _limit > 529: _limit = 450 rs = RadioSetting("limits.upper_uhf", "UHF Upper Limit (200-529 MHz)", RadioSettingValueInteger(200, 529, _limit)) def apply_limit(setting, obj): value = int(setting.value) * 10 obj.upper_uhf = value rs.set_apply_callback(apply_limit, self._memobj.limits) basic.append(rs) vfo_preset = RadioSettingGroup("vfo_preset", "VFO Presets") group.append(vfo_preset) def convert_bytes_to_freq(bytes): real_freq = 0 real_freq = bytes return chirp_common.format_freq(real_freq * 10) def apply_vhf_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 obj.vhf.freq = value val = RadioSettingValueString( 0, 10, convert_bytes_to_freq(int(_vfo.vhf.freq))) rs = RadioSetting("vfo.vhf.freq", "VHF RX Frequency (115.00000-236.00000)", val) rs.set_apply_callback(apply_vhf_freq, _vfo) vfo_preset.append(rs) rs = RadioSetting("vfo.vhf.duplex", "Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_vfo.vhf.duplex])) vfo_preset.append(rs) def convert_bytes_to_offset(bytes): real_offset = 0 real_offset = bytes return chirp_common.format_freq(real_offset * 10000) def apply_vhf_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10000 obj.vhf.offset = value val = RadioSettingValueString( 0, 10, convert_bytes_to_offset(int(_vfo.vhf.offset))) rs = RadioSetting("vfo.vhf.offset", "Offset (0.00-37.995)", val) rs.set_apply_callback(apply_vhf_offset, _vfo) vfo_preset.append(rs) rs = RadioSetting("vfo.vhf.power", "Power Level", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfo.vhf.power])) vfo_preset.append(rs) rs = RadioSetting("vfo.vhf.bandwidth", "Bandwidth", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfo.vhf.bandwidth])) vfo_preset.append(rs) rs = RadioSetting("vfo.vhf.step", "Step", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfo.vhf.step])) vfo_preset.append(rs) def apply_uhf_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 obj.uhf.freq = value val = RadioSettingValueString( 0, 10, convert_bytes_to_freq(int(_vfo.uhf.freq))) rs = RadioSetting("vfo.uhf.freq", "UHF RX Frequency (200.00000-529.00000)", val) rs.set_apply_callback(apply_uhf_freq, _vfo) vfo_preset.append(rs) rs = RadioSetting("vfo.uhf.duplex", "Shift Direction", RadioSettingValueList( DUPLEX_LIST, DUPLEX_LIST[_vfo.uhf.duplex])) vfo_preset.append(rs) def apply_uhf_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10000 obj.uhf.offset = value val = RadioSettingValueString( 0, 10, convert_bytes_to_offset(int(_vfo.uhf.offset))) rs = RadioSetting("vfo.uhf.offset", "Offset (0.00-69.995)", val) rs.set_apply_callback(apply_uhf_offset, _vfo) vfo_preset.append(rs) rs = RadioSetting("vfo.uhf.power", "Power Level", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfo.uhf.power])) vfo_preset.append(rs) rs = RadioSetting("vfo.uhf.bandwidth", "Bandwidth", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfo.uhf.bandwidth])) vfo_preset.append(rs) rs = RadioSetting("vfo.uhf.step", "Step", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfo.uhf.step])) vfo_preset.append(rs) fm_preset = RadioSettingGroup("fm_preset", "FM Radio Presets") group.append(fm_preset) for i in range(0, 16): if self._memobj.fm_presets[i] < 0x01AF: used = True preset = self._memobj.fm_presets[i] / 10.0 + 65 else: used = False preset = 65 rs = RadioSetting("fm_presets_%1i" % i, "FM Preset %i" % (i + 1), RadioSettingValueBoolean(used), RadioSettingValueFloat(65, 108, preset, 0.1, 1)) fm_preset.append(rs) return group def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): if element.get_name() == "fm_preset": self._set_fm_preset(element) else: self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _set_fm_preset(self, settings): for element in settings: try: index = (int(element.get_name().split("_")[-1])) val = list(element.value) if val[0].get_value(): value = int(val[1].get_value() * 10 - 650) else: value = 0x01AF LOG.debug("Setting fm_presets[%1i] = %s" % (index, value)) setting = self._memobj.fm_presets setting[index] = value except Exception: LOG.debug(element.get_name()) raise @classmethod def match_model(cls, filedata, filename): return len(filedata) == 3648 def get_raw_memory(self, number): _rmem = self._memobj.tx_memory[number - 1] _tmem = self._memobj.rx_memory[number - 1] return repr(_rmem) + repr(_tmem) chirp-20240224/chirp/drivers/alinco.py0000644000175000017500000006361714522657251016464 0ustar hibbyhibby# Copyright 2011 Dan Smith # 2016 Matt Weyland # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import chirp_common, bitwise, memmap, errors, directory, util from chirp.settings import RadioSettingGroup, RadioSetting from chirp.settings import RadioSettingValueBoolean import time import logging import codecs LOG = logging.getLogger(__name__) DRX35_MEM_FORMAT = """ #seekto 0x0120; u8 used_flags[25]; #seekto 0x0200; struct { u8 new_used:1, unknown1:1, isnarrow:1, isdigital:1, ishigh:1, unknown2:3; u8 unknown3:6, duplex:2; u8 unknown4:4, tmode:4; u8 unknown5:4, step:4; bbcd freq[4]; u8 unknown6[1]; bbcd offset[3]; u8 rtone; u8 ctone; u8 dtcs_tx; u8 dtcs_rx; u8 name[7]; u8 unknown8[2]; u8 unknown9:6, power:2; u8 unknownA[6]; } memory[100]; #seekto 0x0130; u8 skips[25]; """ # 0000 0111 # 0000 0010 # Response length is: # 1. \r\n # 2. Four-digit address, followed by a colon # 3. 16 bytes in hex (32 characters) # 4. \r\n RLENGTH = 2 + 5 + 32 + 2 STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0] class AlincoStyleRadio(chirp_common.CloneModeRadio): """Base class for all known Alinco radios""" _memsize = 0 _model = b"NONE" NEEDS_COMPAT_SERIAL = False def _send(self, data): LOG.debug("PC->R: (%2i)\n%s" % (len(data), util.hexprint(data))) self.pipe.write(data) self.pipe.read(len(data)) def _read(self, length): data = self.pipe.read(length) LOG.debug("R->PC: (%2i)\n%s" % (len(data), util.hexprint(data))) return data def _download_chunk(self, addr): if addr % 16: raise Exception("Addr 0x%04x not on 16-byte boundary" % addr) cmd = b"AL~F%04XR\r\n" % addr self._send(cmd) resp = self._read(RLENGTH).strip() if len(resp) == 0: raise errors.RadioError("No response from radio") if b":" not in resp: raise errors.RadioError("Unexpected response from radio") addr, _data = resp.split(b":", 1) data = codecs.decode(_data, 'hex') if len(data) != 16: LOG.debug("Response was:") LOG.debug("|%s|") LOG.debug("Which I converted to:") LOG.debug(util.hexprint(data)) raise Exception("Radio returned less than 16 bytes") return data def _download(self, limit): self._identify() data = b"" for addr in range(0, limit, 16): time.sleep(0.1) data += self._download_chunk(addr) if self.status_fn: status = chirp_common.Status() status.cur = addr + 16 status.max = self._memsize status.msg = "Downloading from radio" self.status_fn(status) self._send(b"AL~E\r\n") self._read(20) return memmap.MemoryMap(data) def _identify(self): for _i in range(0, 3): self._send(b"%s\r\n" % self._model) resp = self._read(6) if resp.strip() == b"OK": return True time.sleep(1) return False def _upload_chunk(self, addr): if addr % 16: raise Exception("Addr 0x%04x not on 16-byte boundary" % addr) _data = self._mmap[addr:addr+16] data = codecs.encode(_data, 'hex').upper() cmd = b"AL~F%04XW%s\r\n" % (addr, data) self._send(cmd) def _upload(self, limit): if not self._identify(): raise Exception("I can't talk to this model") for addr in range(0x100, limit, 16): time.sleep(0.1) self._upload_chunk(addr) if self.status_fn: status = chirp_common.Status() status.cur = addr + 16 status.max = self._memsize status.msg = "Uploading to radio" self.status_fn(status) self._send(b"AL~E\r\n") self._read(20) def process_mmap(self): self._memobj = bitwise.parse(DRX35_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._download(self._memsize) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: self._upload(self._memsize) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def get_raw_memory(self, number): return repr(self._memobj.memory[number]) DUPLEX = ["", "-", "+"] TMODES = ["", "Tone", "", "TSQL"] + [""] * 12 TMODES[12] = "DTCS" DCS_CODES = { "Alinco": chirp_common.DTCS_CODES, "Jetstream": (17,) + chirp_common.DTCS_CODES, } CHARSET = (["\x00"] * 0x30) + \ [chr(x + ord("0")) for x in range(0, 10)] + \ [chr(x + ord("A")) for x in range(0, 26)] + [" "] + \ list("\x00" * 128) def _get_name(_mem): name = "" for i in _mem.name: if i in [0x00, 0xFF]: break name += CHARSET[i] return name def _set_name(mem, _mem): name = [0x00] * 7 j = 0 for i in range(0, 7): try: name[j] = CHARSET.index(mem.name[i]) j += 1 except IndexError: pass except ValueError: pass return name ALINCO_TONES = list(chirp_common.TONES) ALINCO_TONES.remove(159.8) ALINCO_TONES.remove(165.5) ALINCO_TONES.remove(171.3) ALINCO_TONES.remove(177.3) ALINCO_TONES.remove(183.5) ALINCO_TONES.remove(189.9) ALINCO_TONES.remove(196.6) ALINCO_TONES.remove(199.5) ALINCO_TONES.remove(206.5) ALINCO_TONES.remove(229.1) ALINCO_TONES.remove(254.1) class DRx35Radio(AlincoStyleRadio): """Base class for the DR-x35 radios""" _range = [(118000000, 155000000)] _power_levels = [] _valid_tones = ALINCO_TONES def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS"] rf.valid_modes = ["FM", "NFM"] rf.valid_skips = ["", "S"] rf.valid_bands = self._range rf.memory_bounds = (0, 99) rf.has_ctone = True rf.has_bank = False rf.has_dtcs_polarity = False rf.can_delete = False rf.valid_tuning_steps = STEPS rf.valid_name_length = 7 rf.valid_power_levels = self._power_levels rf.valid_dtcs_codes = DCS_CODES[self.VENDOR] return rf def _get_used(self, number): _usd = self._memobj.used_flags[number / 8] bit = (0x80 >> (number % 8)) return _usd & bit def _set_used(self, number, is_used): _usd = self._memobj.used_flags[number / 8] bit = (0x80 >> (number % 8)) if is_used: _usd |= bit else: _usd &= ~bit def _get_power(self, _mem): if self._power_levels: return self._power_levels[_mem.ishigh] return None def _set_power(self, _mem, mem): if self._power_levels: _mem.ishigh = mem.power is None or \ mem.power == self._power_levels[1] def _get_extra(self, _mem, mem): mem.extra = RadioSettingGroup("extra", "Extra") dig = RadioSetting("isdigital", "Digital", RadioSettingValueBoolean(bool(_mem.isdigital))) dig.set_doc("Digital/Packet mode enabled") mem.extra.append(dig) def _set_extra(self, _mem, mem): for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_memory(self, number): _mem = self._memobj.memory[number] _skp = self._memobj.skips[number / 8] _usd = self._memobj.used_flags[number / 8] bit = (0x80 >> (number % 8)) mem = chirp_common.Memory() mem.number = number if not self._get_used(number) and self.MODEL != "JT220M": mem.empty = True return mem elif self.MODEL == 'JT220M': mem.immutable = ['empty'] mem.freq = int(_mem.freq) * 100 mem.rtone = self._valid_tones[_mem.rtone] mem.ctone = self._valid_tones[_mem.ctone] mem.duplex = DUPLEX[_mem.duplex] mem.offset = int(_mem.offset) * 100 mem.tmode = TMODES[_mem.tmode] mem.dtcs = DCS_CODES[self.VENDOR][_mem.dtcs_tx] mem.tuning_step = STEPS[_mem.step] if _mem.isnarrow: mem.mode = "NFM" mem.power = self._get_power(_mem) if _skp & bit: mem.skip = "S" mem.name = _get_name(_mem).rstrip() self._get_extra(_mem, mem) return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number] _skp = self._memobj.skips[mem.number / 8] _usd = self._memobj.used_flags[mem.number / 8] bit = (0x80 >> (mem.number % 8)) if self._get_used(mem.number) and not mem.empty: # Initialize the memory _mem.set_raw("\x00" * 32) self._set_used(mem.number, not mem.empty) if mem.empty: return _mem.freq = mem.freq / 100 try: _tone = mem.rtone _mem.rtone = self._valid_tones.index(mem.rtone) _tone = mem.ctone _mem.ctone = self._valid_tones.index(mem.ctone) except ValueError: raise errors.UnsupportedToneError("This radio does not support " + "tone %.1fHz" % _tone) _mem.duplex = DUPLEX.index(mem.duplex) _mem.offset = mem.offset / 100 _mem.tmode = TMODES.index(mem.tmode) _mem.dtcs_tx = DCS_CODES[self.VENDOR].index(mem.dtcs) _mem.dtcs_rx = DCS_CODES[self.VENDOR].index(mem.dtcs) _mem.step = STEPS.index(mem.tuning_step) _mem.isnarrow = mem.mode == "NFM" self._set_power(_mem, mem) if mem.skip: _skp |= bit else: _skp &= ~bit _mem.name = _set_name(mem, _mem) self._set_extra(_mem, mem) @directory.register class DR03Radio(DRx35Radio): """Alinco DR03""" VENDOR = "Alinco" MODEL = "DR03T" _model = b"DR135" _memsize = 4096 _range = [(28000000, 29695000)] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0x64:0x66] == b'\x00\x28' @directory.register class DR06Radio(DRx35Radio): """Alinco DR06""" VENDOR = "Alinco" MODEL = "DR06T" _model = b"DR435" _memsize = 4096 _range = [(50000000, 53995000)] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0x64:0x66] == b'\x00\x50' @directory.register class DR135Radio(DRx35Radio): """Alinco DR135""" VENDOR = "Alinco" MODEL = "DR135T" _model = b"DR135" _memsize = 4096 _range = [(118000000, 173000000)] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0x64:0x66] == b'\x01\x44' @directory.register class DR235Radio(DRx35Radio): """Alinco DR235""" VENDOR = "Alinco" MODEL = "DR235T" _model = b"DR235" _memsize = 4096 _range = [(216000000, 280000000)] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0x64:0x66] == b'\x02\x22' @directory.register class DR435Radio(DRx35Radio): """Alinco DR435""" VENDOR = "Alinco" MODEL = "DR435T" _model = b"DR435" _memsize = 4096 _range = [(350000000, 511000000)] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0x64:0x66] == b'\x04\x00' @directory.register class DJ596Radio(DRx35Radio): """Alinco DJ596""" VENDOR = "Alinco" MODEL = "DJ596" _model = b"DJ596" _memsize = 4096 _range = [(136000000, 174000000), (400000000, 511000000)] _power_levels = [chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("High", watts=5.00)] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0x64:0x66] == b'\x45\x01' @directory.register class JT220MRadio(DRx35Radio): """Jetstream JT220""" VENDOR = "Jetstream" MODEL = "JT220M" _model = b"DR136" _memsize = 8192 _range = [(216000000, 280000000)] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and \ filedata[0x60:0x64] == b'2009' @directory.register class DJ175Radio(DRx35Radio): """Alinco DJ175""" VENDOR = "Alinco" MODEL = "DJ175" _model = b"DJ175" _memsize = 6896 _range = [(136000000, 174000000), (400000000, 511000000)] _power_levels = [ chirp_common.PowerLevel("Low", watts=0.50), chirp_common.PowerLevel("Mid", watts=2.00), chirp_common.PowerLevel("High", watts=5.00), ] @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize def _get_used(self, number): return self._memobj.memory[number].new_used def _set_used(self, number, is_used): self._memobj.memory[number].new_used = is_used def _get_power(self, _mem): return self._power_levels[_mem.power] def _set_power(self, _mem, mem): if mem.power in self._power_levels: _mem.power = self._power_levels.index(mem.power) def _download_chunk(self, addr): if addr % 16: raise Exception("Addr 0x%04x not on 16-byte boundary" % addr) cmd = b"AL~F%04XR\r\n" % addr self._send(cmd) _data = self._read(34).strip() if len(_data) == 0: raise errors.RadioError("No response from radio") data = codecs.decode(_data, 'hex') if len(data) != 16: LOG.debug("Response was:") LOG.debug("|%r|" % _data) LOG.debug("Which I converted to:") LOG.debug(util.hexprint(data)) raise Exception("Radio returned less than 16 bytes") return data DJG7_MEM_FORMAT = """ #seekto 0x200; ul16 bank[50]; ul16 special_bank[7]; #seekto 0x1200; struct { u8 empty; ul32 freq; u8 mode; u8 step; ul32 offset; u8 duplex; u8 squelch_type; u8 tx_tone; u8 rx_tone; u8 dcs; ul24 unknown1; u8 skip; ul32 unknown2; ul32 unknown3; ul32 unknown4; char name[32]; } memory[1000]; """ class AlincoDJG7(AlincoStyleRadio): """Alinco DJ-G7EG""" VENDOR = "Alinco" MODEL = "DJ-G7EG" BAUD_RATE = 57600 # Those are different from the other Alinco radios. STEPS = [5.0, 6.25, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0, 125.0, 150.0, 200.0, 500.0, 1000.0] DUPLEX = ["", "+", "-"] MODES = ["NFM", "FM", "AM", "WFM"] TMODES = ["", "??1", "Tone", "TSQL", "TSQL-R", "DTCS"] # This is a bit of a hack to avoid overwriting _identify() _memsize = 0x1a7c0 _range = [(500000, 1300000000)] @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "1. Ensure your firmware version is 4_10 or higher\n" "2. Turn radio off\n" "3. Connect your interface cable\n" "4. Turn radio on\n" "5. Press and release PTT 3 times while holding MONI key\n" "6. Supported baud rates: 57600 (default) and 19200\n" " (rotate dial while holding MONI to change)\n" "7. Click OK\n") rp.pre_upload = _( "1. Ensure your firmware version is 4_10 or higher\n" "2. Turn radio off\n" "3. Connect your interface cable\n" "4. Turn radio on\n" "5. Press and release PTT 3 times while holding MONI key\n" "6. Supported baud rates: 57600 (default) and 19200\n" " (rotate dial while holding MONI to change)\n" "7. Click OK\n") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_dtcs_polarity = False rf.has_bank = False rf.has_settings = False rf.valid_modes = self.MODES rf.valid_tmodes = ["", "Tone", "TSQL", "Cross", "TSQL-R", "DTCS"] rf.valid_tuning_steps = self.STEPS rf.valid_bands = self._range rf.valid_skips = ["", "S"] rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 16 rf.memory_bounds = (0, 999) return rf def _download_chunk(self, addr): if addr % 0x40: raise Exception("Addr 0x%04x not on 64-byte boundary" % addr) cmd = b"AL~F%05XR\r" % addr self._send(cmd) # Response: "\r\n[ ... data ... ]\r\n # data is encoded in hex, hence we read two chars per byte _data = self._read(2+2*64+2).strip() if len(_data) == 0: raise errors.RadioError("No response from radio") data = codecs.decode(_data, "hex") if len(data) != 64: LOG.debug("Response was:") LOG.debug("|%s|" % _data) LOG.debug("Which I converted to:") LOG.debug(util.hexprint(data)) raise Exception("Chunk from radio has wrong size") return data def _detect_baudrate_and_identify(self): if self._identify(): return True else: # Apparently Alinco support suggests to try again at a lower baud # rate if their cable fails with the default rate. See #4355. LOG.info("Could not talk to radio. Trying again at 19200 baud") self.pipe.baudrate = 19200 return self._identify() def _download(self, limit): self._detect_baudrate_and_identify() data = b"\x00"*0x200 for addr in range(0x200, limit, 0x40): data += self._download_chunk(addr) # Other Alinco drivers delay here, but doesn't seem to be necessary # for this model. if self.status_fn: status = chirp_common.Status() status.cur = addr status.max = limit status.msg = "Downloading from radio" self.status_fn(status) return memmap.MemoryMapBytes(data) def _upload_chunk(self, addr): if addr % 0x40: raise Exception("Addr 0x%04x not on 64-byte boundary" % addr) _data = self._mmap[addr:addr+0x40] data = codecs.encode(_data, "hex").upper() cmd = b"AL~F%05XW%s\r" % (addr, data) self._send(cmd) resp = self._read(6) if resp.strip() != b"OK": raise Exception("Unexpected response from radio: %s" % resp) def _upload(self, limit): if not self._detect_baudrate_and_identify(): raise Exception("I can't talk to this model") for addr in range(0x200, self._memsize, 0x40): self._upload_chunk(addr) # Other Alinco drivers delay here, but doesn't seem to be necessary # for this model. if self.status_fn: status = chirp_common.Status() status.cur = addr status.max = self._memsize status.msg = "Uploading to radio" self.status_fn(status) def _get_empty_flag(self, freq, mode): # Returns flag used to hide a channel from the main band. This occurs # when the mode is anything but NFM or FM (main band can only do those) # or when the frequency is outside of the range supported by the main # band. if mode not in ("NFM", "FM"): return 0x01 if (freq >= 136000000 and freq < 174000000) or \ (freq >= 400000000 and freq < 470000000) or \ (freq >= 1240000000 and freq < 1300000000): return 0x02 else: return 0x01 def _check_channel_consistency(self, number): _mem = self._memobj.memory[number] if _mem.empty != 0x00: if _mem.unknown1 == 0xffffff: # Previous versions of this code have skipped the unknown # fields. They contain bytes of value if the channel is empty # and thus those bytes remain 0xff when the channel is put to # use. The radio is totally fine with this but the Alinco # programming software is not (see #5275). Here, we check for # this and report if it is encountered. LOG.warning("Channel %d is inconsistent: Found 0xff in " "non-empty channel. Touch channel to fix." % number) if _mem.empty != self._get_empty_flag(_mem.freq, self.MODES[_mem.mode]): LOG.warning("Channel %d is inconsistent: Found out of band " "frequency. Touch channel to fix." % number) def process_mmap(self): self._memobj = bitwise.parse(DJG7_MEM_FORMAT, self._mmap) # We check all channels for corruption (see bug #5275) but we don't fix # it automatically because it would be unpolite to modify something on # a read operation. A log message is emitted though for the user to # take actions. for number in range(len(self._memobj.memory)): self._check_channel_consistency(number) def get_memory(self, number): _mem = self._memobj.memory[number] mem = chirp_common.Memory() mem.number = number if _mem.empty == 0: mem.empty = True else: mem.freq = int(_mem.freq) mem.mode = self.MODES[_mem.mode] mem.tuning_step = self.STEPS[_mem.step] mem.offset = int(_mem.offset) mem.duplex = self.DUPLEX[_mem.duplex] if self.TMODES[_mem.squelch_type] == "TSQL" and \ _mem.tx_tone != _mem.rx_tone: mem.tmode = "Cross" mem.cross_mode = "Tone->Tone" else: mem.tmode = self.TMODES[_mem.squelch_type] mem.rtone = ALINCO_TONES[_mem.tx_tone-1] mem.ctone = ALINCO_TONES[_mem.rx_tone-1] mem.dtcs = DCS_CODES[self.VENDOR][_mem.dcs] if _mem.skip: mem.skip = "S" # FIXME find out what every other byte is used for. Japanese? mem.name = str(_mem.name.get_raw(asbytes=False)[::2]).rstrip('\0') return mem def set_memory(self, mem): # Get a low-level memory object mapped to the image _mem = self._memobj.memory[mem.number] if mem.empty: _mem.set_raw("\xff" * (_mem.size() // 8)) _mem.empty = 0x00 else: _mem.empty = self._get_empty_flag(mem.freq, mem.mode) _mem.freq = mem.freq _mem.mode = self.MODES.index(mem.mode) _mem.step = self.STEPS.index(mem.tuning_step) _mem.offset = mem.offset _mem.duplex = self.DUPLEX.index(mem.duplex) if mem.tmode == "Cross": _mem.squelch_type = self.TMODES.index("TSQL") try: _mem.tx_tone = ALINCO_TONES.index(mem.rtone)+1 except ValueError: raise errors.UnsupportedToneError( "This radio does not support tone %.1fHz" % mem.rtone) try: _mem.rx_tone = ALINCO_TONES.index(mem.ctone)+1 except ValueError: raise errors.UnsupportedToneError( "This radio does not support tone %.1fHz" % mem.ctone) elif mem.tmode == "TSQL": _mem.squelch_type = self.TMODES.index("TSQL") # Note how the same TSQL tone is copied to both memory # locations try: _mem.tx_tone = ALINCO_TONES.index(mem.ctone)+1 _mem.rx_tone = ALINCO_TONES.index(mem.ctone)+1 except ValueError: raise errors.UnsupportedToneError( "This radio does not support tone %.1fHz" % mem.ctone) else: _mem.squelch_type = self.TMODES.index(mem.tmode) try: _mem.tx_tone = ALINCO_TONES.index(mem.rtone)+1 except ValueError: raise errors.UnsupportedToneError( "This radio does not support tone %.1fHz" % mem.rtone) try: _mem.rx_tone = ALINCO_TONES.index(mem.ctone)+1 except ValueError: raise errors.UnsupportedToneError( "This radio does not support tone %.1fHz" % mem.ctone) _mem.dcs = DCS_CODES[self.VENDOR].index(mem.dtcs) _mem.skip = (mem.skip == "S") _mem.name = "\x00".join(mem.name.rstrip()).ljust(32, "\x00") _mem.unknown1 = 0x3e001c _mem.unknown2 = 0x0000000a _mem.unknown3 = 0x00000000 _mem.unknown4 = 0x00000000 @directory.register class AlincoDJG7EG(AlincoDJG7): """Alinco DJ-G7EG""" MODEL = "DJ-G7EG" _model = b"AL~DJ-G7EG" @directory.register class AlincoDJG7T(AlincoDJG7): """Alinco DJ-G7T""" MODEL = "DJ-G7T" _model = b"AL~DJ-G7T" chirp-20240224/chirp/drivers/ft818.py0000755000175000017500000002274214446523722016066 0ustar hibbyhibby# # Copyright 2012 Filippi Marco # Copyright 2018 Vinny Stipo # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """FT818 management module""" from chirp.drivers import ft817 from chirp import chirp_common, errors, directory from chirp.settings import RadioSetting, RadioSettingValueBoolean import logging LOG = logging.getLogger(__name__) @directory.register class FT818Radio(ft817.FT817Radio): """Yaesu FT-818""" BAUD_RATE = 9600 MODEL = "FT-818" _model = "" _memsize = 6573 _block_lengths = [2, 40, 208, 208, 208, 208, 198, 53, 130, 118, 130] MEM_FORMAT = """ struct mem_struct { u8 tag_on_off:1, tag_default:1, unknown1:3, mode:3; u8 duplex:2, is_duplex:1, is_cwdig_narrow:1, is_fm_narrow:1, freq_range:3; u8 skip:1, unknown2:1, ipo:1, att:1, unknown3:4; u8 ssb_step:2, am_step:3, fm_step:3; u8 unknown4:6, tmode:2; u8 unknown5:2, tx_mode:3, tx_freq_range:3; u8 unknown6:1, unknown_toneflag:1, tone:6; u8 unknown7:1, dcs:7; ul16 rit; u32 freq; u32 offset; u8 name[8]; }; #seekto 0x4; struct { u8 fst:1, lock:1, nb:1, pbt:1, unknownb:1, dsp:1, agc:2; u8 vox:1, vlt:1, bk:1, kyr:1, unknown5:1, cw_paddle:1, pwr_meter_mode:2; u8 vfob_band_select:4, vfoa_band_select:4; u8 unknowna; u8 backlight:2, color:2, contrast:4; u8 beep_freq:1, beep_volume:7; u8 arts_beep:2, main_step:1, cw_id:1, scope:1, pkt_rate:1, resume_scan:2; u8 op_filter:2, lock_mode:2, cw_pitch:4; u8 sql_rf_gain:1, ars_144:1, ars_430:1, cw_weight:5; u8 cw_delay; u8 unknown8:1, sidetone:7; u8 batt_chg:2, cw_speed:6; u8 disable_amfm_dial:1, vox_gain:7; u8 cat_rate:2, emergency:1, vox_delay:5; u8 dig_mode:3, mem_group:1, unknown9:1, apo_time:3; u8 dcs_inv:2, unknown10:1, tot_time:5; u8 mic_scan:1, ssb_mic:7; u8 mic_key:1, am_mic:7; u8 unknown11:1, fm_mic:7; u8 unknown12:1, dig_mic:7; u8 extended_menu:1, pkt_mic:7; u8 unknown14:1, pkt9600_mic:7; il16 dig_shift; il16 dig_disp; i8 r_lsb_car; i8 r_usb_car; i8 t_lsb_car; i8 t_usb_car; u8 unknown15:2, menu_item:6; u8 unknown16:4, menu_sel:4; u16 unknown17; u8 art:1, scn_mode:2, dw:1, pri:1, unknown18:1, tx_power:2; u8 spl:1, unknown:1, uhf_antenna:1, vhf_antenna:1, air_antenna:1, bc_antenna:1, sixm_antenna:1, hf_antenna:1; } settings; #seekto 0x2A; struct mem_struct vfoa[16]; struct mem_struct vfob[16]; struct mem_struct home[4]; struct mem_struct qmb; struct mem_struct mtqmb; struct mem_struct mtune; #seekto 0x431; u8 visible[25]; u8 pmsvisible; #seekto 0x44B; u8 filled[25]; u8 pmsfilled; #seekto 0x465; struct mem_struct memory[200]; struct mem_struct pms[2]; #seekto 0x1903; u8 callsign[7]; #seekto 0x19AD; struct mem_struct sixtymeterchannels[5]; """ SPECIAL_MEMORIES = { "VFOa-1.8M": -37, "VFOa-3.5M": -36, "VFOa-5M": -35, "VFOa-7M": -34, "VFOa-10M": -33, "VFOa-14M": -32, "VFOa-18M": -31, "VFOa-21M": -30, "VFOa-24M": -29, "VFOa-28M": -28, "VFOa-50M": -27, "VFOa-FM": -26, "VFOa-AIR": -25, "VFOa-144": -24, "VFOa-430": -23, "VFOa-HF": -22, "VFOb-1.8M": -21, "VFOb-3.5M": -20, "VFOb-5M": -19, "VFOb-7M": -18, "VFOb-10M": -17, "VFOb-14M": -16, "VFOb-18M": -15, "VFOb-21M": -14, "VFOb-24M": -13, "VFOb-28M": -12, "VFOb-50M": -11, "VFOb-FM": -10, "VFOb-AIR": -9, "VFOb-144": -8, "VFOb-430": -7, "VFOb-HF": -6, "HOME HF": -5, "HOME 50M": -4, "HOME 144": -3, "HOME 430": -2, "QMB": -1, } FIRST_VFOB_INDEX = -6 LAST_VFOB_INDEX = -21 FIRST_VFOA_INDEX = -22 LAST_VFOA_INDEX = -37 SPECIAL_PMS = { "PMS-L": -39, "PMS-U": -38, } LAST_PMS_INDEX = -39 SPECIAL_MEMORIES.update(SPECIAL_PMS) SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys())) @directory.register class FT818NDUSRadio(FT818Radio): """Yaesu FT-818ND (US version)""" MODEL = "FT-818ND (US)" _model = "" _US_model = True _memsize = 6703 _block_lengths = [2, 40, 208, 208, 208, 208, 198, 53, 130, 118, 130, 130] SPECIAL_60M = { "M-601": -44, "M-602": -43, "M-603": -42, "M-604": -41, "M-605": -40, } LAST_SPECIAL60M_INDEX = -44 SPECIAL_MEMORIES = dict(FT818Radio.SPECIAL_MEMORIES) SPECIAL_MEMORIES.update(SPECIAL_60M) SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys())) def _get_special_60m(self, number): mem = chirp_common.Memory() mem.number = self.SPECIAL_60M[number] mem.extd_number = number _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number] mem = self._get_memory(mem, _mem) mem.immutable = ["number", "rtone", "ctone", "extd_number", "name", "dtcs", "tmode", "cross_mode", "dtcs_polarity", "power", "duplex", "offset", "comment", "empty"] return mem def _set_special_60m(self, mem): if mem.empty: # can't delete 60M memories! raise Exception("Sorry, 60M memory can't be deleted") cur_mem = self._get_special_60m(self.SPECIAL_MEMORIES_REV[mem.number]) for key in cur_mem.immutable: if cur_mem.__dict__[key] != mem.__dict__[key]: raise errors.RadioError("Editing field `%s' " % key + "is not supported on M-60x channels") if mem.mode not in ["USB", "LSB", "CW", "CWR", "NCW", "NCWR", "DIG"]: raise errors.RadioError("Mode {mode} is not valid " "in 60m channels".format(mode=mem.mode)) _mem = self._memobj.sixtymeterchannels[-self.LAST_SPECIAL60M_INDEX + mem.number] self._set_memory(mem, _mem) def get_memory(self, number): if number in self.SPECIAL_60M.keys(): return self._get_special_60m(number) elif number < 0 and \ self.SPECIAL_MEMORIES_REV[number] in self.SPECIAL_60M.keys(): # I can't stop delete operation from losing extd_number but # I know how to get it back return self._get_special_60m(self.SPECIAL_MEMORIES_REV[number]) else: return FT818Radio.get_memory(self, number) def set_memory(self, memory): if memory.number in self.SPECIAL_60M.values(): return self._set_special_60m(memory) else: return FT818Radio.set_memory(self, memory) def get_settings(self): top = FT818Radio.get_settings(self) basic = top[0] rs = RadioSetting("emergency", "Emergency", RadioSettingValueBoolean( self._memobj.settings.emergency)) basic.append(rs) return top chirp-20240224/chirp/drivers/th350.py0000644000175000017500000002444714430171343016047 0ustar hibbyhibby# Copyright 2019 Zhaofeng Li # Copyright 2013 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from __future__ import division import struct import logging from math import floor from chirp import chirp_common, directory, bitwise, memmap, errors, util from .uvb5 import BaofengUVB5 LOG = logging.getLogger(__name__) mem_format = """ struct memory { lbcd freq[4]; lbcd offset[4]; u8 unknown1:2, txpol:1, rxpol:1, compander:1, scrambler:1, unknown2:2; u8 rxtoneb; u8 rxtonea; u8 txtoneb; u8 txtonea; u8 pttid:1, scanadd:1, isnarrow:1, bcl:1, highpower:1, revfreq:1, duplex:2; u8 unknown[2]; }; #seekto 0x0000; char ident[32]; u8 blank[16]; struct memory vfo1; struct memory channels[128]; #seekto 0x0840; struct memory vfo3; struct memory vfo2; #seekto 0x09D0; u16 fm_presets[16]; #seekto 0x0A30; struct { u8 name[5]; } names[128]; #seekto 0x0D30; struct { u8 squelch; u8 freqmode_ab:1, save_funct:1, backlight:1, beep_tone_disabled:1, roger:1, tdr:1, scantype:2; u8 language:1, workmode_b:1, workmode_a:1, workmode_fm:1, voice_prompt:1, fm:1, pttid:2; u8 unknown_0:5, timeout:3; u8 mdf_b:2, mdf_a:2, unknown_1:2, txtdr:2; u8 unknown_2:4, ste_disabled:1, unknown_3:2, sidetone:1; u8 vox; u8 unk1; u8 mem_chan_a; u16 fm_vfo; u8 unk4; u8 unk5; u8 mem_chan_b; u8 unk6; u8 last_menu; // number of last menu item accessed } settings; #seekto 0x0D50; struct { u8 code[6]; } pttid; #seekto 0x0F30; struct { lbcd lower_vhf[2]; lbcd upper_vhf[2]; lbcd lower_uhf[2]; lbcd upper_uhf[2]; } limits; #seekto 0x0FF0; struct { u8 vhfsquelch0; u8 vhfsquelch1; u8 vhfsquelch2; u8 vhfsquelch3; u8 vhfsquelch4; u8 vhfsquelch5; u8 vhfsquelch6; u8 vhfsquelch7; u8 vhfsquelch8; u8 vhfsquelch9; u8 unknown1[6]; u8 uhfsquelch0; u8 uhfsquelch1; u8 uhfsquelch2; u8 uhfsquelch3; u8 uhfsquelch4; u8 uhfsquelch5; u8 uhfsquelch6; u8 uhfsquelch7; u8 uhfsquelch8; u8 uhfsquelch9; u8 unknown2[6]; u8 vhfhipwr0; u8 vhfhipwr1; u8 vhfhipwr2; u8 vhfhipwr3; u8 vhfhipwr4; u8 vhfhipwr5; u8 vhfhipwr6; u8 vhfhipwr7; u8 vhflopwr0; u8 vhflopwr1; u8 vhflopwr2; u8 vhflopwr3; u8 vhflopwr4; u8 vhflopwr5; u8 vhflopwr6; u8 vhflopwr7; u8 uhfhipwr0; u8 uhfhipwr1; u8 uhfhipwr2; u8 uhfhipwr3; u8 uhfhipwr4; u8 uhfhipwr5; u8 uhfhipwr6; u8 uhfhipwr7; u8 uhflopwr0; u8 uhflopwr1; u8 uhflopwr2; u8 uhflopwr3; u8 uhflopwr4; u8 uhflopwr5; u8 uhflopwr6; u8 uhflopwr7; } test; """ def do_ident(radio): radio.pipe.timeout = 3 radio.pipe.write(b"\x05TROGRAM") for x in range(10): ack = radio.pipe.read(1) if ack == b'\x06': break else: raise errors.RadioError("Radio did not ack programming mode") radio.pipe.write(b"\x02") ident = radio.pipe.read(8) LOG.debug(util.hexprint(ident)) if not ident.startswith(b'HKT511'): raise errors.RadioError("Unsupported model") radio.pipe.write(b"\x06") ack = radio.pipe.read(1) if ack != b"\x06": raise errors.RadioError("Radio did not ack ident") def do_status(radio, direction, addr): status = chirp_common.Status() status.msg = "Cloning %s radio" % direction status.cur = addr status.max = 0x1000 radio.status_fn(status) def do_download(radio): do_ident(radio) data = b"TRI350 Radio Program data v1.08\x00" data += (b"\x00" * 16) for i in range(0, 0x1000, 16): frame = struct.pack(">cHB", b"R", i, 16) radio.pipe.write(frame) result = radio.pipe.read(20) if frame[1:4] != result[1:4]: LOG.debug(util.hexprint(result)) raise errors.RadioError("Invalid response for address 0x%04x" % i) data += result[4:] do_status(radio, "from", i) return memmap.MemoryMapBytes(data) def do_upload(radio): do_ident(radio) data = radio._mmap.get_byte_compatible()[0x0030:] for i in range(0, 0x1000, 16): frame = struct.pack(">cHB", b"W", i, 16) frame += data[i:i + 16] radio.pipe.write(frame) ack = radio.pipe.read(1) if ack != b"\x06": # UV-B5/UV-B6 radios with 27 menus do not support service settings # and will stop ACKing when the upload reaches 0x0F10 if i == 0x0F10: # must be a radio with 27 menus detected - stop upload break else: LOG.debug("Radio NAK'd block at address 0x%04x" % i) raise errors.RadioError( "Radio NAK'd block at address 0x%04x" % i) LOG.debug("Radio ACK'd block at address 0x%04x" % i) do_status(radio, "to", i) DUPLEX = ["", "-", "+"] CHARSET = "0123456789- ABCDEFGHIJKLMNOPQRSTUVWXYZ/_+*" POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=1), chirp_common.PowerLevel("High", watts=5)] @directory.register class Th350Radio(BaofengUVB5): """TYT TH-350""" VENDOR = "TYT" MODEL = "TH-350" BAUD_RATE = 9600 NEEDS_COMPAT_SERIAL = False SPECIALS = { "VFO1": -3, "VFO2": -2, "VFO3": -1, } _memsize = 0x1000 @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ("This TYT TH-350 driver is an alpha version. " "Proceed with Caution and backup your data. " "Always confirm the correctness of your settings with the " "official programmer.") return rp def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_cross = True rf.has_rx_dtcs = True rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_duplexes = DUPLEX + ["split"] rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_characters = CHARSET rf.valid_name_length = 5 rf.valid_bands = [(130000000, 175000000), (220000000, 269000000), (400000000, 520000000)] rf.valid_modes = ["FM", "NFM"] rf.valid_special_chans = list(self.SPECIALS.keys()) rf.valid_power_levels = POWER_LEVELS rf.valid_tuning_steps = [5.0, 6.25, 10.0, 12.5, 20.0, 25.0] rf.has_ctone = True rf.has_bank = False rf.has_tuning_step = False rf.memory_bounds = (1, 128) return rf def sync_in(self): try: self._mmap = do_download(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): try: do_upload(self) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) def _decode_tone(self, _mem, which): def _get(field): return int(getattr(_mem, "%s%s" % (which, field))) tonea, toneb = _get('tonea'), _get('toneb') if tonea == 0xff: mode = val = pol = None elif tonea >= 0x80: # DTCS # D754N -> 0x87 0x54 # D754I -> 0xc7 0x54 # Yes. Decimal digits as hex. You're seeing that right. # No idea why TYT engineers would do something like that. pold = tonea // 16 if pold not in [0x8, 0xc]: LOG.warn("Bug: tone is %04x %04x" % (tonea, toneb)) mode = val = pol = None else: mode = 'DTCS' val = ((tonea % 16) * 100 + toneb // 16 * 10 + (toneb % 16)) pol = 'N' if pold == 8 else 'R' else: # Tone # 107.2 -> 0x10 0x72. Seriously. mode = 'Tone' val = (tonea // 16 * 100 + (tonea % 16) * 10 + toneb // 16 + toneb % 16 / 10) pol = None return mode, val, pol def _encode_tone(self, _mem, which, mode, val, pol): def _set(field, value): setattr(_mem, "%s%s" % (which, field), value) if mode == "Tone": tonea = int( val // 100 * 16 + val // 10 % 10 ) toneb = int( floor(val % 10) * 16 + floor(val * 10) % 10 ) elif mode == "DTCS": tonea = (0x80 if pol == 'N' else 0xc0) + \ val // 100 toneb = (val // 10) % 10 * 16 + \ val % 10 else: tonea = toneb = 0xff _set('tonea', tonea) _set('toneb', toneb) def _get_memobjs(self, number): if isinstance(number, str): return (getattr(self._memobj, number.lower()), None) elif number < 0: for k, v in list(self.SPECIALS.items()): if number == v: return (getattr(self._memobj, k.lower()), None) else: return (self._memobj.channels[number - 1], self._memobj.names[number - 1].name) @classmethod def match_model(cls, filedata, filename): return (filedata.startswith(b"TRI350 Radio Program data") and len(filedata) == (cls._memsize + 0x30)) chirp-20240224/chirp/drivers/th7800.py0000644000175000017500000006051214556146076016145 0ustar hibbyhibby# Copyright 2014 Tom Hayward # Copyright 2014 Jens Jensen # Copyright 2014 James Lee N1DDK # Copyright 2016 Nathan Crapo (TH-7800 only) # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import bitwise, chirp_common, directory, errors, util, memmap import struct from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueBoolean, \ RadioSettingValueString, RadioSettings, \ RadioSettingValueMap, zero_indexed_seq_map from chirp.chirp_common import format_freq import logging from datetime import date LOG = logging.getLogger(__name__) TH7800_MEM_FORMAT = """ struct mem { lbcd rx_freq[4]; lbcd tx_freq[4]; lbcd ctcss[2]; lbcd dtcs[2]; u8 power:2, clk_sft:1, unknown0a:2, display:1, // freq=0, name=1 scan:2; u8 fmdev:2, // wide=00, mid=01, narrow=10 scramb:1, compand:1, emphasis:1, unknown1a:2, sqlmode:1; // carrier, tone u8 rptmod:2, // off, -, + reverse:1, talkaround:1, step:4; u8 dtcs_pol:2, unknown3:4, tmode:2; lbcd offset[4]; u8 hsdtype:2, // off, 2-tone, 5-tone, dtmf unknown5a:1, am:1, unknown5b:4; u8 unknown6[3]; char name[6]; u8 empty[2]; }; #seekto 0x%04X; struct mem memory[800]; #seekto 0x%04X; struct { struct mem lower; struct mem upper; } scanlimits[5]; #seekto 0x%04X; struct { u8 unk0xdc20:5, left_sql:3; u8 apo; u8 unk0xdc22:5, backlight:3; u8 unk0xdc23; u8 beep:1, keylock:1, pttlock:2, unk0xdc24_32:2, hyper_chan:1, right_func_key:1; u8 tbst_freq:2, unk0xdc25_4:2, mute_mode:2, unk0xdc25_10:2; u8 ars:1, unk0xdc26_54:3, auto_am:1, unk0xdc26_210:3; u8 unk0xdc27_76543:5, scan_mode:1, unk0xdc27_1:1, scan_resume:1; u16 scramb_freq; u16 scramb_freq1; u8 unk0xdc2c; u8 unk0xdc2d; u8 unk0xdc2e:5, right_sql:3; u8 unk0xdc2f:8; u8 tot; u8 unk0xdc30; u8 unk0xdc31; u8 unk0xdc32; u8 unk0xdc34; u8 unk0xdc35; u8 unk0xdc36; u8 unk0xdc37; u8 p1; u8 p2; u8 p3; u8 p4; } settings; #seekto 0x%04X; u8 chan_active[128]; u8 scan_enable[128]; u8 priority[128]; #seekto 0x%04X; struct { char sn[8]; char model[8]; char code[16]; u8 empty[8]; lbcd prog_yr[2]; lbcd prog_mon; lbcd prog_day; u8 empty_10f2c[4]; } info; struct { lbcd lorx[4]; lbcd hirx[4]; lbcd lotx[4]; lbcd hitx[4]; } bandlimits[9]; """ BLANK_MEMORY = "\xFF" * 8 + "\x00\x10\x23\x00\xC0\x08\x06\x00" \ "\x00\x00\x76\x00\x00\x00" + "\xFF" * 10 DTCS_POLARITY = ["NN", "RN", "NR", "RR"] SCAN_MODES = ["", "S", "P"] MODES = ["WFM", "FM", "NFM"] TMODES = ["", "Tone", "TSQL", "DTCS"] POWER_LEVELS = [chirp_common.PowerLevel("Low", watts=5.00), chirp_common.PowerLevel("Mid2", watts=10.00), chirp_common.PowerLevel("Mid1", watts=20.00), chirp_common.PowerLevel("High", watts=50.00)] BUSY_LOCK = ["off", "Carrier", "2 tone"] MICKEYFUNC = ["None", "SCAN", "SQL.OFF", "TCALL", "PPTR", "PRI", "LOW", "TONE", "MHz", "REV", "HOME", "BAND", "VFO/MR"] SQLPRESET = ["Off", "2", "5", "9", "Full"] BANDS = ["30 MHz", "50 MHz", "60 MHz", "108 MHz", "150 MHz", "250 MHz", "350 MHz", "450 MHz", "850 MHz"] STEPS = [2.5, 5.0, 6.25, 7.5, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] def add_radio_setting(radio_setting_group, mem_field, ui_name, option_map, current, doc=None): setting = RadioSetting(mem_field, ui_name, RadioSettingValueMap(option_map, current)) if doc is not None: setting.set_doc(doc) radio_setting_group.append(setting) def add_radio_bool(radio_setting_group, mem_field, ui_name, current, doc=None): setting = RadioSetting(mem_field, ui_name, RadioSettingValueBoolean(bool(current))) radio_setting_group.append(setting) class TYTTH7800Base(chirp_common.Radio): """Base class for TYT TH-7800""" VENDOR = "TYT" def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 800) rf.has_bank = False rf.has_tuning_step = True rf.valid_tuning_steps = STEPS rf.can_odd_split = True rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = TMODES rf.has_ctone = False rf.valid_power_levels = POWER_LEVELS rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC + "#*-+" rf.valid_bands = [(108000000, 180000000), (350000000, 399995000), (400000000, 512000000)] rf.valid_skips = SCAN_MODES rf.valid_modes = MODES + ["AM"] rf.valid_name_length = 6 rf.has_settings = True return rf def process_mmap(self): self._memobj = bitwise.parse( TH7800_MEM_FORMAT % (self._mmap_offset, self._scanlimits_offset, self._settings_offset, self._chan_active_offset, self._info_offset), self._mmap) def get_active(self, banktype, num): """get active flag for channel active, scan enable, or priority banks""" bank = getattr(self._memobj, banktype) index = (num - 1) // 8 bitpos = (num - 1) % 8 mask = 2**bitpos enabled = bank[index] & mask if enabled: return True else: return False def set_active(self, banktype, num, enable=True): """set active flag for channel active, scan enable, or priority banks""" bank = getattr(self._memobj, banktype) index = (num - 1) // 8 bitpos = (num - 1) % 8 mask = 2**bitpos if enable: bank[index] |= mask else: bank[index] &= ~mask def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) def get_memory(self, number): _mem = self._memobj.memory[number - 1] mem = chirp_common.Memory() mem.number = number mem.empty = not self.get_active("chan_active", number) if mem.empty: return mem mem.freq = int(_mem.rx_freq) * 10 txfreq = int(_mem.tx_freq) * 10 if txfreq == mem.freq: mem.duplex = "" elif txfreq == 0: mem.duplex = "off" mem.offset = 0 elif abs(txfreq - mem.freq) > 70000000: mem.duplex = "split" mem.offset = txfreq elif txfreq < mem.freq: mem.duplex = "-" mem.offset = mem.freq - txfreq elif txfreq > mem.freq: mem.duplex = "+" mem.offset = txfreq - mem.freq mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_pol] mem.tmode = TMODES[int(_mem.tmode)] mem.ctone = mem.rtone = int(_mem.ctcss) / 10.0 mem.dtcs = int(_mem.dtcs) mem.name = str(_mem.name) mem.name = mem.name.replace("\xFF", " ").rstrip() if not self.get_active("scan_enable", number): mem.skip = "S" elif self.get_active("priority", number): mem.skip = "P" else: mem.skip = "" mem.mode = _mem.am and "AM" or MODES[int(_mem.fmdev)] mem.power = POWER_LEVELS[_mem.power] mem.tuning_step = STEPS[_mem.step] mem.extra = RadioSettingGroup("extra", "Extra") add_radio_setting(mem.extra, "display", "Display", zero_indexed_seq_map(["Frequency", "Name"]), _mem.display) add_radio_setting(mem.extra, "hsdtype", "HSD TYPE", zero_indexed_seq_map(["OFF", "2TON", "5TON", "DTMF"]), _mem.hsdtype) add_radio_bool(mem.extra, "clk_sft", "CLK-SFT", _mem.clk_sft) add_radio_bool(mem.extra, "compand", "Compand", _mem.compand, doc="Compress Audio") add_radio_bool(mem.extra, "talkaround", "Talk Around", _mem.talkaround, doc="Simplex mode when out of range of repeater") add_radio_bool(mem.extra, "scramb", "Scramble", _mem.scramb, doc="Frequency inversion Scramble") return mem def set_memory(self, mem): _mem = self._memobj.memory[mem.number - 1] _prev_active = self.get_active("chan_active", mem.number) self.set_active("chan_active", mem.number, not mem.empty) if mem.empty or not _prev_active: LOG.debug("initializing memory channel %d" % mem.number) _mem.set_raw(BLANK_MEMORY) if mem.empty: return _mem.rx_freq = mem.freq / 10 if mem.duplex == "split": _mem.tx_freq = mem.offset / 10 elif mem.duplex == "-": _mem.tx_freq = (mem.freq - mem.offset) / 10 elif mem.duplex == "+": _mem.tx_freq = (mem.freq + mem.offset) / 10 elif mem.duplex == "off": _mem.tx_freq = 0 _mem.offset = 0 else: _mem.tx_freq = mem.freq / 10 _mem.tmode = TMODES.index(mem.tmode) if mem.tmode == "TSQL" or mem.tmode == "DTCS": _mem.sqlmode = 1 else: _mem.sqlmode = 0 _mem.ctcss = mem.rtone * 10 _mem.dtcs = mem.dtcs _mem.dtcs_pol = DTCS_POLARITY.index(mem.dtcs_polarity) _mem.name = mem.name.ljust(6, "\xFF") # autoset display to name if filled, else show frequency if mem.extra: # mem.extra only seems to be populated when called from edit panel display = mem.extra["display"] else: display = None if mem.name: _mem.display = True else: _mem.display = False _mem.scan = SCAN_MODES.index(mem.skip) if mem.skip == "P": self.set_active("priority", mem.number, True) self.set_active("scan_enable", mem.number, True) elif mem.skip == "S": self.set_active("priority", mem.number, False) self.set_active("scan_enable", mem.number, False) elif mem.skip == "": self.set_active("priority", mem.number, False) self.set_active("scan_enable", mem.number, True) if mem.mode == "AM": _mem.am = True _mem.fmdev = 0 else: _mem.am = False _mem.fmdev = MODES.index(mem.mode) if mem.power: _mem.power = POWER_LEVELS.index(mem.power) else: _mem.power = 0 # low _mem.step = STEPS.index(mem.tuning_step) for setting in mem.extra: LOG.debug("@set_mem: %s %s", setting.get_name(), setting.value) setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _settings = self._memobj.settings _info = self._memobj.info _bandlimits = self._memobj.bandlimits basic = RadioSettingGroup("basic", "Basic") info = RadioSettingGroup("info", "Model Info") top = RadioSettings(basic, info) add_radio_bool(basic, "beep", "Beep", _settings.beep) add_radio_bool(basic, "ars", "Auto Repeater Shift", _settings.ars) add_radio_setting(basic, "keylock", "Key Lock", zero_indexed_seq_map(["Manual", "Auto"]), _settings.keylock) add_radio_bool(basic, "auto_am", "Auto AM", _settings.auto_am) add_radio_setting(basic, "left_sql", "Left Squelch", zero_indexed_seq_map(SQLPRESET), _settings.left_sql) add_radio_setting(basic, "right_sql", "Right Squelch", zero_indexed_seq_map(SQLPRESET), _settings.right_sql) add_radio_setting(basic, "apo", "Auto Power off (Hours)", [("Off", 0), ("0.5", 5), ("1.0", 10), ("1.5", 15), ("2.0", 20)], _settings.apo) add_radio_setting(basic, "backlight", "Display Backlight", zero_indexed_seq_map(["Off", "1", "2", "3", "Full"]), _settings.backlight) add_radio_setting(basic, "pttlock", "PTT Lock", zero_indexed_seq_map(["Off", "Right", "Left", "Both"]), _settings.pttlock) add_radio_setting(basic, "hyper_chan", "Hyper Channel", zero_indexed_seq_map(["Manual", "Auto"]), _settings.hyper_chan) add_radio_setting(basic, "right_func_key", "Right Function Key", zero_indexed_seq_map(["Key 1", "Key 2"]), _settings.right_func_key) add_radio_setting(basic, "mute_mode", "Mute Mode", zero_indexed_seq_map(["Off", "TX", "RX", "TX RX"]), _settings.mute_mode) add_radio_setting(basic, "scan_mode", "Scan Mode", zero_indexed_seq_map(["MEM", "MSM"]), _settings.scan_mode, doc="MEM = Normal scan, bypass channels marked " "skip. MSM = Scan only channels marked priority.") add_radio_setting(basic, "scan_resume", "Scan Resume", zero_indexed_seq_map(["Time", "Busy"]), _settings.scan_resume) basic.append(RadioSetting( "tot", "Time Out Timer (minutes)", RadioSettingValueInteger(0, 30, _settings.tot))) add_radio_setting(basic, "p1", "P1 Function", zero_indexed_seq_map(MICKEYFUNC), _settings.p1) add_radio_setting(basic, "p2", "P2 Function", zero_indexed_seq_map(MICKEYFUNC), _settings.p2) add_radio_setting(basic, "p3", "P3 Function", zero_indexed_seq_map(MICKEYFUNC), _settings.p3) add_radio_setting(basic, "p4", "P4 Function", zero_indexed_seq_map(MICKEYFUNC), _settings.p4) def _filter(name): filtered = "" for char in str(name): if char in chirp_common.CHARSET_ASCII: filtered += char else: filtered += " " return filtered rsvs = RadioSettingValueString(0, 8, _filter(_info.sn)) rsvs.set_mutable(False) rs = RadioSetting("sn", "Serial Number", rsvs) info.append(rs) rsvs = RadioSettingValueString(0, 8, _filter(_info.model)) rsvs.set_mutable(False) rs = RadioSetting("model", "Model Name", rsvs) info.append(rs) rsvs = RadioSettingValueString(0, 16, _filter(_info.code)) rsvs.set_mutable(False) rs = RadioSetting("code", "Model Code", rsvs) info.append(rs) progdate = "%d/%d/%d" % (_info.prog_mon, _info.prog_day, _info.prog_yr) rsvs = RadioSettingValueString(0, 10, progdate) rsvs.set_mutable(False) rs = RadioSetting("progdate", "Last Program Date", rsvs) info.append(rs) # Band Limits for i in range(0, len(BANDS)): rx_start = int(_bandlimits[i].lorx) * 10 if not rx_start == 0: objname = BANDS[i] + "lorx" objnamepp = BANDS[i] + " Rx Start" rsv = RadioSettingValueString(0, 10, format_freq(rx_start)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) rx_end = int(_bandlimits[i].hirx) * 10 objname = BANDS[i] + "hirx" objnamepp = BANDS[i] + " Rx end" rsv = RadioSettingValueString(0, 10, format_freq(rx_end)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) tx_start = int(_bandlimits[i].lotx) * 10 if not tx_start == 0: objname = BANDS[i] + "lotx" objnamepp = BANDS[i] + " Tx Start" rsv = RadioSettingValueString(0, 10, format_freq(tx_start)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) tx_end = int(_bandlimits[i].hitx) * 10 objname = BANDS[i] + "hitx" objnamepp = BANDS[i] + " Tx end" rsv = RadioSettingValueString(0, 10, format_freq(tx_end)) rsv.set_mutable(False) rs = RadioSetting(objname, objnamepp, rsv) info.append(rs) return top def set_settings(self, settings): _settings = self._memobj.settings _info = self._memobj.info _bandlimits = self._memobj.bandlimits for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue if not element.changed(): continue try: setting = element.get_name() oldval = getattr(_settings, setting) newval = element.value LOG.debug("Setting %s(%s) <= %s" % (setting, oldval, newval)) setattr(_settings, setting, newval) except Exception: LOG.debug(element.get_name()) raise @directory.register class TYTTH7800File(TYTTH7800Base, chirp_common.FileBackedRadio): """TYT TH-7800 .dat file""" MODEL = "TH-7800 File" FILE_EXTENSION = "dat" _memsize = 69632 _mmap_offset = 0x1100 _scanlimits_offset = 0xC800 + _mmap_offset _settings_offset = 0xCB20 + _mmap_offset _chan_active_offset = 0xCB80 + _mmap_offset _info_offset = 0xfe00 + _mmap_offset def __init__(self, pipe): self.errors = [] self._mmap = None if isinstance(pipe, str): self.pipe = None self.load_mmap(pipe) else: chirp_common.FileBackedRadio.__init__(self, pipe) @classmethod def match_model(cls, filedata, filename): return len(filedata) == cls._memsize and filename.endswith('.dat') def _identify(radio): """Do identify handshake with TYT""" try: radio.pipe.write(b"\x02SPECPR") ack = radio.pipe.read(1) if ack != b"A": util.hexprint(ack) raise errors.RadioError("Radio did not ACK first command: %r" % ack) except: raise errors.RadioError("Unable to communicate with the radio") radio.pipe.write(b"G\x02") ident = radio.pipe.read(16) radio.pipe.write(b"A") r = radio.pipe.read(2) if r != b"A": raise errors.RadioError("Ack failed") return ident def _download(radio, memsize=0x10000, blocksize=0x80): """Download from TYT TH-7800""" data = _identify(radio) LOG.info("ident:", util.hexprint(data)) offset = 0x100 for addr in range(offset, memsize, blocksize): msg = struct.pack(">cHB", b"R", addr, blocksize) radio.pipe.write(msg) block = radio.pipe.read(blocksize + 4) if len(block) != (blocksize + 4): LOG.debug(util.hexprint(block)) raise errors.RadioError("Radio sent a short block") radio.pipe.write(b"A") ack = radio.pipe.read(1) if ack != b"A": LOG.debug(util.hexprint(ack)) raise errors.RadioError("Radio NAKed block") data += block[4:] if radio.status_fn: status = chirp_common.Status() status.cur = addr status.max = memsize status.msg = "Cloning from radio" radio.status_fn(status) radio.pipe.write(b"ENDR") return memmap.MemoryMapBytes(data) def _upload(radio, memsize=0xF400, blocksize=0x80): """Upload to TYT TH-7800""" data = _identify(radio) radio.pipe.timeout = 1 if data != radio._mmap[0:radio._mmap_offset]: raise errors.RadioError( "Model mismatch: \n%s\n%s" % (util.hexprint(data), util.hexprint(radio._mmap[:radio._mmap_offset]))) # in the factory software they update the last program date when # they upload, So let's do the same today = date.today() y = today.year m = today.month d = today.day _info = radio._memobj.info ly = _info.prog_yr lm = _info.prog_mon ld = _info.prog_day LOG.debug("Updating last program date:%d/%d/%d" % (lm, ld, ly)) LOG.debug(" to today:%d/%d/%d" % (m, d, y)) _info.prog_yr = y _info.prog_mon = m _info.prog_day = d offset = 0x0100 for addr in range(offset, memsize, blocksize): mapaddr = addr + radio._mmap_offset - offset LOG.debug("addr: 0x%04X, mmapaddr: 0x%04X" % (addr, mapaddr)) msg = struct.pack(">cHB", b"W", addr, blocksize) msg += radio._mmap[mapaddr:(mapaddr + blocksize)] LOG.debug(util.hexprint(msg)) radio.pipe.write(msg) ack = radio.pipe.read(1) if ack != b"A": LOG.debug(util.hexprint(ack)) raise errors.RadioError("Radio did not ack block 0x%04X" % addr) if radio.status_fn: status = chirp_common.Status() status.cur = addr status.max = memsize status.msg = "Cloning to radio" radio.status_fn(status) # End of clone radio.pipe.write(b"ENDW") # Checksum? final_data = radio.pipe.read(3) LOG.debug("final:", util.hexprint(final_data)) @directory.register class TYTTH7800Radio(TYTTH7800Base, chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): VENDOR = "TYT" MODEL = "TH-7800" BAUD_RATE = 38400 NEEDS_COMPAT_SERIAL = False _memsize = 65296 _mmap_offset = 0x0010 _scanlimits_offset = 0xC800 + _mmap_offset _settings_offset = 0xCB20 + _mmap_offset _chan_active_offset = 0xCB80 + _mmap_offset _info_offset = 0xfe00 + _mmap_offset @classmethod def match_model(cls, filedata, filename): if len(filedata) != cls._memsize: return False # TYT used TH9800 as model for TH-7800 _AND_ TH-9800. Check # for TH7800 in case they fix it or if users update the model # in their own radio. if not (filedata[0xfe18:0xfe1e] == b"TH9800" or filedata[0xfe18:0xfe1e] == b"TH7800"): return False # TH-7800 bandlimits differ from TH-9800. First band Invalid # (zero). first_bandlimit = struct.unpack("BBBBBBBBBBBBBBBB", filedata[0xfe40:0xfe50]) if not all(v == 0 for v in first_bandlimit): return False return True @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ( 'This is experimental support for TH-7800 ' 'which is still under development.\n' 'Please ensure you have a good backup with OEM software.\n' 'Also please send in bug and enhancement requests!\n' 'You have been warned. Proceed at your own risk!') return rp def sync_in(self): try: self._mmap = _download(self) except Exception as e: raise errors.RadioError( "Failed to communicate with the radio: %s" % e) self.process_mmap() def sync_out(self): try: _upload(self) except Exception as e: raise errors.RadioError( "Failed to communicate with the radio: %s" % e) chirp-20240224/chirp/drivers/kguv8dplus.py0000644000175000017500000012174714520142245017320 0ustar hibbyhibby# Copyright 2017 Krystian Struzik # Based on Ron Wellsted driver for Wouxun KG-UV8D. # KG-UV8D Plus model has all serial data encrypted. # Figured out how the data is encrypted and implement # serial data encryption and decryption functions. # The algorithm of decryption works like this: # - the first byte of data stream is XOR by const 57h # - each next byte is encoded by previous byte using the XOR # including the checksum (e.g data[i - 1] xor data[i]) # I also changed the data structure to fit radio memory # and implement set_settings function. # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """Wouxun KG-UV8D Plus radio management module""" import struct import time import logging from chirp import util, chirp_common, bitwise, memmap, errors, directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueInteger, RadioSettingValueString, \ RadioSettings LOG = logging.getLogger(__name__) CMD_ID = 128 CMD_END = 129 CMD_RD = 130 CMD_WR = 131 MEM_VALID = 158 AB_LIST = ["A", "B"] STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 25.0, 50.0, 100.0] STEP_LIST = [str(x) for x in STEPS] ROGER_LIST = ["Off", "Begin", "End", "Both"] TIMEOUT_LIST = ["Off"] + [str(x) + "s" for x in range(15, 901, 15)] VOX_LIST = ["Off"] + ["%s" % x for x in range(1, 10)] BANDWIDTH_LIST = ["Narrow", "Wide"] VOICE_LIST = ["Off", "On"] LANGUAGE_LIST = ["Chinese", "English"] SCANMODE_LIST = ["TO", "CO", "SE"] PF1KEY_LIST = ["Call", "VFTX"] PF3KEY_LIST = ["Disable", "Scan", "Lamp", "Tele Alarm", "SOS-CH", "Radio"] WORKMODE_LIST = ["VFO", "Channel No.", "Ch. No.+Freq.", "Ch. No.+Name"] BACKLIGHT_LIST = ["Always On"] + [str(x) + "s" for x in range(1, 21)] + \ ["Always Off"] OFFSET_LIST = ["+", "-"] PONMSG_LIST = ["Bitmap", "Battery Volts"] SPMUTE_LIST = ["QT", "QT+DTMF", "QT*DTMF"] DTMFST_LIST = ["DT-ST", "ANI-ST", "DT-ANI", "Off"] DTMF_TIMES = ["%s" % x for x in range(50, 501, 10)] RPTSET_LIST = ["X-TWRPT", "X-DIRRPT"] ALERTS = [1750, 2100, 1000, 1450] ALERTS_LIST = [str(x) for x in ALERTS] PTTID_LIST = ["Begin", "End", "Both"] LIST_10 = ["Off"] + ["%s" % x for x in range(1, 11)] SCANGRP_LIST = ["All"] + ["%s" % x for x in range(1, 11)] SCQT_LIST = ["Decoder", "Encoder", "All"] SMUTESET_LIST = ["Off", "Tx", "Rx", "Tx/Rx"] POWER_LIST = ["Lo", "Hi"] HOLD_TIMES = ["Off"] + ["%s" % x for x in range(100, 5001, 100)] RPTMODE_LIST = ["Radio", "Repeater"] # memory slot 0 is not used, start at 1 (so need 1000 slots, not 999) # structure elements whose name starts with x are currently unidentified _MEM_FORMAT = """ #seekto 0x0044; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } uhf_limits; #seekto 0x0054; struct { u32 rx_start; u32 rx_stop; u32 tx_start; u32 tx_stop; } vhf_limits; #seekto 0x0400; struct { u8 oem1[8]; u8 unknown[2]; u8 unknown2[10]; u8 unknown3[10]; u8 unknown4[8]; u8 model[10]; u8 version[6]; u8 date[8]; u8 unknown5[1]; u8 oem2[8]; } oem_info; #seekto 0x0480; struct { u16 lower; u16 upper; } scan_groups[10]; #seekto 0x0500; struct { u8 call_code[6]; } call_groups[20]; #seekto 0x0580; struct { char call_name[6]; } call_group_name[20]; #seekto 0x0800; struct { u8 ponmsg; char dispstr[15]; u8 x0810; u8 x0811; u8 x0812; u8 x0813; u8 x0814; u8 voice; u8 timeout; u8 toalarm; u8 channel_menu; u8 power_save; u8 autolock; u8 keylock; u8 beep; u8 stopwatch; u8 vox; u8 scan_rev; u8 backlight; u8 roger_beep; u8 x0822[6]; u8 x0823[6]; u16 pri_ch; u8 ani_sw; u8 ptt_delay; u8 ani_code[6]; u8 dtmf_st; u8 bcl_a; u8 bcl_b; u8 ptt_id; u8 prich_sw; u8 rpt_set; u8 rpt_spk; u8 rpt_ptt; u8 alert; u8 pf1_func; u8 pf3_func; u8 x0843; u8 workmode_a; u8 workmode_b; u8 dtmf_tx_time; u8 dtmf_interval; u8 main_ab; u16 work_cha; u16 work_chb; u8 x084d; u8 x084e; u8 x084f; u8 x0850; u8 x0851; u8 x0852; u8 x0853; u8 x0854; u8 rpt_mode; u8 language; u8 x0857; u8 x0858; u8 x0859; u8 x085a; u8 x085b; u8 x085c; u8 x085d; u8 x085e; u8 single_display; u8 ring_time; u8 scg_a; u8 scg_b; u8 x0863; u8 rpt_tone; u8 rpt_hold; u8 scan_det; u8 sc_qt; u8 x0868; u8 smuteset; u8 callcode; } settings; #seekto 0x0880; struct { u32 rxfreq; u32 txoffset; u16 rxtone; u16 txtone; u8 scrambler:4, unknown1:2, power:1, unknown2:1; u8 unknown3:1, shift_dir:2, unknown4:1, compander:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfoa; #seekto 0x08c0; struct { u32 rxfreq; u32 txoffset; u16 rxtone; u16 txtone; u8 scrambler:4, unknown1:2, power:1, unknown2:1; u8 unknown3:1, shift_dir:2, unknown4:1, compander:1, mute_mode:2, iswide:1; u8 step; u8 squelch; } vfob; #seekto 0x0900; struct { u32 rxfreq; u32 txfreq; u16 rxtone; u16 txtone; u8 scrambler:4, unknown1:2, power:1, unknown2:1; u8 unknown3:2, scan_add:1, unknown4:1, compander:1, mute_mode:2, iswide:1; u16 padding; } memory[1000]; #seekto 0x4780; struct { u8 name[8]; u8 unknown[4]; } names[1000]; #seekto 0x7670; u8 valid[1000]; """ # Support for the Wouxun KG-UV8D Plus radio # Serial coms are at 19200 baud # The data is passed in variable length records # Record structure: # Offset Usage # 0 start of record (\x7a) # 1 Command (\x80 Identify \x81 End/Reboot \x82 Read \x83 Write) # 2 direction (\xff PC-> Radio, \x00 Radio -> PC) # 3 length of payload (excluding header/checksum) (n) # 4 payload (n bytes) # 4+n+1 checksum - byte sum (% 256) of bytes 1 -> 4+n # # Memory Read Records: # the payload is 3 bytes, first 2 are offset (big endian), # 3rd is number of bytes to read # Memory Write Records: # the maximum payload size (from the Wouxun software) seems to be 66 bytes # (2 bytes location + 64 bytes data). @directory.register class KGUV8DPlusRadio(chirp_common.CloneModeRadio, chirp_common.ExperimentalRadio): """Wouxun KG-UV8D Plus""" VENDOR = "Wouxun" MODEL = "KG-UV8D Plus" _model = b"KG-UV8D" _file_ident = b"kguv8dplus" BAUD_RATE = 19200 POWER_LEVELS = [chirp_common.PowerLevel("L", watts=1), chirp_common.PowerLevel("H", watts=5)] NEEDS_COMPAT_SERIAL = False _mmap = "" _record_start = 0x7A def _checksum(self, data): cs = 0 for byte in data: cs += byte return cs % 256 def _write_record(self, cmd, payload=b''): _packet = struct.pack('BBBB', self._record_start, cmd, 0xFF, len(payload)) checksum = bytes([self._checksum(_packet[1:] + payload)]) _packet += self.encrypt(payload + checksum) LOG.debug("Sent:\n%s" % util.hexprint(_packet)) self.pipe.write(_packet) def _read_record(self): # read 4 chars for the header _header = self.pipe.read(4) if len(_header) != 4: raise errors.RadioError('Radio did not respond') _length = struct.unpack('xxxB', _header)[0] _packet = self.pipe.read(_length) _rcs_xor = _packet[-1] _packet = self.decrypt(_packet) _cs = self._checksum(_header[1:]) _cs += self._checksum(_packet) _cs %= 256 _rcs = self.strxor(self.pipe.read(1)[0], _rcs_xor)[0] LOG.debug("_cs =%x", _cs) LOG.debug("_rcs=%x", _rcs) return (_rcs != _cs, _packet) def decrypt(self, data): result = b'' for i in range(len(data)-1, 0, -1): result += self.strxor(data[i], data[i - 1]) result += self.strxor(data[0], 0x57) return result[::-1] def encrypt(self, data): result = self.strxor(0x57, data[0]) for i in range(1, len(data), 1): result += self.strxor(result[i - 1], data[i]) return result def strxor(self, xora, xorb): return bytes([xora ^ xorb]) # Identify the radio # # A Gotcha: the first identify packet returns a bad checksum, subsequent # attempts return the correct checksum... (well it does on my radio!) # # The ID record returned by the radio also includes the current frequency range # as 4 bytes big-endian in 10 Hz increments # # Offset # 0:10 Model, zero padded (Use first 7 chars for 'KG-UV8D') # 11:14 UHF rx lower limit (in units of 10 Hz) # 15:18 UHF rx upper limit # 19:22 UHF tx lower limit # 23:26 UHF tx upper limit # 27:30 VHF rx lower limit # 31:34 VHF rx upper limit # 35:38 VHF tx lower limit # 39:42 VHF tx upper limit # @classmethod def match_model(cls, filedata, filename): return (cls._file_ident in b'kg' + filedata[0x426:0x430].replace(b'(', b'').replace(b')', b'').lower()) def _identify(self): """Do the identification dance""" for _i in range(0, 10): self._write_record(CMD_ID) _chksum_err, _resp = self._read_record() LOG.debug("Got:\n%s" % util.hexprint(_resp)) if _chksum_err: LOG.error("Checksum error: retrying ident...") time.sleep(0.100) continue LOG.debug("Model %s" % util.hexprint(_resp[0:7])) if _resp[0:7] == self._model: return if len(_resp) == 0: raise Exception("Radio not responding") else: raise Exception("Unable to identify radio") def _finish(self): self._write_record(CMD_END) def process_mmap(self): self._memobj = bitwise.parse(_MEM_FORMAT, self._mmap) def sync_in(self): try: self._mmap = self._download() except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) self.process_mmap() def sync_out(self): self._upload() # TODO: Load all memory. # It would be smarter to only load the active areas and none of # the padding/unused areas. Padding still need to be investigated. def _download(self): """Talk to a Wouxun KG-UV8D Plus and do a download""" try: self._identify() return self._do_download(0, 32768, 64) except errors.RadioError: raise except Exception as e: LOG.exception('Unknown error during download process') raise errors.RadioError("Failed to communicate with radio: %s" % e) def _do_download(self, start, end, blocksize): # allocate & fill memory image = b"" for i in range(start, end, blocksize): req = struct.pack('>HB', i, blocksize) self._write_record(CMD_RD, req) cs_error, resp = self._read_record() if cs_error: LOG.debug(util.hexprint(resp)) raise Exception("Checksum error on read") LOG.debug("Got:\n%s" % util.hexprint(resp)) image += resp[2:] if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning from radio" self.status_fn(status) self._finish() return memmap.MemoryMapBytes(image) def _upload(self): """Talk to a Wouxun KG-UV8D Plus and do a upload""" try: self._identify() self._do_upload(0, 32768, 64) except errors.RadioError: raise except Exception as e: raise errors.RadioError("Failed to communicate with radio: %s" % e) return def _do_upload(self, start, end, blocksize): ptr = start for i in range(start, end, blocksize): req = struct.pack('>H', i) chunk = self.get_mmap()[ptr:ptr + blocksize] self._write_record(CMD_WR, req + chunk) LOG.debug(util.hexprint(req + chunk)) cserr, ack = self._read_record() LOG.debug(util.hexprint(ack)) j = struct.unpack('>H', ack)[0] if cserr or j != ptr: raise Exception("Radio did not ack block %i" % ptr) ptr += blocksize if self.status_fn: status = chirp_common.Status() status.cur = i status.max = end status.msg = "Cloning to radio" self.status_fn(status) self._finish() def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_ctone = True rf.has_rx_dtcs = True rf.has_cross = True rf.has_tuning_step = False rf.has_bank = False rf.can_odd_split = True rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = [ "Tone->Tone", "Tone->DTCS", "DTCS->Tone", "DTCS->", "->Tone", "->DTCS", "DTCS->DTCS", ] rf.valid_modes = ["FM", "NFM"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_name_length = 8 rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_bands = [(134000000, 175000000), # supports 2m (300000000, 520000000)] # supports 70cm rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_tuning_steps = STEPS rf.memory_bounds = (1, 999) # 999 memories return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = ("This radio driver is currently under development. " "There are no known issues with it, but you should " "proceed with caution.") return rp def get_raw_memory(self, number): return repr(self._memobj.memory[number]) def _get_tone(self, _mem, mem): def _get_dcs(val): code = int("%03o" % (val & 0x07FF)) pol = (val & 0x2000) and "R" or "N" return code, pol tpol = False if _mem.txtone != 0xFFFF and (_mem.txtone & 0x4000) == 0x4000: tcode, tpol = _get_dcs(_mem.txtone) mem.dtcs = tcode txmode = "DTCS" elif _mem.txtone != 0xFFFF and _mem.txtone != 0x0: mem.rtone = (_mem.txtone & 0x7fff) / 10.0 txmode = "Tone" else: txmode = "" rpol = False if _mem.rxtone != 0xFFFF and (_mem.rxtone & 0x4000) == 0x4000: rcode, rpol = _get_dcs(_mem.rxtone) mem.rx_dtcs = rcode rxmode = "DTCS" elif _mem.rxtone != 0xFFFF and _mem.rxtone != 0x0: mem.ctone = (_mem.rxtone & 0x7fff) / 10.0 rxmode = "Tone" else: rxmode = "" if txmode == "Tone" and not rxmode: mem.tmode = "Tone" elif txmode == rxmode and txmode == "Tone" and mem.rtone == mem.ctone: mem.tmode = "TSQL" elif txmode == rxmode and txmode == "DTCS" and mem.dtcs == mem.rx_dtcs: mem.tmode = "DTCS" elif rxmode or txmode: mem.tmode = "Cross" mem.cross_mode = "%s->%s" % (txmode, rxmode) # always set it even if no dtcs is used mem.dtcs_polarity = "%s%s" % (tpol or "N", rpol or "N") LOG.debug("Got TX %s (%i) RX %s (%i)" % (txmode, _mem.txtone, rxmode, _mem.rxtone)) def get_memory(self, number): _mem = self._memobj.memory[number] _nam = self._memobj.names[number] mem = chirp_common.Memory() mem.number = number _valid = self._memobj.valid[mem.number] LOG.debug("%d %s", number, _valid == MEM_VALID) if _valid != MEM_VALID: mem.empty = True return mem else: mem.empty = False mem.freq = int(_mem.rxfreq) * 10 if _mem.txfreq == 0xFFFFFFFF: # TX freq not set mem.duplex = "off" mem.offset = 0 elif int(_mem.rxfreq) == int(_mem.txfreq): mem.duplex = "" mem.offset = 0 elif abs(int(_mem.rxfreq) * 10 - int(_mem.txfreq) * 10) > 70000000: mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 else: mem.duplex = int(_mem.rxfreq) > int(_mem.txfreq) and "-" or "+" mem.offset = abs(int(_mem.rxfreq) - int(_mem.txfreq)) * 10 for char in _nam.name: if char != 0: mem.name += chr(char) mem.name = mem.name.rstrip() self._get_tone(_mem, mem) mem.skip = "" if bool(_mem.scan_add) else "S" mem.power = self.POWER_LEVELS[_mem.power] mem.mode = _mem.iswide and "FM" or "NFM" return mem def _set_tone(self, mem, _mem): def _set_dcs(code, pol): val = int("%i" % code, 8) + 0x4000 if pol == "R": val += 0x2000 return val rx_mode = tx_mode = None rxtone = txtone = 0x0000 if mem.tmode == "Tone": tx_mode = "Tone" rx_mode = None txtone = int(mem.rtone * 10) + 0x8000 elif mem.tmode == "TSQL": rx_mode = tx_mode = "Tone" rxtone = txtone = int(mem.ctone * 10) + 0x8000 elif mem.tmode == "DTCS": tx_mode = rx_mode = "DTCS" txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) rxtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[1]) elif mem.tmode == "Cross": tx_mode, rx_mode = mem.cross_mode.split("->") if tx_mode == "DTCS": txtone = _set_dcs(mem.dtcs, mem.dtcs_polarity[0]) elif tx_mode == "Tone": txtone = int(mem.rtone * 10) + 0x8000 if rx_mode == "DTCS": rxtone = _set_dcs(mem.rx_dtcs, mem.dtcs_polarity[1]) elif rx_mode == "Tone": rxtone = int(mem.ctone * 10) + 0x8000 _mem.rxtone = rxtone _mem.txtone = txtone LOG.debug("Set TX %s (%i) RX %s (%i)" % (tx_mode, _mem.txtone, rx_mode, _mem.rxtone)) def set_memory(self, mem): number = mem.number _mem = self._memobj.memory[number] _nam = self._memobj.names[number] if mem.empty: _mem.set_raw("\x00" * (_mem.size() // 8)) self._memobj.valid[number] = 0 self._memobj.names[number].set_raw("\x00" * (_nam.size() // 8)) return _mem.rxfreq = int(mem.freq / 10) if mem.duplex == "off": _mem.txfreq = 0xFFFFFFFF elif mem.duplex == "split": _mem.txfreq = int(mem.offset / 10) elif mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw("\xFF") elif mem.duplex == "+": _mem.txfreq = int(mem.freq / 10) + int(mem.offset / 10) elif mem.duplex == "-": _mem.txfreq = int(mem.freq / 10) - int(mem.offset / 10) else: _mem.txfreq = int(mem.freq / 10) _mem.scan_add = int(mem.skip != "S") _mem.iswide = int(mem.mode == "FM") # set the tone self._set_tone(mem, _mem) # set the scrambler and compander to off by default _mem.scrambler = 0 _mem.compander = 0 # set the power if mem.power: _mem.power = self.POWER_LEVELS.index(mem.power) else: _mem.power = True # set to mute mode to QT (not QT+DTMF or QT*DTMF) by default _mem.mute_mode = 0 for i in range(0, len(_nam.name)): if i < len(mem.name) and mem.name[i]: _nam.name[i] = ord(mem.name[i]) else: _nam.name[i] = 0x0 self._memobj.valid[mem.number] = MEM_VALID def _get_settings(self): _settings = self._memobj.settings _vfoa = self._memobj.vfoa _vfob = self._memobj.vfob cfg_grp = RadioSettingGroup("cfg_grp", "Configuration") vfoa_grp = RadioSettingGroup("vfoa_grp", "VFO A Settings") vfob_grp = RadioSettingGroup("vfob_grp", "VFO B Settings") key_grp = RadioSettingGroup("key_grp", "Key Settings") lmt_grp = RadioSettingGroup("lmt_grp", "Frequency Limits") uhf_lmt_grp = RadioSettingGroup("uhf_lmt_grp", "UHF") vhf_lmt_grp = RadioSettingGroup("vhf_lmt_grp", "VHF") oem_grp = RadioSettingGroup("oem_grp", "OEM Info") lmt_grp.append(uhf_lmt_grp) lmt_grp.append(vhf_lmt_grp) group = RadioSettings(cfg_grp, vfoa_grp, vfob_grp, key_grp, lmt_grp, oem_grp) # # Configuration Settings # rs = RadioSetting("channel_menu", "Menu available in channel mode", RadioSettingValueBoolean(_settings.channel_menu)) cfg_grp.append(rs) rs = RadioSetting("ponmsg", "Poweron message", RadioSettingValueList( PONMSG_LIST, PONMSG_LIST[_settings.ponmsg])) cfg_grp.append(rs) rs = RadioSetting("voice", "Voice Guide", RadioSettingValueBoolean(_settings.voice)) cfg_grp.append(rs) rs = RadioSetting("language", "Language", RadioSettingValueList(LANGUAGE_LIST, LANGUAGE_LIST[_settings. language])) cfg_grp.append(rs) rs = RadioSetting("timeout", "Timeout Timer", RadioSettingValueList( TIMEOUT_LIST, TIMEOUT_LIST[_settings.timeout])) cfg_grp.append(rs) rs = RadioSetting("toalarm", "Timeout Alarm", RadioSettingValueInteger(0, 10, _settings.toalarm)) cfg_grp.append(rs) rs = RadioSetting("roger_beep", "Roger Beep", RadioSettingValueList(ROGER_LIST, ROGER_LIST[ _settings.roger_beep])) cfg_grp.append(rs) rs = RadioSetting("power_save", "Power save", RadioSettingValueBoolean(_settings.power_save)) cfg_grp.append(rs) rs = RadioSetting("autolock", "Autolock", RadioSettingValueBoolean(_settings.autolock)) cfg_grp.append(rs) rs = RadioSetting("keylock", "Keypad Lock", RadioSettingValueBoolean(_settings.keylock)) cfg_grp.append(rs) rs = RadioSetting("beep", "Keypad Beep", RadioSettingValueBoolean(_settings.beep)) cfg_grp.append(rs) rs = RadioSetting("stopwatch", "Stopwatch", RadioSettingValueBoolean(_settings.stopwatch)) cfg_grp.append(rs) rs = RadioSetting("backlight", "Backlight", RadioSettingValueList(BACKLIGHT_LIST, BACKLIGHT_LIST[_settings. backlight])) cfg_grp.append(rs) rs = RadioSetting("dtmf_st", "DTMF Sidetone", RadioSettingValueList(DTMFST_LIST, DTMFST_LIST[_settings. dtmf_st])) cfg_grp.append(rs) rs = RadioSetting("ani_sw", "ANI-ID Switch", RadioSettingValueBoolean(_settings.ani_sw)) cfg_grp.append(rs) rs = RadioSetting("ptt_id", "PTT-ID Delay", RadioSettingValueList(PTTID_LIST, PTTID_LIST[_settings.ptt_id])) cfg_grp.append(rs) rs = RadioSetting("ring_time", "Ring Time", RadioSettingValueList(LIST_10, LIST_10[_settings.ring_time])) cfg_grp.append(rs) rs = RadioSetting("scan_rev", "Scan Mode", RadioSettingValueList(SCANMODE_LIST, SCANMODE_LIST[_settings. scan_rev])) cfg_grp.append(rs) rs = RadioSetting("vox", "VOX", RadioSettingValueList(LIST_10, LIST_10[_settings.vox])) cfg_grp.append(rs) rs = RadioSetting("prich_sw", "Priority Channel Switch", RadioSettingValueBoolean(_settings.prich_sw)) cfg_grp.append(rs) rs = RadioSetting("pri_ch", "Priority Channel", RadioSettingValueInteger(1, 999, _settings.pri_ch)) cfg_grp.append(rs) rs = RadioSetting("rpt_mode", "Radio Mode", RadioSettingValueList(RPTMODE_LIST, RPTMODE_LIST[_settings. rpt_mode])) cfg_grp.append(rs) rs = RadioSetting("rpt_set", "Repeater Setting", RadioSettingValueList(RPTSET_LIST, RPTSET_LIST[_settings. rpt_set])) cfg_grp.append(rs) rs = RadioSetting("rpt_spk", "Repeater Mode Speaker", RadioSettingValueBoolean(_settings.rpt_spk)) cfg_grp.append(rs) rs = RadioSetting("rpt_ptt", "Repeater PTT", RadioSettingValueBoolean(_settings.rpt_ptt)) cfg_grp.append(rs) rs = RadioSetting("dtmf_tx_time", "DTMF Tx Duration", RadioSettingValueList(DTMF_TIMES, DTMF_TIMES[_settings. dtmf_tx_time])) cfg_grp.append(rs) rs = RadioSetting("dtmf_interval", "DTMF Interval", RadioSettingValueList(DTMF_TIMES, DTMF_TIMES[_settings. dtmf_interval])) cfg_grp.append(rs) rs = RadioSetting("alert", "Alert Tone", RadioSettingValueList(ALERTS_LIST, ALERTS_LIST[_settings.alert])) cfg_grp.append(rs) rs = RadioSetting("rpt_tone", "Repeater Tone", RadioSettingValueBoolean(_settings.rpt_tone)) cfg_grp.append(rs) rs = RadioSetting("rpt_hold", "Repeater Hold Time", RadioSettingValueList(HOLD_TIMES, HOLD_TIMES[_settings. rpt_hold])) cfg_grp.append(rs) rs = RadioSetting("scan_det", "Scan DET", RadioSettingValueBoolean(_settings.scan_det)) cfg_grp.append(rs) rs = RadioSetting("sc_qt", "SC-QT", RadioSettingValueList(SCQT_LIST, SCQT_LIST[_settings.sc_qt])) cfg_grp.append(rs) rs = RadioSetting("smuteset", "SubFreq Mute", RadioSettingValueList(SMUTESET_LIST, SMUTESET_LIST[_settings. smuteset])) cfg_grp.append(rs) # VFO A Settings # rs = RadioSetting("workmode_a", "VFO A Workmode", RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[ _settings.workmode_a])) vfoa_grp.append(rs) rs = RadioSetting("work_cha", "VFO A Channel", RadioSettingValueInteger(1, 999, _settings.work_cha)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.rxfreq", "VFO A Rx Frequency", RadioSettingValueInteger( 134000000, 520000000, _vfoa.rxfreq * 10, 5000)) vfoa_grp.append(rs) rs = RadioSetting("vfoa.txoffset", "VFO A Tx Offset", RadioSettingValueInteger( 0, 520000000, _vfoa.txoffset * 10, 5000)) vfoa_grp.append(rs) # u16 rxtone; # u16 txtone; rs = RadioSetting("vfoa.power", "VFO A Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfoa.power])) vfoa_grp.append(rs) # shift_dir:2 rs = RadioSetting("vfoa.iswide", "VFO A NBFM", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfoa.iswide])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.mute_mode", "VFO A Mute", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfoa.mute_mode])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.step", "VFO A Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfoa.step])) vfoa_grp.append(rs) rs = RadioSetting("vfoa.squelch", "VFO A Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfoa.squelch])) vfoa_grp.append(rs) rs = RadioSetting("bcl_a", "Busy Channel Lock-out A", RadioSettingValueBoolean(_settings.bcl_a)) vfoa_grp.append(rs) # VFO B Settings # rs = RadioSetting("workmode_b", "VFO B Workmode", RadioSettingValueList(WORKMODE_LIST, WORKMODE_LIST[ _settings.workmode_b])) vfob_grp.append(rs) rs = RadioSetting("work_chb", "VFO B Channel", RadioSettingValueInteger(1, 999, _settings.work_chb)) vfob_grp.append(rs) rs = RadioSetting("vfob.rxfreq", "VFO B Rx Frequency", RadioSettingValueInteger( 134000000, 520000000, _vfob.rxfreq * 10, 5000)) vfob_grp.append(rs) rs = RadioSetting("vfob.txoffset", "VFO B Tx Offset", RadioSettingValueInteger( 0, 520000000, _vfob.txoffset * 10, 5000)) vfob_grp.append(rs) # u16 rxtone; # u16 txtone; rs = RadioSetting("vfob.power", "VFO B Power", RadioSettingValueList( POWER_LIST, POWER_LIST[_vfob.power])) vfob_grp.append(rs) # shift_dir:2 rs = RadioSetting("vfob.iswide", "VFO B NBFM", RadioSettingValueList( BANDWIDTH_LIST, BANDWIDTH_LIST[_vfob.iswide])) vfob_grp.append(rs) rs = RadioSetting("vfob.mute_mode", "VFO B Mute", RadioSettingValueList( SPMUTE_LIST, SPMUTE_LIST[_vfob.mute_mode])) vfob_grp.append(rs) rs = RadioSetting("vfob.step", "VFO B Step (kHz)", RadioSettingValueList( STEP_LIST, STEP_LIST[_vfob.step])) vfob_grp.append(rs) rs = RadioSetting("vfob.squelch", "VFO B Squelch", RadioSettingValueList( LIST_10, LIST_10[_vfob.squelch])) vfob_grp.append(rs) rs = RadioSetting("bcl_b", "Busy Channel Lock-out B", RadioSettingValueBoolean(_settings.bcl_b)) vfob_grp.append(rs) # Key Settings # _msg = str(_settings.dispstr).split("\0")[0] val = RadioSettingValueString(0, 15, _msg) val.set_mutable(True) rs = RadioSetting("dispstr", "Display Message", val) key_grp.append(rs) dtmfchars = "0123456789" _codeobj = _settings.ani_code _code = "".join([dtmfchars[x] for x in _codeobj if int(x) < 0x0A]) val = RadioSettingValueString(3, 6, _code, False) val.set_charset(dtmfchars) rs = RadioSetting("ani_code", "ANI Code", val) def apply_ani_id(setting, obj): value = [] for j in range(0, 6): try: value.append(dtmfchars.index(str(setting.value)[j])) except IndexError: value.append(0xFF) obj.ani_code = value rs.set_apply_callback(apply_ani_id, _settings) key_grp.append(rs) rs = RadioSetting("pf1_func", "PF1 Key function", RadioSettingValueList( PF1KEY_LIST, PF1KEY_LIST[_settings.pf1_func])) key_grp.append(rs) rs = RadioSetting("pf3_func", "PF3 Key function", RadioSettingValueList( PF3KEY_LIST, PF3KEY_LIST[_settings.pf3_func])) key_grp.append(rs) # # Limits settings # rs = RadioSetting("uhf_limits.rx_start", "UHF RX Lower Limit", RadioSettingValueInteger( 300000000, 520000000, self._memobj.uhf_limits.rx_start * 10, 5000)) uhf_lmt_grp.append(rs) rs = RadioSetting("uhf_limits.rx_stop", "UHF RX Upper Limit", RadioSettingValueInteger( 300000000, 520000000, self._memobj.uhf_limits.rx_stop * 10, 5000)) uhf_lmt_grp.append(rs) rs = RadioSetting("uhf_limits.tx_start", "UHF TX Lower Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.tx_start * 10, 5000)) uhf_lmt_grp.append(rs) rs = RadioSetting("uhf_limits.tx_stop", "UHF TX Upper Limit", RadioSettingValueInteger( 400000000, 520000000, self._memobj.uhf_limits.tx_stop * 10, 5000)) uhf_lmt_grp.append(rs) rs = RadioSetting("vhf_limits.rx_start", "VHF RX Lower Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.rx_start * 10, 5000)) vhf_lmt_grp.append(rs) rs = RadioSetting("vhf_limits.rx_stop", "VHF RX Upper Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.rx_stop * 10, 5000)) vhf_lmt_grp.append(rs) rs = RadioSetting("vhf_limits.tx_start", "VHF TX Lower Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.tx_start * 10, 5000)) vhf_lmt_grp.append(rs) rs = RadioSetting("vhf_limits.tx_stop", "VHF TX Upper Limit", RadioSettingValueInteger( 134000000, 174997500, self._memobj.vhf_limits.tx_stop * 10, 5000)) vhf_lmt_grp.append(rs) # # OEM info # def _decode(lst): _str = ''.join([chr(c) for c in lst if chr(c) in chirp_common.CHARSET_ASCII]) return _str def do_nothing(setting, obj): return _str = _decode(self._memobj.oem_info.model) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.model", "Model", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.oem1) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.oem1", "OEM String 1", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.oem2) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.oem2", "OEM String 2", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.version) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.version", "Software Version", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) _str = _decode(self._memobj.oem_info.date) val = RadioSettingValueString(0, 15, _str) val.set_mutable(False) rs = RadioSetting("oem_info.date", "OEM Date", val) rs.set_apply_callback(do_nothing, _settings) oem_grp.append(rs) return group def get_settings(self): try: return self._get_settings() except Exception: import traceback LOG.error("Failed to parse settings: %s", traceback.format_exc()) return None def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: if "." in element.get_name(): bits = element.get_name().split(".") obj = self._memobj for bit in bits[:-1]: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() else: LOG.debug("Setting %s = %s" % (setting, element.value)) if self._is_freq(element): setattr(obj, setting, int(element.value)/10) else: setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def _is_freq(self, element): return "rxfreq" in element.get_name() \ or "txoffset" in element.get_name() \ or "rx_start" in element.get_name() \ or "rx_stop" in element.get_name() \ or "tx_start" in element.get_name() \ or "tx_stop" in element.get_name() chirp-20240224/chirp/drivers/thd74.py0000644000175000017500000003746214563632215016146 0ustar hibbyhibbyimport itertools import logging import struct import sys import time from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp import errors from chirp import memmap LOG = logging.getLogger(__name__) CALL_CHANS = ['VHF Call (A)', 'VHF Call (D)', '220M Call (A)', '220M Call (D)', 'UHF Call (A)', 'UHF Call (D)'] # This is the order of special channels in memory directly after # regular memory #999 EXTD_NUMBERS = list(itertools.chain( ['%s%02i' % (i % 2 and 'Upper' or 'Lower', i // 2) for i in range(100)], ['Priority'], ['WX%i' % (i + 1) for i in range(10)], [None for i in range(20)], # 20-channel buffer? [CALL_CHANS[i] for i in range(len(CALL_CHANS))])) D74_FILE_HEADER = ( b'MCP-D74\xFFV1.03\xFF\xFF\xFF' + b'TH-D74' + (b'\xFF' * 10) + b'\x00' + (b'\xFF' * 15) + b'\xFF' * (5 * 16) + b'K2' + (b'\xFF' * 14) + b'\xFF' * (7 * 16)) GROUP_NAME_OFFSET = 1152 MEM_FORMAT = """ #seekto 0x2000; struct { u8 used; u8 unknown1:7, lockout:1; u8 group; u8 unknownFF; } flags[1200]; #seekto 0x4000; struct memory { ul32 freq; ul32 offset; u8 tuning_step:4, split_tuning_step:3, unknown2:1; u8 unknown3_0:1, mode:3, narrow:1, fine_mode:1, fine_step:2; u8 tone_mode:1, ctcss_mode:1, dtcs_mode:1, cross_mode:1, unknown4_0:1, split:1, duplex:2; u8 rtone; u8 unknownctone:2, ctone:6; u8 unknowndtcs:1, dtcs_code:7; u8 unknown5_1:2, cross_mode_mode:2, unknown5_2:2, dig_squelch:2; char dv_urcall[8]; char dv_rpt1call[8]; char dv_rpt2call[8]; u8 unknown9:1, dv_code:7; }; struct { struct memory memories[6]; u8 pad[16]; } memgroups[192]; //#seekto 0x10000; struct { char name[16]; } names[1200]; """ def decode_call(call): return ''.join(str(c) for c in call if ord(str(c)) > 0) def encode_call(call): return call[:8].ljust(8, '\x00') DUPLEX = ['', '+', '-'] TUNE_STEPS = [5.0, 6.25, 8.33, 9.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] CROSS_MODES = ['DTCS->', 'Tone->DTCS', 'DTCS->Tone', 'Tone->Tone'] MODES = ['FM', 'DV', 'AM', 'LSB', 'USB', 'CW', 'NFM', 'DV', # Actually DR in the radio ] DSQL_MODES = ['', 'Code', 'Callsign'] FINE_STEPS = [20, 100, 500, 1000] class KenwoodGroup(chirp_common.NamedBank): def __init__(self, model, index): # Default name until we are initialized, then we will report # the value from memory super().__init__(model, index, 'GRP-%i' % index) def get_name(self): name = self._model._radio._memobj.names[ GROUP_NAME_OFFSET + self._index].name return str(name).rstrip() def set_name(self, name): names = self._model._radio._memobj.names names[GROUP_NAME_OFFSET + self._index].name = str(name)[:16].ljust(16) super().set_name(name.strip()) class KenwoodTHD74Bankmodel(chirp_common.BankModel): channelAlwaysHasBank = True def get_num_mappings(self): return 30 def get_mappings(self): groups = [] for i in range(self.get_num_mappings()): groups.append(KenwoodGroup(self, i)) return groups def add_memory_to_mapping(self, memory, bank): self._radio._memobj.flags[memory.number].group = bank.get_index() def remove_memory_from_mapping(self, memory, bank): self._radio._memobj.flags[memory.number].group = 0 def get_mapping_memories(self, bank): features = self._radio.get_features() memories = [] for i in range(0, features.memory_bounds[1]): if self._radio._memobj.flags[i].group == bank.get_index(): memories.append(self._radio.get_memory(i)) return memories def get_memory_mappings(self, memory): index = self._radio._memobj.flags[memory.number].group return [self.get_mappings()[index]] def get_used_flag(mem): if mem.empty: return 0xFF if mem.duplex == 'split': freq = mem.offset else: freq = mem.freq if freq < chirp_common.to_MHz(150): return 0x00 elif freq < chirp_common.to_MHz(400): return 0x01 else: return 0x02 @directory.register class THD74Radio(chirp_common.CloneModeRadio, chirp_common.IcomDstarSupport): VENDOR = "Kenwood" MODEL = "TH-D74 (clone mode)" NEEDS_COMPAT_SERIAL = False BAUD_RATE = 9600 HARDWARE_FLOW = sys.platform == "darwin" # only OS X driver needs hw flow FORMATS = [directory.register_format('Kenwood MCP-D74', '*.d74')] _memsize = 0x7A300 def read_block(self, block, count=256): hdr = struct.pack(">cHH", b"R", block, 0) self.pipe.write(hdr) r = self.pipe.read(5) if len(r) != 5: raise errors.RadioError("Did not receive block response") cmd, _block, zero = struct.unpack(">cHH", r) if cmd != b"W" or _block != block: raise errors.RadioError("Invalid response: %s %i" % (cmd, _block)) data = b"" while len(data) < count: data += self.pipe.read(count - len(data)) self.pipe.write(b'\x06') if self.pipe.read(1) != b'\x06': raise errors.RadioError("Did not receive post-block ACK!") return data def write_block(self, block, map, size=256): hdr = struct.pack(">cHH", b"W", block, size < 256 and size or 0) base = block * size data = map[base:base + size] self.pipe.write(hdr + data) self.pipe.flush() for i in range(10): ack = self.pipe.read(1) if ack != b'\x06': LOG.error('Ack for block %i was: %r' % (block, ack)) else: break return ack == b'\x06' def download(self, raw=False, blocks=None): if blocks is None: blocks = range(self._memsize // 256) else: blocks = [b for b in blocks if b < self._memsize // 256] if self.command("0M PROGRAM") != "0M": raise errors.RadioError("No response from self") allblocks = range(self._memsize // 256) self.pipe.baudrate = 57600 self.pipe.read(1) data = b"" LOG.debug("reading blocks %d..%d" % (blocks[0], blocks[-1])) total = len(blocks) count = 0 for i in allblocks: if i not in blocks: data += 256 * b'\xff' continue data += self.read_block(i) count += 1 if self.status_fn: s = chirp_common.Status() s.msg = "Cloning from radio" s.max = total s.cur = count self.status_fn(s) self.pipe.write(b"E") if raw: return data return memmap.MemoryMapBytes(data) def upload(self, blocks=None): if blocks is None: blocks = range((self._memsize // 256) - 2) else: blocks = [b for b in blocks if b < self._memsize // 256] if self.command("0M PROGRAM") != "0M": raise errors.RadioError("No response from self") self.pipe.baudrate = 57600 self.pipe.read(1) try: LOG.debug("writing blocks %d..%d" % (blocks[0], blocks[-1])) total = len(blocks) count = 0 for i in blocks: r = self.write_block(i, self._mmap) count += 1 if not r: raise errors.RadioError("self NAK'd block %i" % i) if self.status_fn: s = chirp_common.Status() s.msg = "Cloning to radio" s.max = total s.cur = count self.status_fn(s) finally: self.pipe.write(b"E") def command(self, cmd, timeout=1): start = time.time() data = b"" LOG.debug("PC->D74: %s" % cmd) self.pipe.write((cmd + "\r").encode()) while not data.endswith(b"\r") and (time.time() - start) < timeout: data += self.pipe.read(1) LOG.debug("D74->PC: %s" % data.strip()) return data.decode().strip() def get_id(self): r = self.command("ID") if r.startswith("ID "): return r.split(" ")[1] else: raise errors.RadioError("No response to ID command") def _detect_baud(self): id = None for baud in [9600, 19200, 38400, 57600]: self.pipe.baudrate = baud try: self.pipe.write(b"\r\r") except Exception: break self.pipe.read(32) try: id = self.get_id() LOG.info("Radio %s at %i baud" % (id, baud)) break except errors.RadioError: pass if id and not self.MODEL.startswith(id): raise errors.RadioError(_('Unsupported model %r' % id)) elif id: return id else: raise errors.RadioError("No response from radio") def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): self._detect_baud() self._mmap = self.download() self.process_mmap() def sync_out(self): self._detect_baud() self.upload() def load_mmap(self, filename): if filename.lower().endswith('.d74'): with open(filename, 'rb') as f: f.seek(0x100) self._mmap = memmap.MemoryMapBytes(f.read()) LOG.info('Loaded MCP d74 file at offset 0x100') self.process_mmap() else: chirp_common.CloneModeRadio.load_mmap(self, filename) def save_mmap(self, filename): if filename.lower().endswith('.d74'): with open(filename, 'wb') as f: f.write(D74_FILE_HEADER) f.write(self._mmap.get_packed()) LOG.info('Wrote MCP d74 file') else: chirp_common.CloneModeRadio.save_mmap(self, filename) def get_features(self): rf = chirp_common.RadioFeatures() rf.valid_tuning_steps = list(TUNE_STEPS) rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = list(CROSS_MODES) rf.valid_duplexes = DUPLEX + ['split'] rf.valid_skips = ['', 'S'] rf.valid_modes = list(MODES) rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_name_length = 16 rf.valid_bands = [(100000, 470000000)] rf.valid_special_chans = [x for x in EXTD_NUMBERS if x] rf.has_cross = True rf.has_dtcs_polarity = False rf.has_bank = True rf.has_bank_names = True rf.can_odd_split = True rf.requires_call_lists = False rf.memory_bounds = (0, 999) return rf def _get_raw_memory(self, number): # Why Kenwood ... WHY? return self._memobj.memgroups[number // 6].memories[number % 6] def get_memory(self, number): if isinstance(number, str): extd_number = number number = 1000 + EXTD_NUMBERS.index(number) else: extd_number = None _mem = self._get_raw_memory(number) _flg = self._memobj.flags[number] if MODES[_mem.mode] == 'DV': mem = chirp_common.DVMemory() else: mem = chirp_common.Memory() mem.number = number if extd_number: mem.extd_number = extd_number if _flg.used == 0xFF: mem.empty = True return mem mem.freq = int(_mem.freq) if 'Call' in mem.extd_number: name_index_adj = 5 else: name_index_adj = 0 _nam = self._memobj.names[number + name_index_adj] mem.name = str(_nam.name).rstrip().strip('\x00') mem.offset = int(_mem.offset) if _mem.split: mem.duplex = 'split' else: mem.duplex = DUPLEX[_mem.duplex] mem.tuning_step = TUNE_STEPS[_mem.tuning_step] mem.mode = MODES[_mem.mode] mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs_code] if _mem.tone_mode: mem.tmode = 'Tone' elif _mem.ctcss_mode: mem.tmode = 'TSQL' elif _mem.dtcs_mode: mem.tmode = 'DTCS' elif _mem.cross_mode: mem.tmode = 'Cross' mem.cross_mode = CROSS_MODES[_mem.cross_mode_mode] else: mem.tmode = '' mem.skip = _flg.lockout and 'S' or '' if mem.mode == 'DV': mem.dv_urcall = decode_call(_mem.dv_urcall) mem.dv_rpt1call = decode_call(_mem.dv_rpt1call) mem.dv_rpt2call = decode_call(_mem.dv_rpt2call) mem.dv_code = int(_mem.dv_code) if mem.extd_number: mem.immutable.append('empty') if 'WX' in mem.extd_number: mem.tmode = '' mem.immutable.extend(['rtone', 'ctone', 'dtcs', 'rx_dtcs', 'tmode', 'cross_mode', 'dtcs_polarity', 'skip', 'power', 'offset', 'mode', 'tuning_step']) if 'Call' in mem.extd_number and mem.mode == 'DV': mem.immutable.append('mode') return mem def set_memory(self, mem): if mem.number > 999 and 'Call' in EXTD_NUMBERS[mem.number - 1000]: name_index_adj = 5 else: name_index_adj = 0 _mem = self._get_raw_memory(mem.number) _flg = self._memobj.flags[mem.number] _nam = self._memobj.names[mem.number + name_index_adj] _flg.used = get_used_flag(mem) if mem.empty: _flg.lockout = 0 _flg.group = 0 _nam.name = ('\x00' * 16) _mem.set_raw(b'\xFF' * 40) return _mem.set_raw(b'\x00' * 40) _flg.group = 0 # FIXME _mem.freq = mem.freq _nam.name = mem.name.ljust(16) _mem.offset = int(mem.offset) if mem.duplex == 'split': _mem.split = True _mem.duplex = 0 _mem.split_tuning_step = TUNE_STEPS.index( chirp_common.required_step(mem.offset)) else: _mem.split = False _mem.duplex = DUPLEX.index(mem.duplex) _mem.tuning_step = TUNE_STEPS.index(mem.tuning_step) _mem.mode = MODES.index(mem.mode) _mem.narrow = mem.mode == 'NFM' _mem.rtone = chirp_common.TONES.index(mem.rtone) _mem.ctone = chirp_common.TONES.index(mem.ctone) _mem.dtcs_code = chirp_common.DTCS_CODES.index(mem.dtcs) _mem.tone_mode = mem.tmode == 'Tone' _mem.ctcss_mode = mem.tmode == 'TSQL' _mem.dtcs_mode = mem.tmode == 'DTCS' _mem.cross_mode = mem.tmode == 'Cross' if mem.tmode == 'Cross': _mem.cross_mode_mode = CROSS_MODES.index(mem.cross_mode) _flg.lockout = mem.skip == 'S' if isinstance(mem, chirp_common.DVMemory): _mem.dv_urcall = encode_call(mem.dv_urcall) _mem.dv_rpt1call = encode_call(mem.dv_rpt1call) _mem.dv_rpt2call = encode_call(mem.dv_rpt2call) _mem.dv_code = mem.dv_code def get_raw_memory(self, number): return (repr(self._get_raw_memory(number)) + repr(self._memobj.flags[number])) def get_bank_model(self): return KenwoodTHD74Bankmodel(self) @classmethod def match_model(cls, filedata, filename): if filename.endswith('.d74'): return True else: return chirp_common.CloneModeRadio.match_model(filedata, filename) @directory.register class THD75Radio(THD74Radio): MODEL = 'TH-D75' chirp-20240224/chirp/drivers/ic9x_icf.py0000644000175000017500000000471514430171343016675 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp.drivers import icf, ic9x_icf_ll from chirp import chirp_common, util, errors # Don't register as this module is used to load icf file from File-Open menu # see do_open in mainapp.py class IC9xICFRadio(chirp_common.CloneModeRadio): VENDOR = "Icom" MODEL = "IC-91/92AD" VARIANT = "ICF File" _model = None _upper = 1200 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_bank = False rf.memory_bounds = (0, self._upper) rf.has_sub_devices = True rf.valid_modes = ["FM", "AM"] if "A" in self.VARIANT: rf.valid_modes.append("WFM") else: rf.valid_modes.append("DV") rf.valid_modes.append("NFM") return rf def get_raw_memory(self, number): raw = ic9x_icf_ll.get_raw_memory(self._mmap, number).get_packed() return util.hexprint(raw) def get_memory(self, number): return ic9x_icf_ll.get_memory(self._mmap, number) def load_mmap(self, filename): _icf_data, self._mmap = icf.read_file(filename) def get_sub_devices(self): return [IC9xICFRadioA(self._mmap), IC9xICFRadioB(self._mmap)] class IC9xICFRadioA(IC9xICFRadio): VARIANT = "ICF File Band A" _upper = 800 def get_memory(self, number): if number > self._upper: raise errors.InvalidMemoryLocation("Number must be <800") return ic9x_icf_ll.get_memory(self._mmap, number) class IC9xICFRadioB(IC9xICFRadio): VARIANT = "ICF File Band B" _upper = 400 def get_memory(self, number): if number > self._upper: raise errors.InvalidMemoryLocation("Number must be <400") mem = ic9x_icf_ll.get_memory(self._mmap, 850 + number) mem.number = number return mem chirp-20240224/chirp/drivers/icx8x.py0000644000175000017500000001753014411666130016244 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import bitwise from chirp.drivers import icf from chirp import chirp_common, directory LOG = logging.getLogger(__name__) MEM_FORMAT = """ struct { ul16 freq; ul16 offset; char name[5]; u8 unknown1:2, rtone:6; u8 unknown2:2, ctone:6; u8 dtcs; u8 unknown3[5]; u8 tuning_step:4, unknown4:4; u8 unknown5[3]; u8 mult:1, unknown6_0:1, narrow:1, unknown6:1, unknown7:2, tmode:2; u8 dtcs_pol:2, duplex:2, unknown9:4; u8 unknown10:1, txinhibit:1, unknown11:2, dvmode:1, unknown12:3; } memories[207]; #seekto 0x1370; struct { u8 unknown:2, empty:1, skip:1, bank:4; } flags[206]; struct dvcall { char call[8]; char pad[8]; }; #seekto 0x15E0; struct dvcall mycall[6]; #seekto 0x1640; struct dvcall urcall[6]; #seekto 0x16A0; struct dvcall rptcall[6]; #seekto 0x1700; #seekto 0x1930; u8 isuhf; """ TMODES = ["", "Tone", "TSQL", "DTCS"] DUPLEXES = ["", '-', '+'] TUNING_STEPS = [5.0, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0] DTCS_POLARITY = ['NN', 'NR', 'RN', 'RR'] SPECIALS = ['L0', 'U0', 'L1', 'U1', 'L2', 'U2', 'C'] class ICx8xRadio(icf.IcomCloneModeRadio, chirp_common.IcomDstarSupport): """Icom IC-V/U82""" VENDOR = "Icom" MODEL = "IC-V82/U82" _model = "\x28\x26\x00\x01" _memsize = 6464 _endframe = "Icom Inc\x2eCD" _can_hispeed = False _double_ident = True _memories = [] _ranges = [(0x0000, 0x1340, 32), (0x1340, 0x1360, 16), (0x1360, 0x136B, 8), (0x1370, 0x1440, 32), (0x1460, 0x15D0, 32), (0x15E0, 0x1930, 32), (0x1938, 0x1940, 8), ] MYCALL_LIMIT = (0, 6) URCALL_LIMIT = (0, 6) RPTCALL_LIMIT = (0, 6) def _get_bank(self, loc): bank = int(self._memobj.flags[loc].bank) if bank > 9: return None else: return bank def _set_bank(self, loc, bank): if bank is None: self._memobj.flags[loc].bank = 0x0A else: self._memobj.flags[loc].bank = bank def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (0, 199) rf.valid_modes = ["FM", "NFM", "DV"] rf.valid_tmodes = list(TMODES) rf.valid_duplexes = list(DUPLEXES) rf.valid_tuning_steps = list(TUNING_STEPS) rf.valid_skips = ["", "S"] rf.valid_name_length = 5 rf.valid_special_chans = list(SPECIALS) return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def get_memory(self, number): mem = chirp_common.Memory() if isinstance(number, str): mem.extd_number = number number = 200 + SPECIALS.index(number) _mem = self._memobj.memories[number] if number < 206: _flg = self._memobj.flags[number] mem.skip = _flg.skip and 'S' or '' empty = _flg.empty else: empty = False if _mem.mult: mult = 6250 else: mult = 5000 mem.number = number if empty: mem.empty = True return mem mem.name = str(_mem.name).rstrip() if _mem.dvmode: mem.mode = 'DV' elif _mem.narrow: mem.mode = 'NFM' else: mem.mode = 'FM' mem.duplex = DUPLEXES[_mem.duplex] mem.tmode = TMODES[_mem.tmode] mem.tuning_step = TUNING_STEPS[_mem.tuning_step] mem.rtone = chirp_common.TONES[_mem.rtone] mem.ctone = chirp_common.TONES[_mem.ctone] mem.dtcs = chirp_common.DTCS_CODES[_mem.dtcs] mem.dtcs_polarity = DTCS_POLARITY[_mem.dtcs_pol] mem.freq = (_mem.freq * mult) + chirp_common.to_MHz(self._base) mem.offset = _mem.offset * 5000 return mem def set_memory(self, memory): _mem = self._memobj.memories[memory.number] if memory.number < 206: _flg = self._memobj.flags[memory.number] _flg.skip = memory.skip == 'S' _flg.empty = memory.empty if memory.empty: return _mem.mult = chirp_common.is_fractional_step(memory.freq) if _mem.mult: mult = 6250 else: mult = 5000 _mem.freq = (memory.freq - chirp_common.to_MHz(self._base)) // mult _mem.offset = memory.offset // 5000 _mem.name = memory.name[:5].ljust(5) _mem.dvmode = memory.mode == 'DV' _mem.narrow = memory.mode == 'NFM' _mem.duplex = DUPLEXES.index(memory.duplex) _mem.tmode = TMODES.index(memory.tmode) _mem.tuning_step = TUNING_STEPS.index(memory.tuning_step) _mem.rtone = chirp_common.TONES.index(memory.rtone) _mem.ctone = chirp_common.TONES.index(memory.ctone) _mem.dtcs = chirp_common.DTCS_CODES.index(memory.dtcs) _mem.dtcs_pol = DTCS_POLARITY.index(memory.dtcs_polarity) def get_raw_memory(self, number): if isinstance(number, str): number = 200 + SPECIALS.index(number) return repr(self._memobj.memories[number]) def get_urcall_list(self): calls = [] for i in range(*self.URCALL_LIMIT): calls.append(str(self._memobj.urcall[i].call).rstrip()) return calls def get_repeater_call_list(self): calls = [] for i in range(*self.RPTCALL_LIMIT): calls.append(str(self._memobj.rptcall[i].call).rstrip()) return calls def get_mycall_list(self): calls = [] for i in range(*self.MYCALL_LIMIT): calls.append(str(self._memobj.mycall[i].call).rstrip()) return calls def set_urcall_list(self, calls): for i in range(*self.URCALL_LIMIT): try: call = calls[i].ljust(8) except IndexError: call = " " * 8 self._memobj.urcall[i].call = call def set_repeater_call_list(self, calls): for i in range(*self.RPTCALL_LIMIT): try: call = calls[i].ljust(8) except IndexError: call = " " * 8 self._memobj.rptcall[i].call = call def set_mycall_list(self, calls): for i in range(*self.MYCALL_LIMIT): try: call = calls[i].ljust(8) except IndexError: call = " " * 8 self._memobj.mycall[i].call = call @directory.register class ICV82Radio(ICx8xRadio): MODEL = 'IC-V82' _base = 0 def get_features(self): rf = super().get_features() rf.valid_bands = [(118000000, 176000000)] return rf @classmethod def match_model(cls, filedata, filename): if super().match_model(filedata, filename): return filedata[0x1930] == 0 @directory.register class ICU82Radio(ICx8xRadio): MODEL = 'IC-U82' _base = 400 def get_features(self): rf = super().get_features() rf.valid_bands = [(420000000, 470000000)] return rf @classmethod def match_model(cls, filedata, filename): if super().match_model(filedata, filename): return filedata[0x1930] == 1 chirp-20240224/chirp/drivers/icf.py0000644000175000017500000010501314446523722015743 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from builtins import bytes import binascii import hashlib import os import struct import re import time import logging from chirp import chirp_common, errors, util, memmap from chirp import directory from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueString, RadioSettings LOG = logging.getLogger(__name__) CMD_CLONE_ID = 0xE0 CMD_CLONE_MODEL = 0xE1 CMD_CLONE_OUT = 0xE2 CMD_CLONE_IN = 0xE3 CMD_CLONE_DAT = 0xE4 CMD_CLONE_END = 0xE5 CMD_CLONE_OK = 0xE6 CMD_CLONE_HISPEED = 0xE8 ADDR_PC = 0xEE ADDR_RADIO = 0xEF SAVE_PIPE = None TRACE_ICF = 'CHIRP_DEBUG_ICF' in os.environ class IcfFrame: """A single ICF communication frame""" def __str__(self): addrs = {ADDR_PC: "PC", ADDR_RADIO: "Radio"} cmds = {CMD_CLONE_ID: "ID", CMD_CLONE_MODEL: "Model", CMD_CLONE_OUT: "Clone out", CMD_CLONE_IN: "Clone in", CMD_CLONE_DAT: "Clone data", CMD_CLONE_END: "Clone end", CMD_CLONE_OK: "Clone OK", CMD_CLONE_HISPEED: "Clone hispeed"} return "%s -> %s [%s]:\n%s" % (addrs.get(self.src, '??'), addrs.get(self.dst, '??'), cmds.get(self.cmd, '??'), util.hexprint(self.payload)) def __init__(self, src=0, dst=0, cmd=0): self.src = src self.dst = dst self.cmd = cmd self.payload = b'' @classmethod def parse(cls, data): """Parse an ICF frame of unknown type from the beginning of @data""" frame = cls(util.byte_to_int(data[2]), util.byte_to_int(data[3]), util.byte_to_int(data[4])) try: end = data.index(b"\xFD") except ValueError: LOG.warning('Frame parsed with no end') return None assert isinstance(data, bytes), ( 'parse_frame_generic() expected bytes, ' 'but got %s' % data.__class__) if data[end + 1:]: LOG.warning('Frame parsed with trailing data') frame.payload = data[5:end] return frame def pack(self): return (b'\xfe\xfe' + struct.pack('BBB', self.src, self.dst, self.cmd) + self.payload + b'\xfd') class RadioStream: """A class to make reading a stream of IcfFrames easier""" def __init__(self, pipe): self.pipe = pipe self.data = bytes() self.iecho = None def _process_frames(self): if not self.data.startswith(b"\xFE\xFE"): LOG.error("Out of sync with radio:\n%s" % util.hexprint(self.data)) raise errors.InvalidDataError("Out of sync with radio") elif len(self.data) < 5: return [] # Not enough data for a full frame frames = [] while self.data: # Hispeed clone frames start with a pad of \xFE, so strip those # away until we have the two we expect while self.data.startswith(b'\xfe\xfe\xfe'): self.data = self.data[1:] try: cmd = self.data[4] except IndexError: break # Out of data try: end = self.data.index(b'\xFD') frame = IcfFrame.parse(self.data[:end + 1]) self.data = self.data[end + 1:] if frame.src == 0xEE and frame.dst == 0xEF: # PC echo, ignore if self.iecho is None: LOG.info('Detected an echoing cable') self.iecho = True else: if TRACE_ICF: LOG.debug('Received frame:\n%s' % frame) frames.append(frame) except ValueError: # no data break except errors.InvalidDataError as e: LOG.error("Failed to parse frame (cmd=%i): %s" % (cmd, e)) return [] if frames and self.iecho is None: LOG.info('Non-echoing cable detected') self.iecho = False return frames def get_frames(self, nolimit=False, limit=None): """Read any pending frames from the stream""" while True: _data = self.pipe.read(1) if not _data: if limit: LOG.warning('Hit timeout before one frame') break else: self.data += _data if limit and 0xFD in self.data: break if not nolimit and len(self.data) > 128 and 0xFD in self.data: break # Give us a chance to do some status if len(self.data) > 1024: break # Avoid an endless loop of chewing garbage if not self.data: return [] return self._process_frames() def munch_echo(self): if self.iecho is not False: f = self.get_frames(limit=1) if len(f) != 0: LOG.warning('Expected to read one echo frame, found %i', len(f)) if f and f[0].src == 0xEF: LOG.warning('Expected PC echo but found radio frame!') def decode_model(data): if len(data) != 49: LOG.info('Unable to decode %i-byte model data' % len(data)) return None rev = util.byte_to_int(data[5]) LOG.info('Radio revision is %i' % rev) comment = data[6:6 + 16] LOG.info('Radio comment is %r' % comment) serial = binascii.unhexlify(data[35:35 + 14]) model, b1, b2, u1, s3 = struct.unpack('>HBBBH', serial) serial_num = '%04i%02i%02i%04i' % (model, b1, b2, s3) LOG.info('Radio serial is %r' % serial_num) return rev def get_model_data(radio, mdata=b"\x00\x00\x00\x00", stream=None): """Query the @radio for its model data""" send_clone_frame(radio, 0xe0, mdata, raw=True) if stream is None: stream = RadioStream(radio.pipe) frames = stream.get_frames() if len(frames) != 1: raise errors.RadioError("Unexpected response from radio") LOG.debug('Model query result:\n%s' % frames[0]) return frames[0].payload def get_clone_resp(pipe, length=None, max_count=None): """Read the response to a clone frame""" def exit_criteria(buf, length, cnt, max_count): """Stop reading a clone response if we have enough data or encounter the end of a frame""" if max_count is not None: if cnt >= max_count: return True if length is None: return buf.endswith("\xfd") else: return len(buf) == length resp = "" cnt = 0 while not exit_criteria(resp, length, cnt, max_count): resp += pipe.read(1) cnt += 1 return resp def send_clone_frame(radio, cmd, data, raw=False, checksum=False): """Send a clone frame with @cmd and @data to the @radio""" frame = IcfFrame(ADDR_PC, ADDR_RADIO, cmd) frame.payload = radio.get_payload(data, raw, checksum) if SAVE_PIPE: LOG.debug("Saving data...") SAVE_PIPE.write(frame.pack()) if TRACE_ICF: LOG.debug('Sending:\n%s' % frame) if cmd == 0xe4: # Uncomment to avoid cloning to the radio # return frame pass radio.pipe.write(frame.pack()) return frame def process_data_frame(radio, frame, _mmap): """Process a data frame, adding the payload to @_mmap""" _data = radio.process_frame_payload(frame.payload) # NOTE: On the _data[N:N+1] below. Because: # - on py2 bytes[N] is a bytes # - on py3 bytes[N] is an int # - on both bytes[N:M] is a bytes # So we do a slice so we get consistent behavior # Checksum logic added by Rick DeWitt, 9/2019, issue # 7075 if len(_mmap) >= 0x10000: # This map size not tested for checksum saddr, = struct.unpack(">I", _data[0:4]) length, = struct.unpack("B", _data[4:5]) data = _data[5:5+length] sumc, = struct.unpack("B", _data[5+length:]) addr1, = struct.unpack("B", _data[0:1]) addr2, = struct.unpack("B", _data[1:2]) addr3, = struct.unpack("B", _data[2:3]) addr4, = struct.unpack("B", _data[3:4]) else: # But this one has been tested for raw mode radio (IC-2730) saddr, = struct.unpack(">H", _data[0:2]) length, = struct.unpack("B", _data[2:3]) data = _data[3:3+length] sumc, = struct.unpack("B", _data[3+length:]) addr1, = struct.unpack("B", _data[0:1]) addr2, = struct.unpack("B", _data[1:2]) addr3 = 0 addr4 = 0 cs = addr1 + addr2 + addr3 + addr4 + length for byte in data: cs += byte vx = ((cs ^ 0xFFFF) + 1) & 0xFF if sumc != vx: LOG.error("Bad checksum in address %04X frame: %02x " "calculated, %02x sent!" % (saddr, vx, sumc)) raise errors.InvalidDataError( "Checksum error in download!") try: _mmap[saddr] = data except IndexError: LOG.error("Error trying to set %i bytes at %05x (max %05x)" % (length, saddr, len(_mmap))) return saddr, saddr + length def start_hispeed_clone(radio, cmd): """Send the magic incantation to the radio to go fast""" frame = IcfFrame(ADDR_PC, ADDR_RADIO, CMD_CLONE_HISPEED) frame.payload = radio.get_model() + b'\x00\x00\x02\x01\xFD' LOG.debug("Starting HiSpeed:\n%s" % frame) radio.pipe.write(b'\xFE' * 20 + frame.pack()) radio.pipe.flush() resp = radio.pipe.read(128) LOG.debug("Response:\n%s" % util.hexprint(resp)) LOG.info("Switching to 38400 baud") radio.pipe.baudrate = 38400 frame = IcfFrame(ADDR_PC, ADDR_RADIO, cmd) frame.payload = radio.get_model()[:3] + b'\x00' LOG.debug("Starting HiSpeed Clone:\n%s" % frame) radio.pipe.write(b'\xFE' * 14 + frame.pack()) radio.pipe.flush() def _clone_from_radio(radio): md = get_model_data(radio) try: radio_rev = decode_model(md) except Exception: LOG.error('Failed to decode model data') radio_rev = None if md[0:4] != radio.get_model(): LOG.info("This model: %s" % util.hexprint(md[0:4])) LOG.info("Supp model: %s" % util.hexprint(radio.get_model())) raise errors.RadioError("I can't talk to this model") if radio.is_hispeed(): start_hispeed_clone(radio, CMD_CLONE_OUT) else: send_clone_frame(radio, CMD_CLONE_OUT, radio.get_model(), raw=True) LOG.debug("Sent clone frame") stream = RadioStream(radio.pipe) addr = 0 _mmap = memmap.MemoryMapBytes(bytes(b'\x00') * radio.get_memsize()) last_size = 0 got_end = False last_frame = time.time() timeout = 10 while not got_end: frames = stream.get_frames() if not frames and (time.time() - last_frame) > timeout: break for frame in frames: last_frame = time.time() if frame.cmd == CMD_CLONE_DAT: src, dst = process_data_frame(radio, frame, _mmap) if last_size != (dst - src): LOG.debug("ICF Size change from %i to %i at %04x" % (last_size, dst - src, src)) last_size = dst - src if addr != src: LOG.debug("ICF GAP %04x - %04x" % (addr, src)) addr = dst elif frame.cmd == CMD_CLONE_END: LOG.debug("End frame (%i):\n%s" % (len(frame.payload), util.hexprint(frame.payload))) LOG.debug("Last addr: %04x" % addr) # For variable-length radios, make sure we don't # return a longer map than we got from the radio. _mmap.truncate(addr) got_end = True if radio.status_fn: status = chirp_common.Status() status.msg = "Cloning from radio" status.max = radio.get_memsize() status.cur = addr radio.status_fn(status) if not got_end: LOG.error('clone_from_radio ending at address %06X before ' 'CLONE_END; stream buffer is:\n%s', addr, util.hexprint(stream.data)) raise errors.RadioError('Data stream stopped before end-of-clone ' 'received') return _mmap def clone_from_radio(radio): """Do a full clone out of the radio's memory""" try: return _clone_from_radio(radio) except Exception as e: raise errors.RadioError("Failed to communicate with the radio: %s" % e) def send_mem_chunk(radio, stream, start, stop, bs=32): """Send a single chunk of the radio's memory from @start-@stop""" _mmap = radio.get_mmap().get_byte_compatible() status = chirp_common.Status() status.msg = "Cloning to radio" status.max = radio.get_memsize() LOG.debug('Sending memory range %06x - %06x @ %i bytes' % ( start, stop, bs)) for i in range(start, stop, bs): if i + bs < stop: size = bs else: size = stop - i if radio.get_memsize() >= 0x10000: chunk = struct.pack(">IB", i, size) else: chunk = struct.pack(">HB", i, size) chunk += _mmap[i:i+size] send_clone_frame(radio, CMD_CLONE_DAT, chunk, raw=False, checksum=True) stream.munch_echo() if radio.status_fn: status.cur = i+bs radio.status_fn(status) return True def _clone_to_radio(radio): global SAVE_PIPE # Uncomment to save out a capture of what we actually write to the radio # SAVE_PIPE = file("pipe_capture.log", "w", 0) stream = RadioStream(radio.pipe) md = get_model_data(radio, stream=stream) if radio._double_ident: md = get_model_data(radio, stream=stream) if md[0:4] != radio.get_model(): raise errors.RadioError("I can't talk to this model") try: radio_rev = decode_model(md) except Exception: LOG.error('Failed to decode model data') radio_rev = None image_rev = radio._icf_data.get('MapRev', 1) if radio_rev is not None and radio_rev != image_rev: raise errors.RadioError('Radio revision %i does not match image %i' % ( radio_rev, image_rev)) # This mimics what the Icom software does, but isn't required and just # takes longer # md = get_model_data(radio, mdata=md[0:2]+"\x00\x00") # md = get_model_data(radio, mdata=md[0:2]+"\x00\x00") if radio.is_hispeed(): start_hispeed_clone(radio, CMD_CLONE_IN) else: send_clone_frame(radio, CMD_CLONE_IN, radio.get_model(), raw=True) frames = [] for start, stop, bs in radio.get_ranges(): if not send_mem_chunk(radio, stream, start, stop, bs): break send_clone_frame(radio, CMD_CLONE_END, radio.get_endframe(), raw=True) if SAVE_PIPE: SAVE_PIPE.close() SAVE_PIPE = None for i in range(0, 10): try: frames += stream.get_frames(True) result = frames[-1] except IndexError: LOG.debug("Waiting for clone result...") time.sleep(0.5) if len(frames) == 0: raise errors.RadioError("Did not get clone result from radio") elif result.cmd != CMD_CLONE_OK: LOG.error('Clone failed result frame:\n%s' % result) raise errors.RadioError('Radio rejected clone') else: LOG.debug('Clone result frame:\n%s' % result) return result.payload[0] == bytes(b'\x00') def clone_to_radio(radio): """Initiate a full memory clone out to @radio""" try: return _clone_to_radio(radio) except Exception as e: logging.exception("Failed to communicate with the radio") raise errors.RadioError("Failed to communicate with the radio: %s" % e) def convert_model(mod_str): """Convert an ICF-style model string into what we get from the radio""" data = b"" for i in range(0, len(mod_str), 2): hexval = mod_str[i:i+2] intval = int(hexval, 16) data += bytes([intval]) return data def convert_data_line(line): """Convert an ICF data line to raw memory format""" if line.startswith("#"): return "" line = line.strip() # Detection of the prefix length. The code assumes that the data line # length (without the prefix) is multiply of 8 characters (i.e. multiply # of 4 bytes), so the rest (remainder of division by 8) has to be the # prefix (prefix = address + length) - for small memory the address is # 2 bytes long and the length indicator is 1 byte long which means 3 bytes # in total which is 6 characters in total for the prefix on the ICF line. if len(line) % 8 == 6: # Small memory (< 0x10000) size = int(line[4:6], 16) data = line[6:] else: # Large memory (>= 0x10000) size = int(line[8:10], 16) data = line[10:] _mmap = b"" i = 0 while i < (size * 2): try: val = int("%s%s" % (data[i], data[i+1]), 16) i += 2 _mmap += struct.pack("B", val) except ValueError as e: LOG.debug("Failed to parse byte: %s" % e) break return _mmap def read_file(filename): """Read an ICF file and return the model string and memory data""" f = open(filename) mod_str = f.readline() dat = f.readlines() icfdata = { 'model': convert_model(mod_str.strip()) } _mmap = b"" for line in dat: if line.startswith("#"): try: key, value = line.strip().split('=', 1) if key == '#EtcData': value = int(value, 16) elif value.isdigit(): value = int(value) icfdata[key[1:]] = value except ValueError: # Some old files have lines with just # pass else: line_data = convert_data_line(line) _mmap += line_data if 'recordsize' not in icfdata: icfdata['recordsize'] = len(line_data) return icfdata, memmap.MemoryMapBytes(_mmap) def _encode_model_for_icf(model): """ Encode the model magically for the ICF file hash. If model is: AB CD 00 00 Then the magic is AA BB CC DD AB CD """ a = (util.byte_to_int(model[0]) & 0xF0) >> 4 b = util.byte_to_int(model[0]) & 0x0F c = (util.byte_to_int(model[1]) & 0xF0) >> 4 d = util.byte_to_int(model[1]) & 0x0F sequence = [(a << 4) | a, (b << 4) | b, (c << 4) | c, (d << 4) | d, (a << 4) | b, (c << 4) | d] return b''.join(util.int_to_byte(x) for x in sequence) def write_file(radio, filename): """Write an ICF file""" f = open(filename, 'w', newline='\r\n') model = radio._model mdata = '%02x%02x%02x%02x' % (ord(model[0]), ord(model[1]), ord(model[2]), ord(model[3])) data = radio._mmap.get_packed() f.write('%s\n' % mdata) f.write('#Comment=%s\n' % radio._icf_data.get('Comment', '')) f.write('#MapRev=%i\n' % radio._icf_data.get('MapRev', 1)) f.write('#EtcData=%06x\n' % radio._icf_data.get('EtcData', 0)) binicf = _encode_model_for_icf(model) # ICF files for newer models (probably everything with an SD card # slot) store a hash on the last line of the ICF file, as # #CD=$hexdigest. This is an MD5 sum of a sequence that starts # with the specially-encoded model from _encode_model_for_icf(), # followed by the unencoded lines of the ICF file (including # address and length values). So for an ID31 the value we hash # looks like this (in hex, line breaks for the humans and pep8): # # 333322223322 # 0000000020 # dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd # 0000002020 # dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd # ... and so on LOG.debug('ICF hash header: %r' % binascii.hexlify(binicf)) blksize = radio._icf_data.get('recordsize', 32) for addr in range(0, len(data), blksize): block = binascii.hexlify(data[addr:addr + blksize]).decode().upper() if blksize == 32: line = '%08X%02X%s' % (addr, blksize, block) binicf += binascii.unhexlify(line) else: line = '%04X%02X%s' % (addr, blksize, block) f.write(line + '\n') if blksize == 32: hash = hashlib.md5(binicf) digest = hash.hexdigest().upper() LOG.debug('ICF hash digest: %s' % digest) f.write('#CD=%s\n' % digest) f.close() def is_9x_icf(filename): """Returns True if @filename is an IC9x ICF file""" try: with open(filename) as f: mdata = f.read(8) except UnicodeDecodeError: # ICF files are ASCII, so any unicode failure means no. return False return mdata in ["30660000", "28880000"] def is_icf_file(filename): """Returns True if @filename is an ICF file""" try: with open(filename) as f: data = f.readline() data += f.readline() except UnicodeDecodeError: # ICF files are ASCII, so any unicode failure means no. return False data = data.replace("\n", "").replace("\r", "") return bool(re.match("^[0-9]{8}#", data)) class IcomBank(chirp_common.Bank): """A bank that works for all Icom radios""" # Integral index of the bank (not to be confused with per-memory # bank indexes index = 0 class IcomNamedBank(IcomBank): """A bank with an adjustable name""" def set_name(self, name): """Set the name of the bank""" pass class IcomBankModel(chirp_common.BankModel): """Icom radios all have pretty much the same simple bank model. This central implementation can, with a few icom-specific radio interfaces serve most/all of them""" def get_num_mappings(self): return self._radio._num_banks def get_mappings(self): banks = [] for i in range(0, self._radio._num_banks): index = chr(ord("A") + i) bank = self._radio._bank_class(self, index, "BANK-%s" % index) bank.index = i banks.append(bank) return banks def add_memory_to_mapping(self, memory, bank): self._radio._set_bank(memory.number, bank.index) def remove_memory_from_mapping(self, memory, bank): if self._radio._get_bank(memory.number) != bank.index: raise Exception("Memory %i not in bank %s. Cannot remove." % (memory.number, bank)) self._radio._set_bank(memory.number, None) def get_mapping_memories(self, bank): memories = [] for i in range(*self._radio.get_features().memory_bounds): if self._radio._get_bank(i) == bank.index: memories.append(self._radio.get_memory(i)) return memories def get_memory_mappings(self, memory): index = self._radio._get_bank(memory.number) if index is None: return [] else: return [self.get_mappings()[index]] class IcomIndexedBankModel(IcomBankModel, chirp_common.MappingModelIndexInterface): """Generic bank model for Icom radios with indexed banks""" def get_index_bounds(self): return self._radio._bank_index_bounds def get_memory_index(self, memory, bank): return self._radio._get_bank_index(memory.number) def set_memory_index(self, memory, bank, index): if bank not in self.get_memory_mappings(memory): raise Exception("Memory %i is not in bank %s" % (memory.number, bank)) if index not in list(range(*self._radio._bank_index_bounds)): raise Exception("Invalid index") self._radio._set_bank_index(memory.number, index) def get_next_mapping_index(self, bank): indexes = [] for i in range(*self._radio.get_features().memory_bounds): if self._radio._get_bank(i) == bank.index: indexes.append(self._radio._get_bank_index(i)) for i in range(0, 256): if i not in indexes: return i raise errors.RadioError("Out of slots in this bank") def compute_checksum(data): cs = 0 for byte in data: cs += byte return ((cs ^ 0xFFFF) + 1) & 0xFF class IcomCloneModeRadio(chirp_common.CloneModeRadio): """Base class for Icom clone-mode radios""" VENDOR = "Icom" BAUDRATE = 9600 NEEDS_COMPAT_SERIAL = False FORMATS = [directory.register_format('Icom ICF', '*.icf')] _model = "\x00\x00\x00\x00" # 4-byte model string _endframe = "" # Model-unique ending frame _ranges = [] # Ranges of the mmap to send to the radio _num_banks = 10 # Most simple Icoms have 10 banks, A-J _bank_index_bounds = (0, 99) _bank_class = IcomBank _can_hispeed = False _double_ident = False # A couple radios require double ident before upload # Newer radios (ID51Plus2, ID5100, IC2730) use a slightly # different CLONE_DAT format _raw_frames = False _highbit_flip = False # Attributes that get put into ICF files when we export. The meaning # of these are unknown at this time, but differ per model (at least). # Saving ICF files will not be offered unless _icf_data has attributes. _icf_data = { 'recordsize': 16, } @classmethod def is_hispeed(cls): """Returns True if the radio supports hispeed cloning""" return cls._can_hispeed @classmethod def get_model(cls): """Returns the Icom model data for this radio""" return bytes([util.byte_to_int(x) for x in cls._model]) def get_endframe(self): """Returns the magic clone end frame for this radio""" return bytes([util.byte_to_int(x) for x in self._endframe]) def get_ranges(self): """Returns the ranges this radio likes to have in a clone""" return self._ranges def process_frame_payload(self, payload): if self._raw_frames: return unescape_raw_bytes(payload) # Legacy frame format: convert BCD-encoded data to raw""" bcddata = payload data = b"" i = 0 while i+1 < len(bcddata): try: val = int(b"%s%s" % (util.int_to_byte(bcddata[i]), util.int_to_byte(bcddata[i+1])), 16) i += 2 data += struct.pack("B", val) except (ValueError, TypeError) as e: LOG.error("Failed to parse byte %i (%r): %s" % (i, bcddata[i:i+2], e)) break return data def get_payload(self, data, raw, checksum): """Returns the data with optional checksum BCD-encoded for the radio""" if checksum: data += util.int_to_byte(compute_checksum(data)) if self._raw_frames: # Always raw format, no need to check raw return b''.join(escape_raw_byte(b) for b in data) if raw: return data payload = b'' for byte in data: payload += b"%02X" % util.byte_to_int(byte) return payload def sync_in(self): _mmap = clone_from_radio(self) if self._highbit_flip: LOG.debug('Flipping high bits of received image') map_cls = _mmap.__class__ _mmap = flip_high_order_bit(_mmap.get_packed()) self._mmap = map_cls(_mmap) else: self._mmap = _mmap self.process_mmap() def get_mmap(self): if self._highbit_flip: map_cls = self._mmap.__class__ LOG.debug('Flipping high bits of image') return map_cls(flip_high_order_bit(self._mmap.get_packed())) else: return self._mmap def sync_out(self): # We always start at 9600 baud. The UI may have handed us the same # rate we ended with last time (for radios which have variable but # unchanging speeds) but we always have to start in low-speed mode. self.pipe.baudrate = 9600 clone_to_radio(self) def get_bank_model(self): rf = self.get_features() if rf.has_bank: if rf.has_bank_index: return IcomIndexedBankModel(self) else: return IcomBankModel(self) else: return None # Icom-specific bank routines def _get_bank(self, loc): """Get the integral bank index of memory @loc, or None""" raise Exception("Not implemented") def _set_bank(self, loc, index): """Set the integral bank index of memory @loc to @index, or no bank if None""" raise Exception("Not implemented") def _make_call_list_setting_group(self, listname): current = getattr(self, 'get_%s_list' % listname)() nice_name = listname.split('_', 1)[0].upper() group = RadioSettingGroup('%s_list' % listname, '%s List' % nice_name) for i, cs in enumerate(current): group.append(RadioSetting('%03i' % i, '%i' % i, RadioSettingValueString(0, 8, cs))) return group def get_settings(self): if isinstance(self, chirp_common.IcomDstarSupport): dstar = RadioSettingGroup('dstar', 'D-STAR') dstar.append(self._make_call_list_setting_group('urcall')) dstar.append(self._make_call_list_setting_group('repeater_call')) dstar.append(self._make_call_list_setting_group('mycall')) return RadioSettings(dstar) return [] def _apply_call_list_setting(self, dstar, listname): listgroup = dstar['%s_list' % listname] calls = [str(listgroup[i].value) for i in sorted(listgroup.keys())] getattr(self, 'set_%s_list' % listname)(calls) def set_settings(self, settings): for group in settings: if group.get_name() == 'dstar': self._apply_call_list_setting(group, 'mycall') self._apply_call_list_setting(group, 'urcall') self._apply_call_list_setting(group, 'repeater_call') def load_mmap(self, filename): if filename.lower().endswith('.icf'): self._icf_data, self._mmap = read_file(filename) LOG.debug('Loaded ICF file %s with data: %s' % (filename, self._icf_data)) self.process_mmap() else: chirp_common.CloneModeRadio.load_mmap(self, filename) def save_mmap(self, filename): if filename.lower().endswith('.icf'): write_file(self, filename) else: chirp_common.CloneModeRadio.save_mmap(self, filename) @classmethod def match_model(cls, filedata, filename): if (filedata[:4] == binascii.hexlify(cls.get_model())[:4] and filename.lower().endswith('.icf')): return True else: return super(IcomCloneModeRadio, cls).match_model(filedata, filename) def flip_high_order_bit(data): return bytes([d ^ 0x80 for d in list(data)]) def escape_raw_byte(byte): """Escapes a raw byte for sending to the radio""" # Certain bytes are used as control characters to the radio, so if one of # these bytes is present in the stream to the radio, it gets escaped as # 0xff followed by (byte & 0x0f) if byte > 0xf9: return bytes([0xff, byte & 0xf]) return bytes([byte]) def unescape_raw_bytes(escaped_data): """Unescapes raw bytes from the radio.""" data = b"" i = 0 while i < len(escaped_data): byte = escaped_data[i] if byte == 0xff: if i + 1 >= len(escaped_data): raise errors.InvalidDataError( "Unexpected escape character at end of data") i += 1 byte = 0xf0 | escaped_data[i] data += bytes([byte]) i += 1 return data class IcomLiveRadio(chirp_common.LiveRadio): """Base class for an Icom Live-mode radio""" VENDOR = "Icom" BAUD_RATE = 38400 _num_banks = 26 # Most live Icoms have 26 banks, A-Z _bank_index_bounds = (0, 99) _bank_class = IcomBank def get_bank_model(self): rf = self.get_features() if rf.has_bank: if rf.has_bank_index: return IcomIndexedBankModel(self) else: return IcomBankModel(self) else: return None def warp_byte_size(inbytes, obw=8, ibw=8): """Convert between "byte sizes". This will pack N-bit characters into a sequence of 8-bit bytes, and perform the opposite. ibw (input bit width) is the width of the storage obw (output bit width) is the width of the characters to extract ibw=8,obw=7 will pull seven-bit characters from a sequence of bytes ibw=7,obw=8 will pack seven-bit characters into a sequence of bytes """ if isinstance(inbytes, str): inbytes = [ord(x) for x in inbytes] outbit = 0 tmp = 0 stripmask = 1 << (ibw - 1) for byte in inbytes: inbit = 0 for i in range(0, max(obw, ibw - inbit)): if inbit == ibw: # Move to next char inbit = 0 break tmp = (tmp << 1) | ((byte & stripmask) and 1 or 0) byte = (byte << 1) & 0xFF inbit += 1 outbit += 1 if outbit == obw: yield tmp tmp = 0 outbit = 0 chirp-20240224/chirp/drivers/tk8160.py0000644000175000017500000005003114522657251016136 0ustar hibbyhibby# Copyright 2023 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import functools import logging import struct from chirp import bitwise from chirp import chirp_common from chirp import directory from chirp.drivers import tk8180 from chirp import errors from chirp import memmap from chirp import settings from chirp import util LOG = logging.getLogger(__name__) mem_format = """ // Bitmask for zone in use #seekto 0x0020; u8 zoneflag[16]; // (identical?) bitmask for index spot in use #seekto 0x0030; u8 flag1[16]; #seekto 0x0050; u8 flag2[16]; // This is filled in order, regardless of the ordering of the memories or // their positions #seekto 0x00E0; struct { u8 zone; // Zone number u8 memory; // Channel number u8 zero; u8 slot; // Index into the memory array } index[128]; #seekto 0x02E0; struct { u8 used:1, unknown1:4, // Always 0x71? zoneaudiomode:2, // 00=QT/DQT 01=QT/DQT+OptSig 02 QT/DQTorOptSig optsigdecode:1; // 0=Carrier 1=QT/DQT u8 count; // Number of memories in the zone } zoneinfo[128]; #seekto 0x03E0; struct { u8 number; u8 zone; lbcd rx_freq[4]; lbcd tx_freq[4]; u8 unknown1[2]; ul16 rxtone; ul16 txtone; // BCL 0:no 1: carrier u8 unknown2_0:4, bcl:2, // 0:no 1:carrier 2:tone 3:optsig unknown2_01:1, wide:1; u8 beatshift:1, unknown2_1:1, highpower:1, scanadd:1, unknown2_2:4; u8 unknown2_3:6, pttid:2; // 0:off 1:BOT 2:EOT 3:Both char name[8]; u8 unknown3_0:7, compander:1; u8 unknown3_1:7, pttidmute:1; u8 optsig:3, // 0:none 1:DTMF 2:2tone1 3:2tone2 4:2tone3 5:FleetSync unknown4:5; u8 unknown5[2]; } memories[128]; #seekto 0x14F0; struct { char message1[32]; char message2[32]; } messages; #seekto 0x1730; struct { char model[5]; u8 variant; } model; // 28=volup 2A=None 15=2-tone 8=AUX 16=Call1 17=Call2 13=ChDn 12=ChUp // 0B=DisplayCh 09=HornAlert 03=KeyLock 14=Brightness 02=Monitor 25=MonMom // 0C=OST 19=PA 1A=SquelchLevel 05=Scan 06=ScanAdd 0A=Scrambler 18=Selcall // 27=SendGPS 04=TA 28=VolUp 29=VolDn 00=ZoneUp 24=SqlOff 26=SqlOffMom // 1C=Status 1D=SelCall+Status 01=ZoneDn #seekto 0x1820; struct { u8 skey; u8 akey; u8 bkey; u8 ckey; u8 triangle; u8 rightup; u8 rightdn; u8 leftup; u8 leftdn; } keys; """ _KEYS = [ 'Zone Up', 'Zone Down', 'Monitor', 'Key Lock', 'Talk Around', 'Scan', 'Scan Add', '?', 'AUX', 'Horn Alert', 'Scrambler', 'Display Character', 'OST', '?', # 0D '?', # 0E '?', # 0F '?', # 10 '?', # 11 'Channel Up', 'Channel Down', 'Brightness', '2-Tone', 'Call 1', 'Call 2', 'Selcall', 'Public Address', 'Squelch Level', '?', 'Status', 'Selcall+Status', '?', # 1E '?', # 1F '?', # 20 '?', # 21 '?', # 22 '?', # 23 'Squelch Off', 'Monitor Momentary', 'Squelch Off Momentary', 'Send the GPS', 'Volume Up', 'Volume Down', 'None', ] KEYS = {i: key for i, key in enumerate(_KEYS) if not key.startswith('?')} KEY_NAMES = { 'A': 'akey', 'B': 'bkey', 'C': 'ckey', 'S': 'skey', 'Triangle': 'triangle', 'Right Up': 'rightup', 'Right Down': 'rightdn', 'Left Up': 'leftup', 'Left Down': 'leftdn', } POWER_LEVELS = [chirp_common.PowerLevel('Low', watts=25), chirp_common.PowerLevel('High', watts=50)] def ends_program(fn): @functools.wraps(fn) def wrapper(radio): try: return fn(radio) finally: radio.pipe.write(b'E') ack = radio.pipe.read(1) if ack != b'\x06': LOG.warning('Radio did not ACK exiting program mode') return wrapper @ends_program def do_download(radio): tk8180.do_ident(radio) data = b'' def status(): status = chirp_common.Status() status.cur = len(data) status.max = radio._memsize status.msg = 'Cloning from radio' radio.status_fn(status) LOG.debug('Radio address 0x%04x' % len(data)) # This seems to be "give me the whole thing" LOG.debug('Requesting clone image') radio.pipe.write(b'hRDA') ack = radio.pipe.read(1) if ack != b'\x06': LOG.error('No ack from radio; got %r' % ack) raise errors.RadioError('Radio refused to send memory') while len(data) < radio._memsize: cmd = radio.pipe.read(1) if cmd == b'E': LOG.debug('Got clone end') break elif cmd not in b'ZW': LOG.error('Unsupported command %r' % cmd) raise errors.RadioError('Radio sent unknown message') hdr = radio.pipe.read(3) addr, length = struct.unpack('>HB', hdr) LOG.debug('Radio: %r %04x %02x' % (cmd, addr, length)) if cmd == b'Z': data += b'\xFF' * length elif cmd == b'W': block = radio.pipe.read(length) data += block radio.pipe.write(b'\x06') status() return memmap.MemoryMapBytes(data) @ends_program def do_upload(radio): tk8180.do_ident(radio) data = radio._mmap.get_packed() def status(addr): status = chirp_common.Status() status.cur = addr status.max = radio._memsize status.msg = "Cloning to radio" radio.status_fn(status) LOG.debug('Radio address 0x%04x' % addr) for addr in range(0, 0x30E0, 0x40): block = data[addr:addr + 0x40] hdr = struct.pack('>cHB', b'W', addr, 0x40) radio.pipe.write(hdr + block) ack = radio.pipe.read(1) if ack != b'\x06': LOG.error('Expected ack, got %r' % ack) raise errors.RadioError('Radio did not ACK block') status(addr) class TKx160Radio(chirp_common.CloneModeRadio): VENDOR = 'Kenwood' FORMATS = [directory.register_format('Kenwood KPG-99D', '*.dat')] NEEDS_COMPAT_SERIAL = False _memsize = 0x4000 def sync_in(self): try: self._mmap = do_download(self) except errors.RadioError: raise except Exception as e: LOG.exception('Failed download: %s' % e) raise errors.RadioError('Failed to communicate with radio') self.process_mmap() def sync_out(self): try: self._mmap = do_upload(self) except errors.RadioError: raise except Exception as e: LOG.exception('Failed upload: %s' % e) raise errors.RadioError('Failed to communicate with radio') def process_mmap(self): self._memobj = bitwise.parse(mem_format, self._mmap) @classmethod def match_model(cls, filedata, filename): return (filename.endswith('.dat') and filedata[0x1740:0x1746] == cls._model) def get_features(self): rf = chirp_common.RadioFeatures() rf.memory_bounds = (1, 128) rf.has_ctone = True rf.has_cross = True rf.has_bank = False rf.has_sub_devices = not self.VARIANT rf.has_tuning_step = False rf.has_rx_dtcs = True rf.has_settings = True rf.can_odd_split = True rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = ['Tone->Tone', 'DTCS->', '->DTCS', "Tone->DTCS", 'DTCS->Tone', '->Tone', 'DTCS->DTCS'] rf.valid_duplexes = ['', '-', '+', 'split', 'off'] rf.valid_modes = ['FM', 'NFM'] rf.valid_tuning_steps = [2.5, 5.0, 6.25, 12.5, 10.0, 15.0, 20.0, 25.0, 50.0, 100.0] rf.valid_bands = self.VALID_BANDS rf.valid_characters = chirp_common.CHARSET_UPPER_NUMERIC rf.valid_name_length = 8 rf.valid_power_levels = list(reversed(POWER_LEVELS)) rf.valid_skips = ['', 'S'] return rf def _get_zone_info(self): zones = {} for i in range(128): info = self._memobj.zoneinfo[i] if info.used: zones[i + 1] = int(info.count) if not zones: LOG.warning('No zones defined, defaulting to 1') # Default to at least one zone so we have *something* zones[1] = 0 return zones def _set_num_zones(self, count): LOG.debug('Setting zones to %i' % count) for i in range(128): index_obj = self._memobj.index[i] if index_obj.zone != 0xFF and index_obj.zone > count: LOG.debug('Deleting memory %i:%i to delete zone', index_obj.zone, index_obj.memory) self._delete_entry_from_index(i) # This will disable zones with no memories, so do it after deletion # but before we may expand (if we're increasing) self.recalculate_index_entry_bitmask() unused_zones = [] for i in range(128): info = self._memobj.zoneinfo[i] info.used = i < count if not info.used: unused_zones.append(i + 1) def _get_zone(self, zone): class TKx160Zone(self.__class__): MODEL = self.MODEL VARIANT = 'Zone %i' % zone VALID_BANDS = self.VALID_BANDS def __init__(self, parent, zone): self._memobj = parent._memobj self._zone = zone return TKx160Zone(self, zone) def get_sub_devices(self): if not self._memobj: return [self._get_zone(1)] return [self._get_zone(zone) for zone, count in self._get_zone_info().items()] def get_raw_memory(self, number): index_entry, slot = self.check_index(number) return (repr(self._memobj.index[index_entry]) + repr(self._memobj.memories[slot])) def check_index(self, number): """Return the index entry and slot for a channel in our zone""" for i in range(128): index_obj = self._memobj.index[i] if index_obj.zone == self._zone and index_obj.memory == number: LOG.debug('Found %i:%i in slot %i', self._zone, number, index_obj.slot) return i, index_obj.slot return None, None def next_slot(self, number): """Claim the next available slot entry for channel.""" for next_index in range(128): index_obj = self._memobj.index[next_index] if index_obj.zone == 0xFF: break else: raise errors.RadioError('Radio is out if index memory') for next_slot in range(128): if self._memobj.memories[next_slot].number == 0xFF: break else: raise errors.RadioError('Radio is out of memory slots') LOG.debug('Putting channel %i in index spot %i', number, next_index) index_obj = self._memobj.index[next_index] index_obj.zone = self._zone index_obj.memory = number index_obj.zero = 0 index_obj.slot = next_slot self.recalculate_index_entry_bitmask() return next_slot def _delete_entry_from_index(self, index_entry): last_entry = index_entry # Find the last index entry for i in reversed(range(0, 128)): mask = 1 << (i % 8) if self._memobj.flag1[i // 8] & mask: last_entry = i break src_obj = self._memobj.index[last_entry] dst_obj = self._memobj.index[index_entry] if index_entry != last_entry: LOG.debug('Moving index entry %i to %i for delete of %i:%i', last_entry, index_entry, dst_obj.zone, dst_obj.memory) # Move last to current dst_obj.zone = src_obj.zone dst_obj.memory = src_obj.memory dst_obj.zero = src_obj.zero dst_obj.slot = src_obj.slot # Clear out the entry we moved, which may be the last and only one src_obj.set_raw(b'\xFF' * 4) def delete_from_index(self, number): """Delete the index entry for number""" # Find the index entry to delete index_entry, _slot = self.check_index(number) self._delete_entry_from_index(index_entry) self.recalculate_index_entry_bitmask() def recalculate_index_entry_bitmask(self): # Recalculate the pins. This is more laborious than needed, but should # also clean up residue. zone_counts = [0] * 128 mem_flags = [0] * 16 for i in range(128): index_obj = self._memobj.index[i] byte = i // 8 mask = 1 << (i % 8) if index_obj.memory != 0xFF: mem_flags[byte] |= mask zone_counts[index_obj.zone - 1] += 1 for i, byte in enumerate(mem_flags): self._memobj.flag1[i] = byte self._memobj.flag2[i] = byte zone_flags = [0] * 16 # Update zoneinfo for i, count in enumerate(zone_counts): self._memobj.zoneinfo[i].used = bool(count) self._memobj.zoneinfo[i].count = count if count: zone_flags[i // 8] |= (1 << (i % 8)) LOG.debug('Zone %i count is %i', i + 1, count) for i, byte in enumerate(zone_flags): self._memobj.zoneflag[i] = byte def get_memory(self, number): m = chirp_common.Memory(number) _index_entry, slot = self.check_index(number) if slot is None: m.empty = True return m _mem = self._memobj.memories[slot] m.freq = int(_mem.rx_freq) * 10 offset = int(_mem.tx_freq) * 10 - m.freq if _mem.tx_freq.get_raw() == b'\xFF\xFF\xFF\xFF': m.offset = 0 m.duplex = 'off' elif offset < 0: m.offset = abs(offset) m.duplex = '-' elif offset > 0: m.offset = offset m.duplex = '+' else: m.offset = 0 rxtone = tk8180.KenwoodTKx180Radio._decode_tone( _mem.rxtone) txtone = tk8180.KenwoodTKx180Radio._decode_tone( _mem.txtone) chirp_common.split_tone_decode(m, txtone, rxtone) m.name = str(_mem.name).rstrip() m.power = POWER_LEVELS[int(_mem.highpower)] m.mode = 'FM' if _mem.wide else 'NFM' m.skip = '' if _mem.scanadd else 'S' return m def set_memory(self, mem): _index_entry, slot = self.check_index(mem.number) if mem.empty: if slot is not None: self._memobj.memories[slot].set_raw(b'\xFF' * 32) self.delete_from_index(mem.number) return elif slot is None: slot = self.next_slot(mem.number) _mem = self._memobj.memories[slot] _mem.number = mem.number _mem.zone = self._zone LOG.debug('Setting memory %i in slot %i', mem.number, slot) _mem.rx_freq = mem.freq // 10 if mem.duplex == '': _mem.tx_freq = mem.freq // 10 elif mem.duplex == 'split': _mem.tx_freq = mem.offset // 10 elif mem.duplex == 'off': _mem.tx_freq.set_raw(b'\xFF' * 4) elif mem.duplex == '-': _mem.tx_freq = (mem.freq - mem.offset) // 10 elif mem.duplex == '+': _mem.tx_freq = (mem.freq + mem.offset) // 10 else: raise errors.RadioError('Unsupported duplex mode %r' % mem.duplex) txtone, rxtone = chirp_common.split_tone_encode(mem) _mem.rxtone = tk8180.KenwoodTKx180Radio._encode_tone(*rxtone) _mem.txtone = tk8180.KenwoodTKx180Radio._encode_tone(*txtone) _mem.wide = mem.mode == 'FM' _mem.highpower = mem.power == POWER_LEVELS[1] _mem.scanadd = mem.skip == '' _mem.name = mem.name[:8].ljust(8) # Set the flags we don't support _mem.bcl = 0 _mem.beatshift = 0 _mem.pttid = 0 _mem.compander = 0 _mem.pttidmute = 0 _mem.optsig = 0 # Set the unknowns _mem.unknown1[0] = 0x02 _mem.unknown1[1] = 0x02 _mem.unknown2_0 = 0x0F _mem.unknown2_01 = 0x00 _mem.unknown2_1 = 0x00 _mem.unknown2_2 = 0x00 _mem.unknown2_3 = 0x00 _mem.unknown3_0 = 0x00 _mem.unknown3_1 = 0x00 _mem.unknown4 = 0x1F _mem.unknown5[0] = 0xFF _mem.unknown5[1] = 0xFF @staticmethod def make_key_group(keysobj, keynames, keyvals): keyvals_by_label = {v: k for k, v in keyvals.items()} def applycb(setting): element = setting.get_name() value = keyvals_by_label[str(setting.value)] LOG.debug('Setting %s=%s (0x%02x)', element, setting.value, value) setattr(keysobj, element, value) group = settings.RadioSettingGroup('keys', 'Keys') for name, element in keynames.items(): current = keyvals[int(getattr(keysobj, element))] val = settings.RadioSettingValueList(keyvals.values(), current) keysetting = settings.RadioSetting(element, name, val) keysetting.set_apply_callback(applycb) group.append(keysetting) return group def get_settings(self): num_zones = len(self._get_zone_info()) zones = settings.RadioSettingGroup('zones', 'Zones') zone_count = settings.RadioSetting( 'zonecount', 'Number of Zones', settings.RadioSettingValueInteger(1, 128, num_zones)) zone_count.set_doc('Number of zones in the radio. ' 'Requires a save and re-load of the file to take ' 'effect. Reducing this number will DELETE ' 'memories in the affected zones!') zones.append(zone_count) keys = self.make_key_group(self._memobj.keys, KEY_NAMES, KEYS) return settings.RadioSettings(zones, keys) def set_settings(self, _settings): for element in _settings: if not isinstance(element, settings.RadioSetting): self.set_settings(element) elif element.get_name() == 'zonecount': self._set_num_zones(int(element.value)) def save_mmap(self, filename): if filename.lower().endswith('.dat'): with open(filename, 'wb') as f: f.write(b'EX3774'.ljust(16, b'\xFF')) f.write(self._mmap.get_packed()) LOG.info('Wrote DAT file') else: super().save_mmap(filename) def load_mmap(self, filename): if filename.lower().endswith('.dat'): with open(filename, 'rb') as f: header = f.read(16) LOG.debug('DAT header:\n%s' % util.hexprint(header)) self._mmap = memmap.MemoryMapBytes(f.read()) LOG.info('Loaded DAT file') self.process_mmap() else: super().load_mmap(filename) @directory.register class TK7160RadioM(TKx160Radio): MODEL = 'TK-7160M' VALID_BANDS = [(136000000, 174000000)] _model = b'M66- \x04' @directory.register class TK7160RadioK(TKx160Radio): MODEL = 'TK-7160K' VALID_BANDS = [(136000000, 174000000)] _model = b'M66- \x02' @directory.register class TK8160RadioK(TKx160Radio): MODEL = 'TK-8160K' VALID_BANDS = [(400000000, 520000000)] _model = b'M67- "' @directory.register class TK8160RadioM(TKx160Radio): MODEL = 'TK-8160M' VALID_BANDS = [(400000000, 520000000)] _model = b'M67- D' chirp-20240224/chirp/drivers/tmd710.py0000644000175000017500000021513514566340166016227 0ustar hibbyhibby# Copyright 2011 Dan Smith # -- 2019 Rick DeWitt # -- Implementing Kenwood TM-D710G as MCP Clone Mode for Python 2.7 # -- Thanks to Herm Halbach, W7HRM, for the 710 model testing. # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import time import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSettingGroup, RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ RadioSettingValueString, RadioSettingValueInteger, \ RadioSettingValueFloat, RadioSettings from chirp.drivers import kenwood_live LOG = logging.getLogger(__name__) BAUD = 0 STIMEOUT = 0.2 TERM = b'\x0d' # Cmd write terminator (CR) ACK = b'\x06' # Data write acknowledge char W8S = 0.001 # short wait, secs W8L = 0.1 # long wait TMD710_DUPLEX = ["", "+", "-", "", "split"] TMD710_SKIP = ["", "S"] TMD710_MODES = ["FM", "NFM", "AM"] TMD710_BANDS = [(118000000, 135995000), (136000000, 199995000), (200000000, 299995000), (300000000, 399995000), (400000000, 523995000), (800000000, 1299995000)] TMD710_STEPS = [5.0, 6.25, 8.33, 10.0, 12.5, 15.0, 20.0, 25.0, 30.0, 50.0, 100.0] # Need string list of those steps for mem.extra value list STEPS_STR = [] for val in TMD710_STEPS: STEPS_STR.append("%3.2f" % val) TMD710_TONE_MODES = ["", "Tone", "TSQL", "DTCS", "Cross"] TMD710_CROSS = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone"] TMD710_DTSC = list(chirp_common.DTCS_CODES) TMD710_TONES = list(chirp_common.TONES) TMD710_TONES.remove(159.8) TMD710_TONES.remove(165.5) TMD710_TONES.remove(171.3) TMD710_TONES.remove(177.3) TMD710_TONES.remove(183.5) TMD710_TONES.remove(189.9) TMD710_TONES.remove(196.6) TMD710_TONES.remove(199.5) TMD710_CHARS = chirp_common.CHARSET_ASCII TMD710_CHARS += chr(34) # " def _command(ser, cmd, rsplen, w8t=0.01): """Send cmd to radio via ser port cmd is output string with possible terminator rsplen is expected response char count, NOT incl prefix and term If rsplen = 0 then do not0 read after write """ ser.write(cmd) LOG.debug(" Out %4i ->: %s" % (len(cmd), util.hexprint(cmd[0: 32]))) time.sleep(w8t) result = b"" if rsplen > 0: # read response result = ser.read(rsplen) LOG.debug(" In %4i <-: %s" % (len(result), util.hexprint(result[0: 32]))) return result def _connect_radio(radio): """Determine baud rate and verify radio on-line""" global BAUD xid = "D710" + radio.SHORT resp = kenwood_live.get_id(radio.pipe) BAUD = radio.pipe.baudrate # As detected by kenwood_live LOG.debug("Got [%s] at %i Baud." % (resp, BAUD)) resp = resp[3:] # Strip "ID " prefix if len(resp) > 2: # Got something from "ID" if resp == xid: # Good comms return else: stx = "Radio responded as %s, not %s." % (resp, xid) raise errors.RadioError(stx) raise errors.RadioError("No response from radio") def _update_status(self, status, step=1): """ Increment status bar """ status.cur += step self.status_fn(status) return def _val_list(setting, opts, obj, atrb, fix=0, ndx=-1): """Callback:from ValueList. Set the integer index. This function is here to be available to get_mem and get_set fix is optional additive offset to the list index ndx is optional obj[ndx] array index """ value = opts.index(str(setting.value)) value += fix if ndx >= 0: # indexed obj setattr(obj[ndx], atrb, value) else: setattr(obj, atrb, value) return class KenwoodTMx710Radio(chirp_common.CloneModeRadio): """ Base class for TMD-710 """ VENDOR = "Kenwood" MODEL = "TM-x710" SHORT = "X" # Short model ID code NEEDS_COMPAT_SERIAL = False _upper = 999 # Number of normal chans # Put Special memory channels after normal ones SPECIAL_MEMORIES = {"Scan-0Lo": 1000, "Scan-0Hi": 1001, "Scan-1Lo": 1002, "Scan-1Hi": 1003, "Scan-2Lo": 1004, "Scan-2Hi": 1005, "Scan-3Lo": 1006, "Scan-3Hi": 1007, "Scan-4Lo": 1008, "Scan-4Hi": 1009, "Scan-5Lo": 1010, "Scan-5Hi": 1011, "Scan-6Lo": 1012, "Scan-6Hi": 1013, "Scan-7Lo": 1014, "Scan-7Hi": 1015, "Scan-8Lo": 1016, "Scan-8Hi": 1017, "Scan-9Lo": 1018, "Scan-9Hi": 1019, "WX-1": 1020, "WX-2": 1021, "WX-3": 1022, "WX-4": 1023, "WX-5": 1024, "WX-6": 1025, "WX-7": 1026, "WX-8": 1027, "WX-9": 1028, "WX-10": 1029, "Call C0": 1030, "Call C1": 1031 } # _REV dict is used to retrieve name given number SPECIAL_MEMORIES_REV = dict(zip(SPECIAL_MEMORIES.values(), SPECIAL_MEMORIES.keys())) def get_features(self): rf = chirp_common.RadioFeatures() rf.can_odd_split = True rf.has_dtcs = True rf.has_dtcs_polarity = False if self.SHORT == "G": # NOT for D710 rf.has_rx_dtcs = True # Enable DTCS Rx Code column rf.has_cross = True rf.valid_cross_modes = TMD710_CROSS rf.has_bank = False rf.has_settings = True rf.has_ctone = True rf.has_mode = True rf.has_comment = False rf.valid_tmodes = TMD710_TONE_MODES rf.valid_modes = TMD710_MODES rf.valid_duplexes = TMD710_DUPLEX rf.valid_tuning_steps = TMD710_STEPS rf.valid_tones = TMD710_TONES rf.valid_dtcs_codes = TMD710_DTSC # Supports upper and lower case text rf.valid_characters = TMD710_CHARS rf.valid_name_length = 8 rf.valid_skips = TMD710_SKIP rf.valid_bands = TMD710_BANDS rf.memory_bounds = (0, 999) # including special chans 1000-1029 rf.valid_special_chans = sorted(self.SPECIAL_MEMORIES.keys()) return rf @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.pre_download = _( "Connect your interface cable to the PC Port on the\n" "back of the 'TX/RX' unit. NOT the Com Port on the head.\n") rp.pre_upload = _( "Connect your interface cable to the PC Port on the\n" "back of the 'TX/RX' unit. NOT the Com Port on the head.\n") return rp def sync_in(self): """Download from radio""" try: _connect_radio(self) data = bytes(self._read_mem()) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: _connect_radio(self) self._write_mem() except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def process_mmap(self): """Process the mem map into the mem object""" self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) def get_memory(self, number): """Convert raw channel data (_mem) into UI columns (mem)""" mem = chirp_common.Memory() if self.SHORT == "G": mem.extra = RadioSettingGroup("extra", "Extra") # If called from 'Properties', spcl chans number is integer propflg = False if isinstance(number, int): if number > 999: propflg = True if isinstance(number, str) or propflg: if propflg: mem.number = number mem.name = self.SPECIAL_MEMORIES_REV[number] mem.extd_number = mem.name else: mem.name = number # Spcl chns 1st var mem.number = self.SPECIAL_MEMORIES[number] mem.extd_number = number # Uses name as LOC mem.immutable = ["name"] if mem.number < 1030: # Scan edges, WX _mem = self._memobj.ch_mem[mem.number] _map = self._memobj.chmap[mem.number] else: # Call chans _mem = self._memobj.call[mem.number - 1030] else: # Normal mem chans _mem = self._memobj.ch_mem[number] _nam = self._memobj.ch_nam[number] _map = self._memobj.chmap[number] mem.number = number mnx = "" for char in _nam.name: if int(char) < 127: mnx += chr(int(char)) mem.name = mnx.rstrip() if _mem.rxfreq == 0x0ffffffff or _mem.rxfreq == 0: mem.empty = True return mem mem.empty = False if mem.number < 1030 and _map.skip != 0x0ff: # empty mem.skip = TMD710_SKIP[_map.skip] mem.freq = int(_mem.rxfreq) mem.duplex = TMD710_DUPLEX[_mem.duplex] mem.offset = int(_mem.offset) # Duplex = 4 (split); offset contains the TX freq mem.mode = TMD710_MODES[_mem.mode] # _mem.tmode is 4-bit pattern, not number mx = 0 # No tone mem.cross_mode = TMD710_CROSS[0] mem.rx_dtcs = TMD710_DTSC[_mem.dtcs] mem.dtcs = TMD710_DTSC[_mem.dtcs] if self.SHORT == "G": if _mem.tmode & 8: # Tone mx = 1 if _mem.tmode & 4: # Tsql mx = 2 if _mem.tmode & 2: # Dtcs mx = 3 if _mem.tmode & 1: # Cross mx = 4 if _mem.cross == 1: # Tone->DTCS mem.cross_mode = TMD710_CROSS[1] if _mem.cross == 2: # DTCS->Tone mem.cross_mode = TMD710_CROSS[2] else: # D710; may have bit 8 set if _mem.tmode & 4: # Tone mx = 1 if _mem.tmode & 2: # Tsql mx = 2 if _mem.tmode & 1: # Dtcs mx = 3 mem.dtcs = TMD710_DTSC[_mem.dtcs] mem.tmode = TMD710_TONE_MODES[mx] mem.ctone = TMD710_TONES[_mem.ctone] mem.rtone = TMD710_TONES[_mem.rtone] mem.tuning_step = TMD710_STEPS[_mem.tstep] if self.SHORT == "G": # Only the 710G rx = RadioSettingValueList(STEPS_STR, STEPS_STR[_mem.splitstep]) sx = "Split TX step (kHz)" rset = RadioSetting("splitstep", sx, rx) mem.extra.append(rset) return mem def set_memory(self, mem): """Convert UI column data (mem) into MEM_FORMAT memory (_mem)""" if mem.number > 999: # Special chans if mem.number < 1030: # Scan, Wx _mem = self._memobj.ch_mem[mem.number] _map = self._memobj.chmap[mem.number] else: # Call chans _mem = self._memobj.call[mem.number - 1030] _nam = None else: _mem = self._memobj.ch_mem[mem.number] _nam = self._memobj.ch_nam[mem.number] _map = self._memobj.chmap[mem.number] nx = len(mem.name) for ix in range(8): if ix < nx: _nam.name[ix] = mem.name[ix] else: _nam.name[ix] = chr(0x0ff) # needs 8 chrs if mem.empty: _mem.rxfreq = 0x0ffffffff _mem.offset = 0x0ffffff _mem.duplex = 0x0f _mem.tstep = 0x0ff _mem.tmode = 0x0f _mem.mode = 0x0ff _mem.rtone = 0x0ff _mem.ctone = 0x0ff _mem.dtcs = 0x0ff _map.skip = 0x0ff _map.band = 0x0ff if _nam: for ix in range(8): _nam.name[ix] = chr(0x0ff) return if _mem.rxfreq == 0x0ffffffff: # New Channel needs defaults _mem.rxfreq = 144000000 _map.band = 5 _map.skip = 0 _mem.mode = 0 _mem.duplex = 0 _mem.offset = 0 _mem.rtone = 8 _mem.ctone = 8 _mem.dtcs = 0 _mem.tstep = 0 _mem.splitstep = 0 # Now use the UI values entered so far _mem.rxfreq = mem.freq _mem.mode = TMD710_MODES.index(mem.mode) try: _tone = mem.rtone _mem.rtone = TMD710_TONES.index(mem.rtone) _tone = mem.ctone _mem.ctone = TMD710_TONES.index(mem.ctone) except ValueError: raise errors.UnsupportedToneError("This radio does not support " + "tone %.1fHz" % _tone) _mem.dtcs = TMD710_DTSC.index(mem.dtcs) _mem.tmode = 0 # None _mem.cross = 0 if self.SHORT == "G": if mem.tmode == "Tone": _mem.tmode = 8 if mem.tmode == "TSQL": _mem.tmode = 4 if mem.tmode == "DTCS": _mem.tmode = 2 if mem.tmode == "Cross": _mem.tmode = 1 mx = TMD710_CROSS.index(mem.cross_mode) _mem.cross = 3 # t -t if mx == 1: _mem.cross = 1 # t-d _mem.dtcs = TMD710_DTSC.index(mem.rx_dtcs) if mx == 2: _mem.cross = 2 # d-t _mem.dtcs = TMD710_DTSC.index(mem.dtcs) else: _mem.tmode = 0x80 # None if mem.tmode == "Tone": _mem.tmode = 0x0c if mem.tmode == "TSQL": _mem.tmode = 0x0a if mem.tmode == "DTCS": _mem.tmode = 0x09 if mem.duplex == "n/a": # Not valid mem.duplex = "" _mem.duplex = TMD710_DUPLEX.index(mem.duplex) _mem.offset = mem.offset _mem.tstep = TMD710_STEPS.index(mem.tuning_step) # Set _map.band for this bank. Not Calls! if mem.number < 1030: _map.band = 5 val = mem.freq for mx in range(6): # Band codes are 0, 5, 6, 7, 8, 9 if val >= TMD710_BANDS[mx][0] and \ val <= TMD710_BANDS[mx][1]: _map.band = mx if mx > 0: _map.band = mx + 4 _map.skip = TMD710_SKIP.index(mem.skip) # Only 1 mem.extra entry now for ext in mem.extra: if ext.get_name() == "splitstep": val = STEPS_STR.index(str(ext.value)) setattr(_mem, "splitstep", val) else: setattr(_mem, ext.get_name(), ext.value) return def get_settings(self): """Translate the MEM_FORMAT structs into settings in the UI""" # Define mem struct write-back shortcuts if self.SHORT == "G": _bmp = self._memobj.bitmap _blk1 = self._memobj.block1 _blk1a = self._memobj.block1a _pmg = self._memobj.pmg # array[6] of settings _dtmc = self._memobj.dtmc _dtmn = self._memobj.dtmn _com = self._memobj.mcpcom _skyc = self._memobj.skycmd basic = RadioSettingGroup("basic", "Basic") disp = RadioSettingGroup("disp", "PM0: Display") # PM[0] settings aud = RadioSettingGroup("aud", "PM0: Audio") aux = RadioSettingGroup("aux", "PM0: Aux") txrx = RadioSettingGroup("txrc", "PM0: Transmit/Receive") memz = RadioSettingGroup("memz", "PM0: Memory") pfk = RadioSettingGroup("pfk", "PM0: PF Keys") pvfo = RadioSettingGroup("pvfo", "PM0: Programmable VFO") bmsk = RadioSettingGroup("bmsk", "PM0: Band Masks") # end PM[0] rptr = RadioSettingGroup("rptr", "Repeater") dtmf = RadioSettingGroup("dtmf", "DTMF") skyk = RadioSettingGroup("skyk", "Sky Command") pmm = RadioSettingGroup("pmm", "PM Groups 1-5(Partial)") group = RadioSettings(basic, disp, aud, aux, txrx, memz, pvfo, pfk, bmsk, rptr, dtmf, skyk, pmm) mhz1 = 1000000. # Raw freq is stored with 0.1 Hz resolution def _adjraw(setting, obj, atrb, fix=0, ndx=-1): """Callback for Integer add or subtract fix from value.""" vx = int(str(setting.value)) value = vx + int(fix) if value < 0: value = 0 if ndx < 0: setattr(obj, atrb, value) else: setattr(obj[ndx], atrb, value) return def _mhz_val(setting, obj, atrb, ndx=-1, ndy=-1): """ Callback to set freq back to Hz """ vx = float(str(setting.value)) vx = int(vx * mhz1) if ndx < 0: setattr(obj, atrb, vx) else: if atrb[0:7] == "progvfo": # 2-deep stx = atrb.split(".") setattr(obj[ndx].progvfo[ndy], stx[1], vx) else: setattr(obj[ndx], atrb, vx) return def _char_to_str(chrx): """ Remove ff pads from char array """ # chrx is char array str1 = "" for sx in chrx: if int(sx) > 31 and int(sx) < 127: str1 += chr(int(sx)) return str1 def _pswd_vfy(setting, obj, atrb): """ Verify password is 1-6 chars, numbers 1-5 """ str1 = str(setting.value).strip() # initial str2 = ''.join(filter(lambda c: c in '12345', str1)) # valid chars if str1 != str2: # Two lines due to python 73 char limit sx = "Bad characters in Password" raise errors.RadioError(sx) str2 = str1.ljust(6, chr(255)) # pad to 6 with ff's setattr(obj, atrb, str2) return def _pad_str(setting, lenstr, padchr, obj, atrb, ndx=-1): """ pad string to lenstr with padchr """ str1 = str(setting.value).strip() # initial string str2 = str1.ljust(lenstr, padchr) if ndx < 0: setattr(obj, atrb, str2) else: setattr(obj[ndx], atrb, str2) return # ===== BASIC GROUP ===== sx = _char_to_str(_com.comnt) rx = RadioSettingValueString(0, 32, sx) sx = "Comment" rset = RadioSetting("mcpcom.comnt", sx, rx) basic.append(rset) rx = RadioSettingValueInteger(0, 5, _blk1.pmrecall) sx = "Current PM Select" rset = RadioSetting("block1.pmrecall", sx, rx) basic.append(rset) rx = RadioSettingValueBoolean(bool(_blk1.pwdon)) sx = "Password" rset = RadioSetting("block1.pwdon", sx, rx) basic.append(rset) sx = _char_to_str(_blk1.pswd).strip() rx = RadioSettingValueString(0, 6, sx) # rx.set_charset("12345") # Keeps finding `' sx = "- Password (numerals 1-5)" rset = RadioSetting("block1.pswd", sx, rx) rset.set_apply_callback(_pswd_vfy, _blk1, "pswd") basic.append(rset) # ===== PM0 (off) DISPLAY GROUP ===== rx = RadioSettingValueString(0, 8, _char_to_str(_pmg[0].pwron)) sx = "Power-On message" rset = RadioSetting("pmg/0.pwron", sx, rx) disp.append(rset) if self.SHORT == "G": # TMD-710G rx = RadioSettingValueBoolean(bool(_bmp.bmpon)) sx = "PM0: Custom display bitmap" rset = RadioSetting("bitmap.bmpon", sx, rx) disp.append(rset) rx = RadioSettingValueString(0, 64, _char_to_str(_bmp.bmpfyl)) rx.set_mutable(False) sx = "- Custom bitmap filename" rset = RadioSetting("bitmap.bmpfyl", sx, rx) rset.set_doc("Read-only: To modify, use MCP-6 s/w") disp.append(rset) opts = ["VFO", "Mem Recall"] rx = RadioSettingValueList(opts, opts[_pmg[0].a_mr]) sx = "A: Left Side VFO/MR" rset = RadioSetting("pmg/0.a_mr", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "a_mr") disp.append(rset) rx = RadioSettingValueInteger(0, 999, _pmg[0].a_chn) sx = "A: Left Side MR Channel" rset = RadioSetting("pmg/0.a_chn", sx, rx) disp.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[0].b_mr]) sx = "B: Right Side VFO/MR" rset = RadioSetting("pmg/0.b_mr", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "b_mr") disp.append(rset) rx = RadioSettingValueInteger(0, 999, _pmg[0].b_chn) sx = "B: Right Side MR Channel" rset = RadioSetting("pmg/0.b_chn", sx, rx) disp.append(rset) rx = RadioSettingValueInteger(0, 8, _pmg[0].bright) sx = "Brightness level" rset = RadioSetting("pmg/0.bright", sx, rx) disp.append(rset) opts = ["Amber", "Green"] rx = RadioSettingValueList(opts, opts[_pmg[0].bkltclr]) sx = "Backlight color" rset = RadioSetting("pmg/0.bkltclr", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "bkltclr") disp.append(rset) val = _pmg[0].bkltcont + 1 rx = RadioSettingValueInteger(1, 16, val) sx = "Contrast level" rset = RadioSetting("pmg/0.bkltcont", sx, rx) rset.set_apply_callback(_adjraw, _pmg[0], "bkltcont", -1) disp.append(rset) opts = ["Positive", "Negative"] rx = RadioSettingValueList(opts, opts[_pmg[0].dsprev]) sx = "Color mode" rset = RadioSetting("pmg/0.dsprev", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "dsprev") disp.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].autobri)) sx = "Auto brightness" rset = RadioSetting("pmg/0.autobri", sx, rx) disp.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].dispbar)) sx = "Display partition bar" rset = RadioSetting("pmg/0.dispbar", sx, rx) disp.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].single)) sx = "Single band display" rset = RadioSetting("pmg/0.single", sx, rx) disp.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].autopm)) sx = "Auto PM Store" rset = RadioSetting("pmg/0.autopm", sx, rx) disp.append(rset) # ===== AUDIO GROUP ===== rx = RadioSettingValueBoolean(bool(_pmg[0].beepon)) sx = "Beep On" rset = RadioSetting("pmg/0.beepon", sx, rx) aud.append(rset) val = _pmg[0].beepvol + 1 # 1-7 downloads as 0-6 rx = RadioSettingValueInteger(1, 7, val) sx = "Beep volume (1 - 7)" rset = RadioSetting("pmg/0.beepvol", sx, rx) rset.set_apply_callback(_adjraw, _pmg[0], "beepvol", -1) aud.append(rset) opts = ["Mode1", "Mode2"] rx = RadioSettingValueList(opts, opts[_pmg[0].extspkr]) sx = "External Speaker" rset = RadioSetting("pmg/0.extspkr", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "extspkr") aud.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].pbkrpt)) sx = "VGS Plugin: Playback repeat" rset = RadioSetting("pmg/0.pbkrpt", sx, rx) aud.append(rset) rx = RadioSettingValueInteger(0, 60, _pmg[0].pbkint) sx = " Playback repeat interval (0 - 60 secs)" rset = RadioSetting("pmg/0.pbkint", sx, rx) aud.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].cntrec)) sx = " Continuous recording" rset = RadioSetting("pmg/0.cntrec", sx, rx) aud.append(rset) opts = ["Off", "Auto", "Manual"] rx = RadioSettingValueList(opts, opts[_pmg[0].ance]) sx = " Announce mode" rset = RadioSetting("pmg/0.ance", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "ance") aud.append(rset) opts = ["English", "Japanese"] rx = RadioSettingValueList(opts, opts[_pmg[0].lang]) sx = " Announce language" rset = RadioSetting("pmg/0.lang", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "lang") aud.append(rset) rx = RadioSettingValueInteger(1, 7, _pmg[0].vcvol + 1) sx = " Voice volume (1 - 7)" rset = RadioSetting("pmg/0.vcvol", sx, rx) rset.set_apply_callback(_adjraw, _pmg[0], "vcvol", -1) aud.append(rset) rx = RadioSettingValueInteger(0, 4, _pmg[0].vcspd) sx = " Voice speed (0 - 4)" rset = RadioSetting("pmg/0.vcspd", sx, rx) aud.append(rset) # ===== AUX GROUP ===== opts = ["9600", "19200", "38400", "57600"] rx = RadioSettingValueList(opts, opts[_blk1.pcbaud]) sx = "PC port baud rate" rset = RadioSetting("block1.pcbaud", sx, rx) rset.set_apply_callback(_val_list, opts, _blk1, "pcbaud") aux.append(rset) opts = ["A-Band", "B-Band", "TX-A / RX-B", "RX-A / TX-B"] rx = RadioSettingValueList(opts, opts[_pmg[0].intband]) sx = "Internal TNC band" rset = RadioSetting("pmg/0.intband", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "intband") aux.append(rset) opts = ["A-Band", "B-Band", "TX-A / RX-B", "RX-A / TX-B"] rx = RadioSettingValueList(opts, opts[_pmg[0].extband]) sx = "External TNC band" rset = RadioSetting("pmg/0.extband", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "extband") aux.append(rset) opts = ["1200", "9600"] rx = RadioSettingValueList(opts, opts[_pmg[0].extbaud]) sx = "External TNC baud" rset = RadioSetting("pmg/0.extbaud", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "extbaud") aux.append(rset) opts = ["Off", "BUSY", "SQL", "TX", "BUSY/TX", "SQL/TX"] rx = RadioSettingValueList(opts, opts[_pmg[0].sqcsrc]) sx = "SQC output source" rset = RadioSetting("pmg/0.sqcsrc", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "sqcsrc") aux.append(rset) opts = ["Low", "High"] rx = RadioSettingValueList(opts, opts[_pmg[0].sqclogic]) sx = "SQC logic" rset = RadioSetting("pmg/0.sqclogic", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "sqclogic") aux.append(rset) opts = ["Off", "30", "60", "90", "120", "180"] rx = RadioSettingValueList(opts, opts[_pmg[0].apo]) sx = "APO: Auto Power Off (Mins)" rset = RadioSetting("pmg/0.apo", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "apo") aux.append(rset) opts = ["Time Operate (TO)", "Carrier Operate (CO)", "Seek"] rx = RadioSettingValueList(opts, opts[_pmg[0].scnrsm]) sx = "Scan resume mode" rset = RadioSetting("pmg/0.scnrsm", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "scnrsm") aux.append(rset) rx = RadioSettingValueInteger(1, 10, _pmg[0].scntot + 1) sx = " Scan TO delay (Secs)" rset = RadioSetting("pmg/0.scntot", sx, rx) rset.set_apply_callback(_adjraw, _pmg[0], "scntot", -1) aux.append(rset) rx = RadioSettingValueInteger(1, 10, _pmg[0].scncot + 1) sx = " Scan CO delay (Secs)" rset = RadioSetting("pmg/0.scncot", sx, rx) rset.set_apply_callback(_adjraw, _pmg[0], "scncot", -1) aux.append(rset) opts = ["Mode 1: 1ch", "Mode 2: 61ch", "Mode 3: 91ch", "Mode 4: 181ch"] rx = RadioSettingValueList(opts, opts[_pmg[0].vsmode]) sx = "Visual scan" rset = RadioSetting("pmg/0.vsmode", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "vsmode") aux.append(rset) rx = RadioSettingValueBoolean(bool(_blk1.m10mz)) sx = "10 MHz mode" rset = RadioSetting("block1.m10mz", sx, rx) aux.append(rset) rx = RadioSettingValueBoolean(bool(_blk1.ansbck)) sx = "Remote control answerback" rset = RadioSetting("block1.ansbck", sx, rx) aux.append(rset) # ===== TX / RX Group ========= opts = ["A: Left", "B: Right"] rx = RadioSettingValueList(opts, opts[_pmg[0].txband]) sx = "TX Side (PTT)" rset = RadioSetting("pmg/0.txband", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "txband") txrx.append(rset) opts = ["High (50W)", "Medium (10W)", "Low (5W)"] rx = RadioSettingValueList(opts, opts[_pmg[0].a_pwr]) sx = "A-Band transmit power" rset = RadioSetting("pmg/0.a_pwr", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "a_pwr") txrx.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[0].b_pwr]) sx = "B-Band transmit power" rset = RadioSetting("pmg/0.b_pwr", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "b_pwr") txrx.append(rset) opts = ["Off", "125", "250", "500", "750", "1000"] rx = RadioSettingValueList(opts, opts[_pmg[0].mutehu]) sx = "Rx Mute hangup time (ms)" rset = RadioSetting("pmg/0.mutehu", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "mutehu") txrx.append(rset) opts = ["Off", "125", "250", "500"] rx = RadioSettingValueList(opts, opts[_pmg[0].ssqlhu]) sx = "S-meter SQL hangup time (ms)" rset = RadioSetting("pmg/0.ssqlhu", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "ssqlhu") txrx.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].beatshft)) sx = "Beat shift" rset = RadioSetting("pmg/0.beatshft", sx, rx) txrx.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].asmsql)) sx = "A-Band S-meter SQL" rset = RadioSetting("pmg/0.asmsql", sx, rx) txrx.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].bsmsql)) sx = "B-Band S-meter SQL" rset = RadioSetting("pmg/0.bsmsql", sx, rx) txrx.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].vhfaip)) sx = "VHF band AIP" rset = RadioSetting("pmg/0.vhfaip", sx, rx) txrx.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].uhfaip)) sx = "UHF band AIP" rset = RadioSetting("pmg/0.uhfaip", sx, rx) txrx.append(rset) opts = ["High", "Medium", "Low"] rx = RadioSettingValueList(opts, opts[_blk1.micsens]) sx = "Microphone sensitivity (gain)" rset = RadioSetting("block1.micsens", sx, rx) txrx.append(rset) opts = ["3", "5", "10"] rx = RadioSettingValueList(opts, opts[_pmg[0].tot]) sx = "Time-Out timer (Mins)" rset = RadioSetting("pmg/0.tot", sx, rx) # rset.set_apply_callback(_val_list, opts, _pmg[0], "tot") txrx.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].wxalerta)) sx = "WX Alert A-band" rset = RadioSetting("pmg/0.wxalerta", sx, rx) txrx.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].wxalertb)) sx = "WX Alert B-band" rset = RadioSetting("pmg/0.wxalertb", sx, rx) txrx.append(rset) opts = ["Off", "15", "30", "60"] rx = RadioSettingValueList(opts, opts[_pmg[0].wxscntm]) sx = "WX alert scan memory time (Mins)" rset = RadioSetting("pmg/0.wxscntm", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "wxscntm") txrx.append(rset) # ===== DTMF GROUP ===== rx = RadioSettingValueBoolean(bool(_pmg[0].dtmfhld)) sx = "DTMF hold" rset = RadioSetting("pmg/0.dtmfhld", sx, rx) dtmf.append(rset) opts = ["100", "250", "500", "750", "1000", "1500", "2000"] rx = RadioSettingValueList(opts, opts[_pmg[0].dtmfpau]) sx = "DTMF pause duration (mS)" rset = RadioSetting("pmg/0.dtmfpau", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "dtmfpau") dtmf.append(rset) opts = ["Fast", "Slow"] rx = RadioSettingValueList(opts, opts[_pmg[0].dtmfspd]) sx = "DTMF speed" rset = RadioSetting("pmg/0.dtmfspd", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "dtmfspd") dtmf.append(rset) for mx in range(0, 10): csx = _char_to_str(_dtmn[mx].id).strip() rx = RadioSettingValueString(0, 8, csx) sx = "DTMF %i Name (8 chars)" % mx rset = RadioSetting("dtmn.id/%d" % mx, sx, rx) rset.set_apply_callback(_pad_str, 8, chr(255), _dtmn, "id", mx) dtmf.append(rset) csx = _char_to_str(_dtmc[mx].code).strip() rx = RadioSettingValueString(0, 16, csx) sx = " Code %i (16 chars)" % mx rset = RadioSetting("dtmc.code/%d" % mx, sx, rx) rset.set_apply_callback(_pad_str, 16, chr(255), _dtmc, "code", mx) dtmf.append(rset) # ===== MEMORY GROUP ===== opts = ["All Bands", "Current Band"] rx = RadioSettingValueList(opts, opts[_pmg[0].recall]) sx = "Memory recall method" rset = RadioSetting("pmg/0.recall", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "recall") memz.append(rset) rx = RadioSettingValueString(0, 10, _char_to_str(_pmg[0].memgrplk)) sx = "Group link" rset = RadioSetting("pmg/0.memgrplk", sx, rx) memz.append(rset) opts = ["Fast", "Slow"] rx = RadioSettingValueList(opts, opts[_pmg[0].eclnkspd]) sx = "Echolink speed" rset = RadioSetting("pmg/0.eclnkspd", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "eclnkspd") memz.append(rset) rx = RadioSettingValueBoolean(bool(_blk1.dspmemch)) sx = "Display memory channel number" rset = RadioSetting("block1.dspmemch", sx, rx) memz.append(rset) # ===== REPEATER GROUP ===== rx = RadioSettingValueBoolean(bool(_pmg[0].rptr1750)) sx = "1750 Hz transmit hold" rset = RadioSetting("pmg/0.rptr1750", sx, rx) rptr.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].rptrofst)) sx = "Auto repeater offset" rset = RadioSetting("pmg/0.rptrofst", sx, rx) rptr.append(rset) opts = ["Cross Band", "TX:A-Band / RX:B-Band", "RX:A-Band / TX:B-Band"] rx = RadioSettingValueList(opts, opts[_blk1.rptrmode]) sx = "Repeater Mode" rset = RadioSetting("block1.rptrmode", sx, rx) rset.set_apply_callback(_val_list, opts, _blk1, "rptrmode") rptr.append(rset) opts = ["Off", "Morse", "Voice"] rx = RadioSettingValueList(opts, opts[_blk1.rptridx]) sx = "Repeater ID transmit" rset = RadioSetting("block1.rptridx", sx, rx) rset.set_apply_callback(_val_list, opts, _blk1, "rptridx") rptr.append(rset) rx = RadioSettingValueString(0, 12, _char_to_str(_blk1a.rptrid)) sx = "Repeater ID" rset = RadioSetting("block1a.rptrid", sx, rx) rptr.append(rset) rx = RadioSettingValueBoolean(bool(_blk1.rptrhold)) sx = "Repeater transmit hold" rset = RadioSetting("block1.rptrhold", sx, rx) rptr.append(rset) # ===== Prog VFO Group ============= for mx in range(0, 10): # Raw freq is 0.1 MHz resolution vfx = int(_pmg[0].progvfo[mx].blow) / mhz1 if vfx == 0: vfx = 118 rx = RadioSettingValueFloat(118.0, 1299.9, vfx, 0.005, 3) sx = "VFO-%i Low Limit (MHz)" % mx rset = RadioSetting("pmg/0.progvfo/%d.blow" % mx, sx, rx) rset.set_apply_callback(_mhz_val, _pmg, "progvfo.blow", 0, mx) pvfo.append(rset) vfx = int(_pmg[0].progvfo[mx].bhigh) / mhz1 if vfx == 0: vfx = 118 rx = RadioSettingValueFloat(118.0, 1300.0, vfx, 0.005, 3) sx = " VFO-%i High Limit (MHz)" % mx rset = RadioSetting("pmg/0.progvfo/%d.bhigh" % mx, sx, rx) rset.set_apply_callback(_mhz_val, _pmg, "progvfo.bhigh", 0, mx) pvfo.append(rset) # ===== PFK GROUP ===== opts = ["WX CH", "FRQ.BAND", "CTRL", "MONITOR", "VGS", "VOICE", "GROUP UP", "MENU", "MUTE", "SHIFT", "DUAL", "M>V", "1750 Tone"] rx = RadioSettingValueList(opts, opts[_pmg[0].pf1key]) sx = "Front panel PF1 key" rset = RadioSetting("pmg/0.pf1key", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "pf1key") pfk.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[0].pf2key]) sx = "Front panel PF2 key" rset = RadioSetting("pmg/0.pf2key", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "pf2key") pfk.append(rset) opts = ["WX CH", "FRQ.BAND", "CTRL", "MONITOR", "VGS", "VOICE", "GROUP UP", "MENU", "MUTE", "SHIFT", "DUAL", "M>V", "VFO", "MR", "CALL", "MHz", "TONE", "REV", "LOW", "LOCK", "A/B", "ENTER", "1750 Tone", "M.LIST", "S.LIST", "MSG.NEW", "REPLY", "POS", "P.MONI", "BEACON", "DX", "WX"] rx = RadioSettingValueList(opts, opts[_pmg[0].micpf1]) sx = "Microphone PF1 key" rset = RadioSetting("pmg/0.micpf1", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "micpf1") pfk.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[0].micpf2]) sx = "Microphone PF2 key" rset = RadioSetting("pmg/0.micpf2", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "micpf2") pfk.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[0].micpf3]) sx = "Microphone PF3 key" rset = RadioSetting("pmg/0.micpf3", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "micpf3") pfk.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[0].micpf4]) sx = "Microphone PF4 key" rset = RadioSetting("pmg/0.micpf4", sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[0], "micpf4") pfk.append(rset) # ===== BMSK GROUP ===== rx = RadioSettingValueBoolean(bool(_pmg[0].abnd118)) sx = "A/Left: 118 MHz Band" rset = RadioSetting("pmg/0.abnd118", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].abnd144)) sx = "A/Left: 144 MHz Band" rset = RadioSetting("pmg/0.abnd144", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].abnd220)) sx = "A/Left: 220 MHz Band" rset = RadioSetting("pmg/0.abnd220", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].abnd300)) sx = "A/Left: 300 MHz Band" rset = RadioSetting("pmg/0.abnd300", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].abnd430)) sx = "A/Left: 430 MHz Band" rset = RadioSetting("pmg/0.abnd430", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].bbnd144)) sx = "B/Right: 144 MHz Band" rset = RadioSetting("pmg/0.bbnd144", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].bbnd220)) sx = "B/Right: 220 MHz Band" rset = RadioSetting("pmg/0.bbnd220", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].bbnd300)) sx = "B/Right: 300 MHz Band" rset = RadioSetting("pmg/0.bbnd300", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].bbnd430)) sx = "B/Right: 430 MHz Band" rset = RadioSetting("pmg/0.bbnd430", sx, rx) bmsk.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[0].bbnd800)) sx = "B/Right: 800 MHz Band" rset = RadioSetting("pmg/0.bbnd800", sx, rx) bmsk.append(rset) # ===== Sky command Group ============= rx = RadioSettingValueString(0, 10, _char_to_str(_skyc.cmdr)) sx = "Commandr call sign" rset = RadioSetting("skycmd.cmdr", sx, rx) rset.set_apply_callback(_pad_str, 10, chr(0), _skyc, "cmdr") skyk.append(rset) rx = RadioSettingValueString(0, 10, _char_to_str(_skyc.tptr)) sx = "Transporter call sign" rset = RadioSetting("skycmd.tptr", sx, rx) rset.set_apply_callback(_pad_str, 10, chr(0), _skyc, "tptr") skyk.append(rset) opts = [] for val in TMD710_TONES: opts.append(str(val)) rx = RadioSettingValueList(opts, opts[_skyc.skytone]) sx = "Tone frequency" rset = RadioSetting("skycmd.skytone", sx, rx) rset.set_apply_callback(_val_list, opts, _skyc, "skytone") skyk.append(rset) # ===== PM MEMORY GROUP ===== """ These 5 blocks of 512 bytes are repeats of the major settings """ # Only showing limited settings for now... _pmn = self._memobj.pm_name for ix in range(1, 6): nx = ix - 1 # Names are [0-4] rx = RadioSettingValueString(0, 16, _char_to_str(_pmn[nx].pmname)) sx = "PM Group %i Name" % ix rset = RadioSetting("pm_name/%i.pmname" % nx, sx, rx) rset.set_apply_callback(_pad_str, 16, chr(0xff), _pmn, "pmname", nx) pmm.append(rset) rx = RadioSettingValueString(0, 8, _char_to_str(_pmg[ix].pwron)) sx = "- Power-On Message" rset = RadioSetting("pmg/%i.pwron" % ix, sx, rx) rset.set_apply_callback(_pad_str, 8, chr(0xff), _pmg, "pwron", ix) pmm.append(rset) opts = ["VFO", "Mem Recall"] rx = RadioSettingValueList(opts, opts[_pmg[ix].a_mr]) sx = "- A: Left Side VFO/MR" rset = RadioSetting("pmg/%i.a_mr" % ix, sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[ix], "a_mr") pmm.append(rset) rx = RadioSettingValueInteger(0, 999, _pmg[ix].a_chn) sx = "- A: Left Side MR Channel" rset = RadioSetting("pmg/%i.a_chn" % ix, sx, rx) pmm.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[ix].b_mr]) sx = "- B: Right Side VFO/MR" rset = RadioSetting("pmg/%i.b_mr" % ix, sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[ix], "b_mr") pmm.append(rset) rx = RadioSettingValueInteger(0, 999, _pmg[ix].b_chn) sx = "- B: Right Side MR Channel" rset = RadioSetting("pmg/%i.b_chn" % ix, sx, rx) pmm.append(rset) rx = RadioSettingValueInteger(0, 8, _pmg[ix].bright) sx = "- Brightness level" rset = RadioSetting("pmg/%i.bright" % ix, sx, rx) pmm.append(rset) opts = ["Amber", "Green"] rx = RadioSettingValueList(opts, opts[_pmg[ix].bkltclr]) sx = "- Backlight color" rset = RadioSetting("pmg/%i.bkltclr" % ix, sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[ix], "bkltclr") pmm.append(rset) val = _pmg[ix].bkltcont + 1 rx = RadioSettingValueInteger(1, 16, val) sx = "- Contrast level" rset = RadioSetting("pmg/%i.bkltcont" % ix, sx, rx) rset.set_apply_callback(_adjraw, _pmg[ix], "bkltcont", -1) pmm.append(rset) opts = ["Positive", "Negative"] rx = RadioSettingValueList(opts, opts[_pmg[ix].dsprev]) sx = "- Color mode" rset = RadioSetting("pmg/%i.dsprev" % ix, sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[ix], "dsprev") pmm.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[ix].beepon)) sx = "- Beep On" rset = RadioSetting("pmg/%i.beepon" % ix, sx, rx) pmm.append(rset) val = _pmg[ix].beepvol + 1 # 1-7 downloads as 0-6 rx = RadioSettingValueInteger(1, 7, val) sx = "- Beep volume (1 - 7)" rset = RadioSetting("pmg/%i.beepvol" % ix, sx, rx) rset.set_apply_callback(_adjraw, _pmg[ix], "beepvol", -1) pmm.append(rset) rx = RadioSettingValueBoolean(bool(_pmg[ix].autopm)) sx = "- Auto PM Store" rset = RadioSetting("pmg/%i.autopm" % ix, sx, rx) pmm.append(rset) opts = ["A: Left", "B: Right"] rx = RadioSettingValueList(opts, opts[_pmg[ix].txband]) sx = "- X Side (PTT)" rset = RadioSetting("pmg/%i.txband" % ix, sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[ix], "txband") pmm.append(rset) opts = ["High (50W)", "Medium (10W)", "Low (5W)"] rx = RadioSettingValueList(opts, opts[_pmg[ix].a_pwr]) sx = "- A-Band transmit power" rset = RadioSetting("pmg/%i.a_pwr" % ix, sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[ix], "a_pwr") pmm.append(rset) rx = RadioSettingValueList(opts, opts[_pmg[ix].b_pwr]) sx = "- B-Band transmit power" rset = RadioSetting("pmg/%i.b_pwr" % ix, sx, rx) rset.set_apply_callback(_val_list, opts, _pmg[ix], "b_pwr") pmm.append(rset) return group # END get_settings() def set_settings(self, settings): """ Convert UI modified changes into mem_format values """ blks = (self._memobj.block1, self._memobj.block1a, self._memobj.pmg, self._memobj.pm_name) for _settings in blks: for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise return @classmethod def match_model(cls, fdata, fyle): """ Included to prevent 'File > New' error """ return False @directory.register class KenwoodTMD710Radio(KenwoodTMx710Radio): """ Kenwood TM-D710 VHF/UHF/APRS Radio model. """ VENDOR = "Kenwood" MODEL = "TM-D710_CloneMode" SHORT = "" # Quick model code _num_blocks = 3 _num_packets = [0x9c, 1, 1] MEM_FORMAT = """ struct chns { // 16 bytes channel structure ul32 rxfreq; u8 tstep; u8 mode; u8 tmode:4, duplex:4; // 4 = split u8 rtone; u8 ctone; u8 dtcs; ul32 offset; // or Split mode TX freq u8 splitstep; u8 cross; // not used }; struct pm_grp { // 512 bytes per group u8 unk0200; u8 a_mr; u8 unk0202; u8 unk0203; u8 unk0204; u8 unk0205; u8 unk0206; u8 a_pwr; u8 wxalerta; u8 asmsql; u8 a_chn; u8 unk020b; u8 unk020c; u8 b_mr; u8 unk020e; u8 unk020f; u8 unk0210; u8 unk0211; u8 unk0212; u8 b_pwr; u8 wxalertb; u8 bsmsql; u8 b_chn; u8 unk0217; u8 unk0218; u8 unk0219; u8 unk021a; u8 unk021b; u8 unk021c; u8 unk021d; u8 unk021e; u8 unk021f; u8 unk0220; u8 unk0221; u8 unk0222; u8 unk0223; u8 unk0224; u8 unk0225; u8 unk0226; u8 unk0227; u8 unk0228; u8 unk0229; u8 unk022a; u8 unk022b; u8 unk022c; u8 unk022d; u8 unk022e; u8 unk022f; u8 unk0230; u8 unk0231; u8 sqclogic; u8 txband; u8 single; u8 unk0235; u8 mute; u8 unk0237; u8 unk0238; u8 unk0239; u8 unk0237a; u8 unk023b; u8 unk023c; u8 unk023d; u8 unk023e; u8 unk023f; struct chns vfo[10]; // 0x0240 - 0x02df char pwron[8]; u8 unk02e8; u8 unk02e9; u8 unk02ea; u8 unk02eb; u8 unk02ec; u8 unk02ed; u8 unk02ee; u8 unk02ef; char memgrplk[10]; u8 unk02fa; u8 unk02fb; u8 unk02fc; u8 unk02fd; u8 unk02fe; u8 unk02ff; struct { ul32 blow; ul32 bhigh; } progvfo[10]; u8 beepon; u8 beepvol; u8 extspkr; u8 ance; u8 lang; u8 vcvol; u8 vcspd; u8 pbkrpt; u8 pbkint; u8 cntrec; u8 vhfaip; u8 uhfaip; u8 ssqlhu; u8 mutehu; u8 beatshft; u8 tot; u8 recall; u8 eclnkspd; u8 dtmfhld; u8 dtmfspd; u8 dtmfpau; u8 dtmflck; u8 rptrofst; u8 rptr1750; u8 bright; u8 autobri; u8 bkltclr; u8 pf1key; u8 pf2key; u8 micpf1; u8 micpf2; u8 micpf3; u8 micpf4; u8 miclck; u8 unk0372; u8 scnrsm; u8 apo; u8 extband; u8 extbaud; u8 sqcsrc; u8 autopm; u8 dispbar; u8 unk037a; u8 bkltcont; u8 dsprev; u8 vsmode; u8 intband; u8 wxscntm; u8 scntot; u8 scncot; u8 unk0382; u8 unk0383; u8 unk0384; u8 unk0385; u8 unk0386; u8 unk0387; u8 unk0388; u8 unk0389; u8 unk038a; u8 unk038b; u8 unk038c; u8 unk038d; u8 unk038e; u8 unk038f; u8 abnd118; u8 abnd144; u8 abnd220; u8 abnd300; u8 abnd430; u8 bbnd144; u8 bbnd220; u8 bbnd300; u8 bbnd430; u8 bbnd800; u8 unk039a; u8 unk039b; u8 unk039c; u8 unk039d; u8 unk039e; u8 unk039f; u8 unk03a0[96]; // to 0x03ff }; // end of struct pm #seekto 0x0000; // block1: x000 - x023f struct { u8 unk000[16]; u8 unk010; u8 unk011; char unk012[3]; u8 ansbck; u8 pmrecall; // 0x0016 u8 pnlklk; u8 dspmemch; u8 m10mz; u8 micsens; u8 opband; u8 unk01c; u8 rptrmode; u8 rptrhold; u8 rptridx; u8 unk020; u8 pcbaud; u8 unk022; u8 pwdon; // 0x0023 u8 unk024; u8 unk025; u8 unk026; u8 unk027; u8 unk028; u8 unk029; char pswd[6]; // 0x023a - 23f } block1; #seekto 0x0030; struct { char code[16]; // @ 0x0030 } dtmc[10]; struct { char id[8]; // 0x00d0 - 0x011f } dtmn[10]; struct { // block1a: 0x0120 - 0x023f u8 unk0120; u8 unk0121; u8 unk0122[78]; char rptrid[12]; // 0x0170 - 017b u8 unk017c; u8 unk017d; u8 unk017e; u8 unk017f; u8 unk0180[128]; // 0x0180 - 0x01ff } block1a; struct pm_grp pmg[6]; // 0x0200 - 0x0dff #seekto 0x0e00; struct { u8 band; u8 skip; } chmap[1030]; // to 0x0160b #seekto 0x01700; // 0x01700 - 0x0575f struct chns ch_mem[1030]; // 0-999 MR and 1000 -1029 Specials #seekto 0x05760; struct chns call[2]; #seekto 0x05800; struct { char name[8]; } ch_nam[1020]; // ends @ 0x07e0 #seekto 0x077e0; // 0x077e0 - 0x07830 struct { char name[8]; } wxnam[10]; #seekto 0x07da0; struct { char pmname[16]; } pm_name[5]; #seekto 0x07df0; struct { char comnt[32]; } mcpcom; #seekto 0x08660; struct { char cmdr[10]; char tptr[10]; u8 skytone; // 0x08674 } skycmd; // data stops at 0x09b98 """ def _read_mem(radio): """ Load the memory map """ global BAUD status = chirp_common.Status() status.cur = 0 val = 0 for mx in range(0, radio._num_blocks): val += radio._num_packets[mx] status.max = val status.msg = "Reading %i packets" % val radio.status_fn(status) data = "" radio.pipe.baudrate = BAUD cmc = b"0M PROGRAM" + TERM resp0 = _command(radio.pipe, cmc, 3, W8S) junk = radio.pipe.read(16) # flushit for bkx in range(0, 0x09c): if bkx != 0x07f: # Skip block 7f !!?? cmc = struct.pack('>cHB', b'R', bkx << 8, 0) resp0 = _command(radio.pipe, cmc, 260, W8S) junk = _command(radio.pipe, ACK, 1, W8S) if len(resp0) < 260: junk = _command(radio.pipe, b"E", 2, W8S) sx = "Block 0x%x read error: " % bkx sx += "Got %i bytes, expected 260." % len(resp0) LOG.error(sx) sx = "Block read error! Check debug.log" raise errors.RadioError(sx) if bkx == 0: # 1st packet of 1st block mht = resp0[4:7] # [57 00 00 00] 03 4b 01 ff ff ... data = resp0[5:6] # 2nd byte (4b) replaces 1st data += resp0[5:] # then bytes 2 on (4b 4b 01 ff ...) else: data += resp0[4:] # skip cmd echo _update_status(radio, status) # UI Update cmc = struct.pack('>cHB', b'R', 0xFEF0, 0x10) resp0 = _command(radio.pipe, cmc, 0x014, W8S) data += resp0[4:] junk = _command(radio.pipe, ACK, 1, W8S) _update_status(radio, status) cmc = struct.pack('>cHB', b'R', 0xFF00, 0x90) resp0 = _command(radio.pipe, cmc, 0x094, W8S) data += resp0[4:] junk = _command(radio.pipe, ACK, 1, W8S) _update_status(radio, status) # Exit Prog mode, no TERM resp = _command(radio.pipe, b"E", 2, W8S) # Rtns 06 0d radio.pipe.baudrate = BAUD return data def _write_mem(radio): """ PROG MCP Blocks Send """ global BAUD # UI progress status = chirp_common.Status() status.cur = 0 val = 0 for mx in range(0, radio._num_blocks): val += radio._num_packets[mx] status.max = val status.msg = "Writing %i packets" % val radio.status_fn(status) imgadr = 0 radio.pipe.baudrate = BAUD resp0 = _command(radio.pipe, b"0M PROGRAM" + TERM, 3, W8S) # Read block 0 magic header thingy, save it cmc = b"R" + bytes([0, 0, 4]) resp0 = _command(radio.pipe, cmc, 8, W8S) mht0 = resp0[4:] # Expecting [57 00 00 04] 03 4b 01 ff junk = _command(radio.pipe, ACK, 1, W8S) cmc = b"W" + bytes([0, 0, 1, 0xff]) junk = _command(radio.pipe, cmc, 1, W8S) # responds ACK cmc = b"R" + bytes([0x80, 0, 3]) resp = _command(radio.pipe, cmc, 7, W8S) # [57 80 00 03] 00 33 00 mht1 = resp[4:] junk = _command(radio.pipe, ACK, 1, W8S) cmc = b"W" + bytes([0x80, 0, 1, 0xff]) junk = _command(radio.pipe, cmc, 1, W8S) imgadr = 4 # After 03 4b 01 ff for bkx in range(0, radio._num_packets[0]): cmc = b"W" + bytes([bkx, 0, 0]) imgstep = 256 if bkx == 0: imgstep = 0x0fc cmc = b"W" + bytes([0, 4, imgstep]) cmc += radio.get_mmap()[imgadr:imgadr + imgstep] else: # after first packet cmc += radio.get_mmap()[imgadr:imgadr + imgstep] if bkx != 0x07f: # don't send 7f ! resp0 = _command(radio.pipe, cmc, 1, W8S) if resp0 != ACK: LOG.error("Packet 0x%x Write error, no ACK." % bkx) sx = "Radio failed to acknowledge upload packet!" raise errors.RadioError(sx) imgadr += imgstep _update_status(radio, status) # UI Update # write fe and ff blocks cmc = b"W" + bytes([0xfe, 0xf0, 16]) cmc += radio.get_mmap()[imgadr:imgadr + 16] resp0 = _command(radio.pipe, cmc, 1, W8S) if resp0 != ACK: LOG.error("Packet 0xfe Write error, no ACK.") sx = "Radio failed to acknowledge upload packet!" raise errors.RadioError(sx) imgadr += 16 cmc = b"W" + bytes([0xff, 0, 0x90]) cmc += radio.get_mmap()[imgadr:imgadr + 0x090] resp0 = _command(radio.pipe, cmc, 1, W8S) if resp0 != ACK: LOG.error("Packet 0xff Write error, no ACK.") sx = "Radio failed to acknowledge upload packet!" raise errors.RadioError(sx) # Write mht1 cmc = b"W" + bytes([0x80, 0, 3]) + mht1 resp0 = _command(radio.pipe, cmc, 1, W8S) if resp0 != ACK: LOG.error("Mht1 Write error at 0x080 00 03 , no ACK.") sx = "Radio failed to acknowledge upload packet!" raise errors.RadioError(sx) # and mht0 cmc = b"W" + bytes([0, 0, 4]) + mht0 resp0 = _command(radio.pipe, cmc, 1, W8S) if resp0 != ACK: LOG.error("Mht0 Write error at 00 00 04 , no ACK.") sx = "Radio failed to acknowledge upload packet!" raise errors.RadioError(sx) # Write E to Exit PROG mode resp = _command(radio.pipe, b"E", 2, W8S) return @directory.register class KenwoodTMD710GRadio(KenwoodTMx710Radio): """ Kenwood TM-D710G VHF/UHF/GPS/APRS Radio model. """ VENDOR = "Kenwood" MODEL = "TM-D710G_CloneMode" SHORT = "G" # Quick model code 1 for G _num_blocks = 2 # Only reading first 2, not GPS logs _packet_size = [261, 261, 261] _block_addr = [0, 0x100, 0x200] # starting addr, each block _num_packets = [0x7f, 0x0fe, 0x200] # num packets per block, 0-based MEM_FORMAT = """ struct chns { // 16 bytes channel structure ul32 rxfreq; u8 tstep; u8 mode; u8 tmode:4, duplex:4; // 4 = split u8 rtone; u8 ctone; u8 dtcs; u8 cross; ul32 offset; // or Split mode TX freq u8 splitstep; }; struct pm_grp { // 512 bytes per group u8 unk0200; u8 a_mr; u8 unk0202; u8 unk0203; u8 unk0204; u8 unk0205; u8 unk0206; u8 a_pwr; u8 wxalerta; u8 asmsql; u8 a_chn; u8 unk020b; u8 unk020c; u8 b_mr; u8 unk020e; u8 unk020f; u8 unk0210; u8 unk0211; u8 unk0212; u8 b_pwr; u8 wxalertb; u8 bsmsql; u8 b_chn; u8 unk0217; u8 unk0218; u8 unk0219; u8 unk021a; u8 unk021b; u8 unk021c; u8 unk021d; u8 unk021e; u8 unk021f; u8 unk0220; u8 unk0221; u8 unk0222; u8 unk0223; u8 unk0224; u8 unk0225; u8 unk0226; u8 unk0227; u8 unk0228; u8 unk0229; u8 unk022a; u8 unk022b; u8 unk022c; u8 unk022d; u8 unk022e; u8 unk022f; u8 unk0230; u8 unk0231; u8 sqclogic; u8 txband; u8 single; u8 unk0235; u8 mute; u8 unk0237; u8 unk0238; u8 unk0239; u8 unk0237a; u8 unk023b; u8 unk023c; u8 unk023d; u8 unk023e; u8 unk023f; struct chns vfo[10]; // 0x0240 - 0x02df char pwron[8]; u8 unk02e8; u8 unk02e9; u8 unk02ea; u8 unk02eb; u8 unk02ec; u8 unk02ed; u8 unk02ee; u8 unk02ef; char memgrplk[10]; u8 unk02fa; u8 unk02fb; u8 unk02fc; u8 unk02fd; u8 unk02fe; u8 unk02ff; struct { ul32 blow; ul32 bhigh; } progvfo[10]; u8 beepon; u8 beepvol; u8 extspkr; u8 ance; u8 lang; u8 vcvol; u8 vcspd; u8 pbkrpt; u8 pbkint; u8 cntrec; u8 vhfaip; u8 uhfaip; u8 ssqlhu; u8 mutehu; u8 beatshft; u8 tot; u8 recall; u8 eclnkspd; u8 dtmfhld; u8 dtmfspd; u8 dtmfpau; u8 dtmflck; u8 rptrofst; u8 rptr1750; u8 bright; u8 autobri; u8 bkltclr; u8 pf1key; u8 pf2key; u8 micpf1; u8 micpf2; u8 micpf3; u8 micpf4; u8 miclck; u8 unk0372; u8 scnrsm; u8 apo; u8 extband; u8 extbaud; u8 sqcsrc; u8 autopm; u8 dispbar; u8 unk037a; u8 bkltcont; u8 dsprev; u8 vsmode; u8 intband; u8 wxscntm; u8 scntot; u8 scncot; u8 unk0382; u8 unk0383; u8 unk0384; u8 unk0385; u8 unk0386; u8 unk0387; u8 unk0388; u8 unk0389; u8 unk038a; u8 unk038b; u8 unk038c; u8 unk038d; u8 unk038e; u8 unk038f; u8 abnd118; u8 abnd144; u8 abnd220; u8 abnd300; u8 abnd430; u8 bbnd144; u8 bbnd220; u8 bbnd300; u8 bbnd430; u8 bbnd800; u8 unk039a; u8 unk039b; u8 unk039c; u8 unk039d; u8 unk039e; u8 unk039f; u8 unk03a0[96]; // to 0x03ff }; // end of struct pm #seekto 0x0000; // block1: x000 - x023f struct { u8 unk000[16]; u8 unk010; u8 unk011; char unk012[3]; u8 ansbck; u8 pmrecall; // 0x0016 u8 pnlklk; u8 dspmemch; u8 m10mz; u8 micsens; u8 opband; u8 unk01c; u8 rptrmode; u8 rptrhold; u8 rptridx; u8 unk020; u8 pcbaud; u8 unk022; u8 pwdon; // 0x0023 u8 unk024; u8 unk025; u8 unk026; u8 unk027; u8 unk028; u8 unk029; char pswd[6]; // 0x023a - 23f } block1; #seekto 0x0030; struct { char code[16]; // @ 0x0030 } dtmc[10]; struct { char id[8]; // 0x00d0 - 0x011f } dtmn[10]; struct { // block1a: 0x0120 - 0x023f u8 unk0120; u8 unk0121; u8 unk0122[78]; char rptrid[12]; // 0x0170 - 017b u8 unk017c; u8 unk017d; u8 unk017e; u8 unk017f; u8 unk0180[128]; // 0x0180 - 0x01ff } block1a; struct pm_grp pmg[6]; // 0x0200 - 0x0dff #seekto 0x0e00; struct { u8 band; u8 skip; } chmap[1030]; // to 0x0160b #seekto 0x01700; // 0x01700 - 0x0575f struct chns ch_mem[1030]; // 0-999 MR and 1000 -1029 Specials #seekto 0x058a0; struct chns call[2]; #seekto 0x05900; struct { char name[8]; } ch_nam[1020]; // ends @ 0x07840 #seekto 0x078e0; // 0x078e0 - 0x0792f struct { char name[8]; } wxnam[10]; #seekto 0x07da0; struct { char pmname[16]; } pm_name[5]; #seekto 0x07df0; struct { char comnt[32]; } mcpcom; // Block 1 ends @ 0x07eff // Block 2 starts @ 0x07f00 #seekto 0x08660; struct { char cmdr[10]; char tptr[10]; u8 skytone; // 0x08674 } skycmd; #seekto 0x10ef0; struct { u8 bmp[1896]; u8 unk11658[8]; // 0x11658 char bmpfyl[64]; // 0x11660 u8 unk116a0[95]; u8 bmpon; // 0x116ff } bitmap; // 2nd block ends @ 0x017cff """ def _make_command(self, cmd, addr, length, data=b''): cmc = struct.pack('>IB', addr, length) return cmd + cmc[1:] + data def _read_mem(radio): """ Load the memory map """ global BAUD status = chirp_common.Status() status.cur = 0 val = 0 for mx in range(0, radio._num_blocks): val += radio._num_packets[mx] status.max = val status.msg = "Reading %i packets" % val radio.status_fn(status) data = b"" radio.pipe.baudrate = BAUD resp0 = radio.pipe.read(16) # flush cmc = b"0M PROGRAM" + TERM resp0 = _command(radio.pipe, cmc, 3, W8S) if resp0[:1] == "?": # try once more resp0 = _command(radio.pipe, cmc, 3, W8S) radio.pipe.baudrate = 57600 # PROG mode is always 57.6 LOG.debug("Switching to 57600 baud download.") junk = radio.pipe.read(1) # trailing byte for blkn in range(0, radio._num_blocks): for bkx in range(0, radio._num_packets[blkn]): addr = (radio._block_addr[blkn] << 8) | (bkx << 8) resp0 = _command(radio.pipe, radio._make_command(b'R', addr, 0), radio._packet_size[blkn], W8S) if len(resp0) < radio._packet_size[blkn]: junk = _command(radio.pipe, b"E", 0, W8S) lb = len(resp0) xb = radio._packet_size[blkn] sx = "Block 0x%x, 0x%x read error: " % (blkn, bkx) sx += "Got %i bytes, expected %i." % (lb, xb) LOG.error(sx) sx = "Block read error! Check debug.log" raise errors.RadioError(sx) if blkn == 0 and bkx == 0: # 1st packet of 1st block mht = resp0[5:9] # Magic Header Thingy after cmd echo data += mht[0:1] data += b'\xff\xff\xff' data += resp0[9:] else: data += resp0[5:] # skip cmd echo _update_status(radio, status) # UI Update # Exit Prog mode, no TERM resp = _command(radio.pipe, b"E", 0, W8S) radio.pipe.baudrate = BAUD return data def _write_mem(radio): """ PROG MCP Blocks Send """ global BAUD # UI progress status = chirp_common.Status() status.cur = 0 val = 0 for mx in range(0, radio._num_blocks): val += radio._num_packets[mx] status.max = val status.msg = "Writing %i packets" % val radio.status_fn(status) imgadr = 0 radio.pipe.baudrate = BAUD resp0 = _command(radio.pipe, b"0M PROGRAM" + TERM, 3, W8S) radio.pipe.baudrate = 57600 LOG.debug("Switching to 57600 baud upload.") junk = radio.pipe.read(1) # Read block 0 magic header thingy, save it addr = radio._block_addr[0] << 8 resp0 = _command(radio.pipe, radio._make_command(b'R', addr, 4), 16, W8S) mht0 = resp0[5:] # Now get block 1 mht addr = radio._block_addr[1] << 8 resp0 = _command(radio.pipe, radio._make_command(b'R', addr, 5), 16, W8S) mht1 = resp0[5:] for blkn in range(0, radio._num_blocks): for bkx in range(0, radio._num_packets[blkn]): addr = (radio._block_addr[blkn] << 8) | (bkx << 8) if bkx == 0: # First packet of the block includes mht if blkn == 0: data = (b'\xff\x4b\x01\x32' + radio.get_mmap()[4:imgadr + 256]) elif blkn == 1: data = mht1 + radio.get_mmap()[imgadr + 5:imgadr + 256] else: # after first packet data = radio.get_mmap()[imgadr:imgadr + 256] cmc = radio._make_command(b'W', addr, 0, data) resp0 = _command(radio.pipe, cmc, 6, W8S) if bkx > 0 and resp0 != ACK: LOG.error("Packet 0x%x Write error, no ACK!" % bkx) sx = "Radio failed to acknowledge upload. " sx += "See debug.log" raise errors.RadioError(sx) imgadr += 256 _update_status(radio, status) # UI Update # Re-write magic headers cmc = radio._make_command(b'W', (radio._block_addr[0] << 8) | 1, 3, mht0[1:3] + b'\x32') resp0 = _command(radio.pipe, cmc, 1, W8S) cmc = radio._make_command(b'W', radio._block_addr[1] << 8, 5, mht1) resp0 = _command(radio.pipe, cmc, 1, W8S) cmc = radio._make_command(b'Z', radio._block_addr[0], 1, mht0[0:1]) resp0 = _command(radio.pipe, cmc, 16, W8S) # Write E to Exit PROG mode resp = _command(radio.pipe, b"E", 0, W8S) radio.pipe.baudrate = BAUD return chirp-20240224/chirp/drivers/iradio_uv_5118plus.py0000644000175000017500000011242614566340166020555 0ustar hibbyhibby# Copyright 2023 Jim Unroe # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import logging from chirp import chirp_common, directory, memmap from chirp import bitwise, errors, util from chirp.settings import RadioSetting, RadioSettingGroup, \ RadioSettingValueInteger, RadioSettingValueList, \ RadioSettingValueBoolean, RadioSettingValueString, \ RadioSettingValueFloat, RadioSettings LOG = logging.getLogger(__name__) MEM_FORMAT = """ // #seekto 0x0000; struct { char startuplabel[32]; // Startup Label 0000-001f char personalid[16]; // Personal ID 0020-002f u8 displaylogo:1, // Display Startup Logo 0030 displayvoltage:1, // Display Voltage displaylabel:1, // Display Startup Label tailtone:1, // Tail Tone startupringtone:1, // Startup Ringtone voiceprompt:1, // Voice Prompt keybeep:1, // Key Beep unknown_0:1; u8 txpriority:1, // TX Priority 0031 rogerbeep:2, // Roger Beep savemode:1, // Save Mode frequencystep:4; // Frequency Step u8 squelch:4, // Squelch 0032 talkaround:2, // Talkaround noaaalarm:1, // NOAA Alarm dualdisplay:1; // Dual Display u8 displaytimer; // Display Timer 0033 u8 locktimer; // Lock Timer 0034 u8 timeouttimer; // Timeout Timer 0035 u8 voxlevel:4, // VOX Level 0036 voxdelay:4; // Delay ul16 tonefrequency; // Tone Frequency 0037-0038 ul16 fmfrequency; // FM Frequency 0039-003a u8 fmstandby:1, // FM Standby 003b dualstandby:1, // Dual Standby standbyarea:1, // Standby Area scandirection:1, // Scan Direction unknown_2:2, workmode:1, // Work Mode unknown_3:1; ul16 areaach; // Area A CH 003c-003d ul16 areabch; // Area B CH 003e-003f u8 unused_0:4, // 0040 key1long:4; // Key 1 Long u8 unused_1:4, // 0041 key1short:4; // Key 1 Short u8 unused_2:4, // 0042 key2long:4; // Key 2 Long u8 unused_3:4, // 0043 key2short:4; // Key 2 Short u8 unknown_4:4, // 0044 vox:1, // VOX unknown_5:3; u8 xposition; // X position (0-159) 0045 u8 yposition; // Y position (0-110) 0046 ul16 bordercolor; // Border Color 0047-0048 u8 unknown_6[9]; // 0x00 0049-0051 u8 unknown_7[2]; // 0xFF 0052-0053 u8 range174_240; // 174-240 MHz 0054 u8 range240_320; // 240-320 MHz 0055 u8 range320_400; // 320-400 MHz 0056 u8 range480_560; // 480-560 MHz 0057 u8 unused_4[7]; // 0xFF 0058-005e u8 unknown_8; // 0x00 005f u8 unused_5[12]; // 0xFF 0060-006b u8 unknown_9[4]; // 0x00 006c-006f ul16 quickch2; // Quick CH 2 0070-0071 ul16 quickch1; // Quick CH 1 0072-0073 ul16 quickch4; // Quick CH 4 0074-0075 ul16 quickch3; // Quick CH 3 0076-0077 } settings; struct memory { ul32 rxfreq; // RX Frequency 00-03 ul16 rx_tone; // PL/DPL Decode 04-05 ul32 txfreq; // TX Frequency 06-09 ul16 tx_tone; // PL/DPL Encode 0a-0b ul24 mutecode; // Mute Code 0c-0e u8 unknown_0:2, // 0f mutetype:2, // Mute Type unknown_1:4; // u8 isnarrow:1, // Bandwidth 00 lowpower:1, // Power scan:1, // Scan Add bcl:2, // Busy Lock is_airband:1, // Air Band (AM) unknown_3:1, // unknown_4:1; // u8 unknown_5; // 01 u8 unused_0:4, // 02 scno:4; // SC No. u8 unknown_6[3]; // 03-05 char name[10]; // 06-0f }; #seekto 0x1000; struct memory channels[999]; #seekto 0x8D20; struct { u8 senddelay; // Send Delay 8d20 u8 sendinterval; // Send Interval 8d21 u8 unused_0:6, // 8d22 sendmode:2; // Send Mode u8 unused_2:4, // 8d23 sendselect:4; // Send Select u8 unused_3:7, // 8d24 recvdisplay:1; // Recv Display u8 encodegain; // Encode Gain 8d25 u8 decodeth; // Decode TH 8d26 } dtmf; #seekto 0x8D30; struct { char code[14]; // DTMF code u8 unused_ff; u8 code_len; // DTMF code length } dtmfcode[16]; // #seekto 0x8E30; struct { char kill[14]; // Remotely Kill 8e30-8e3d u8 unknown_0; // 8e3e u8 kill_len; // Remotely Kill Length 83ef char stun[14]; // Remotely Stun 8e40-834d u8 unknown_1; // 8e4e u8 stun_len; // Remotely Stun Length 8e4f char wakeup[14]; // Wake Up 8e50-8e5d u8 unknown_2; // 8e5e u8 wakeup_len; // Wake Up Length 8e5f } dtmf2; """ CMD_ACK = b"\x06" DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) _STEP_LIST = [0.25, 1.25, 2.5, 5., 6.25, 10., 12.5, 25., 50., 100., 500., 1000., 5000.] LIST_AB = ["A", "B"] LIST_BCL = ["Off", "Carrier", "CTC/DCS"] LIST_DELAY = ["%s ms" % x for x in range(0, 2100, 100)] LIST_DIRECTION = ["Up", "Down"] LIST_FREQSTEP = ["0.25K", "1.25K", "2.5K", "5K", "6.25K", "10K", "12.5K", "20K", "25K", "50K", "100K", "500K", "1M", "5M"] LIST_INTERVAL = ["%s ms" % x for x in range(30, 210, 10)] LIST_MUTETYPE = ["Off", "-", "23b", "24b"] LIST_ROGER = ["Off", "Roger 1", "Roger 2", "Send ID"] LIST_SENDM = ["Off", "TX Start", "TX End", "Start and End"] LIST_SENDS = ["DTMF %s" % x for x in range(1, 17)] LIST_SKEY = ["None", "Monitor", "Frequency Detect", "Talkaround", "Quick CH", "Local Alarm", "Remote Alarm", "Weather CH", "Send Tone", "Roger Beep"] LIST_REPEATER = ["Off", "Talkaround", "Frequency Reversal"] LIST_TIMER = ["Off", "5 seconds", "10 seconds"] + [ "%s seconds" % x for x in range(15, 615, 15)] LIST_TXPRI = ["Edit", "Busy"] LIST_WORKMODE = ["Frequency", "Channel"] TXALLOW_CHOICES = ["RX Only", "TX/RX"] TXALLOW_VALUES = [0xFF, 0x00] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "`{|}!\"#$%&'()*+,-./:;<=>?@[]^_" DTMF_CHARS = list("0123456789ABCD*#") def _checksum(data): cs = 0 for byte in data: cs += byte return cs % 256 def _enter_programming_mode(radio): serial = radio.pipe exito = False for i in range(0, 5): serial.write(radio.magic) ack = serial.read(1) try: if ack == CMD_ACK: exito = True break except Exception: LOG.debug("Attempt #%s, failed, trying again" % i) pass # check if we had EXITO if exito is False: msg = "The radio did not accept program mode after five tries.\n" msg += "Check you interface cable and power cycle your radio." raise errors.RadioError(msg) def _exit_programming_mode(radio): serial = radio.pipe try: serial.write(b"58" + b"\x05\xEE\x60") except Exception: raise errors.RadioError("Radio refused to exit programming mode") def _read_block(radio, block_addr, block_size): serial = radio.pipe cmd = struct.pack(">BH", ord(b'R'), block_addr + radio.READ_OFFSET) ccs = bytes([_checksum(cmd)]) expectedresponse = b"R" + cmd[1:] cmd = cmd + ccs LOG.debug("Reading block %04x..." % block_addr) try: serial.write(cmd) response = serial.read(3 + block_size + 1) cs = _checksum(response[:-1]) if response[:3] != expectedresponse: raise Exception("Error reading block %04x." % block_addr) chunk = response[3:] if chunk[-1] != cs: raise Exception("Block failed checksum!") block_data = chunk[:-1] except Exception: raise errors.RadioError("Failed to read block at %04x" % block_addr) return block_data def _write_block(radio, block_addr, block_size): serial = radio.pipe # map the upload address to the mmap start and end addresses start_addr = block_addr * block_size end_addr = start_addr + block_size data = radio.get_mmap()[start_addr:end_addr] cmd = struct.pack(">BH", ord(b'I'), block_addr) cs = bytes([_checksum(cmd + data)]) data += cs LOG.debug("Writing Data:") LOG.debug(util.hexprint(cmd + data)) try: serial.write(cmd + data) if serial.read(1) != CMD_ACK: raise Exception("No ACK") except Exception: raise errors.RadioError("Failed to send block " "to radio at %04x" % block_addr) def do_download(radio): LOG.debug("download") _enter_programming_mode(radio) data = b"" status = chirp_common.Status() status.msg = "Cloning from radio" status.cur = 0 status.max = radio.END_ADDR for addr in range(radio.START_ADDR, radio.END_ADDR, 1): status.cur = addr radio.status_fn(status) block = _read_block(radio, addr, radio.BLOCK_SIZE) data += block LOG.debug("Address: %04x" % addr) LOG.debug(util.hexprint(block)) _exit_programming_mode(radio) return memmap.MemoryMapBytes(data) def do_upload(radio): status = chirp_common.Status() status.msg = "Uploading to radio" _enter_programming_mode(radio) status.cur = 0 status.max = radio._memsize # The OEM software reads the 1st block from the radio before commencing # with the upload. That behavior will be mirrored here. _read_block(radio, radio.START_ADDR, radio.BLOCK_SIZE) for start_addr, end_addr in radio._ranges: for addr in range(start_addr, end_addr, 1): status.cur = addr * radio.BLOCK_SIZE radio.status_fn(status) _write_block(radio, addr, radio.BLOCK_SIZE) _exit_programming_mode(radio) def _split(rf, f1, f2): """Returns False if the two freqs are in the same band (no split) or True otherwise""" # determine if the two freqs are in the same band for low, high in rf.valid_bands: if f1 >= low and f1 <= high and \ f2 >= low and f2 <= high: # if the two freqs are on the same Band this is not a split return False # if you get here is because the freq pairs are split return True class IradioUV5118plus(chirp_common.CloneModeRadio): """IRADIO UV5118plus""" VENDOR = "Iradio" MODEL = "UV-5118plus" NAME_LENGTH = 10 BAUD_RATE = 115200 NEEDS_COMPAT_SERIAL = False BLOCK_SIZE = 0x80 magic = b"58" + b"\x05\x10\x82" VALID_BANDS = [(108000000, 136000000), # RX only (Air Band) (136000000, 174000000), # TX/RX (VHF) (174000000, 240000000), # TX/RX (240000000, 320000000), # TX/RX (320000000, 400000000), # TX/RX (400000000, 480000000), # TX/RX (UHF) (480000000, 560000000)] # TX/RX POWER_LEVELS = [chirp_common.PowerLevel("High", watts=2.00), chirp_common.PowerLevel("Low", watts=0.50)] # Radio's write address starts at 0x0000 # Radio's write address ends at 0x0140 START_ADDR = 0 END_ADDR = 0x0140 # Radio's read address starts at 0x7820 # Radio's read address ends at 0x795F READ_OFFSET = 0x7820 _ranges = [ (0x0000, 0x0140), ] _memsize = 0xA000 # 0x0140 * 0x80 _upper = 999 def get_features(self): rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_ctone = True rf.has_cross = True rf.has_rx_dtcs = True rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.valid_name_length = self.NAME_LENGTH rf.valid_characters = chirp_common.CHARSET_ASCII rf.valid_skips = ["", "S"] rf.valid_tmodes = ["", "Tone", "TSQL", "DTCS", "Cross"] rf.valid_cross_modes = ["Tone->Tone", "Tone->DTCS", "DTCS->Tone", "->Tone", "->DTCS", "DTCS->", "DTCS->DTCS"] rf.valid_power_levels = self.POWER_LEVELS rf.valid_duplexes = ["", "-", "+", "split"] rf.valid_modes = ["FM", "NFM"] # 25 kHz, 12.5 kHz. rf.valid_dtcs_codes = DTCS_CODES rf.memory_bounds = (1, self._upper) rf.valid_tuning_steps = _STEP_LIST rf.valid_bands = self.VALID_BANDS return rf def process_mmap(self): self._memobj = bitwise.parse(MEM_FORMAT, self._mmap) def sync_in(self): """Download from radio""" try: data = do_download(self) except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = data self.process_mmap() def sync_out(self): """Upload to radio""" try: do_upload(self) except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_raw_memory(self, number): return repr(self._memobj.memory[number - 1]) @staticmethod def _decode_tone(toneval): # DCS examples: # D023N - 1013 - 0001 0000 0001 0011 # ^-DCS # D023I - 2013 - 0010 0000 0001 0100 # ^--DCS inverted # D754I - 21EC - 0010 0001 1110 1100 # code in octal-------^^^^^^^^^^^ if toneval == 0x3000: return '', None, None elif toneval & 0x1000: # DTCS N code = int('%o' % (toneval & 0x1FF)) return 'DTCS', code, 'N' elif toneval & 0x2000: # DTCS R code = int('%o' % (toneval & 0x1FF)) return 'DTCS', code, 'R' else: return 'Tone', toneval / 10.0, None @staticmethod def _encode_tone(mode, val, pol): if not mode: return 0x3000 elif mode == 'Tone': return int(val * 10) elif mode == 'DTCS': code = int('%i' % val, 8) if pol == 'N': code |= 0x1800 if pol == 'R': code |= 0x2800 return code else: raise errors.RadioError('Unsupported tone mode %r' % mode) def get_memory(self, number): mem = chirp_common.Memory() _mem = self._memobj.channels[number - 1] mem.number = number mem.freq = int(_mem.rxfreq) * 10 # We'll consider any blank (i.e. 0 MHz frequency) to be empty if mem.freq == 0: mem.empty = True return mem if _mem.rxfreq.get_raw() == b"\xFF\xFF\xFF\xFF": mem.freq = 0 mem.empty = True return mem # Freq and offset mem.freq = int(_mem.rxfreq) * 10 # TX freq set offset = (int(_mem.txfreq) * 10) - mem.freq if offset != 0: if _split(self.get_features(), mem.freq, int( _mem.txfreq) * 10): mem.duplex = "split" mem.offset = int(_mem.txfreq) * 10 elif offset < 0: mem.offset = abs(offset) mem.duplex = "-" elif offset > 0: mem.offset = offset mem.duplex = "+" else: mem.offset = 0 mem.name = str(_mem.name).rstrip(" ").replace("\xFF", " ") mem.mode = _mem.isnarrow and "NFM" or "FM" if mem.freq < 136000000: _mem.is_airband = True else: _mem.is_airband = False chirp_common.split_tone_decode(mem, self._decode_tone(_mem.tx_tone), self._decode_tone(_mem.rx_tone)) mem.power = self.POWER_LEVELS[_mem.lowpower] if not _mem.scan: mem.skip = "S" mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSettingValueList(LIST_BCL, LIST_BCL[_mem.bcl]) rset = RadioSetting("bcl", "Busy Channel Lockout", rs) mem.extra.append(rset) rs = RadioSettingValueList(LIST_MUTETYPE, LIST_MUTETYPE[_mem.mutetype]) rset = RadioSetting("mutetype", "Mute Type", rs) mem.extra.append(rset) rs = RadioSettingValueInteger(0, 16777215, _mem.mutecode) rset = RadioSetting("mutecode", "Mute Code", rs) rset.set_doc('Value between 0-16777215') mem.extra.append(rset) rs = RadioSettingValueInteger(0, 8, _mem.scno) rset = RadioSetting("scno", "SC No.", rs) rset.set_doc('Value between 0-8') mem.extra.append(rset) return mem def set_memory(self, mem): LOG.debug("Setting %i(%s)" % (mem.number, mem.extd_number)) _mem = self._memobj.channels[mem.number - 1] # if empty memory if mem.empty: _mem.set_raw("\xFF" * 22 + "\x20" * 10) return _mem.set_raw("\xFF" * 4 + "\x00\x30" + "\xFF" * 4 + "\x00\x30" + "\x00" * 10 + "\x20" * 10) _mem.rxfreq = mem.freq / 10 if mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 _mem.name = mem.name.rstrip('\xFF').ljust(10, '\x20') _mem.scan = mem.skip != "S" _mem.isnarrow = mem.mode == "NFM" # dtcs_pol = ["N", "N"] txtone, rxtone = chirp_common.split_tone_encode(mem) _mem.tx_tone = self._encode_tone(*txtone) _mem.rx_tone = self._encode_tone(*rxtone) _mem.lowpower = mem.power == self.POWER_LEVELS[1] for setting in mem.extra: setattr(_mem, setting.get_name(), setting.value) def get_settings(self): _dtmf = self._memobj.dtmf _dtmf2 = self._memobj.dtmf2 _settings = self._memobj.settings basic = RadioSettingGroup("basic", "Basic Settings") dtmf = RadioSettingGroup("dtmf", "DTMF Settings") startup = RadioSettingGroup("startup", "Startup Settings") txallow = RadioSettingGroup("txallow", "TX Allow Settings") top = RadioSettings(basic, dtmf, startup, txallow) # Basic Settings # Menu 21 - Personal ID _codeobj = _settings.personalid _code = str(_codeobj).rstrip('\x20') rs = RadioSettingValueString(0, 16, _code, True) rset = RadioSetting("personalid", "Personal ID", rs) basic.append(rset) rs = RadioSettingValueList(LIST_WORKMODE, LIST_WORKMODE[_settings.workmode]) rset = RadioSetting("workmode", "Work Mode", rs) basic.append(rset) # Menu 05 - Voice Prompt rs = RadioSettingValueBoolean(_settings.voiceprompt) rset = RadioSetting("voiceprompt", "Voice Prompt", rs) basic.append(rset) # Menu 06 - Key Beep rs = RadioSettingValueBoolean(_settings.keybeep) rset = RadioSetting("keybeep", "Key Beep", rs) basic.append(rset) # Menu 07 - Roger Beep rs = RadioSettingValueList(LIST_ROGER, LIST_ROGER[_settings.rogerbeep]) rset = RadioSetting("rogerbeep", "Roger Beep", rs) basic.append(rset) # Menu 09 - TX Priority rs = RadioSettingValueList(LIST_TXPRI, LIST_TXPRI[_settings.txpriority]) rset = RadioSetting("txpriority", "TX Priority", rs) basic.append(rset) # Menu 10 - Save Mode rs = RadioSettingValueBoolean(_settings.savemode) rset = RadioSetting("savemode", "Save Mode", rs) basic.append(rset) # Menu 11 - Freq Step val = min(_settings.frequencystep, 0x0D) rs = RadioSettingValueList(LIST_FREQSTEP, LIST_FREQSTEP[val]) rset = RadioSetting("frequencystep", "Frequency Step", rs) basic.append(rset) # Menu 12 - SQ Level val = min(_settings.squelch, 0x09) rs = RadioSettingValueInteger(0, 9, val) rset = RadioSetting("squelch", "Squelch Level (0-9)", rs) basic.append(rset) # Menu 13 - LED Timer val = min(_settings.displaytimer, 0x2A) rs = RadioSettingValueList(LIST_TIMER, LIST_TIMER[val]) rset = RadioSetting("displaytimer", "Display Timer", rs) basic.append(rset) # Menu 14 - Lcok Timer val = min(_settings.locktimer, 0x2A) rs = RadioSettingValueList(LIST_TIMER, LIST_TIMER[val]) rset = RadioSetting("locktimer", "Lock Timer", rs) basic.append(rset) # Menu 15 - TOT val = min(_settings.timeouttimer, 0x2A) rs = RadioSettingValueList(LIST_TIMER, LIST_TIMER[val]) rset = RadioSetting("timeouttimer", "Timeout Timer", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.vox) rset = RadioSetting("vox", "VOX", rs) basic.append(rset) # Menu 16 - VOX Level val = min(_settings.voxlevel, 0x09) rs = RadioSettingValueInteger(0, 9, val) rset = RadioSetting("voxlevel", "VOX Level (0-9)", rs) basic.append(rset) # Menu 17 - VOX Delay val = min(_settings.voxdelay, 0x09) rs = RadioSettingValueInteger(0, 9, val) rset = RadioSetting("voxdelay", "VOX Delay (0-9)", rs) basic.append(rset) # Menu 18 - NOAA Monitor rs = RadioSettingValueBoolean(_settings.noaaalarm) rset = RadioSetting("noaaalarm", "NOAA Alarm", rs) basic.append(rset) # Menu 19 - FM Standby rs = RadioSettingValueBoolean(_settings.fmstandby) rset = RadioSetting("fmstandby", "FM Standby", rs) basic.append(rset) def myset_freq(setting, obj, atrb, mult): """ Callback to set frequency by applying multiplier""" value = int(float(str(setting.value)) * mult) setattr(obj, atrb, value) return # FM Broadcast Settings val = _settings.fmfrequency val = val / 10.0 if val < 64.0 or val > 108.0: val = 90.4 rx = RadioSettingValueFloat(64.0, 108.0, val, 0.1, 1) rset = RadioSetting("fmfrequency", "Broadcast FM Freq (MHz)", rx) rset.set_apply_callback(myset_freq, _settings, "fmfrequency", 10) basic.append(rset) # Menu 20 - Tail Tone rs = RadioSettingValueBoolean(_settings.tailtone) rset = RadioSetting("tailtone", "Tail Tone", rs) basic.append(rset) # Menu 21 - Scan DIR rs = RadioSettingValueList(LIST_DIRECTION, LIST_DIRECTION[_settings.scandirection]) rset = RadioSetting("scandirection", "Scan Direction", rs) basic.append(rset) # Menu 08 - Dual Display rs = RadioSettingValueBoolean(_settings.dualdisplay) rset = RadioSetting("dualdisplay", "Dual Display", rs) basic.append(rset) # Menu 23 - Repeater Mode val = min(_settings.talkaround, 0x02) rs = RadioSettingValueList(LIST_REPEATER, LIST_REPEATER[val]) rset = RadioSetting("talkaround", "Talkaround", rs) basic.append(rset) # Menu 37 - K1 Short val = min(_settings.key1short, 0x09) rs = RadioSettingValueList(LIST_SKEY, LIST_SKEY[val]) rset = RadioSetting("key1short", "Key 1 Short", rs) basic.append(rset) # Menu 36 - K1 Long val = min(_settings.key1long, 0x09) rs = RadioSettingValueList(LIST_SKEY, LIST_SKEY[val]) rset = RadioSetting("key1long", "Key 1 Long", rs) basic.append(rset) # Menu 39 - K2 Short val = min(_settings.key2short, 0x09) rs = RadioSettingValueList(LIST_SKEY, LIST_SKEY[val]) rset = RadioSetting("key2short", "Key 2 Short", rs) basic.append(rset) # Menu 38 - K2 Long val = min(_settings.key2long, 0x09) rs = RadioSettingValueList(LIST_SKEY, LIST_SKEY[val]) rset = RadioSetting("key2long", "Key 2 Long", rs) basic.append(rset) rs = RadioSettingValueInteger(0, 20000, _settings.tonefrequency) rset = RadioSetting("tonefrequency", "Tone Frequency (0-2000)", rs) basic.append(rset) rs = RadioSettingValueBoolean(_settings.dualstandby) rset = RadioSetting("dualstandby", "Dual Standby", rs) basic.append(rset) rs = RadioSettingValueList(LIST_AB, LIST_AB[_settings.standbyarea]) rset = RadioSetting("standbyarea", "Standby Area", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 999, _settings.areaach + 1) rset = RadioSetting("areaach", "Area A CH (1-999)", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 999, _settings.areabch + 1) rset = RadioSetting("areabch", "Area B CH (1-999)", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 999, _settings.quickch1 + 1) rset = RadioSetting("quickch1", "Quick CH 1 (1-999)", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 999, _settings.quickch2 + 1) rset = RadioSetting("quickch2", "Quick CH 2 (1-999)", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 999, _settings.quickch3 + 1) rset = RadioSetting("quickch3", "Quick CH 3 (1-999)", rs) basic.append(rset) rs = RadioSettingValueInteger(1, 999, _settings.quickch4 + 1) rset = RadioSetting("quickch4", "Quick CH 4 (1-999)", rs) basic.append(rset) rs = RadioSettingValueInteger(0, 65535, _settings.bordercolor) rset = RadioSetting("bordercolor", "Border Color (0-65535)", rs) basic.append(rset) # DTMF Settings # Menu 40 - DTMF Delay val = min(_dtmf.senddelay, 0x14) rs = RadioSettingValueList(LIST_DELAY, LIST_DELAY[val]) rset = RadioSetting("dtmf.senddelay", "Send Delay", rs) dtmf.append(rset) # Menu 41 - DTMF Interval val = min(_dtmf.sendinterval, 0x11) rs = RadioSettingValueList(LIST_INTERVAL, LIST_INTERVAL[val]) rset = RadioSetting("dtmf.sendinterval", "Send Interval", rs) dtmf.append(rset) # Menu 42 - DTMF Mode rs = RadioSettingValueList(LIST_SENDM, LIST_SENDM[_dtmf.sendmode]) rset = RadioSetting("dtmf.sendmode", "Send Mode", rs) dtmf.append(rset) # Menu 43 - DTMF Select rs = RadioSettingValueList(LIST_SENDS, LIST_SENDS[_dtmf.sendselect]) rset = RadioSetting("dtmf.sendselect", "Send Select", rs) dtmf.append(rset) # Menu 44 - DTMF Display rs = RadioSettingValueBoolean(_dtmf.recvdisplay) rset = RadioSetting("dtmf.recvdisplay", "Receive Display", rs) dtmf.append(rset) val = min(_dtmf.encodegain, 0x7F) rs = RadioSettingValueInteger(0, 127, val) rset = RadioSetting("dtmf.encodegain", "Encode Gain (0-127)", rs) dtmf.append(rset) val = min(_dtmf.decodeth, 0x3F) rs = RadioSettingValueInteger(0, 63, val) rset = RadioSetting("dtmf.decodeth", "Decode TH (0-63)", rs) dtmf.append(rset) for i in range(0, 16): _codeobj = self._memobj.dtmfcode[i].code _code = str(_codeobj).rstrip('\xFF') rs = RadioSettingValueString(0, 14, _code, False) rs.set_charset(DTMF_CHARS) rset = RadioSetting("dtmfcode/%i.code" % i, "Code %i" % (i + 1), rs) def apply_code(setting, obj, length): code = "" for char in str(setting.value): if char in DTMF_CHARS: code += char else: code += "" obj.code_len = len(str(code)) obj.code = code.ljust(length, chr(255)) rset.set_apply_callback(apply_code, self._memobj.dtmfcode[i], 14) dtmf.append(rset) _codeobj = _dtmf2.kill _code = str(_codeobj).rstrip('\xFF') rs = RadioSettingValueString(0, 14, _code, False) rs.set_charset(DTMF_CHARS) rset = RadioSetting("dtmf2.kill", "Remotely Kill", rs) def apply_code(setting, obj, length): code = "" for char in str(setting.value): if char in DTMF_CHARS: code += char else: code += "" obj.kill_len = len(str(code)) obj.kill = code.ljust(length, chr(255)) rset.set_apply_callback(apply_code, _dtmf2, 14) dtmf.append(rset) _codeobj = _dtmf2.stun _code = str(_codeobj).rstrip('\xFF') rs = RadioSettingValueString(0, 14, _code, False) rs.set_charset(DTMF_CHARS) rset = RadioSetting("dtmf2.stun", "Remotely Stun", rs) def apply_code(setting, obj, length): code = "" for char in str(setting.value): if char in DTMF_CHARS: code += char else: code += "" obj.stun_len = len(str(code)) obj.stun = code.ljust(length, chr(255)) rset.set_apply_callback(apply_code, _dtmf2, 14) dtmf.append(rset) _codeobj = _dtmf2.wakeup _code = str(_codeobj).rstrip('\xFF') rs = RadioSettingValueString(0, 14, _code, False) rs.set_charset(DTMF_CHARS) rset = RadioSetting("dtmf2.wakeup", "Wake Up", rs) def apply_code(setting, obj, length): code = "" for char in str(setting.value): if char in DTMF_CHARS: code += char else: code += "" obj.wakeup_len = len(str(code)) obj.wakeup = code.ljust(length, chr(255)) rset.set_apply_callback(apply_code, _dtmf2, 14) dtmf.append(rset) # Startup Settings _codeobj = _settings.startuplabel _code = str(_codeobj).rstrip('\x20') rs = RadioSettingValueString(0, 32, _code, True) rset = RadioSetting("startuplabel", "Startup Label", rs) startup.append(rset) # Menu 04 - Prompt Text rs = RadioSettingValueBoolean(_settings.displaylabel) rset = RadioSetting("displaylabel", "Display Startup Label", rs) startup.append(rset) # Menu 02 - Voltage rs = RadioSettingValueBoolean(_settings.displayvoltage) rset = RadioSetting("displayvoltage", "Display Voltage", rs) startup.append(rset) # Menu 01 - Startup Logo rs = RadioSettingValueBoolean(_settings.displaylogo) rset = RadioSetting("displaylogo", "Display Startup Logo", rs) startup.append(rset) # Menu 03 - Ringtone rs = RadioSettingValueBoolean(_settings.startupringtone) rset = RadioSetting("startupringtone", "Startup Ringtone", rs) startup.append(rset) val = min(_settings.xposition, 0x9F) rs = RadioSettingValueInteger(0, 159, val) rset = RadioSetting("xposition", "X Position (0-159)", rs) startup.append(rset) val = min(_settings.yposition, 0x6E) rs = RadioSettingValueInteger(16, 110, val) rset = RadioSetting("yposition", "Y Position (16-110)", rs) startup.append(rset) # TX Allow Settings def apply_txallow_listvalue(setting, obj): LOG.debug("Setting value: " + str( setting.value) + " from list") val = str(setting.value) index = TXALLOW_CHOICES.index(val) val = TXALLOW_VALUES[index] obj.set_value(val) if _settings.range174_240 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_settings.range174_240) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("range174_240", "174-240 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _settings.range174_240) txallow.append(rset) if _settings.range240_320 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_settings.range240_320) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("range240_320", "240-320 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _settings.range240_320) txallow.append(rset) if _settings.range320_400 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_settings.range320_400) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("range320_400", "320-400 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _settings.range320_400) txallow.append(rset) if _settings.range480_560 in TXALLOW_VALUES: idx = TXALLOW_VALUES.index(_settings.range480_560) else: idx = TXALLOW_VALUES.index(0xFF) rs = RadioSettingValueList(TXALLOW_CHOICES, TXALLOW_CHOICES[idx]) rset = RadioSetting("range480_560", "480-560 MHz", rs) rset.set_apply_callback(apply_txallow_listvalue, _settings.range480_560) txallow.append(rset) return top def set_settings(self, settings): for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = self._memobj.settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif setting in ["areaach", "areabch", "quickch1", "quickch2", "quickch3", "quickch4" ]: setattr(obj, setting, int(element.value) - 1) elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception as e: LOG.debug(element.get_name(), e) raise @classmethod def match_model(cls, filedata, filename): # This radio has always been post-metadata, so never do # old-school detection return False @directory.register class RuyageUV58PlusRadio(IradioUV5118plus): """Ruyage UV58Plus""" VENDOR = "Ruyage" MODEL = "UV58Plus" chirp-20240224/chirp/drivers/baofeng_uv17Pro.py0000644000175000017500000013466514565075506020171 0ustar hibbyhibby# Copyright 2023: # * Sander van der Wel, # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp.drivers import baofeng_common as bfc from chirp import chirp_common, directory, memmap from chirp import bitwise from chirp.settings import RadioSetting, \ RadioSettingValueBoolean, RadioSettingValueList, \ InvalidValueError, RadioSettingValueString, \ RadioSettings, RadioSettingGroup import struct from chirp import errors, util LOG = logging.getLogger(__name__) # Baofeng UV-17L magic string MSTRING_UV17L = b"PROGRAMBFNORMALU" MSTRING_UV17PROGPS = b"PROGRAMCOLORPROU" DTMF_CHARS = "0123456789 *#ABCD" STEPS = [2.5, 5.0, 6.25, 10.0, 12.5, 20.0, 25.0, 50.0] LIST_STEPS = ["2.5", "5.0", "6.25", "10.0", "12.5", "20.0", "25.0", "50.0"] LIST_AB = ["A", "B"] LIST_BANDWIDTH = ["Wide", "Narrow"] LIST_DTMFSPEED = ["%s ms" % x for x in [50, 100, 200, 300, 500]] LIST_HANGUPTIME = ["%s s" % x for x in [3, 4, 5, 6, 7, 8, 9, 10]] LIST_SIDE_TONE = ["Off", "Side Key", "ID", "Side + ID"] LIST_PTTID = ["Off", "BOT", "EOT", "Both"] LIST_TIMEOUT_ALARM = ["Off"] + ["%s sec" % x for x in range(1, 11)] LIST_PILOT_TONE = ["1000 Hz", "1450 Hz", "1750 Hz", "2100 Hz"] LIST_VOICE = ["Off", "English", "Chinese"] LIST_WORKMODE = ["Frequency", "Channel"] LIST_BEEP = ["Off", "Beep", "Voice", "Both"] LIST_SCANMODE = ["Time", "Carrier", "Search"] LIST_ALARMMODE = ["Local", "Send Tone", "Send Code"] LIST_MENU_QUIT_TIME = ["%s sec" % x for x in range(5, 55, 5)] + ["60 sec"] LIST_ID_DELAY = ["%s ms" % x for x in range(100, 3100, 100)] LIST_QT_SAVEMODE = ["Both", "RX", "TX"] LIST_SKEY2_SHORT = ["FM", "Scan", "Search", "Vox"] LIST_RPT_TAIL_CLEAR = ["%s ms" % x for x in range(0, 1100, 100)] LIST_VOX_DELAY_TIME = ["%s ms" % x for x in range(500, 2100, 100)] LIST_VOX_LEVEL = ["Off"] + ["%s" % x for x in range(1, 10, 1)] LIST_VOX_LEVEL_ALT = ["%s" % x for x in range(1, 10, 1)] LIST_GPS_MODE = ["GPS", "Beidou", "GPS + Beidou"] LIST_GPS_TIMEZONE = ["%s" % x for x in range(-12, 13, 1)] LIST_SHIFTS = ["Off", "+", "-"] CHARSET_GB2312 = chirp_common.CHARSET_ASCII for x in range(0xB0, 0xD7): for y in range(0xA1, 0xFF): CHARSET_GB2312 += bytes([x, y]).decode('gb2312') def model_match(cls, data): """Match the opened image to the correct version""" return data[cls.MEM_TOTAL:] == bytes(cls.MODEL, 'utf-8') def _crypt(symbol_index, buffer): # Some weird encryption is used. From the table below, we only use "CO 7". tblEncrySymbol = [b"BHT ", b"CO 7", b"A ES", b" EIY", b"M PQ", b"XN Y", b"RVB ", b" HQP", b"W RC", b"MS N", b" SAT", b"K DH", b"ZO R", b"C SL", b"6RB ", b" JCG", b"PN V", b"J PK", b"EK L", b"I LZ"] tbl_encrypt_symbols = tblEncrySymbol[symbol_index] dec_buffer = b"" index1 = 0 for index2 in range(len(buffer)): bool_encrypt_char = ((tbl_encrypt_symbols[index1] != 32) and (buffer[index2] != 0) and (buffer[index2] != 255) and (buffer[index2] != tbl_encrypt_symbols[index1]) and (buffer[index2] != (tbl_encrypt_symbols[index1] ^ 255))) if (bool_encrypt_char): dec_byte = buffer[index2] ^ tbl_encrypt_symbols[index1] dec_buffer += struct.pack('>B', dec_byte) else: dec_buffer += struct.pack('>B', buffer[index2]) index1 = (index1 + 1) % 4 return dec_buffer def _sendmagic(radio, magic, response_len): bfc._rawsend(radio, magic) return bfc._rawrecv(radio, response_len) def _do_ident(radio): # Flush input buffer bfc._clean_buffer(radio) # Ident radio ack = _sendmagic(radio, radio._magic, len(radio._fingerprint)) if not ack.startswith(radio._fingerprint): if ack: LOG.debug(repr(ack)) raise errors.RadioError("Radio did not respond as expected (A)") for magic, resplen in radio._magics: _sendmagic(radio, magic, resplen) return True def _download(radio): """Get the memory map""" # Put radio in program mode and identify it _do_ident(radio) data = b"" # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio.MEM_TOTAL // radio.BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) for i in range(len(radio.MEM_SIZES)): MEM_SIZE = radio.MEM_SIZES[i] MEM_START = radio.MEM_STARTS[i] for addr in range(MEM_START, MEM_START + MEM_SIZE, radio.BLOCK_SIZE): frame = radio._make_read_frame(addr, radio.BLOCK_SIZE) # DEBUG LOG.debug("Frame=" + util.hexprint(frame)) # Sending the read request bfc._rawsend(radio, frame) # Now we read data d = bfc._rawrecv(radio, radio.BLOCK_SIZE + 4) LOG.debug("Response Data= " + util.hexprint(d)) d = _crypt(1, d[4:]) # Aggregate the data data += d # UI Update status.cur = len(data) // radio.BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) return data def _upload(radio): # Put radio in program mode and identify it _do_ident(radio) data = b"" # UI progress status = chirp_common.Status() status.cur = 0 status.max = radio.MEM_TOTAL // radio.BLOCK_SIZE status.msg = "Cloning from radio..." radio.status_fn(status) data_addr = 0x00 radio_mem = radio.get_mmap() for i in range(len(radio.MEM_SIZES)): MEM_SIZE = radio.MEM_SIZES[i] MEM_START = radio.MEM_STARTS[i] for addr in range(MEM_START, MEM_START + MEM_SIZE, radio.BLOCK_SIZE): data = radio_mem[data_addr:data_addr + radio.BLOCK_SIZE] data = _crypt(1, data) data_addr += radio.BLOCK_SIZE frame = radio._make_frame(b"W", addr, radio.BLOCK_SIZE, data) # DEBUG LOG.debug("Frame=" + util.hexprint(frame)) # Sending the read request bfc._rawsend(radio, frame) # receiving the response ack = bfc._rawrecv(radio, 1) if ack != b"\x06": msg = "Bad ack writing block 0x%04x" % addr raise errors.RadioError(msg) # UI Update status.cur = data_addr // radio.BLOCK_SIZE status.msg = "Cloning to radio..." radio.status_fn(status) return data @directory.register class UV17Pro(bfc.BaofengCommonHT): """Baofeng UV-17Pro""" VENDOR = "Baofeng" MODEL = "UV-17Pro" NEEDS_COMPAT_SERIAL = False MEM_STARTS = [0x0000, 0x9000, 0xA000, 0xD000] MEM_SIZES = [0x8040, 0x0040, 0x02C0, 0x0040] MEM_TOTAL = 0x8380 BLOCK_SIZE = 0x40 BAUD_RATE = 115200 download_function = _download upload_function = _upload _gmrs = False _bw_shift = False _has_support_for_banknames = False _has_workmode_support = True _has_savemode = True _tri_band = True _fileid = [] _magic = MSTRING_UV17L _fingerprint = b"\x06" _magics = [(b"\x46", 16), (b"\x4d", 15), (b"\x53\x45\x4E\x44\x21\x05\x0D\x01\x01\x01\x04\x11\x08\x05" + b"\x0D\x0D\x01\x11\x0F\x09\x12\x09\x10\x04\x00", 1)] _fw_ver_start = 0x1EF0 _recv_block_size = 0x40 _mem_size = MEM_TOTAL _ack_block = True _has_when_to_send_aniid = True _vfoscan = False _has_gps = False _has_voxsw = False _has_pilot_tone = False _has_send_id_delay = False _has_skey2_short = False _scode_offset = 0 MODES = ["NFM", "FM"] VALID_CHARS = chirp_common.CHARSET_ALPHANUMERIC + \ "!@#$%^&*()+-=[]:\";'<>?,./" LENGTH_NAME = 12 SKIP_VALUES = ["", "S"] DTCS_CODES = tuple(sorted(chirp_common.DTCS_CODES + (645,))) RXTX_CODES = ('Off', ) LIST_PW_SAVEMODE = ["Off", "On"] for code in chirp_common.TONES: RXTX_CODES = (RXTX_CODES + (str(code), )) for code in DTCS_CODES: RXTX_CODES = (RXTX_CODES + ('D' + str(code) + 'N', )) for code in DTCS_CODES: RXTX_CODES = (RXTX_CODES + ('D' + str(code) + 'I', )) POWER_LEVELS = [chirp_common.PowerLevel("High", watts=5.00), chirp_common.PowerLevel("Low", watts=1.00)] _airband = (108000000, 136000000) _vhf_range = (136000000, 174000000) _vhf2_range = (200000000, 260000000) _uhf_range = (400000000, 520000000) _uhf2_range = (350000000, 390000000) VALID_BANDS = [_vhf_range, _vhf2_range, _uhf_range] PTTID_LIST = LIST_PTTID SCODE_LIST = ["%s" % x for x in range(1, 21)] SQUELCH_LIST = ["Off"] + list("12345") LIST_POWERON_DISPLAY_TYPE = ["LOGO", "BATT voltage"] LIST_TIMEOUT = ["Off"] + ["%s sec" % x for x in range(15, 195, 15)] LIST_VOICE = ["English", "Chinese"] LIST_BACKLIGHT_TIMER = ["Always On"] + ["%s sec" % x for x in range(5, 25, 5)] LIST_MODE = ["Name", "Frequency", "Channel Number"] CHANNELS = 1000 MEM_FORMAT = """ struct { lbcd rxfreq[4]; lbcd txfreq[4]; ul16 rxtone; ul16 txtone; u8 scode; u8 pttid; u8 lowpower; u8 unknown1:1, wide:1, sqmode:2, bcl:1, scan:1, unknown2:1, fhss:1; u8 unknown3; u8 unknown4; u8 unknown5; u8 unknown6; char name[12]; } memory[1000]; struct vfo_entry { u8 freq[8]; ul16 rxtone; ul16 txtone; u8 unknown0; u8 bcl; u8 sftd:3, scode:5; u8 unknown1; u8 lowpower; u8 unknown2:1, wide:1, unknown3:5, fhss:1; u8 unknown4; u8 step; u8 offset[6]; u8 unknown5[2]; u8 sqmode; u8 unknown6[3]; }; #seekto 0x8000; struct { struct vfo_entry a; struct vfo_entry b; } vfo; struct { u8 squelch; u8 savemode; u8 vox; u8 backlight; u8 dualstandby; u8 tot; u8 beep; u8 voicesw; u8 voice; u8 sidetone; u8 scanmode; u8 pttid; u8 pttdly; u8 chadistype; u8 chbdistype; u8 bcl; u8 autolock; u8 alarmmode; u8 alarmtone; u8 unknown1; u8 tailclear; u8 rpttailclear; u8 rpttaildet; u8 roger; u8 unknown2; u8 fmenable; u8 chbworkmode:4, chaworkmode:4; u8 keylock; u8 powerondistype; u8 tone; u8 unknown4[2]; u8 voxdlytime; u8 menuquittime; u8 unknown5[6]; u8 totalarm; u8 unknown6[2]; u8 ctsdcsscantype; ul16 vfoscanmin; ul16 vfoscanmax; u8 gpsw; u8 gpsmode; u8 unknown7[2]; u8 key2short; u8 unknown8[2]; u8 rstmenu; u8 unknown9; u8 hangup; u8 voxsw; u8 gpstimezone; } settings; #seekto 0x8080; struct { u8 code[5]; u8 unknown[1]; u8 unused1:6, aniid:2; u8 dtmfon; u8 dtmfoff; } ani; #seekto 0x80A0; struct { u8 code[5]; u8 name[10]; u8 unused; } pttid[20]; #seekto 0x8280; struct { char name[16]; } bank_name[10]; """ def _make_read_frame(self, addr, length): """Pack the info in the header format""" frame = self._make_frame(b"\x52", addr, length) # Return the data return frame def _make_frame(self, cmd, addr, length, data=""): """Pack the info in the header format""" frame = cmd + struct.pack(">i", addr)[2:] + struct.pack("b", length) # add the data if set if len(data) != 0: frame += data # return the data return frame @classmethod def get_prompts(cls): rp = chirp_common.RadioPrompts() rp.experimental = \ ('This driver is a beta version.\n' '\n' 'Please save an unedited copy of your first successful\n' 'download to a CHIRP Radio Images(*.img) file.' ) rp.pre_download = _( "Follow these instructions to download your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the download of your radio data\n") rp.pre_upload = _( "Follow this instructions to upload your info:\n" "1 - Turn off your radio\n" "2 - Connect your interface cable\n" "3 - Turn on your radio\n" "4 - Do the upload of your radio data\n") return rp def process_mmap(self): """Process the mem map into the mem object""" # make lines shorter for style check. self._memobj = bitwise.parse(self.MEM_FORMAT, self._mmap) # DTMF settings def apply_code(self, setting, obj, length): code = [] for j in range(0, length): try: code.append(DTMF_CHARS.index(str(setting.value)[j])) except IndexError: code.append(0xFF) obj.code = code def get_settings_common_dtmf(self, dtmfe, _mem): for i in range(0, len(self.SCODE_LIST)): _codeobj = self._memobj.pttid[i].code _code = "".join([ DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) pttid = RadioSetting("pttid/%i.code" % i, "Signal Code %i" % (i + 1), val) pttid.set_apply_callback(self.apply_code, self._memobj.pttid[i], 5) dtmfe.append(pttid) _codeobj = self._memobj.ani.code _code = "".join([DTMF_CHARS[x] for x in _codeobj if int(x) < 0x1F]) val = RadioSettingValueString(0, 5, _code, False) val.set_charset(DTMF_CHARS) rs = RadioSetting("ani.code", "ANI Code", val) rs.set_apply_callback(self.apply_code, self._memobj.ani, 5) dtmfe.append(rs) def get_settings_pro_dtmf(self, dtmfe, _mem): if _mem.ani.dtmfon > 0xC3: val = 0x03 else: val = _mem.ani.dtmfon rs = RadioSetting("ani.dtmfon", "DTMF Speed (on)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if _mem.ani.dtmfoff > 0xC3: val = 0x03 else: val = _mem.ani.dtmfoff rs = RadioSetting("ani.dtmfoff", "DTMF Speed (off)", RadioSettingValueList(LIST_DTMFSPEED, LIST_DTMFSPEED[val])) dtmfe.append(rs) if self._has_when_to_send_aniid: rs = RadioSetting("ani.aniid", "When to send ANI ID", RadioSettingValueList(LIST_PTTID, LIST_PTTID[ _mem.ani.aniid])) dtmfe.append(rs) if _mem.settings.hangup >= len(LIST_HANGUPTIME): val = 0 else: val = _mem.settings.hangup rs = RadioSetting("settings.hangup", "Hang-up time", RadioSettingValueList(LIST_HANGUPTIME, LIST_HANGUPTIME[ val])) dtmfe.append(rs) def get_settings_common_basic(self, basic, _mem): if _mem.settings.squelch >= len(self.SQUELCH_LIST): val = 0x00 else: val = _mem.settings.squelch rs = RadioSetting("settings.squelch", "Squelch", RadioSettingValueList( self.SQUELCH_LIST, self.SQUELCH_LIST[val])) basic.append(rs) if _mem.settings.tot >= len(self.LIST_TIMEOUT): val = 0x03 else: val = _mem.settings.tot rs = RadioSetting("settings.tot", "Timeout Timer", RadioSettingValueList( self.LIST_TIMEOUT, self.LIST_TIMEOUT[val])) basic.append(rs) rs = RadioSetting("settings.dualstandby", "Dual Watch", RadioSettingValueBoolean(_mem.settings.dualstandby)) basic.append(rs) if _mem.settings.powerondistype >= len(self.LIST_POWERON_DISPLAY_TYPE): val = 0x00 else: rs = RadioSetting("settings.powerondistype", "Power On Display Type", RadioSettingValueList( self.LIST_POWERON_DISPLAY_TYPE, self.LIST_POWERON_DISPLAY_TYPE[ _mem.settings.powerondistype])) basic.append(rs) if _mem.settings.voice >= len(self.LIST_VOICE): val = 0x01 else: val = _mem.settings.voice rs = RadioSetting("settings.voice", "Voice Prompt", RadioSettingValueList( self.LIST_VOICE, self.LIST_VOICE[val])) basic.append(rs) rs = RadioSetting("settings.voicesw", "Enable Voice", RadioSettingValueBoolean(_mem.settings.voicesw)) basic.append(rs) if _mem.settings.backlight >= len(self.LIST_BACKLIGHT_TIMER): val = 0x00 else: val = _mem.settings.backlight rs = RadioSetting("settings.backlight", "Backlight Timer", RadioSettingValueList( self.LIST_BACKLIGHT_TIMER, self.LIST_BACKLIGHT_TIMER[val])) basic.append(rs) rs = RadioSetting("settings.autolock", "Key Auto Lock", RadioSettingValueBoolean(_mem.settings.autolock)) basic.append(rs) rs = RadioSetting("settings.beep", "Beep", RadioSettingValueList( LIST_BEEP, LIST_BEEP[_mem.settings.beep])) basic.append(rs) rs = RadioSetting("settings.roger", "Roger", RadioSettingValueBoolean(_mem.settings.roger)) basic.append(rs) rs = RadioSetting("settings.chadistype", "Channel A display type", RadioSettingValueList( self.LIST_MODE, self.LIST_MODE[_mem.settings.chadistype])) basic.append(rs) rs = RadioSetting("settings.chbdistype", "Channel B display type", RadioSettingValueList( self.LIST_MODE, self.LIST_MODE[_mem.settings.chbdistype])) basic.append(rs) def get_settings_pro_basic(self, basic, _mem): if _mem.settings.savemode > len(self.LIST_PW_SAVEMODE): val = 0x01 # assume values out of range are some form of "On" else: val = _mem.settings.savemode rs = RadioSetting("settings.savemode", "Save Mode", RadioSettingValueList(self.LIST_PW_SAVEMODE, self.LIST_PW_SAVEMODE[val])) basic.append(rs) rs = RadioSetting("settings.totalarm", "Timeout Timer Alarm", RadioSettingValueList( LIST_TIMEOUT_ALARM, LIST_TIMEOUT_ALARM[_mem.settings.totalarm])) basic.append(rs) if self._has_pilot_tone: rs = RadioSetting("settings.tone", "Pilot Tone", RadioSettingValueList( LIST_PILOT_TONE, LIST_PILOT_TONE[_mem.settings.tone])) basic.append(rs) rs = RadioSetting("settings.sidetone", "Side Tone", RadioSettingValueList( LIST_SIDE_TONE, LIST_SIDE_TONE[_mem.settings.sidetone])) basic.append(rs) rs = RadioSetting("settings.tailclear", "Tail Clear", RadioSettingValueBoolean(_mem.settings.tailclear)) basic.append(rs) rs = RadioSetting("settings.scanmode", "Scan Mode", RadioSettingValueList( LIST_SCANMODE, LIST_SCANMODE[_mem.settings.scanmode])) basic.append(rs) rs = RadioSetting("settings.alarmmode", "Alarm Mode", RadioSettingValueList( LIST_ALARMMODE, LIST_ALARMMODE[_mem.settings.alarmmode])) basic.append(rs) rs = RadioSetting("settings.alarmtone", "Sound Alarm", RadioSettingValueBoolean(_mem.settings.alarmtone)) basic.append(rs) rs = RadioSetting("settings.keylock", "Key Lock", RadioSettingValueBoolean(_mem.settings.keylock)) basic.append(rs) rs = RadioSetting("settings.menuquittime", "Menu Quit Timer", RadioSettingValueList( LIST_MENU_QUIT_TIME, LIST_MENU_QUIT_TIME[ _mem.settings.menuquittime])) basic.append(rs) if self._has_send_id_delay: rs = RadioSetting("settings.pttdly", "Send ID Delay", RadioSettingValueList( LIST_ID_DELAY, LIST_ID_DELAY[_mem.settings.pttdly])) basic.append(rs) rs = RadioSetting("settings.ctsdcsscantype", "QT Save Mode", RadioSettingValueList( LIST_QT_SAVEMODE, LIST_QT_SAVEMODE[_mem.settings.ctsdcsscantype])) basic.append(rs) def getKey2shortIndex(value): key_to_index = {0x07: 0, 0x1C: 1, 0x1D: 2, 0x2D: 3} return key_to_index.get(int(value), 0) def apply_Key2short(setting, obj): val = str(setting.value) key_to_index = {'FM': 0x07, 'Scan': 0x1C, 'Search': 0x1D, 'Vox': 0x2D} obj.key2short = key_to_index.get(val, 0x07) if self._has_skey2_short: rs = RadioSetting("settings.key2short", "Skey2 Short", RadioSettingValueList( LIST_SKEY2_SHORT, LIST_SKEY2_SHORT[ getKey2shortIndex( _mem.settings.key2short)])) rs.set_apply_callback(apply_Key2short, _mem.settings) basic.append(rs) rs = RadioSetting("settings.chaworkmode", "Channel A work mode", RadioSettingValueList( LIST_WORKMODE, LIST_WORKMODE[_mem.settings.chaworkmode])) basic.append(rs) rs = RadioSetting("settings.chbworkmode", "Channel B work mode", RadioSettingValueList( LIST_WORKMODE, LIST_WORKMODE[_mem.settings.chbworkmode])) basic.append(rs) rs = RadioSetting("settings.rpttailclear", "Rpt Tail Clear", RadioSettingValueList( LIST_RPT_TAIL_CLEAR, LIST_RPT_TAIL_CLEAR[ _mem.settings.rpttailclear])) basic.append(rs) rs = RadioSetting("settings.rpttaildet", "Rpt Tail Delay", RadioSettingValueList( LIST_RPT_TAIL_CLEAR, LIST_RPT_TAIL_CLEAR[_mem.settings.rpttaildet])) basic.append(rs) rs = RadioSetting("settings.rstmenu", "Enable Menu Rst", RadioSettingValueBoolean(_mem.settings.rstmenu)) basic.append(rs) if self._has_voxsw: rs = RadioSetting("settings.voxsw", "Vox Switch", RadioSettingValueBoolean(_mem.settings.voxsw)) basic.append(rs) rs = RadioSetting("settings.vox", "Vox Level", RadioSettingValueList( LIST_VOX_LEVEL_ALT, LIST_VOX_LEVEL_ALT[_mem.settings.vox])) basic.append(rs) else: rs = RadioSetting("settings.vox", "Vox Level", RadioSettingValueList( LIST_VOX_LEVEL, LIST_VOX_LEVEL[_mem.settings.vox])) basic.append(rs) rs = RadioSetting("settings.voxdlytime", "Vox Delay Time", RadioSettingValueList( LIST_VOX_DELAY_TIME, LIST_VOX_DELAY_TIME[_mem.settings.voxdlytime])) basic.append(rs) if self._has_gps: rs = RadioSetting("settings.gpsw", "GPS On", RadioSettingValueBoolean(_mem.settings.gpsw)) basic.append(rs) rs = RadioSetting("settings.gpsmode", "GPS Mode", RadioSettingValueList( LIST_GPS_MODE, LIST_GPS_MODE[_mem.settings.gpsmode])) basic.append(rs) rs = RadioSetting("settings.gpstimezone", "GPS Timezone", RadioSettingValueList( LIST_GPS_TIMEZONE, LIST_GPS_TIMEZONE[_mem.settings.gpstimezone])) basic.append(rs) rs = RadioSetting("settings.fmenable", "Disable FM radio", RadioSettingValueBoolean(_mem.settings.fmenable)) basic.append(rs) def get_settings_common_workmode(self, workmode, _mem): vfoA = RadioSettingGroup("vfoA", "VFO A") vfoB = RadioSettingGroup("vfoB", "VFO B") def my_validate(value): value = chirp_common.parse_freq(value) for band in self.VALID_BANDS: if value > band[0] and value < band[1]: return chirp_common.format_freq(value) msg = ("{0} is not in a valid band.".format(value)) raise InvalidValueError(msg) def apply_freq(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 10 for i in range(7, -1, -1): obj.freq[i] = value % 10 value /= 10 freqA = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.a.freq)) freqA.set_validate_callback(my_validate) rs = RadioSetting("vfo.a.freq", "Frequency", freqA) rs.set_apply_callback(apply_freq, _mem.vfo.a) vfoA.append(rs) freqB = RadioSettingValueString(0, 10, bfc.bcd_decode_freq(_mem.vfo.b.freq)) freqB.set_validate_callback(my_validate) rs = RadioSetting("vfo.b.freq", "Frequency", freqB) rs.set_apply_callback(apply_freq, _mem.vfo.b) vfoB.append(rs) if _mem.vfo.a.sftd >= len(LIST_SHIFTS): val = 0 else: val = _mem.vfo.a.sftd rs = RadioSetting("vfo.a.sftd", "Shift", RadioSettingValueList(LIST_SHIFTS, LIST_SHIFTS[val])) vfoA.append(rs) if _mem.vfo.b.sftd >= len(LIST_SHIFTS): val = 0 else: val = _mem.vfo.b.sftd rs = RadioSetting("vfo.b.sftd", "Shift", RadioSettingValueList(LIST_SHIFTS, LIST_SHIFTS[val])) vfoB.append(rs) def convert_bytes_to_offset(bytes): real_offset = 0 for byte in bytes: real_offset = (real_offset * 10) + byte return chirp_common.format_freq(real_offset * 1000) def apply_offset(setting, obj): value = chirp_common.parse_freq(str(setting.value)) / 1000 for i in range(5, -1, -1): obj.offset[i] = value % 10 value /= 10 offA = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.a.offset)) rs = RadioSetting("vfo.a.offset", "Offset (0.0-999.999)", offA) rs.set_apply_callback(apply_offset, _mem.vfo.a) vfoA.append(rs) offB = RadioSettingValueString( 0, 10, convert_bytes_to_offset(_mem.vfo.b.offset)) rs = RadioSetting("vfo.b.offset", "Offset (0.0-999.999)", offB) rs.set_apply_callback(apply_offset, _mem.vfo.b) vfoB.append(rs) POWER_LEVELS = [str(x) for x in self.POWER_LEVELS] if _mem.vfo.a.lowpower >= len(POWER_LEVELS): val = 0 else: val = _mem.vfo.a.lowpower rs = RadioSetting("vfo.a.lowpower", "Power", RadioSettingValueList(POWER_LEVELS, POWER_LEVELS[val])) vfoA.append(rs) if _mem.vfo.b.lowpower >= len(POWER_LEVELS): val = 0 else: val = _mem.vfo.b.lowpower rs = RadioSetting("vfo.b.lowpower", "Power", RadioSettingValueList(POWER_LEVELS, POWER_LEVELS[val])) vfoB.append(rs) if _mem.vfo.a.wide >= len(LIST_BANDWIDTH): val = 0 else: val = _mem.vfo.a.wide rs = RadioSetting("vfo.a.wide", "Bandwidth", RadioSettingValueList(LIST_BANDWIDTH, LIST_BANDWIDTH[val])) vfoA.append(rs) if _mem.vfo.b.wide >= len(LIST_BANDWIDTH): val = 0 else: val = _mem.vfo.b.wide rs = RadioSetting("vfo.b.wide", "Bandwidth", RadioSettingValueList(LIST_BANDWIDTH, LIST_BANDWIDTH[val])) vfoB.append(rs) if _mem.vfo.a.scode >= len(self.SCODE_LIST): val = 0 else: val = _mem.vfo.a.scode rs = RadioSetting("vfo.a.scode", "Signal Code", RadioSettingValueList(self.SCODE_LIST, self.SCODE_LIST[val])) vfoA.append(rs) if _mem.vfo.b.scode >= len(self.SCODE_LIST): val = 0 else: val = _mem.vfo.b.scode rs = RadioSetting("vfo.b.scode", "Signal Code", RadioSettingValueList(self.SCODE_LIST, self.SCODE_LIST[val])) vfoB.append(rs) if _mem.vfo.a.step >= len(STEPS): val = 0 else: val = _mem.vfo.a.step rs = RadioSetting("vfo.a.step", "Tuning Step", RadioSettingValueList(LIST_STEPS, LIST_STEPS[val])) vfoA.append(rs) if _mem.vfo.b.step >= len(STEPS): val = 0 else: val = _mem.vfo.b.step rs = RadioSetting("vfo.b.step", "Tuning Step", RadioSettingValueList(LIST_STEPS, LIST_STEPS[val])) vfoB.append(rs) workmode.append(vfoA) workmode.append(vfoB) def get_settings_common_bank(self, bank, _mem): def _filterName(name): fname = b"" for char in name: if ord(str(char)) == 255: break fname += int(char).to_bytes(1, 'big') return fname.decode('gb2312').strip() def apply_bankname(setting, obj): name = str(setting.value).encode('gb2312')[:16].ljust(16, b"\xff") obj.name = name if self._has_support_for_banknames: for i in range(0, 10): _nameobj = self._memobj.bank_name[i] rs = RadioSetting("bank_name/%i.name" % i, "Bank name %i" % (i + 1), RadioSettingValueString( 0, 16, _filterName(_nameobj.name), False, CHARSET_GB2312)) rs.set_apply_callback(apply_bankname, _nameobj) bank.append(rs) def get_settings(self): """Translate the bit in the mem_struct into settings in the UI""" _mem = self._memobj supported = [] basic = RadioSettingGroup("basic", "Basic Settings") self.get_settings_common_basic(basic, _mem) self.get_settings_pro_basic(basic, _mem) supported.append(basic) # add basic menu if self._has_workmode_support: workmode = RadioSettingGroup("workmode", "Work Mode Settings") self.get_settings_common_workmode(workmode, _mem) supported.append(workmode) # add workmode menu if supported dtmfe = RadioSettingGroup("dtmfe", "DTMF Encode Settings") self.get_settings_common_dtmf(dtmfe, _mem) self.get_settings_pro_dtmf(dtmfe, _mem) supported.append(dtmfe) # add dtmfe menu if self._has_support_for_banknames: bank = RadioSettingGroup("bank", "Bank names") self.get_settings_common_bank(bank, _mem) supported.append(bank) # add bank menu if supported top = RadioSettings(*tuple(supported)) return top def set_settings(self, settings): _settings = self._memobj.settings for element in settings: if not isinstance(element, RadioSetting): self.set_settings(element) continue else: try: name = element.get_name() if "." in name: bits = name.split(".") obj = self._memobj for bit in bits[:-1]: if "/" in bit: bit, index = bit.split("/", 1) index = int(index) obj = getattr(obj, bit)[index] else: obj = getattr(obj, bit) setting = bits[-1] else: obj = _settings setting = element.get_name() if element.has_apply_callback(): LOG.debug("Using apply callback") element.run_apply_callback() elif element.value.get_mutable(): LOG.debug("Setting %s = %s" % (setting, element.value)) setattr(obj, setting, element.value) except Exception: LOG.debug(element.get_name()) raise def sync_in(self): """Download from radio""" try: data = self.download_function() except errors.RadioError: # Pass through any real errors we raise raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during download') raise errors.RadioError('Unexpected error communicating ' 'with the radio') self._mmap = memmap.MemoryMapBytes(data) self.process_mmap() def sync_out(self): """Upload to radio""" try: self.upload_function() except errors.RadioError: raise except Exception: # If anything unexpected happens, make sure we raise # a RadioError and log the problem LOG.exception('Unexpected error during upload') raise errors.RadioError('Unexpected error communicating ' 'with the radio') def get_features(self): """Get the radio's features""" rf = chirp_common.RadioFeatures() rf.has_settings = True rf.has_bank = False rf.has_tuning_step = False rf.can_odd_split = True rf.has_name = True rf.has_offset = True rf.has_mode = True rf.has_dtcs = True rf.has_rx_dtcs = True rf.has_dtcs_polarity = True rf.has_ctone = True rf.has_cross = True rf.valid_modes = self.MODES rf.valid_characters = self.VALID_CHARS rf.valid_name_length = self.LENGTH_NAME if self._gmrs: rf.valid_duplexes = ["", "+", "off"] else: rf.valid_duplexes = ["", "-", "+", "split", "off"] rf.valid_tmodes = ['', 'Tone', 'TSQL', 'DTCS', 'Cross'] rf.valid_cross_modes = [ "Tone->Tone", "DTCS->", "->DTCS", "Tone->DTCS", "DTCS->Tone", "->Tone", "DTCS->DTCS"] rf.valid_skips = self.SKIP_VALUES rf.valid_dtcs_codes = self.DTCS_CODES rf.memory_bounds = (1, self.CHANNELS) rf.valid_power_levels = self.POWER_LEVELS rf.valid_bands = self.VALID_BANDS rf.valid_tuning_steps = STEPS return rf def decode_tone(self, val): mode = "" pol = "N" if val in [0, 0xFFFF]: xval = 0 elif val >= 0x0258: mode = "Tone" xval = int(val) / 10.0 elif val <= 0x0258: mode = "DTCS" if val > 0x69: index = val - 0x6A pol = "R" else: index = val - 1 xval = self.DTCS_CODES[index] else: LOG.warn("Bug: tone is %04x" % val) return mode, xval, pol def encode_tone(self, memtone, mode, tone, pol): if mode == "Tone": memtone.set_value(int(tone * 10)) elif mode == "TSQL": memtone.set_value(int(tone * 10)) elif mode == "DTCS": if pol == 'R': memtone.set_value(self.DTCS_CODES.index(tone) + 1 + 0x69) else: memtone.set_value(self.DTCS_CODES.index(tone) + 1) else: memtone.set_value(0) def split_txfreq(self, _mem, freq): if self._is_txinh(_mem): # TX freq not set duplex = "off" offset = 0 else: offset = (int(_mem.txfreq) * 10) - freq if offset != 0: if bfc._split(self.get_features(), freq, int( _mem.txfreq) * 10): duplex = "split" offset = int(_mem.txfreq) * 10 elif offset < 0: offset = abs(offset) duplex = "-" elif offset > 0: duplex = "+" else: duplex = "" offset = 0 return offset, duplex def get_memory_common(self, _mem, name, mem): if _mem.get_raw()[0] == 255: mem.empty = True return mem mem.freq = int(_mem.rxfreq) * 10 # TX freq set mem.offset, mem.duplex = self.split_txfreq(_mem, mem.freq) txtone = self.decode_tone(_mem.txtone) rxtone = self.decode_tone(_mem.rxtone) chirp_common.split_tone_decode(mem, txtone, rxtone) if not _mem.scan: mem.skip = "S" levels = self.POWER_LEVELS try: mem.power = levels[_mem.lowpower] except IndexError: mem.power = levels[0] mem.mode = _mem.wide and self.MODES[0] or self.MODES[1] if (mem.freq >= self._airband[0] and mem.freq <= self._airband[1]): # NOTE: AM is not in valid_modes because you can't arbitrarily # enable it on this radio. However, we can expose it as immutable # which will display properly in the UI and not allow the user # to change those channels to FM. mem.mode = "AM" mem.immutable = ['mode'] mem.extra = RadioSettingGroup("Extra", "extra") rs = RadioSetting("bcl", "BCL", RadioSettingValueBoolean(_mem.bcl)) mem.extra.append(rs) rs = RadioSetting("pttid", "PTT ID", RadioSettingValueList(self.PTTID_LIST, self.PTTID_LIST[ _mem.pttid])) mem.extra.append(rs) scode = (_mem.scode - self._scode_offset) % len(self.SCODE_LIST) rs = RadioSetting("scode", "S-CODE", RadioSettingValueList(self.SCODE_LIST, self.SCODE_LIST[ scode])) mem.extra.append(rs) mem.name = str(name).replace('\xFF', ' ').replace('\x00', ' ').rstrip() def get_raw_memory(self, number): return self._memobj.memory[number - 1] def get_memory(self, number): _mem = self.get_raw_memory(number) mem = chirp_common.Memory() mem.number = number self.get_memory_common(_mem, _mem.name, mem) return mem def unsplit_txfreq(self, mem): _mem = self.get_raw_memory(mem.number) if mem.duplex == "off": for i in range(0, 4): _mem.txfreq[i].set_raw(b"\xFF") elif mem.duplex == "split": _mem.txfreq = mem.offset / 10 elif mem.duplex == "+": _mem.txfreq = (mem.freq + mem.offset) / 10 elif mem.duplex == "-": _mem.txfreq = (mem.freq - mem.offset) / 10 else: _mem.txfreq = mem.freq / 10 def set_memory_common(self, mem, _mem): _mem.rxfreq = mem.freq / 10 self.unsplit_txfreq(mem) ((txmode, txtone, txpol), (rxmode, rxtone, rxpol)) = \ chirp_common.split_tone_encode(mem) self.encode_tone(_mem.txtone, txmode, txtone, txpol) self.encode_tone(_mem.rxtone, rxmode, rxtone, rxpol) _mem.scan = mem.skip != "S" _mem.wide = mem.mode == self.MODES[0] if mem.power: _mem.lowpower = self.POWER_LEVELS.index(mem.power) else: _mem.lowpower = 0 # extra settings if len(mem.extra) > 0: # there are setting, parse for setting in mem.extra: if setting.get_name() == "scode": setattr(_mem, setting.get_name(), str(int(setting.value) + self._scode_offset)) else: setattr(_mem, setting.get_name(), setting.value) else: # there are no extra settings, load defaults _mem.bcl = 0 _mem.pttid = 0 _mem.scode = self._scode_offset def set_memory(self, mem): _mem = self.get_raw_memory(mem.number) _mem.set_raw(b"\x00"*16 + b"\xff" * 16) if mem.empty: _mem.set_raw(b"\xff" * 32) return _namelength = self.get_features().valid_name_length _mem.name = mem.name.ljust(_namelength, '\xFF') self.set_memory_common(mem, _mem) @directory.register class UV17ProGPS(UV17Pro): VENDOR = "Baofeng" MODEL = "UV-17ProGPS" _has_support_for_banknames = True _has_workmode_support = True _magic = MSTRING_UV17PROGPS _magics = [(b"\x46", 16), (b"\x4d", 7), (b"\x53\x45\x4E\x44\x21\x05\x0D\x01\x01" + b"\x01\x04\x11\x08\x05\x0D\x0D\x01\x11\x0F\x09\x12\x09" + b"\x10\x04\x00", 1)] _has_when_to_send_aniid = False _vfoscan = True _has_gps = True _has_voxsw = True _has_pilot_tone = True _has_send_id_delay = True _has_skey2_short = True VALID_BANDS = [UV17Pro._airband, UV17Pro._vhf_range, UV17Pro._vhf2_range, UV17Pro._uhf_range, UV17Pro._uhf2_range] def check_set_memory_immutable_policy(self, existing, new): if (self._airband[0] <= new.freq <= self._airband[1] and new.mode == 'AM'): # This is valid, so mark mode as immutable so it doesn't get # blocked, and let the radio override it during set. new.immutable.append('mode') existing.immutable = [] elif existing.mode == 'AM' and new.mode in self.MODES: # If we're going from a forced-AM channel to some valid one, # clear immutable so we allow the change. try: existing.immutable.remove('mode') except ValueError: pass super().check_set_memory_immutable_policy(existing, new) @directory.register class BF5RM(UV17Pro): VENDOR = "Baofeng" MODEL = "5RM" VALID_BANDS = [UV17Pro._airband, UV17Pro._vhf_range, UV17Pro._vhf2_range, UV17Pro._uhf_range, UV17Pro._uhf2_range] POWER_LEVELS = [chirp_common.PowerLevel("High", watts=8.00), chirp_common.PowerLevel("Low", watts=1.00), chirp_common.PowerLevel("Medium", watts=5.00)] SCODE_LIST = ["%s" % x for x in range(1, 16)] LIST_PW_SAVEMODE = ["Off", "1:1", "1:2", "1:4"] _has_workmode_support = True def check_set_memory_immutable_policy(self, existing, new): if (self._airband[0] <= new.freq <= self._airband[1] and new.mode == 'AM'): # This is valid, so mark mode as immutable so it doesn't get # blocked, and let the radio override it during set. new.immutable.append('mode') existing.immutable = [] elif existing.mode == 'AM' and new.mode in self.MODES: # If we're going from a forced-AM channel to some valid one, # clear immutable so we allow the change. try: existing.immutable.remove('mode') except ValueError: pass super().check_set_memory_immutable_policy(existing, new) chirp-20240224/chirp/util.py0000644000175000017500000001004014411666130014465 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import struct import sys def byte_to_int(b): """This does what is needed to convert a bytes()[i] to an int""" if sys.version_info.major == 3 and isinstance(b, int): return b else: return ord(b) def int_to_byte(i): """This does what is needed to convert an int to a bytes""" if sys.version_info.major == 3 and isinstance(i, int): return bytes([i]) elif isinstance(i, int): return chr(i) else: return i def hexprint(data, addrfmt=None): """Return a hexdump-like encoding of @data""" if addrfmt is None: addrfmt = '%(addr)03i' block_size = 8 out = "" blocks = len(data) // block_size if len(data) % block_size: blocks += 1 for block in range(0, blocks): addr = block * block_size try: out += addrfmt % locals() except (OverflowError, ValueError, TypeError, KeyError): out += "%03i" % addr out += ': ' for j in range(0, block_size): try: out += "%02x " % byte_to_int(data[(block * block_size) + j]) except IndexError: out += " " out += " " for j in range(0, block_size): try: char = byte_to_int(data[(block * block_size) + j]) except IndexError: char = ord('.') if char > 0x20 and char < 0x7E: out += "%s" % chr(char) else: out += "." out += "\n" return out def bcd_encode(val, bigendian=True, width=None): """This is really old and shouldn't be used anymore""" digits = [] while val != 0: digits.append(val % 10) val /= 10 result = "" if len(digits) % 2 != 0: digits.append(0) while width and width > len(digits): digits.append(0) for i in range(0, len(digits), 2): newval = struct.pack("B", (digits[i + 1] << 4) | digits[i]) if bigendian: result = newval + result else: result = result + newval return result def get_dict_rev(thedict, value): """Return the first matching key for a given @value in @dict""" _dict = {} for k, v in thedict.items(): _dict[v] = k return _dict[value] def safe_charset_string(indexes, charset, safechar=" "): """Return a string from an array of charset indexes, replaces out of charset values with safechar""" assert safechar in charset _string = "" for i in indexes: try: _string += charset[i] except IndexError: _string += safechar return _string class StringStruct(object): """String-compatible struct module.""" @staticmethod def pack(*args): from chirp import bitwise fmt = args[0] # Encode any string arguments to bytes newargs = (bitwise.string_straight_encode(x) if isinstance(x, str) else x for x in args[1:]) return bitwise.string_straight_decode(struct.pack(fmt, *newargs)) @staticmethod def unpack(fmt, data): from chirp import bitwise result = struct.unpack(fmt, bitwise.string_straight_encode(data)) # Decode any string results return tuple(bitwise.string_straight_decode(x) if isinstance(x, bytes) else x for x in result) chirp-20240224/chirp/bitwise.py0000644000175000017500000010146414566340166015202 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # Language: # # Example definitions: # # bit foo[8]; /* Eight single bit values */ # u8 foo; /* Unsigned 8-bit value */ # u16 foo; /* Unsigned 16-bit value */ # ul16 foo; /* Unsigned 16-bit value (LE) */ # u24 foo; /* Unsigned 24-bit value */ # ul24 foo; /* Unsigned 24-bit value (LE) */ # u32 foo; /* Unsigned 32-bit value */ # ul32 foo; /* Unsigned 32-bit value (LE) */ # i8 foo; /* Signed 8-bit value */ # i16 foo; /* Signed 16-bit value */ # il16 foo; /* Signed 16-bit value (LE) */ # i24 foo; /* Signed 24-bit value */ # il24 foo; /* Signed 24-bit value (LE) */ # i32 foo; /* Signed 32-bit value */ # il32 foo; /* Signed 32-bit value (LE) */ # char foo; /* Character (single-byte */ # lbcd foo; /* BCD-encoded byte (LE) */ # bbcd foo; /* BCD-encoded byte (BE) */ # char foo[8]; /* 8-char array */ # struct { # u8 foo; # u16 bar; # } baz; /* Structure with u8 and u16 */ # # Example directives: # # #seekto 0x1AB; /* Set the data offset to 0x1AB */ # #seek 4; /* Set the data offset += 4 */ # #printoffset "foobar" /* Echo the live data offset, # prefixed by string while parsing */ # # Usage: # # Create a data definition in a string, and pass it and the data # to parse to the parse() function. The result is a structure with # dict-like objects for structures, indexed by name, and lists of # objects for arrays. The actual data elements can be interpreted # as integers directly (for int types). Strings and BCD arrays # behave as expected. import struct import os import logging import re import warnings import six from builtins import bytes from chirp import bitwise_grammar LOG = logging.getLogger(__name__) class ParseError(Exception): """Indicates an error parsing a definition""" pass def byte_to_int(b): if six.PY3 or isinstance(b, int): return b else: return ord(b) def int_to_byte(i): if six.PY3: return bytes([i]) else: return chr(i) def string_straight_encode(string): """str -> bytes""" # So, there are a lot of py2-thinking chirp drivers that # will do something like this: # # memobj.name = 'foo\xff' # # because they need the string to be stored in radio memory # with a 0xFF byte terminating the string. If they do that in # py3 we will get the unicode equivalent, which is a non-ASCII # character. Conventional unicode wisdom would tell us we need # to encode() the string to get UTF-8 bytes, but that's not # what we want here (the radio doesn't support UTF-8 and we need # specific binary values in memory). Ideally we would have # written all of chirp with bytes() for these values, but alas. # We can get the intended string here by doing bytes([ord(char)]). return bytes(b''.join(int_to_byte(ord(b)) for b in string)) def string_straight_decode(string): """bytes -> str""" # Normally, we would want to decode bytes() to str() for py3. # However...chirp drivers are currently using strings with # hex escapes for setting binary byte values in memories. # Technically, this is char, which is a little more like bytes() # in py3, but until every driver has converted its strings to # bytes(), this is massively simpler. Since set_value() is # doing the inverse, we can do this here. If something sets # a char to '\xFF' it will arrive below as the unicode character, # and be converted to the integer/bytes value. When it is read out # here, we will return that same unicode character and the driver # will detect '\xFF' properly. # FIXMEPY3: Remove this and the hack below when drivers convert to # bytestrings. return ''.join(chr(byte_to_int(b)) for b in string) def format_binary(nbits, value, pad=8): s = "" for i in range(0, nbits): s = "%i%s" % (value & 0x01, s) value >>= 1 return "%s%s" % ((pad - len(s)) * ".", s) def bits_between(start, end): bits = (1 << (int(end) - int(start))) - 1 return bits << int(start) def pp(structure, level=0): for i in structure: if isinstance(i, list): pp(i, level+2) elif isinstance(i, tuple): if isinstance(i[1], str): print("%s%s: %s" % (" " * level, i[0], i[1])) else: print("%s%s:" % (" " * level, i[0])) pp(i, level+2) elif isinstance(i, str): print("%s%s" % (" " * level, i)) def array_copy(dst, src): """Copy an array src into DataElement array dst""" if len(dst) != len(src): raise Exception("Arrays differ in size") for i in range(0, len(dst)): dst[i].set_value(src[i]) def bcd_to_int(bcd_array): """Convert an array of bcdDataElement like \x12\x34 into an int like 1234""" value = 0 for bcd in bcd_array: a, b = bcd.get_value() value = (value * 100) + (a * 10) + b return value def int_to_bcd(bcd_array, value): """Convert an int like 1234 into bcdDataElements like "\x12\x34" """ for i in reversed(range(0, len(bcd_array))): bcd_array[i].set_value(value % 100) value /= 100 def get_string(char_array): """Convert an array of charDataElements into a string""" return "".join([x.get_value() for x in char_array]) def set_string(char_array, string): """Set an array of charDataElements from a string""" array_copy(char_array, list(string)) class DataElement: _size = 1 def __init__(self, data, offset, count=1): self._data = data self._offset = int(offset) self._count = count def _compat_bytes(self, bs, asbytes): if asbytes: return bytes(bs) else: warnings.warn('Driver is using non-byte-native get_raw()', DeprecationWarning, stacklevel=3) return string_straight_decode(bs) def size(self): return int(self._size * 8) def get_offset(self): return int(self._offset) def _get_value(self, data): raise Exception("Not implemented") def get_value(self): value = self._data[self._offset:self._offset + self._size] return self._get_value(value) def set_value(self, value): raise Exception("Not implemented for %s" % self.__class__) def get_raw(self, asbytes=True): raw = self._data[self._offset:self._offset+self._size] return self._compat_bytes(raw, asbytes) def set_raw(self, data): if isinstance(data, str): warnings.warn('Driver is using non-byte-native set_raw()', DeprecationWarning, stacklevel=2) data = string_straight_encode(data) self._data[self._offset] = data[:self._size] def get_path(self, path): """Retrieve a child element starting from here by symbolic path. Examples: .mystruct.foo[2].field1 [3] .bar """ tok = re.search('[.[]', path) if tok: tok = tok.group(0) if path.startswith('.'): return self.get_path(path[1:]) elif path.startswith('['): index, rest = path.split(']', 1) index = int(index[1:]) return self[index].get_path(rest) elif tok == '.': field, rest = path.split('.', 1) return getattr(self, field).get_path(rest) elif tok == '[': field, rest = path.split('[', 1) return getattr(self, field).get_path('[' + rest) elif path: return getattr(self, path) else: return self def fill_raw(self, byteval): """Fill object with bytes :param byteval: A bytes of length 1 to fill the object's memory with """ assert isinstance(byteval, bytes) and len(byteval) == 1 self.set_raw(byteval * (self.size() // 8)) def __getattr__(self, name): raise AttributeError("Unknown attribute %s in %s" % (name, self.__class__)) def __repr__(self): return "(%s:%i bytes @ %04x)" % (self.__class__.__name__, self._size, self._offset) class arrayDataElement(DataElement): def __repr__(self): if isinstance(self.__items[0], bcdDataElement): return "%i:[(%i)]" % (len(self.__items), int(self)) if isinstance(self.__items[0], charDataElement): return "%i:[(%s)]" % (len(self.__items), repr(str(self))[1:-1]) s = "%i:[" % len(self.__items) s += ",".join([repr(item) for item in self.__items]) s += "]" return s def __init__(self, offset): self.__items = [] self._offset = offset def append(self, item): self.__items.append(item) def get_value(self): return list(self.__items) def get_raw(self, asbytes=True): raw = [item.get_raw(asbytes=True) for item in self.__items] return self._compat_bytes(bytes(b''.join(raw)), asbytes) def set_raw(self, data): item_size = self.__items[0].size() // 8 assert len(data) / item_size == len(self), 'Invalid raw data length' for i in range(len(self)): self[i].set_raw(data[i * item_size:(i + 1) * item_size]) def __setitem__(self, index, val): self.__items[index].set_value(val) def __getitem__(self, index): if isinstance(index, slice): return self.__items[int(index.start):int(index.stop)] else: return self.__items[int(index)] def __len__(self): return len(self.__items) def __str__(self): if isinstance(self.__items[0], charDataElement): # NOTE: All the values should be strings coming out of py3. # and on py2 they could be a mix of unicode and str, the latter # for non-ASCII values. On py2 we can just coerce all of these # types to a string for compatibility. return "".join([str(x.get_value()) for x in self.__items]) else: return str(self.__items) def __int__(self): if isinstance(self.__items[0], bcdDataElement): val = 0 if isinstance(self.__items[0], bbcdDataElement): items = self.__items else: items = reversed(self.__items) for i in items: tens, ones = i.get_value() val = (val * 100) + (tens * 10) + ones return val else: raise ValueError("Cannot coerce this to int") def __set_value_bbcd(self, value): for i in reversed(self.__items): twodigits = value % 100 value /= 100 i.set_value(twodigits) def __set_value_lbcd(self, value): for i in self.__items: twodigits = value % 100 value /= 100 i.set_value(twodigits) def __set_value_char(self, value): if len(value) != len(self.__items): raise ValueError("String expects exactly %i characters, not %i" % ( len(self.__items), len(value))) for i in range(0, len(self.__items)): self.__items[i].set_value(value[i]) def set_value(self, value): if isinstance(self.__items[0], bbcdDataElement): self.__set_value_bbcd(int(value)) elif isinstance(self.__items[0], lbcdDataElement): self.__set_value_lbcd(int(value)) elif isinstance(self.__items[0], charDataElement): self.__set_value_char(value) elif len(value) != len(self.__items): raise ValueError("Array cardinality mismatch") else: for i in range(0, len(value)): self.__items[i].set_value(value[i]) def index(self, value): index = 0 for i in self.__items: if i.get_value() == value: return index index += 1 raise IndexError() def __iter__(self): return iter(self.__items) def items(self): index = 0 for item in self.__items: yield (str(index), item) index += 1 def size(self): size = 0 for i in self.__items: size += i.size() return int(size) class intDataElement(DataElement): def __repr__(self): fmt = "0x%%0%iX" % (self._size * 2) return fmt % int(self) def __int__(self): return self.get_value() def __nonzero__(self): return int(self) != 0 def __invert__(self): return ~self.get_value() def __trunc__(self): return self.get_value() def __abs__(self): return abs(self.get_value()) def __mod__(self, val): return self.get_value() % val def __mul__(self, val): return self.get_value() * val def __truediv__(self, val): return self.get_value() / val def __div__(self, val): return self.get_value() / val def __floordiv__(self, val): return self.get_value() // val def __add__(self, val): return self.get_value() + val def __sub__(self, val): return self.get_value() - val def __or__(self, val): return self.get_value() | val def __xor__(self, val): return self.get_value() ^ val def __and__(self, val): return self.get_value() & val def __radd__(self, val): return val + self.get_value() def __rsub__(self, val): return val - self.get_value() def __rmul__(self, val): return val * self.get_value() def __rdiv__(self, val): return val / self.get_value() def __rand__(self, val): return val & self.get_value() def __ror__(self, val): return val | self.get_value() def __rxor__(self, val): return val ^ self.get_value() def __rmod__(self, val): return val % self.get_value() def __lshift__(self, val): return self.get_value() << val def __rshift__(self, val): return self.get_value() >> val def __iadd__(self, val): self.set_value(self.get_value() + val) return self def __isub__(self, val): self.set_value(self.get_value() - val) return self def __imul__(self, val): self.set_value(self.get_value() * val) return self def __idiv__(self, val): self.set_value(self.get_value() / val) return self def __imod__(self, val): self.set_value(self.get_value() % val) return self def __iand__(self, val): self.set_value(self.get_value() & val) return self def __ior__(self, val): self.set_value(self.get_value() | val) return self def __ixor__(self, val): self.set_value(self.get_value() ^ val) return self def __index__(self): return abs(self) def __eq__(self, val): return self.get_value() == val def __ne__(self, val): return self.get_value() != val def __lt__(self, val): return self.get_value() < val def __le__(self, val): return self.get_value() <= val def __gt__(self, val): return self.get_value() > val def __ge__(self, val): return self.get_value() >= val def __bool__(self): return self.get_value() != 0 class u8DataElement(intDataElement): _size = 1 def _get_value(self, data): return ord(data) def set_value(self, value): self._data[self._offset] = (int(value) & 0xFF) class u16DataElement(intDataElement): _size = 2 _endianess = ">" def _get_value(self, data): return struct.unpack(self._endianess + "H", data)[0] def set_value(self, value): self._data[self._offset] = struct.pack(self._endianess + "H", int(value) & 0xFFFF) class ul16DataElement(u16DataElement): _endianess = "<" class u24DataElement(intDataElement): _size = 3 _endianess = ">" def _get_value(self, data): pre = self._endianess == ">" and b"\x00" or b"" post = self._endianess == "<" and b"\x00" or b"" return struct.unpack(self._endianess + "I", pre+data+post)[0] def set_value(self, value): if self._endianess == "<": start = 0 end = 3 else: start = 1 end = 4 packed = struct.pack(self._endianess + "I", int(value) & 0xFFFFFFFF) self._data[self._offset] = packed[start:end] class ul24DataElement(u24DataElement): _endianess = "<" class u32DataElement(intDataElement): _size = 4 _endianess = ">" def _get_value(self, data): return struct.unpack(self._endianess + "I", data)[0] def set_value(self, value): self._data[self._offset] = struct.pack(self._endianess + "I", int(value) & 0xFFFFFFFF) class ul32DataElement(u32DataElement): _endianess = "<" class i8DataElement(u8DataElement): _size = 1 def _get_value(self, data): return struct.unpack("b", data)[0] def set_value(self, value): self._data[self._offset] = struct.pack("b", int(value)) class i16DataElement(intDataElement): _size = 2 _endianess = ">" def _get_value(self, data): return struct.unpack(self._endianess + "h", data)[0] def set_value(self, value): self._data[self._offset] = struct.pack(self._endianess + "h", int(value)) class il16DataElement(i16DataElement): _endianess = "<" class i24DataElement(intDataElement): _size = 3 _endianess = ">" def _get_value(self, data): pre = self._endianess == ">" and "\x00" or "" post = self._endianess == "<" and "\x00" or "" return struct.unpack(self._endianess + "i", pre+data+post)[0] def set_value(self, value): if self._endianess == "<": start = 0 end = 3 else: start = 1 end = 4 self._data[self._offset] = struct.pack(self._endianess + "i", int(value))[start:end] class il24DataElement(i24DataElement): _endianess = "<" class i32DataElement(intDataElement): _size = 4 _endianess = ">" def _get_value(self, data): return struct.unpack(self._endianess + "i", data)[0] def set_value(self, value): self._data[self._offset] = struct.pack(self._endianess + "i", int(value)) class il32DataElement(i32DataElement): _endianess = "<" class charDataElement(DataElement): _size = 1 def __str__(self): return str(self.get_value()) def __int__(self): return ord(self.get_value()) def _get_value(self, data): return string_straight_decode(data) def set_value(self, value): if isinstance(value, int): # This is the case if bytes() are passed in to arrayDataElement # to set a string self._data[self._offset] = value else: self._data[self._offset] = string_straight_encode(value) class bcdDataElement(DataElement): def __int__(self): tens, ones = self.get_value() return (tens * 10) + ones def set_bits(self, mask): self._data[self._offset] = ord(self._data[self._offset]) | int(mask) def clr_bits(self, mask): self._data[self._offset] = ord(self._data[self._offset]) & ~int(mask) def get_bits(self, mask): return ord(self._data[self._offset]) & int(mask) def set_raw(self, data): if isinstance(data, int): self._data[self._offset] = data & 0xFF elif isinstance(data, str): warnings.warn('Driver is using non-byte-native set_raw()', DeprecationWarning, stacklevel=2) self._data[self._offset] = string_straight_encode(data[0]) elif isinstance(data, bytes) and len(data) == 1: self._data[self._offset] = int(data[0]) & 0xFF else: raise TypeError("Unable to set bcdDataElement from type %s" % type(data)) def set_value(self, value): self._data[self._offset] = int("%02i" % value, 16) def _get_value(self, data): a = (ord(data) & 0xF0) >> 4 b = ord(data) & 0x0F return (a, b) class lbcdDataElement(bcdDataElement): _size = 1 class bbcdDataElement(bcdDataElement): _size = 1 class bitDataElement(intDataElement): _nbits = 0 _shift = 0 _subgen = u8DataElement # Default to a byte def __repr__(self): fmt = "0x%%0%iX (%%sb)" % (self._size * 2) return fmt % (int(self), format_binary(self._nbits, self.get_value())) def get_value(self): data = self._subgen(self._data, self._offset).get_value() mask = bits_between(self._shift-self._nbits, self._shift) val = (data & mask) >> int(self._shift - self._nbits) return val def set_value(self, value): mask = bits_between(self._shift-self._nbits, self._shift) data = self._subgen(self._data, self._offset).get_value() data &= ~mask value = ((int(value) << int(self._shift-self._nbits)) & mask) | data self._subgen(self._data, self._offset).set_value(value) def size(self): return int(self._nbits) class structDataElement(DataElement): def __repr__(self): s = "struct {" + os.linesep for prop in self._keys: s += " %15s: %s%s" % (prop, repr(self._generators[prop]), os.linesep) s += "} %s (%i bytes at 0x%04X)%s" % (self._name, self.size() // 8, self._offset, os.linesep) return s def __init__(self, *args, **kwargs): self._generators = {} self._keys = [] self._count = 1 if "name" in kwargs.keys(): self._name = kwargs["name"] del kwargs["name"] else: self._name = "(anonymous)" DataElement.__init__(self, *args, **kwargs) self.__init = True def _value(self, data, generators): result = {} for name, gen in generators.items(): result[name] = gen.get_value(data) return result def get_value(self): result = [] for i in range(0, self._count): result.append(self._value(self._data, self._generators[i])) if self._count == 1: return result[0] else: return result def __contains__(self, key): return key in self._generators.keys() def __getitem__(self, key): return self._generators[key] def __setitem__(self, key, value): if key in self._generators: self._generators[key].set_value(value) else: self._generators[key] = value self._keys.append(key) def __getattr__(self, name): try: return self._generators[name] except KeyError: LOG.error('Request for struct element %s not in %s' % ( name, self._generators.keys())) raise AttributeError("No attribute %s in struct %s" % ( name, self._name)) def __setattr__(self, name, value): if "_structDataElement__init" not in self.__dict__: self.__dict__[name] = value else: self.__dict__["_generators"][name].set_value(value) def size(self): size = 0 for name, gen in self._generators.items(): if not isinstance(gen, list): gen = [gen] i = 0 for el in gen: i += 1 size += el.size() return int(size) def get_raw(self, asbytes=True): size = self.size() // 8 raw = self._data[self._offset:self._offset+size] return self._compat_bytes(raw, asbytes) def set_raw(self, buffer): if len(buffer) != (self.size() // 8): raise ValueError("Struct size mismatch during set_raw()") if isinstance(buffer, str): warnings.warn('Driver is using non-byte-native set_raw()', DeprecationWarning, stacklevel=2) buffer = string_straight_encode(buffer) self._data[self._offset] = buffer def __iter__(self): for item in self._generators.values(): yield item def items(self): for key in self._keys: yield key, self._generators[key] class Processor: _types = { "u8": u8DataElement, "u16": u16DataElement, "ul16": ul16DataElement, "u24": u24DataElement, "ul24": ul24DataElement, "u32": u32DataElement, "ul32": ul32DataElement, "i8": i8DataElement, "i16": i16DataElement, "il16": il16DataElement, "i24": i24DataElement, "il24": il24DataElement, "i32": i32DataElement, "char": charDataElement, "lbcd": lbcdDataElement, "bbcd": bbcdDataElement, } def __init__(self, data, offset, input): if hasattr(data, 'get_byte_compatible'): # bitwise uses the byte-compatible interface of MemoryMap, # if that is what was passed in data = data.get_byte_compatible() self._data = data self._offset = offset self._obj = None self._user_types = {} self._input = input.split('\n') def do_symbol(self, symdef, gen): name = symdef[1] self._generators[name] = gen def get_source_line(self, lineno): return self._input[lineno] def get_line_from_sym(self, sym): name = sym.__name__ if ':' in name.line: _, num = name.line.split(':') else: num = 0 return int(num) def get_line_sym(self, sym): num = self.get_line_from_sym(sym) return '%i: %s' % (num, self.get_source_line(num)) def do_bitfield(self, dtype, bitfield): bytes = self._types[dtype](self._data, 0).size() // 8 bitsleft = bytes * 8 for _bitdef, defn in bitfield: name = defn[0][1] if name in self._generators: newname = '%s_%06x' % (name, self._offset) prevline = self._lines.get(name, 'unknown') LOG.error('Duplicate definition for %s on line %s; ' 'renaming to %s (previous definition line %s)', name, self.get_line_sym(defn[0]), newname, prevline) name = newname bits = int(defn[1][1]) if bitsleft < 0: raise ParseError("Invalid bitfield spec") class bitDE(bitDataElement): _nbits = bits _shift = bitsleft _subgen = self._types[dtype] self._generators[name] = bitDE(self._data, self._offset) self._lines[name] = self.get_line_from_sym(defn[0]) bitsleft -= bits if bitsleft: LOG.warn("WARNING: %i trailing bits unaccounted for in %s" % (bitsleft, name)) return bytes def do_bitarray(self, i, count): if count % 8 != 0: raise ValueError("bit array must be divisible by 8.") class bitDE(bitDataElement): _nbits = 1 _shift = 8 - i % 8 return bitDE(self._data, self._offset) def parse_defn(self, defn): dtype = defn[0] if defn[1][0] == "bitfield": size = self.do_bitfield(dtype, defn[1][1]) count = 1 self._offset += size else: if defn[1][0] == "array": sym = defn[1][1][0] count = int(defn[1][1][1][1]) else: count = 1 sym = defn[1] name = sym[1] if name in self._generators: newname = '%s_%06x' % (name, self._offset) prevline = self._lines.get(name, 'unknown') LOG.error('Duplicate definition for %s on line %s; ' 'renaming to %s (previous definition line %s)', name, self.get_line_sym(sym), newname, prevline) name = newname res = arrayDataElement(self._offset) size = 0 for i in range(0, count): if dtype == "bit": gen = self.do_bitarray(i, count) self._offset += int((i+1) % 8 == 0) else: gen = self._types[dtype](self._data, self._offset) self._offset += (gen.size() // 8) res.append(gen) if count == 1: self._generators[name] = res[0] else: self._generators[name] = res self._lines[name] = self.get_line_from_sym(sym) def parse_struct_decl(self, struct): block = struct[:-1] if block[0][0] == "symbol": # This is a pre-defined struct block = self._user_types[block[0][1]] deftype = struct[-1] if deftype[0] == "array": name = deftype[1][0][1] count = int(deftype[1][1][1]) elif deftype[0] == "symbol": name = deftype[1] count = 1 result = arrayDataElement(self._offset) for i in range(0, count): element = structDataElement(self._data, self._offset, count, name=name) result.append(element) tmp = self._generators tmp_lines = self._lines self._generators = element self._lines = {} self.parse_block(block) self._generators = tmp self._lines = tmp_lines if count == 1: self._generators[name] = result[0] else: self._generators[name] = result def parse_struct_defn(self, struct): name = struct[0][1] block = struct[1:] self._user_types[name] = block def parse_struct(self, struct): if struct[0][0] == "struct_defn": return self.parse_struct_defn(struct[0][1]) elif struct[0][0] == "struct_decl": return self.parse_struct_decl(struct[0][1]) else: raise Exception("Internal error: What is `%s'?" % struct[0][0]) def assert_negative_seek(self, message): warnings.warn(message, DeprecationWarning, stacklevel=6) def assert_unnecessary_seek(self, message): warnings.warn(message, DeprecationWarning, stacklevel=6) def parse_directive(self, directive): name = directive[0][0] value = directive[0][1][0][1] if name == "seekto": target = int(value, 0) if self._offset == target: self.assert_unnecessary_seek('Unnecessary #seekto %s' % value) elif target < self._offset: self.assert_negative_seek( 'Invalid negative seek from 0x%04x to 0x%04x' % ( self._offset, target)) self._offset = target elif name == "seek": self._offset += int(value, 0) elif name == "printoffset": LOG.debug("%s: %i (0x%08X)" % (value[1:-1], self._offset, self._offset)) def parse_block(self, lang): for t, d in lang: if t == "struct": self.parse_struct(d) elif t == "definition": self.parse_defn(d) elif t == "directive": self.parse_directive(d) def parse(self, lang): self._lines = {} self._generators = structDataElement(self._data, self._offset) self.parse_block(lang) return self._generators def parse(spec, data, offset=0): ast = bitwise_grammar.parse(spec) p = Processor(data, offset, spec) return p.parse(ast) chirp-20240224/chirp/share/0000755000175000017500000000000014566340177014260 5ustar hibbyhibbychirp-20240224/chirp/share/chirp.svg0000644000175000017500000003333214533322706016102 0ustar hibbyhibby image/svg+xml c h i r p chirp-20240224/chirp/share/chirp-logo.png0000644000175000017500000160212714562640504017033 0ustar hibbyhibby‰PNG  IHDRиQaz pHYsТТnаu>tEXtSoftwarewww.inkscape.org›ю< IDATxа„/{џџџ3\."ў§њыо‟џџЯџџџwX$њмЇŠџџџњџџџH„1  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєєєљљљђђђяяя§§§ўЮ{џџџКџџџYŠ(((444444%%%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ)O>0 IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџзззОООМММвввюююџџџуsџџџЋџџџ3Џ'''KKKHHHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџлллЙЙЙяяятPџџџЯџџџЋM===bbb,,,џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЊЊЊ†††пппџБWџџџњџџџ1О777qqq$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЖЖЖtttхххяBџџџаyЬ‡‡‡•••$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?ƒФ IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџKKKжжжsssЭtџџџ˜g>>>€€€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџчччMMMкккЁџџџ`ЕgtttџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЪЪЪXXX_ВЖJXXXџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ™™™MГœI–––;;;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџfИ! IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџppp™™™L˜yc...џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџWWW”””gs,„‰‰‰...џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџZZZ‚‚‚Š1Уqqq;;;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџnnnUUUНЌAAAVVVџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџop z IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ›››!!!Ја„/{3L}}}џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџГГГP0ЏrrrџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkkkЏU777DDDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ TŽqqqџџџџџџџџџџџџџџџ ‰›Ы IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŽŽŽH===$$$џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџLLLF…bbbџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ{{{„0''',,,џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџYYY2xKKKј$1К IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџEEEqWHHHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџuuu]#)))џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ+++%5444џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџM‡ IDATџџџ,,,3[333џџџџџџџџџџџџџџџџџџџџџџџџџџџђђђчччїїїїїїѓѓѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџHHHУУУ[/'''џџџџџџџџџџџџџџџџџџџџџџџџђђђЭЭЭЪЪЪкккпппэээ%%%333===,,,џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBBB.р СССџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёёЗЗЗЗЗЗдддўўўDDDUUU>>>џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўў§§§пє ***ЂЂЂџџџџџџџџџџџџџџџџџџџџџџџџџџџгггЁЁЁСССћћћ іііљљљљљљђђђшшшщщщфффьььYYYeeeџџџџџџџџџџџџџџџџџџџџџџџџџъЁЃ IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяѕћ>>>ŽŽŽџџџџџџџџџџџџџџџџџџџџџџџџЮЮЮ›››ЧЧЧ333)))###юююииижжжаааћћћ ___jjjџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ,,,сссћа„/{§HHH„„„џџџџџџџџџџџџџџџџџџџџџџџџэээЗЗЗ666:::$$$їїїЭЭЭУУУррр{{{\\\џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ333йййў џџџџџџџџџџџџџџџџџџ­­­‘‘‘ѓѓѓ===FFF <<<<<<зззЕЕЕлллёёёvvvЉЉЉ%%%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ џџџџџџџџџџџџџџџџџџџџџііі‚‚‚ЙЙЙ222WWWаўIж IDAT))))))вввЈЈЈэээЭЭЭGGGŠŠŠUUUџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџпппqqqссс\\\,,,...(((ГГГЛЛЛіііlllЪЪЪ………џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџзззcccссс(((zzz,,,SSSqqqЂЂЂaaaјјјџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЩЩЩeeeяяяMMMppp'''{{{ МММWWWѓѓѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжжжqqqіііZZZ===єєєщщщьььњњњіііЅBЄ IDAT rrr™™™еееШШШ^^^ЉЉЉџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџсссkkkіііccc444ћћћааадддкккююю '''111jjj›››аааЧЧЧkkkšššџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€---999џџџџџџѓѓѓcccъъъ[[[999ъъъЏЏЏ   ЪЪЪфффїїїџџџяяямммУУУЭЭЭ111мммэээкккљљљ@@@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЃЃЃуууџџџџџџџџџџџџџџџ‚‚‚фффMMM===ёёёЎЎЎЪЪЪўўў ),)*  ћііјђёѓцхяпоъждяпнџџџчччЇЇЇЕЕЕMMM===iii‹‹‹ццц•••<<<AAAџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ­­­МММ,,,KKKТТТЎЎЎїїї25"BE13ЂA Љ IDAT #% =@їюэрФСмЛИєщшђђђЅЅЅХХХ``` jjj„„„јјјkkkОООџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ€---999џџџџџџџџџщщщpppќќќoooјјјŸŸŸЙЙЙќќќ7:;qw'JM ')&HKюонћіѕ№№№ЧЧЧ ЮЮЮїїїуууPPPџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЃЃЃуууџџџџџџџџџїїїaaa ѓѓѓЬЬЬ @z€A(MQ џџџрТПкИДюонџџ01*QU$&іьь юююџџџџџџџџџџџџџџџџџџџџџџџџџџџDDDЫЫЫ‘‘‘–––№№№ ```yyyџџџџџџџџџџџџџџџeee џџџ```lllџџџџџџџџџџџџџџџџџџџџџџџџ ѕѕѕ№№№џџџїяюѓчхТŠ…ђхфћїїсФСтЧФ-VZ+PTњѕєХ‹шбЯў§§чбЮчбЮ >A6gkсХТ٘“§љљѕыъд­ЉмМИ;rx)+їяяФŒ†ьлй§ћњфЫЩфЬЪ&HL2^bіьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ xxxkkkЅЅЅЇЇЇЯЯЯ%%%XXXaaaџџџџџџџџџџџџџџџџџџ[[[€€€ёёё xxxKKKџџџџџџџџџџџџџџџџџЈ 5 IDATџџџџџџџџџџѕѕѕ№№№ ѓѓѓїюэђхфЛ}wњєѓџ§§вЇЃљђђ2_cћііМ~xёутрТПїюэ@{мЛИЫœ—џџјёёПƒ}?x~.0ј№яЛ|uѕыъџџкЗГј№ю;pvѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ iiihhhхххСССЮЮЮмммчччѕѕѕ§§§ $$$///@@@###џџџџџџџџџџџџџџџџџџџџџа„/{===ЇЇЇННН888wwwџџџџџџџџџџџџџџџџџџџџџџџџџџџррр№№№ѓѓѓїюю§ћњТŠ„њєѓйЕБ#$>>џџџџџџџџџџџџџџџџџџџџџџџџџџџёёёџџџїюэлЙЖіэьхЬЩлЙЖў§§мМК№спыйзрУРћіілЙЖћїїрТПіьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAbПr IDAT%%%ppppppчччзззсссыыыіііџџџ (((џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќєєє љђёўќќёфуєъщцЯЭ:=џўўчаЭчЯЬ1]aцЮЭўќќшгб79њѕѕыйзцЮЬ(MQѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёё џџџј№я ѕъщєщшљђёќјјєщщџџєъшєщчіьыџўўєъщіьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№іяюќјїћїіћїї§ћњў§§ќјїќїїћјїћіііэьяяя џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяїюэ ѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџ2LYœ IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їюэ !# "#!#"$  "#іьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёё їюю *,7:697925 $&4779ѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяіюэ+TX14#$'LO !@C &GK+SW*PT!58џўўїяюјјјіііџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёёїяю)+%FI 3bf2`e7gl,TX-/#AD -V[7hmїюэџ§§@rв IDATюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їюэ2af7: =u{ #BE-UY6gl/1 >w} $&;qv*PS&HK:ot#$ѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџєєєќќќіюэ "AD8:тЦУцЮЬѓчцњіі!"6913ѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їюэ &IM&IM!?B!?B  Ѓq Ј IDAT #CG#CGіэь юююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їююіьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџа„/{џџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№іюэѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їююіьыўўў№№№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№ їяэюђ­3 IDATћїїњѕѕёёё§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№іююіьъюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їюэѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їяюіьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњњњіііјђё^Њœљ IDATѕъъяяяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓѓѓўћћўќќёфтэээџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ јјјќјї№тсшшш"""џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ љљљћїїїяюѕыъњњњыыы)))џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџb2дO IDATџџџџџџџџџџџџџџџ їїїѕъщщдв'''цццџџџ)))џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьььђчцчаЮ ттт+++џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ъъъ элй§љљхЬЩ,,,ззз###џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ щщщ###ъждфЬЩћїї666џџџййй???џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџTŒ(r IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ###сссўўў'''єщш№тскЖГ +++сссѕѕѕ>>>џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ555іііффф333сУРьйиьлй???ЫЫЫCCCџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџа„/{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ555ккк"""нПМ§љљбІЁ@@@џџџЬЬЬ;;;џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџаааBBBљђёоРМуШХъзеAAAззз№№№UUUџџџџџџџџџџџџџџџџџџџџџџџџю5 є IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџGGGмммэээ222дЌЈњѕѕњєѓЭŸ› IIIООО MMMџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџLLLџџџЪЪЪQQQјёёвЈЃЬ˜їяюSSS цццдддZZZџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&&&&&&УУУ§§§333(((лКЗхЭЫйЕВсХУ///:::КККџџџjjjџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџZZZэээЫЫЫ^^^ џџШ•ђхфцЮЬЯЄŸ]]]_6H- IDATфффЩЩЩMMM!!!џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNNNИИИџџџ\\\њєѓР†€іэьшбЯФˆџ§§jjj ЋЋЋўўўxxxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ]]]чччФФФ444NNNѕыъМ~xѓчхсХТТŠ…§ћњfffЯЯЯиииbbb%%%џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџZZZАААѕѕѕJJJDDDѕыъК{vхЭЫџ§§вЇЃЦ’§ћњeee---ѓѓѓІІІvvvџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџvvvєєє­­­UUUNNNњєѓТŠ„Ь™њѕѕзTщW IDATђхуЛ}wеЏЋџџ nnn000ЅЅЅђђђ†††џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDDD;;;ХХХЭЭЭKKKgggџџлЙЕЕpiкЗГ§љљљѓђЮ ›Зtnэмкwww(((ТТТЯЯЯOOOUUUџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒƒƒRRR№№№ЄЄЄ222ЄЄЄииијё№ЭŸ›еЎЊ =A =@!"ёутлКЖоРН§љљDDDOOOкккЈЈЈŒŒŒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџZZZrrrџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРРРmmmџџџuuu ЫЫЫГГГщщщ*,    ћїїэлйъждфЫЩёус(((UUUыыыˆˆˆєєєВВВ444џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ===ЪЪЪџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџAAA___   ццц———nnn555333ЮЮЮТТТкккџџџјё№тЧФтЧФ9{) IDAT   ћїїќјјѓшчј№я+++FFF'''эээєєє444џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџsssцццКККкккšššfff444444яяявввйййооояяяџўўњѕєњѕє222555юююŽŽŽэээuuuVVVџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџˆˆˆяяяЫЫЫввв’’’kkk??????љљљыыыѕѕѕљљљћћћўўўјјјїїїџџџћћћњњњіііњњњќќќўўўјјјїїїџџџћћћњњњ $$$ ффф”””яяяoooxxxџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџа„/{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ•••lllЪЪЪкккŒŒŒhhhвввœœœљљљjjj~~~џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ™™™DDDууу………ббб‡.šВ IDATќќќААА–––љљљƒƒƒƒƒƒџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŽŽŽ___ііі———ЄЄЄіііччч‰‰‰ЗЗЗџџџ ЂЂЂjjjџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџwww222|||ѓѓѓУУУаааTTT777їїїЖЖЖОООќќќ...™™™&&&џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџDDD­­­;;;ѓѓѓŸŸŸЪЪЪўўўљљљООО}}}КККќќќpppИИИ&&&џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ э IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ›››ЗЗЗˆˆˆыыычччБББ:::888ёёёСССРРРѕѕѕ888†††///џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџљљљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIII???ЉЉЉŸŸŸььььььВВВГГГ$$$***'''!!!ѓѓѓбббЫЫЫкккўўў!!!{{{OOOџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїўіііџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ aaaZZZ­­­ЌЌЌиииџџџлллллл   ѕѕѕщщщщщщпппкккшшшџџџ222lllMMMџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїїўўіііџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџZZZ[[[йййВВВСССнннњњњуууууу њњњњњњѕѕѕјјјPPPRRR222џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїї§є ***ЂЂЂQ4Э IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџьььШШШгггооорррцццџџџ444:::>>>666џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓѓѓєп ТТТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџћћћїїїёёёііі§§§џџџџџџџџџџџџђђђџџџџџџџџџџџџџџџїїїњњњџџџџџџџџџўўўєєєџџџџџџџџџѓѓѓџџџџџџџџџџџџџџџјјјљљљџџџџџџџџџџџџђђђџџџїїїњњњџџџџџџќќќєєєџџџџџџџџџ !!!$$$ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§§§ ўўўор іііэээџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџвввўўўпайййџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџУ%Ž" IDATџџџџџџџџџџџџџџџџџџџџџџџџИИИаЂЬЬЬџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЖЖЖЅџџџЯћЬЬЬџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџжжжљџџџЯлиииэээџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџаааѓѓѓла„/{ЇўўўЙЙЙџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„М"… IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒƒƒЃŠўЕЕЕџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџООО§џџџњЮйййвввџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѕѕѕЭџџџњ{ŸŸŸџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‚‚‚zџџџКтФФФкккџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЋ* IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЋЋЋчччсџџџНtџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџooorџџџЋсЪЪЪКККџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџtttьььоџџџЎQџђђђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџммм———џOџџџЯБыыы€€€џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘Ÿ IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўEEEќќќЌџџџдWяТТТЇЇЇџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџVVVцццэZџџџњ>ўОООџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„„„ГГГўDџџџќџџџдyўўў~~~вввџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџƒƒƒsџџџаџџџŠšјјјpppбббџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѓШ™Ц IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkkkџџџ—џџџџџџgЋђђђiiiОООџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ„„„kkkўўўВџџџjџџџVГњњњyyyЄЄЄџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўTTTƒƒƒџџџАџџџOџџџN—§§§rrrёёёџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџммм###ГГГ•џџџQhB—НџџџjtўУУУWWWИИИџџџџџџџџџџџџџџџџџџпHМ§ IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§§§qqq///цццўoџџџlџџџ.П444qqq'''џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЉЉЉqqqээээ>џџџжџџџвЎџЬЬЬ\\\oooвввџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџžžž ^^^эээџЋџџџжџџџ0Џ $$$KKKHHHџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯЯЯˆˆˆЛЛЛѕѕѕоOџџџд•bKг IDATџџџR%%%555444&&&џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЯЯЯЙЙЙИИИеееѓѓѓрqџџџАџџџF„2  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџѕѕѕјјјѓѓѓєєєўўў§ЭzџџџНџџџsZ%љкЄŽџџџќџџџ0\/#%i–DIDATў§љъобЂџџџвафи#„ ђIENDЎB`‚chirp-20240224/chirp/share/chirp.ico0000644000175000017500000026544414534315077016074 0ustar hibbyhibby ю'V€€ (D(00 Ј%l0  ЈV hМf‰PNG  IHDR\rЈf'ЕIDATxкэyœEšїYgпUеG5нє4є4Hгиœ‚4xЭ2рЪ‚€ тŒ3//Л ŽЪ ћЮ 8уЪЌтЈшрЌКЮŒЎЏю(ŠrШ‚Hs5ƒмwCе]}Ww]™ћTYY•ueнЯїѓё#™ODtХяЩx2"’с8AHYЌ @Dь   C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@Fь УLАРpЅRYЈT*“b]‰x‡eй˜их8.жUЅl1+|<З›;,ЫіиэіыŽx‡уИСмЯRY†a’ќ>))ivOOO’NЇУаЁCQTT„ŒŒ (AыHT№WЗ@ъ.”&аћ†qІ Д,ЎїхуЯŽ˜4bлЩWОсЖшuoi"бN‘hЗ`кжfГЁЕЕЕЕЕмѕызaБXЙ\оmЗлџРbŽуzќЕ•O`FрпU*е“JЅR1gЮ<№РшпППп?BЌaЦыБkg єž@гDЫŽ­p—?–v„Ht;ю:мvОњъ+lиАЛwяЧqVЛнўЧqЯњЌЋ7`FЋRЉj8Ž+œ7o.\ˆєєt$ёмнЉЧПHwрpй1 XВd Зmл6†a˜,Ыч8ЎIА­„€a˜1*•ъЏ999ъW_}EEEHШг_ўXк"бэ„C(-‹{џuMГwя^<ђШ#œйl6лэі‰ЧіА!A™JЅњ[EE…ќХ_L8ЏLу9 OZЙžHvbхщУ™ЏƒккZL:•ЋЏЏЗГ,;„уИѓМДnMQЉTuХХХяОћ.дj5ђєёcGˆожcхщ§wtt ММœkkkыДлэљЧu:гЙfЌRЉŽЇЇЇWМџўћШЮЮF"Bž>ё;pДьє&Oяz,TЇSЇNaвЄIœеj=ЪВьHЧu™KТћьv{ХкЕkЖѓЛWоqькё тјЗЗcЏ||йqф'”ЏћЙ`ѓuOЈ`кЩ[šxГ#$юСиqˆgАvм_гњ[ёї›sџ§‰§ х;tшPЌ^Нšс8nУ0SœuudЂVЋo>}WЏ^E[[:;;ƒZ$тЯлŠН'\i‚Н'PЛў<с=НпIf^ЭЪЪњчэлЗЧњo$š` O=ѕАdЩоу С`РЋЏП{r**њ‘U2(же""DgC=ŽНГ­ЮaёЂE())с]џрƒадд„]ЛvyLЋш}Иьшt:ЮbБМžА/13иŽ=Š}ћіaюмЙМЮпооŽпОє’њ— jѕ дљ{9iЙ}pїђEёдћБў•Wp§њuоѕщгЇуђхЫјьГЯD'(чjЧ5ЏHйqА fЊылoПБcЧBЏз;ЏГ,‹7~џ{ЄсЎ%OCЎRХКjD4` ›3§ю™Šзпx&“Щy)55SЇNХкЕky[КЧSЧТ7 AРŸЇjЌЦЦF}аъф! t7щ6шлЗoТ{z_Сѓ„њ nИWиѕиб 9998uъяКVЋE—1Д€сЬwhKg‡ѓЧ(\мНwћўОDzŸМsћжfУчK~ц3Mж ёk:Кš аefёЮFp‡О}ћ:ЯХcеN\ €Зщ—О*ъЏт …­­­(,,tžзiЕшn‰м@ѓљshЛq™B[Xp @зo†?њ˜зыЇ7w‘–л™JРБ,n9 жf#—ЃяˆбPЅІ"=/%>›о`d2”Tн+|MЎ@zŸ>шЯбх657!+гѓ`jj*4M\w`БvФЅущщi,Н^я1 SЋХЅŒ—. њ?пќУ§wРOЊД4єЉИгыѕЋ_яX™Х’7М#Ва№Зь[їkXЛM0ЗЗaд‹z *#—cдЯў)bхю64ЂH`P0’иbБ`ыж­јьГЯP]] ЃбЙ\Н^Щ“'cњєщ˜0aBX…"*аббжжVЄЅЅyZ|!Цгћ:Fƒž3чDеЫЙЧсТNс]• gOп*ƒLЙJЉ&Ž;r‡CеŠЕјы џУ™яАэйЇpїгЯ…єЈ)К›„чp‡ЇџќѓЯБ|љr А, ЛнюМовв‚Ы—/cуЦ1bжЏ_aУ†‰Ву~OФ ККŸ~њ)іюнЫлpQЅRaьиБ˜6m&OžєjОP†ЙЙЙhhрЃДZё ‚ВKЫœУ•У_їіƒ!“иžƒ™%qякuиѓыUшЈЛ‰ЋžУШџ”LЙ/жEубеd@f&џеdKK  $јћ Їц8+WЎФkЏНЦл€д‹Х8zє(юЙчМѕж[˜9sfШ‚vhllФŠ+pєшQ0 УS2GEіяпЏПў РкЕk=іeег{ Н^ѓчЯѓюбщtш9аїЧ§/МУ™я`Л§"YЋ јнwџ{І ЇlвrћјLW0њ.Єцш‘ЄеŠ*;фWŽ€:- Ъд4бyРІ=sG;2ћ №И––лSџэ7ИєзнsgК НvЭr*},Ђпkф8]ЦfСI@ЎћG‘гЏYГoМё†ЯЮяŠнn‡нnЧO~ђЄЅЅсўћя-H@˜рмЙsXМx1ККК|VШqэтХ‹XА`ж­[‡qуЦ…Эг{†мм\С!€еl†еd‚2%јˆНЎ t§K‚ОЯ§юО' t}GŽFп‘ЃCВ•WQ‰МŠРЇцzУ[€ЮA’V‡!3f˜лїd• Šј7zZ[`Зй<РБР•pхvьиѕызмљ]aYѓчЯGMM oЙr0ЏЮ0.2 XМx1кллaЕZЎ„йlЦ3Я<ƒsчЮ9;ОПe—ю 3н™%''Gx6 - ’$]MШхrh4ч9ŽуаммЬ{[фkA˜=*ьv;–/_.КмЧeYЌYГЦoY|•=lАbХ ПžпvЛЫ–-s]ЌPффф ГГ“'PjЕIЩЩД1ˆD15Ёгё†АX,М'ћNњ:'”Чў§ћqѕъUQ§ХйlЦћяПЮЮNQ+d0 @uu5Ž9АчwЧnЗЃЁЁŸ}іYX<Н{Хљфцц‚у8}4:m "QLMСЧ™L†>}јq1ž…-[Ж@† 0У0иЙsЇЯН0М-ЅТ$Ÿ~њЉпUGўАйlјшЃ8\CF•J%И/ ЄIWSВ@ЏзCy{нF(žоqь~юјёуЮШ~(Шd2|їнw^эј;‹ьлЗЯ#к/†ѓчЯ;Ї`S‰@…B&“!;;лCt z"8˜ˆ_zš‘хe#ЁxzoИОоsmƒЌV+nоМщгг •пAШаооŽЎЎЎАT€Г2о/д!ANNŽЇhЕш16…­Dт`24 .v§u,W‚йЖ.999,х—ЩdHKKѓjзWТ ю) Œ.ž8дрŸуˆk>BЏЕZ-Х$JgS“р‡Гяd0Bсњ†! ђѓѓљF}рКВ.Tl64ЯHЅмчИўQњєщ#И9h$Wё‰нlFOg‡р€ы$ P<Н7ЁЈЊЊт-?‹йlЦФ‰ƒŽ“9YЕpРqђђђ|vр@=НЗ?JNNŽАДЕ†ДЉ‘xt55€‡477 n „oH0mкДƒ€‡VQQtœЬAШ “Щ0fܘАLз,,,ф}П/OяэXhAVЋЧВшik!Кš HJIсyb›Э†ЖЖ6чN@ЁzzoBQXXˆЙsч†ф<хr9VЏ^ ™L&:N–ЗгІM љ5 RЉФŒ3М6^И†ЙЙЙГ322РШdє*Pb˜|lти (œС?G>ŽџV­Z…ŒŒ QѓT*ЦŒƒGyDА,ў†Т"UUUшзЏŸш‰ У %%sцЬёлРЁ rrr`БXxo.d2в32((1LMТЄЄЄ8Їˆ;ыщ} ƒ^ЏЧЧ •JхќјH ЈT*єэл~ј!d2™(Їш ,Р0 žўyШхrQO У`Эš5HII‰X№ЯuР0ŒчЂ ­н”І&ƒр$ зЈК+b=НЏу;яМ{іьA^^žпсУ0P(?~<іяп­Vђ$ЙА­8p ж­[‡gžyvЛ= 9ЮŽТ-_ОуЧьМŽcїћ„мѕœЗcЕZєєtДЖЖђ&{шЂє*аpњŽПџZЏ\†*- ЃЦ`имP†ј^˜ГлqfѓЇИИkLЦ&Єчхc№є‡^]ш‹њЧPѓсŸбv§*д(Кыn”Яžy‚Пэ7oри§MчЮ€‘Ы‘;Д•§ЩКЬѓіGw“Y?рЏ64М@ј[eчž&˜•ЋƒЦ‘#GАqуFМќђЫ0HJJЫВЮ{zzz0hа ЌXБ3fЬрuъ@эжхРуЧЧ;яМƒeЫ–С`0РfГyMЋRЉ””„ЕkзbмИqМkСT*PЁpЭGx2з#М шкС§8А~Г,6s.ьњ7Хз§rЕјƒіЎ{ѕ5ЧСоnѓжЋW№Э†WаV{ sˆЮїтЎ/qј­ Зкœу`3pvычЈ;~їП№dA<ККгrљ"ОќЫŽ{{&iэЗQwь~јЏ"%;''І&2яУ/SK JJJТО•П%юIIIјљЯŽ%K–риБcЈЉЉA]]”J%њіэ‹qуЦЁџў!лq'ь‚”••с“O>СІM›№бGсТ… ЮG›ЭŽЛЕгъŒ30oо<оŒЈpzzЁ{џš Єгjqўтхp7‡ЛйŒoп|ЭуŒЕZajnТЉO>ТА9џ(*яы‡ ўФ1g'rжпnЧщMAПЛ'CSќФsGŽМГбуѕ(kЕЂ§ц œлњ9Ъ~єїЂлфрыыСБ,/‡€ўУ˜єьŠан‡ЮfяИўfТхщ]ёu\YY‰ЪЪJŸУщpи"Д%˜BЁРЬ™31sцLFджжТh4BЃб ??ЙЙЙAWJŒЇїvЌзыy3[ѓ"90^Й›YјћЌеŠ›G‹€њšу№іq2™B‰ЦS5Ђ љТYpvсЁkГтцбjб`щъђњmжfCУЉ“^НV8шnm…нf\ (4 (\žозq4э8ˆјІ ™™™-O/єуa˜[Ы‚Џ\ЙТ;ЏгщаС!€НЇч–7ёrнкн-:okwЗILЌ^>\ъ[ŒŒМЌѓВИьѕt{˜}—‰ГйРБ,˜эЃhj2@цЖ№§$ @~sБьРСxz_q€˜|\ьk>їыСМp=чm2ХdђъЅCE7 ФћЋЙњ!wˆЮ;чe{‹Г6;ВŠл‰7kр иНФqd rя(]цфЬ,Ј34‚з†ІЈ8Ђ›Јv5Ёеzlb6›=†СDе#Е™MИпˆ9ˆЊИWRlvЭO(_їsюyx{ЈNЯР‡ўС#hЦШd`фr”Яš':яUї"93Ы#o™B‰мђaа‹ьЈЉ9z КяAШќя2r9ф*5‹ичЯ•џЬУУпњ2Б№Ї!хэ[xN’ЩdМ=іbнЕ#іеyTРН€b;pЈB‘››‹ЖЖ6оЩЩЩPЉе”Яš‹Ё3ч@&џОЃІчхуо5/„ё–+U˜ВъзШќ§SУ0(ž0žПяT>іЪІЭрuTMAю]ѓяHвhBШ(7Ц,ZТ{ЊЮШРФхПте%˜š Ш˜” •J•0Xь$91љ2P уз4ўЦєОђВЃзыСqкллy*Щˆ№Ю@Œ\Ž;fЮЦрп~ЇЎAJVvXђNЩЪFеПЎЅГ ѕає-ќўУ%! S(P1o†ЮšƒЖызЌЫBrwёGџIUшwї=hПQ ™Bqыл ќЙвнdР€,яРXŒщ#5їХ—Ј @И:pЈBЁеjЁP(аввТ€P> 2…"Ќ[‰ЛЂJKGVZј–h;+U^?б*ŒLMaQDђі†Щ`€n џ;Ў8ˆVP.VBг!€k!] щ!\.GffІрwi=€4шj6Ю(*К%DбЪE{Hр jOБ№єюИцЁзы=іаiЕh шѕи-twoт˜ол<НЗ9Q{ˆ…ЇЪгAŸ>}—›iO€^OgCYYќЗЎНУгћ{ѓѕ!€ЗJЅ T(Фибh4шv›|“žžŽЗЇЂїбtю,єyљМ@КККаккŠвввИŽо‡bЧ‘Ÿ+Q€Htр@=Н7;щщщ‘‘ю0nrJФ'ЭчЮ`@П~Мs—/_FFF†ѓCЕёиCёє^'ЁEЃС#б§5–?;EEE0 Мѓљљљ0w›а~ѓF4š…ˆv‹Е‡ЂbrдЅK—pчw:Ззъ-žо[ŸrqˆЕЇїfЇДДЕЕЕМ5 ‹‹qѓШсH7 #ЎмЕJ‰ŠŠ ољГgЯbТ„ qбУщщ§•%тkOяЭЮаЁCЁRЉpўќyо=cGТ…m›ЫR‰оƒЭмƒSўS&Oц­И~§:.]К„йГgї:Oя- ю jC_•JHЅBБЃP(PUU…У‡љо~вЄIйЌ8П§‹h4 EN~ј>R” L:•w~пО}˜2eŠѓ`oєєBѓ€ @Š—­u3€x№єОьŒ5 eeeиВe /]ee%юНw*іНИ†гЇ"йDDИИыKTПЕ/\шŒђ;ј№У1nм8L:5.е#§ъ‹ `єшбМЧC3f@.—cлš:k~№w3ТВ &=zкZqтя іаAќјёЧ1rфHоѕ#GŽрьйГ8pр@Xfф9юѓ7#Я§ОH.|ѓзЇ"&бъРbэ8дЖЂЂ=і6nмˆчž{ЮЙ/У0˜ўЃЁИЈ~ќ1.nп‚Ђ‰“бwфhh Š LI‰Tг!РqŒЯуњС§И№хVєэлџђмГМ5ўР­РпŸўє'Ќ\ЙХХХЮ{ШюF%6_ї4сВУx5++ыŸЗoп‘?H QЬ=Оf8cЧnЗcётХЈЋЋУвЅKЁvлзfГсаЁC8|фЮ= ЛЭ…JЙR‰@‘+”P„Аыo0(“SР„сSmў)QЊ…Ÿ:Б3К[Zаih€ЅЛKKqoU† ц‘ЖЉЉ ыж­УЌYГ№Т /мВфo2ЧЬ=‘В“––ЦY­жз#"СzњH5žу8ЁшшшРќљѓaЕZБhб"о2aWЌV+ZZZажжцsлsW,KРiCу8й‘"šu2Аї JЅBFF2331pр@Џ_оНrх оzы-Œ?јУxЏУббмЯEK(„№uOD œ• ЇЇї—ІГГЯ<ѓ jjj№ФO`а A z{іьСЧŒ'žx+WЎ„RЉьѕžол9‡„=рЋ‹г{[Ц ;ЉЉЉx§ѕзБ~§zМќђЫ;v,~јУ";;<ЛіБсЬ™3иМy3nоМ‰7bњєщЮkюПxгЛ#6NцЬРЫ:юЩ;v„­СунгЛПFJsъд)ќіЗПEuu5ЪЫЫQYY‰Сƒ####lэDDŽююnдддррСƒИxё",X€ЇžzŠїMŠXxрxЄІІr6›эРЊффф•ћіэ ЉСcеУ1NѓuќЗП§ љЫ_А{їn444@Ѓб ;;лыS&“ё‚ˆўў(bс8jЕš7†rЙм#0)’’’D}eк+hmmECCЎ]Л†ььl<ќ№УXДh‘sЏПовCЕЃVЋСqм*Р?јуоН{‘тЋ­DєєСф[[[‹ . ЎЎЮљyqзGGГй ГйPЛ›Ц§Е­­Mд&˜r8ъф/А;аооаGeНхЃеj‘——‡ввRŒ5 C† qЎюsЕ%%O/tЎЎЎ§n-‡žЇАƒa\О|wмкVЬё6ІІнЇx х[PP јхи`э{;bк оэ8l…в{ы˜>;.У§]2ŽудjЕхШ‘#†ёœ э^ зу@ЇVКцщЭŽP'і—Џ{YМх+;L„Uiк 6_Ёcoљ е);юiЕуN<.|sЗГiг&ШdВŽуeаггSъk@!уTЪ](zKеŽ{^ёа{уœјPэхщы\<ийГgЧВl5№§b чЯž=‹3g‚_§nOп[:0yњФшРНйг йљф“OаййЩxЧЭjЕњЦАaУђп|ѓMKАcz_iФф+t­Б6щƒГ#d+Б‚Xй"RvмћT ї 8ЛqуF“нnз.Ы-ЫТЃGт›oОAАЇ/Lž^Мwтйг;Ь~х•Wp§њu†eй%ЮДЎ™ЊTЊciiiУ?јрƒ€gПIХгЛкъ-vЖz“Ї"бэˆёєюЧ'NœРИqу8Лн~”eYчКhЦ-у•JUW\\œёюЛя<љ#:0 …x;[єЈпvМ E[[JJJИЎЎЎN–eѓ9ŽыtЄсM#у8ЮdБXF]НzеОtщRДЗЗћЌ=Њ{кq/s<и 6_ЁczTМ!qЦŽаяќЪ•+2dзййigYv„kчмž\ 6JЉTюЭЮЮNzѕеWГ†‰7Lž>8;BЖШгЧЗ@‡лЖmУЌYГ8›ЭжУВь$Žу<іЛ€лdЋTЊ,ЫцЯ;?ўИз…0дуУŽУuрјЖŽ1НЏ{ёуџ˜лЙs'У0Ь5–eяф8N№Лї^Р%гпЈTЊЇ …ђ‘GСƒ>ˆФМїFЁpи"O/э,жЮцЭ›ёЛп§ћїяЧqvŽу^у8юIŸmфOnIАA­VЯ1›ЭЩZ­wмqŠ‹‹‘žžЅРжXўђѕvнёƒёuП{їDВ,Ођ{Ÿаuїњ†Ѓн­ƒЗ8BИкЩ§|8л-”r„кŽовњЛѕW.‹Х‚––джжВ ŒЭfcd2YЫВџрŸмЧћB$Мf€'мЉP( U*ULwЧ vѕXИЖнтЌ\1)|€Ю&nл6а:Dг&Чq&–ek№ŸBу|_-AєЂђi0‚ т‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aHBТ„„!  C@†€ $ AH‚0$!aўЭЏnТQIЗAIENDЎB`‚(€ УУ !!! g%%%Ј>>>гMMMоOOOоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоMMMоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоKKKоKKKоKKKоKKKоKKKоKKKоKKKоJJJоKKKоKKKоKKKоJJJоJJJоJJJоJJJоJJJоJJJоJJJоJJJоJJJоIIIоIIIоIIIоIIIоIIIоIIIоIIIнIIIнIIIнHHHнHHHнHHHнHHHнHHHнHHHнHHHнHHHнHHHнHHHнHHHнHHHнGGGнGGGнGGGнGGGнGGGнGGGнGGGнGGGнGGGнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнEEEнEEEнEEEнEEEнEEEнEEEнEEEнEEEнEEEнDDDнDDDнDDDнDDDнDDDнDDDнCCCнDDDнBBBн555г"""ЈgN555ШyyyќЌЌЌџОООџТТТџУУУџУУУџУУУџФФФџФФФџФФФџХХХџХХХџЦЦЦџЦЦЦџЦЦЦџЦЦЦџЧЧЧџЧЧЧџЧЧЧџЧЧЧџШШШџШШШџШШШџЩЩЩџЩЩЩџЪЪЪџЪЪЪџЪЪЪџЪЪЪџЫЫЫџЫЫЫџЫЫЫџЫЫЫџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџбббџвввџвввџвввџгггџгггџгггџгггџдддџдддџдддџеееџеееџеееџжжжџжжжџжжжџзззџзззџзззџзззџиииџиииџиииџйййџйййџйййџкккџкккџкккџкккџлллџлллџлллџмммџмммџмммџнннџнннџнннџоооџоооџоооџоооџпппџпппџрррџрррџрррџрррџсссџсссџсссџтттџтттџтттџтттџуууџуууџфффџфффџфффџфффџфффџсссџШШШџ„„„ќ222ЪN aTTTьЏЏЏџЭЭЭџЮЮЮџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџвввџвввџвввџгггџгггџдддџдддџдддџеееџеееџеееџжжжџжжжџзззџзззџзззџиииџиииџйййџйййџйййџкккџкккџлллџлллџлллџмммџмммџнннџнннџнннџоооџоооџпппџпппџпппџрррџрррџсссџсссџсссџтттџтттџтттџуууџуууџфффџфффџфффџхххџхххџхххџцццџцццџчччџчччџчччџшшшџшшшџщщщџщщщџщщщџъъъџъъъџыыыџыыыџыыыџьььџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџїїїџїїїџјјјџјјјџљљљџљљљџћћћџњњњџЭЭЭџUUUыaEOOOшЛЛЛџЮЮЮџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџбббџвввџвввџвввџвввџгггџгггџдддџдддџдддџеееџеееџжжжџжжжџзззџзззџзззџиииџиииџиииџйййџйййџкккџкккџкккџлллџлллџмммџмммџмммџнннџнннџнннџоооџоооџпппџпппџпппџрррџрррџсссџсссџсссџтттџтттџтттџуууџуууџфффџфффџфффџхххџхххџхххџцццџцццџчччџчччџчччџшшшџшшшџщщщџщщщџщщщџъъъџъъъџыыыџыыыџыыыџьььџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџјјјџјјјџјјјџќќќџоооџPPPшF ---ЗЈЈЈџЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџвввџвввџгггџгггџгггџгггџдддџдддџеееџеееџеееџжжжџжжжџзззџзззџиииџиииџиииџиииџйййџйййџкккџкккџлллџлллџлллџмммџмммџнннџнннџнннџоооџоооџоооџпппџпппџрррџрррџрррџсссџсссџтттџтттџтттџуууџуууџуууџфффџфффџхххџхххџхххџцццџцццџцццџчччџчччџшшшџшшшџшшшџщщщџщщщџъъъџъъъџъъъџыыыџыыыџьььџьььџьььџэээџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџїїїџїїїџјјјџјјјџљљљџќќќџУУУџ(((КYiiiѓЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџбббџбббџвввџвввџгггџгггџдддџдддџдддџдддџеееџеееџжжжџжжжџжжжџзззџзззџиииџйййџйййџкккџкккџкккџлллџлллџмммџмммџмммџнннџнннџоооџоооџоооџпппџпппџрррџрррџрррџсссџсссџтттџтттџтттџуууџуууџфффџфффџфффџхххџхххџцццџцццџчччџчччџчччџчччџшшшџшшшџщщщџщщщџщщщџъъъџъъъџыыыџыыыџьььџьььџьььџьььџэээџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџјјјџјјјџјјјџљљљџїїїџqqqѓX•˜˜˜џЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџаааџбббџбббџвввџвввџвввџгггџгггџдддџдддџеееџеееџеееџеееџжжжџзззџйййџиииџбббџЭЭЭџЮЮЮџЮЮЮџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџаааџаааџаааџбббџбббџбббџвввџвввџгггџгггџгггџгггџдддџгггџвввџгггџгггџгггџдддџдддџдддџеееџеееџеееџжжжџжжжџжжжџеееџеееџеееџжжжџжжжџжжжџзззџйййџрррџьььџяяяџэээџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџјјјџјјјџјјјџљљљџ§§§џЉЉЉџ”###НБББџЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџбббџбббџбббџвввџвввџвввџгггџгггџгггџдддџдддџеееџеееџжжжџиииџЫЫЫџŸŸŸџxxxџhhhџfffџfffџdddџcccџdddџeeeџeeeџeeeџeeeџeeeџfffџfffџfffџfffџfffџeeeџbbbџdddџdddџdddџdddџdddџdddџdddџdddџdddџdddџeeeџdddџaaaџbbbџbbbџbbbџbbbџcccџcccџcccџcccџcccџcccџcccџcccџaaaџ```џaaaџaaaџaaaџaaaџaaaџbbbџcccџjjjџџГГГџфффџяяяџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџїїїџїїїџјјјџјјјџљљљџћћћџдддџ&&&М(((ЯЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџбббџвввџвввџвввџгггџгггџгггџдддџдддџдддџеееџжжжџЈЈЈџaaaџ___џyyyџ‰‰‰џŒŒŒџŒŒŒџŒŒџџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџŽŽŽџџџџџџџџџџџџџџџ‘џ‘‘‘џ‘џ‘џ‘џ‘џ‘џ‘џ‘џ‘џ‘џ‘‘‘џ’’’џ’’’џ’’’џ’’’џ’’’џ’’’џ’’’џ‘‘‘џŒŒŒџyyyџ___џqqqџХХХџяяяџюююџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџјјјџјјјџјјјџћћћџмммџ(((Ю)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџвввџвввџгггџгггџгггџдддџдддџеееџеееџ™™™џVVVџ€€€џšššџ‘‘’џƒџxxyџwwxџwwxџwwxџwwxџvvwџttuџuuuџuuuџuuuџuuuџuuuџuuuџuuuџuuuџuuuџuuuџuuuџttuџrrrџrrrџrrrџrrrџrrrџrrrџrrrџrrrџrrrџrrrџrrrџrrrџrrrџppoџppoџppoџppoџppoџppoџppoџppoџppoџppoџppoџppoџppoџmmlџmlkџmmkџmmkџmmkџppoџ}}~џ’’’џ™™™џyyyџ\\\џДДДџяяяџюююџюююџяяяџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџїїїџјјјџјјјџњњњџмммџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџбббџвввџвввџгггџгггџдддџдддџжжжџЇЇЇџWWWџ‹‹‹џ•••џiigџTR@џ_[8џhd:џie;џie;џie;џie;џhd:џkf;џlh<џlh<џlh<џlh<џlh<џlh<џlh<џlh<џlh<џlh<џlh<џlg<џmh<џpk=џpk=џpk=џpk=џpk=џpk=џpk=џpk=џpk=џpk=џpk=џok=џpk=џrn>џsn>џsn>џsn>џsn>џsn>џsn>џsn>џsn>џsn>џsn>џsn>џrn>џup>џvq?џvq?џvq?џrm>џa^8џRQ@џonmџ——˜џ†††џ\\\џТТТџ№№№џюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџїїїџїїїџјјјџјјјџњњњџмммџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџбббџвввџвввџвввџгггџгггџеееџЧЧЧџ```џџ””•џZZSџie8џ ™OџБЉXџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџДЌZџВЊXџ–Nџb^7џ__[џ———џ|||џlllџсссџяяяџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџїїїџјјјџњњњџмммџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџбббџбббџбббџвввџвввџвввџгггџгггџжжжџšššџ```џšššџhheџje9џЏЇWџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџ­ЅVџd`7џkkiџšššџbbbџЈЈЈџ№№№џюююџяяяџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџїїїџїїїџјјјџњњњџлллџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџбббџвввџвввџвввџгггџгггџгггџqqqџ|||џџSQ>џЂ›PџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџЂšPџSQ<џџџsssџшшшџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџјјјџњњњџлллџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџвввџвввџгггџдддџЩЩЩџdddџŒŒŒџ||~џc_8џВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌYџni;џponџ”””џ^^^џеееџяяяџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџїїїџњњњџлллџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџбббџвввџвввџдддџФФФџ___џџrrrџok=џДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџŠ„Dџ]]Vџš››џaaaџНННџ№№№џюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџїїїџїїїџњњњџлллџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџбббџвввџвввџдддџОООџZZZџ””•џkkhџyt?џДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџДЌZџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџДЋZџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџДЌZџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџ›”MџUTJџ˜˜˜џiiiџЉЉЉџ№№№џюююџюююџюююџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџіііџіііџіііџїїїџїїїџљљљџлллџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџбббџбббџбббџвввџвввџдддџЕЕЕџYYYџ™™™џcb]џƒ}BџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџЃœRџ–KџЉЁTџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЊЃUџ—KџЁšQџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџ­ЅWџ˜’Lџž—OџБЉXџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЅžSџ–KџЇŸSџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЂ›PџVTDџ’““џoooџ———џ№№№џюююџюююџяяяџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџїїїџљљљџлллџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџбббџвввџвввџдддџІІІџ```џ››œџ[ZSџˆFџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџ‰Hџ,*џџ>;џЁ™PџГЋYџВЊYџВЊYџВЊYџВЊYџГЋYџІŸSџGD$џџ%$џ†€CџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџЌЄVџXT,џ џџwq;џВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџ–Kџ20џџ64џ›”MџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЈЁSџXV=џŽŽџwwwџ†††џ№№№џэээџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџѕѕѕџѕѕѕџіііџіііџіііџїїїџљљљџлллџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЯЯЯџЬЬЬџЩЩЩџЮЮЮџЯЯЯџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџаааџбббџбббџвввџдд䟘˜˜џgggџ˜˜™џUTJџ›”LџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџБЊYџQM(џџџџni7џЕ­ZџВЊYџВЊYџВЊYџВЊYџДЌZџ}w>џџџџDA"џЎІWџВЊYџВЊYџВЊYџВЊYџДЌZџ‘ŠHџџџџ-+џЇŸSџГЋYџВЊYџВЊYџВЊYџВЊYџДЌZџ\W.џџџџc_1џЕ­ZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџЎІVџ[X7џ‡ˆ‰џƒƒƒџwwwџыыыџюююџюююџюююџюююџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџёёёџђђђџђђђџѓѓѓџєєєџєєєџєєєџєєєџѕѕѕџѕѕѕџіііџіііџіііџїїїџљљљџкккџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџПППџ†††џZZZџRRRџhhhџЂЂЂџЫЫЫџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџбббџбббџбббџеееџŠŠŠџmmmџ““”џUTEџЁšPџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџUQ+џџџџsn:џЕЌZџВЊYџВЊYџВЊYџВЊYџДЌZџ{@џ џџџIF%џЏЇWџВЊYџВЊYџВЊYџВЊYџДЌZџ”Jџ џџџ20џЈЁTџГЋYџВЊYџВЊYџВЊYџВЊYџДЌZџ`\0џџџџhc4џЕ­ZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџd`9џ||~џ‹‹‹џmmmџуууџюююџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџђђђџђђђџѕѕѕџѓѓѓџъъъџыыыџѕѕѕџїїїџѕѕѕџѕѕѕџѕѕѕџіііџіііџїїїџљљљџкккџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЏЏЏџAAAџџџџџџsssџШШШџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџвввџеееџ}}}џtttџџXU?џЇŸRџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџ—Lџ;8џ џNK'џІžSџГЋYџВЊYџВЊYџВЊYџВЊYџГЋYџЊЂUџWS,џџ42џ‰HџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџЎІWџfb3џџ+)џƒ}AџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџ–NџA>!џ џGC#џЁšPџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџok=џrrqџџdddџлллџюююџюююџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџђђђџёёёџСССџuuuџRRRџUUUџ~~~џЬЬЬџѕѕѕџѕѕѕџѕѕѕџѕѕѕџіііџіііџјјјџкккџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџРРРџDDDџџџџџџџ џ………џЯЯЯџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџбббџбббџбббџвввџpppџ~~~џŠŠ‹џZW9џЌЄUџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЊЂUџЁšQџ­ЅWџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЎЇWџЂšQџЈЁTџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџАЈXџЃ›QџІŸSџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЋЃVџЁšPџЌЄVџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџ{v@џiheџ••–џ\\\џгггџяяяџэээџюююџюююџяяяџяяяџяяяџяяяџ№№№џ№№№џёёёџяяяџ———џџџџџџ)))џЊЊЊџѕѕѕџѕѕѕџѕѕѕџіііџіііџјјјџкккџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЯЯЯџŽŽŽџ џџџџџџџџ333џРРРџЯЯЯџЮЮЮџЯЯЯџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџвввџЬЬЬџgggџˆˆˆџƒƒ„џ^[7џБЉXџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџГЋZџГЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџ‡Cџ`_Yџšš›џ^^^џФФФџяяяџэээџэээџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џѓѓѓџЕЕЕџџџџџџџџ'''џЩЩЩџїїїџѕѕѕџѕѕѕџіііџјјјџкккџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЮЮЮџdddџџџџџџџџџџЊЊЊџЯЯЯџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџаааџвввџЦЦЦџbbbџџxxyџhd:џДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЋZџ•ŽIџWVOџšš›џeeeџБББџяяяџэээџэээџюююџюююџюююџяяяџяяяџ№№№џёёёџьььџaaaџџџџџџџџџxxxџѕѕѕџѕѕѕџіііџіііџјјјџкккџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџ^^^џџџџџџџџџџЃЃЃџЯЯЯџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџбббџвввџРРРџ]]]џ’’’џoonџrn>џДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџŸ˜OџTSGџ••–џlllџ   џяяяџэээџэээџюююџюююџюююџяяяџяяяџяяяџёёёџоооџ111џџџџџџџџџMMMџъъъџіііџѕѕѕџіііџјјјџкккџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЯЯЯџxxxџџџџџџџџџџЕЕЕџЯЯЯџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџвввџКККџYYYџ––—џhgcџ}x@џДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЅžRџWU@џ‘џrrrџŽŽŽџ№№№џэээџэээџюююџюююџюююџяяяџяяяџяяяџёёёџмммџ,,,џџџџџџџџџHHHџшшшџіііџѕѕѕџѕѕѕџјјјџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЮЮЮџЎЎЎџ"""џџџџџџџџ^^^џЪЪЪџЮЮЮџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџвввџ­­­џ[[[џ›››џ`_Yџˆ‚CџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџГЋYџГЋYџГЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЊYџЋЃUџYW:џ‹‹Œџ|||џ~~~џэээџэээџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џшшшџSSSџџџџџџџџџlllџѓѓѓџѕѕѕџѕѕѕџѕѕѕџјјјџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџ………џџџџџџџ:::џДДДџЮЮЮџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџвввџžžžџcccџšš›џXWOџ”IџДЋZџВЊYџВЊYџВЊYџВЊYџВЊYџЎЇWџЊЂUџЊЂUџЊЂUџЌЅVџВЊYџВЊYџВЊYџВЊYџБЉYџЌЄVџЏЇWџВЊYџВЊYџВЊYџЌЄVџЎЇWџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџЏЇXџЌЄVџБЉYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџЏЇWџ­ЅVџВЊYџВЊYџВЊYџЋЃUџЌЄVџВЊYџВЊYџВЊYџВЊYџАЈXџЌЄVџБЉYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџБЉXџ^[7џ‚ƒ„џ‡‡‡џqqqџцццџэээџэээџэээџэээџюююџюююџяяяџяяяџ№№№џђђђџЁЁЁџ џџџџџџџџИИИџїїїџѕѕѕџѕѕѕџѕѕѕџїїїџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЪЪЪџ”””џDDDџџџ&&&џcccџЕЕЕџЭЭЭџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџгггџ‘‘‘џjjjџ––—џTSHџž—NџГЋZџВЊYџВЊYџВЊYџГЋYџŸ˜PџMI'џA> џC@!џB?!џB?!џ‡CџДЌZџВЊYџГЋYџЉЁTџRO)џ€z@џДЌZџГЋYџЋЃUџWS+џ{v>џДЌZџВЊYџВЊYџВЊYџВЊYџДЌZџˆ‚DџNK'џІŸSџГЋYџВЊYџВЊYџВЊYџВЊYџДЌZџ|v>џZV-џЌЅVџБЉYџxr<џGD#џŒ†FџВЊYџВЊYџВЊYџДЋZџˆGџMJ'џЅžSџДЌZџГЋYџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџie;џvwwџџiiiџпппџэээџэээџэээџэээџюююџюююџюююџяяяџяяяџ№№№џшшшџxxxџ џџџџџџ‹‹‹џ№№№џєєєџєєєџѕѕѕџѕѕѕџїїїџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЮЮЮџФФФџДДДџЎЎЎџКККџЪЪЪџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџгггџƒƒƒџpppџ’’’џVTCџЃœQџГЋYџВЊYџВЊYџВЊYџДЌZџ{Aџ џrl9џ‚|Aџ|v>џ/,џ]Y/џДЌZџВЊYџГЋYџЄRџ&%џfb3џВЊYџАЈXџЄœRџ,*џb]1џЕ­[џВЊYџВЊYџВЊYџВЊYџЕЌZџuo:џ џ ™PџГЋZџВЊYџВЊYџВЊYџВЊYџЕ­[џa]1џ+*џš“Mџje5џџgb4џЌЄVџВЊYџВЊYџВЊYџДЌZџ}w?џ џ”JџЈ TџЇŸSџЊЃUџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџup>џmmlџ“““џ```џзззџэээџэээџэээџэээџюююџюююџюююџяяяџяяяџяяяџёёёџшшшџžžžџLLLџ$$$џ'''џTTTџЊЊЊџюююџєєєџєєєџєєєџєєєџѕѕѕџїїїџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЮЮЮџЮЮЮџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџвввџvvvџxxxџŽџYV<џЉЁTџГЋYџВЊYџВЊYџВЊYџДЌZџ}x?џџ ™PџЖЎ[џВЊYџ•KџЁšPџВЊYџВЊYџГЋYџЄRџ'%џ*(џJG%џIF%џDA"џ џd`2џЕ­[џВЊYџВЊYџВЊYџВЊYџДЌZџvp;џ" џЁšPџГЋZџВЊYџВЊYџВЊYџВЊYџЕ­[џd_2џ џ64џџџ>;џ•KџГЋZџВЊYџВЊYџДЌZџy?џџ86џ@= џ>;џ=;џˆ‚DџДЌZџВЊYџВЊYџВЊYџВЊYџДЌZџ{Aџed_џ˜˜˜џ[[[џЬЬЬџюююџьььџэээџэээџюююџюююџюююџяяяџяяяџяяяџ№№№џёёёџѓѓѓџчччџкккџлллџъъъџѕѕѕџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџїїїџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџЮЮЮџkkkџƒƒƒџˆˆ‰џ[X8џЎІVџВЊYџВЊYџВЊYџВЊYџДЌZџ}x?џџš“MџЏЇWџЊЂUџsn:џ‡CџГЋZџВЊYџГЋYџЄRџ'%џ=:џkf5џje5џc^1џџd_2џЕ­[џВЊYџВЊYџВЊYџВЊYџЕЌZџup:џ" џЁ™PџГЋZџВЊYџВЊYџВЊYџВЊYџЕ­[џb^1џ)'џŽ‡Gџ™’Mџˆ‚Dџ!џvq;џДЌZџВЊYџВЊYџДЌZџ~x?џ џ{Aџ“ŒIџŠ„Eџ+)џ[W.џЕ­[џВЊYџВЊYџВЊYџВЊYџДЌZџ‡Eџ[[Tџ››œџaaaџКККџюююџьььџьььџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџђђђџѓѓѓџѓѓѓџѓѓѓџђђђџѓѓѓџѓѓѓџєєєџєєєџєєєџѕѕѕџїїїџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџаааџШШШџdddџŠŠŠџ~~€џb^8џГЊYџВЊYџВЊYџВЊYџВЊYџДЌZџŒ…FџџA>!џJF%џGC#џџe`2џЕ­ZџВЊYџГЋYџЅRџ.,џni7џИЏ\џЖ­[џЊЂUџ42џfa3џЕ­ZџВЊYџВЊYџВЊYџВЊYџДЌZџxr<џ(&џЁšQџГЋZџВЊYџВЊYџВЊYџВЊYџЕ­Zџgb3џџOL(џTQ*џJG%џ џ„~BџДЌZџВЊYџВЊYџДЌZџ{@џ џKH&џUQ*џPL(џ! џie5џЕ­ZџВЊYџВЊYџВЊYџВЊYџГЋZџ›”LџUTJџ˜˜˜џiiiџЉЉЉџюююџьььџьььџэээџэээџэээџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџѕѕѕџїїїџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџаааџТТТџ```џџtttџlh<џДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџ­ЅWџˆ‚Dџwq<џwq<џwq;џ€z@џЅRџГЋYџВЊYџВЊYџЎІWџ†€Cџ›”MџГЋYџВЊYџЎЇWџˆ‚Dџ™’LџГЋYџВЊYџВЊYџВЊYџВЊYџГЋYџŸ—Oџ„~BџЌЅVџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџ™’Mџys=џwq;џvq;џvq;џ†€CџЌЄVџВЊYџВЊYџВЊYџГЋYџЂ›Qџ|v>џwq;џvq;џvq;џy@џЅžSџГЋYџВЊYџВЊYџВЊYџВЊYџГЋYџЂ›PџUTDџ““”џoooџ———џяяяџьььџьььџэээџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџіііџйййџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџаааџЛЛЛџZZZџ”””џlljџwr?џДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџДЌZџДЌZџДЌZџДЌZџГЋYџВЊYџВЊYџВЊYџВЊYџДЌZџГЋZџВЊYџВЊYџВЊYџДЌZџГЋZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџДЌZџДЌZџДЌZџДЌZџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџДЌZџДЌZџДЌZџДЌZџДЌZџГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋYџЈ SџXV=џŽŽџwwwџ………џюююџьььџьььџэээџэээџэээџюююџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџіііџиииџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџаааџДДДџXXXџ˜˜˜џed_џ{AџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџ­ІVџ[W7џˆˆ‰џ‚‚‚џwwwџщщщџьььџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџєєєџєєєџіііџиииџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџаааџГГГџXXXџ™™™џee`џ€{AџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџ­ІVџ[W8џ‰‰Šџ„„„џuuuџщщщџьььџьььџьььџьььџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџєєєџєєєџіііџиииџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџМММџZZZџ“““џsssџkf:џГЋYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџГЋZџЂ›PџTS@џ‘‘’џvvvџ†††џэээџыыыџьььџьььџэээџэээџэээџэээџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџіііџиииџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЯЯЯџЪЪЪџhhhџџŽŽџRP=џž—NџДЌZџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџВЊYџДЌZџxs=џbb^џšššџbbbџЌЌЌџэээџыыыџьььџьььџьььџэээџэээџюююџюююџюююџюююџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџѓѓѓџіііџиииџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџбббџ“““џ___џšššџppoџ[X6џЄœQџДЌZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџГЋZџДЌZџВЊYџ‰ƒDџQPAџŽџˆˆˆџbbbџйййџыыыџыыыџыыыџьььџьььџэээџэээџэээџюююџюююџяяяџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџѓѓѓџѓѓѓџєєєџіііџиииџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџХХХџdddџwwwџ™™šџmmkџTR9џ{u?џ—Jџž—Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž–Nџž—Nџ–MџˆFџie9џSRFџ……†џ–––џ]]]џЄЄЄџьььџъъъџыыыџыыыџыыыџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѓѓѓџѕѕѕџиииџ(((Я)))аЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџаааџВВВџYYYџ{{{џšššџ†††џedaџVUMџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџTSIџZYRџqpoџ’’“џ”””џbbbџ„„„џфффџъъъџъъъџыыыџыыыџыыыџьььџьььџьььџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѕѕѕџзззџ(((Я(((ЯЖЖЖџЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџаааџ­­­џ^^^џfffџ‹‹‹џšššџ™™šџ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ——˜џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ———џ——˜џ›››џ–––џ~~~џ[[[џŠŠŠџрррџъъъџъъъџъъъџъъъџыыыџыыыџьььџьььџьььџэээџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџђђђџђђђџђђђџђђђџѓѓѓџѕѕѕџиииџ(((Ю###НБББџЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџаааџРРРџ„„„џ\\\џ[[[џfffџiiiџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџjjjџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџkkkџjjjџdddџ\\\џqqqџВВВџхххџъъъџщщщџщщщџъъъџъъъџыыыџыыыџыыыџьььџьььџэээџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџѓѓѓџѓѓѓџѕѕѕџЯЯЯџ&&&М•˜˜˜џЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџаааџбббџУУУџЋЋЋџ™™™џ“““џ“““џ“““џ“““џ“““џ“““џ”””џ”””џ”””џ•••џ•••џ•••џ–––џ–––џ–––џ–––џ———џ———џ———џ———џ˜˜˜џ˜˜˜џ˜˜˜џ™™™џ™™™џ™™™џ™™™џšššџšššџšššџ›››џ›››џ›››џ›››џœœœџœœœџœœœџœœœџџџџџžžžџžžžџžžžџžžžџŸŸŸџŸŸŸџŸŸŸџŸŸŸџŸŸŸџ   џ   џЁЁЁџЁЁЁџЃЃЃџАААџЪЪЪџтттџъъъџщщщџщщщџщщщџщщщџъъъџъъъџъъъџыыыџыыыџьььџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџёёёџђђђџђђђџѓѓѓџїїїџІІІџ”ZiiiѓЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџбббџвввџгггџгггџдддџдддџеееџеееџеееџжжжџжжжџжжжџзззџзззџиииџиииџиииџйййџйййџкккџкккџкккџлллџлллџмммџмммџмммџнннџнннџоооџоооџоооџпппџпппџрррџрррџрррџсссџсссџсссџтттџтттџуууџуууџуууџфффџфффџхххџхххџхххџцццџцццџцццџчччџчччџшшшџшшшџщщщџщщщџщщщџщщщџшшшџшшшџшшшџшшшџщщщџщщщџъъъџъъъџъъъџыыыџыыыџыыыџьььџьььџэээџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџђђђџѓѓѓџёёёџoooђY---ЗЉЉЉџЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџвввџвввџвввџгггџгггџгггџдддџдддџеееџеееџеееџжжжџжжжџзззџзззџзззџиииџиииџйййџйййџйййџкккџкккџкккџлллџлллџмммџмммџмммџнннџнннџоооџоооџоооџпппџпппџпппџрррџрррџсссџсссџсссџтттџтттџтттџуууџуууџфффџфффџфффџхххџхххџцццџцццџцццџчччџчччџшшшџшшшџшшшџщщщџщщщџщщщџъъъџъъъџыыыџыыыџыыыџьььџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџёёёџђђђџѕѕѕџОООџ'''ЖEOOOшЛЛЛџЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџбббџвввџвввџгггџгггџгггџдддџдддџдддџеееџеееџжжжџжжжџжжжџзззџзззџиииџиииџиииџйййџйййџкккџкккџкккџлллџлллџлллџмммџмммџнннџнннџнннџоооџоооџпппџпппџпппџрррџрррџрррџсссџсссџтттџтттџтттџуууџуууџуууџфффџфффџхххџхххџхххџцццџцццџчччџчччџчччџшшшџшшшџщщщџщщщџщщщџъъъџъъъџъъъџыыыџыыыџьььџьььџьььџэээџэээџэээџюююџюююџяяяџяяяџяяяџ№№№џ№№№џёёёџёёёџђђђџѕѕѕџйййџPPPшE  bUUUыАААџЭЭЭџЮЮЮџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџаааџаааџаааџбббџбббџвввџвввџвввџгггџгггџдддџдддџеееџеееџеееџжжжџжжжџжжжџзззџзззџиииџиииџиииџйййџйййџйййџкккџкккџлллџлллџлллџмммџмммџнннџнннџнннџоооџоооџпппџпппџпппџрррџрррџрррџсссџсссџтттџтттџтттџуууџуууџфффџфффџфффџхххџхххџцццџцццџцццџчччџчччџчччџшшшџшшшџщщщџщщщџщщщџъъъџъъъџыыыџыыыџыыыџьььџьььџьььџэээџэээџюююџюююџюююџяяяџяяяџ№№№џ№№№џ№№№џёёёџёёёџђђђџѓѓѓџѓѓѓџЩЩЩџUUUыaN666ЩzzzќЌЌЌџОООџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџТТТџУУУџУУУџУУУџУУУџУУУџФФФџФФФџХХХџХХХџХХХџХХХџЦЦЦџЦЦЦџЧЧЧџЧЧЧџЧЧЧџЧЧЧџЧЧЧџШШШџШШШџЩЩЩџЩЩЩџЩЩЩџЩЩЩџЪЪЪџЪЪЪџЪЪЪџЫЫЫџЫЫЫџЫЫЫџЫЫЫџЬЬЬџЬЬЬџЭЭЭџЭЭЭџЭЭЭџЭЭЭџЮЮЮџЮЮЮџЮЮЮџЯЯЯџЯЯЯџЯЯЯџЯЯЯџаааџаааџбббџбббџбббџбббџвввџвввџвввџгггџгггџгггџдддџдддџдддџдддџеееџеееџеееџжжжџжжжџжжжџзззџзззџзззџиииџиииџиииџйййџйййџйййџйййџкккџкккџкккџлллџлллџлллџмммџмммџмммџмммџнннџнннџнннџоооџоооџоооџоооџлллџФФФџƒƒƒќ333ШN""" g%%%Њ>>>дMMMоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоOOOоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоNNNоMMMоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоLLLоKKKоKKKоKKKоKKKоKKKоKKKоKKKоKKKоJJJоKKKоKKKоJJJоJJJоJJJоJJJоJJJоJJJоJJJоJJJоJJJоJJJоIIIоIIIоIIIоIIIоIIIоIIIнIIIнIIIнIIIнHHHнIIIнIIIнHHHнHHHнHHHнHHHнHHHнHHHнHHHнHHHнHHHнGGGнGGGнGGGнGGGнGGGнGGGнGGGнGGGнGGGнFFFнGGGнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнFFFнDDDн777д###Љg###   џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№Р€€Р№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(0` $УУ ppp|||NNND}}}žŒŒŒДДŽŽŽДŽŽŽДŽŽŽДДДДДДД‘‘‘Д‘‘‘Д‘‘‘Д’’’Д’’’Д’’’Д“““Д“““Д“““Д”””Д”””Д•••Д•••Д–––Д–––Д–––Д———Д———Д———Д˜˜˜Д˜˜˜Д˜˜˜Д™™™Д™™™ДšššДšššДšššД›››Д›››Д›››Д›››ДŽŽŽSSSDTTTYЅЅЅщШШШџЬЬЬџЭЭЭџЮЮЮџЯЯЯџаааџбббџвввџгггџдддџеееџжжжџиииџйййџкккџлллџмммџнннџоооџпппџрррџсссџтттџуууџхххџцццџчччџшшшџщщщџъъъџыыыџьььџьььџьььџэээџюююџяяяџ№№№џёёёџђђђџѓѓѓџєєєџѕѕѕџђђђџФФФщZZZYŠŠŠЯЫЫЫџЬЬЬџЬЬЬџЭЭЭџЮЮЮџЯЯЯџбббџвввџгггџдддџеееџзззџЯЯЯџУУУџССТџТТТџУУУџФФФџХХХџХХХџХХЦџЦЦЧџЧЧЧџШШШџШШЩџЩЩЩџЩЩЪџЪЪЫџЫЫЫџЫЫЬџЬЬЬџЭЭЭџЯЯЯџнннџюююџяяяџяяяџ№№№џёёёџђђђџѓѓѓџєєєџѕѕѕџіііџјјјџїїїџ   ЯšššяЭЭЭџЬЬЬџЬЬЬџЭЭЭџЮЮЮџЯЯЯџаааџбббџвввџгггџеееџКККџŠŠŠџ}|zџ{{wџ{{wџ{{wџ|{wџ|{xџ|{wџ{{wџ{{wџ|{wџ|{wџ{{wџ{{wџ{{vџ|{vџ|{wџ{{vџ{{vџ{{vџ||wџ‡‡†џЖЖЗџыыыџяяяџ№№№џёёёџђђђџѓѓѓџєєєџѕѕѕџіііџїїїџњњњџИИИя™™™№ЭЭЭџЬЬЬџЬЬЬџЭЭЭџЮЮЮџЯЯЯџаааџбббџвввџдддџЦЦЦџ„„ƒџ~{aџ”Tџ™“Tџ˜’Tџ™“Tџ™“Tџ™“Tџ™“Tџ™“Tџš“Tџš“Tџš“Tџš“Tџš“Tџš”Tџš”Tџš”Tџš”Tџš”Tџ›”Tџ™“Tџ†Xџ|{wџРРРџ№№№џ№№№џёёёџђђђџѓѓѓџєєєџѕѕѕџіііџїїїџљљљџИИИ№™™™№ЭЭЭџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЮЮЮџЯЯЯџаааџбббџдддџ­ЎЎџyxoџž—RџДЌYџДЋYџДЋYџДЌZџДЌZџГЋYџДЋYџДЌZџДЌZџГЋYџГЋYџДЌZџДЌZџГЋYџГЋYџДЋYџЕЌZџДЌYџГЋYџДЌYџЎІUџ€}]џ––—џъъъџяяяџ№№№џёёёџђђђџѓѓѓџєєєџѕѕѕџіііџљљљџЗЗЗ№™™™№ЭЭЭџЬЬЬџЬЬЬџЮЮЮџЮЮЮџЮЮЮџЯЯЯџаааџбббџдддџЃЃЄџzxgџЈЁTџГЋYџВЊYџВЊYџЃœRџЋЃUџВЊYџВЊYџЇ TџІŸSџВЊYџВЊYџЊЃUџЄœRџВЊYџВЊYџАЈXџЁšQџЎЇWџВЊYџВЊYџГЋYџˆVџ‡‡‡џсссџяяяџ№№№џёёёџђђђџѓѓѓџєєєџѕѕѕџіііџљљљџЗЗЗ№™™™№ЭЭЭџЬЬЬџЪЪЪџАААџВВВџЬЬЬџЯЯЯџЯЯЯџаааџвввџ››œџ|zcџЌЄUџВЊYџГЋYџІžSџ2/џje5џДЌZџБЉXџMI&џIF%џАЈXџДЌZџfa3џ42џЈ TџЕЌZџ“ŒIџ&$џ‡DџДЌZџВЊYџГЋYџ”ŽTџ€€~џиийџ№№№џяяяџ№№№џђђђџѓѓѓџюююџѕѕѕџіііџјјјџЗЗЗ№™™™№ЭЭЭџЭЭЭџ€€€џџџ†††џЯЯЯџЯЯЯџаааџаааџ’“”џ€}_џЏЇVџВЊYџВЊYџ­ЅWџrm9џ‰HџГЋZџВЊYџ{@џy?џВЊYџГЋZџŽ‡Gџtn:џЎІWџГЋZџЄRџlg6џŸ—OџГЋZџВЊYџГЋYџ›”Tџ|{vџЮЮЯџ№№№џяяяџ№№№џщщщџ………џGGGџŒŒŒџюююџјјјџЖЖЖ№™™™№ЮЮЮџХХХџ333џџџ:::џШШШџЯЯЯџаааџЭЭЭџ‹‹Œџ„[џБЉWџВЊYџВЊYџГЋYџДЌZџГЋZџВЊYџВЊYџДЌZџДЌZџВЊYџВЊYџГЋZџДЌZџВЊYџВЊYџГЋYџЕЌZџГЋYџВЊYџВЊYџГЋYџЁšSџzyoџУУУџ№№№џюююџѓѓѓџЏЏЏџ џџ џЛЛЛџћћћџЖЖЖ№™™™№ЮЮЮџЪЪЪџUUUџџџ[[[џЬЬЬџЮЮЮџаааџЩЩЩџ……†џ‰…XџВЊXџВЊYџЌЄVџЋЃVџБЉYџБЉXџБЉYџБЉYџБЉXџВЊYџБЉXџАЈXџВЊYџВЊYџБЉXџВЊYџЏЇXџВЊYџАЈXџГЋZџГЋYџГЋYџЇŸTџzxiџЗЗИџяяяџюююџѓѓѓџЋЋЋџџџ џЗЗЗџњњњџЖЖЖ№™™™№ЭЭЭџЭЭЭџЙЙЙџtttџvvvџЛЛЛџЮЮЮџЮЮЮџаааџУУФџ€€џŠVџЕЌYџ–Oџmh7џwq;џІžSџ”ŽJџ‚|Aџ{@џ—KџЕ­[џš“Mџ‹…EџДЌZџЌЄVџwr<џpk8џ“JџГЋYџ}w>џ“ŒIџЇŸSџГЋYџЋЄUџ|ydџЊЊЌџюююџюююџяяяџфффџuuuџ666џ|||џыыыџїїїџЖЖЖ№™™™№ЭЭЭџЬЬЬџЭЭЭџЯЯЯџЯЯЯџЭЭЭџЬЬЬџЭЭЭџаааџНННџ||yџ•TџЕ­Zџ–Kџid4џ|v>џЅžSџ‹…Fџfa3џd`2џ‰GџЖЎ[џ“ŒIџ€z@џДЌZџЋЃVџYU,џSO*џƒ}BџДЌZџea3џZV-џuo:џГЋYџЏЇVџ|_џŸŸ џьььџэээџюююџ№№№џяяяџцццџёёёџєєєџіііџЕЕЕ№™™™№ЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџаааџЖЖЖџyytџ›•TџДЌYџЎІWџ˜‘Lџ˜‘LџЎЇWџЋЃUџЋЃUџЊЃUџЋЄVџГЋYџЌЄVџЈЁTџВЊYџБЉXџ–Nџ˜‘LџЈЁTџГЋYџЁšPџ—KџЃœRџВЊYџБЉWџ„€[џ””•џшшшџэээџюююџяяяџ№№№џђђђџђђђџѓѓѓџіііџЕЕЕ№™™™№ЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЯЯЯџЕЕЕџyytџ™’SџЕЌZџГЋZџЕ­ZџЕ­ZџГЋYџДЋZџДЋZџДЌZџГЋZџГЋYџГЋZџДЌZџГЋYџГЋYџДЌZџЕ­ZџДЌZџГЋYџДЌZџЕ­ZџДЌZџГЋYџБЉWџƒ[џ’“”џчччџэээџэээџюююџяяяџ№№№џђђђџѓѓѓџѕѕѕџЕЕЕ№™™™№ЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЮЮЮџФФФџ„„…џ|`џœ–SџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЃœTџЂ›Tџ‘ŒSџyxmџЎЏЏџьььџьььџэээџюююџяяяџ№№№џёёёџђђђџѕѕѕџЕЕЕ№šššяЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЯЯЯџВВВџƒƒ‚џyxqџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyxnџyynџyyoџ||xџžџпппџыыыџьььџэээџюююџяяяџ№№№џёёёџђђђџѕѕѕџДДДяŠŠŠЯЫЫЫџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЭЭЭџЯЯЯџУУУџААБџ­­­џ­­ЎџЎЎЏџЏЏАџАААџААБџББВџВВГџГГДџДДДџДДЕџЕЕЖџЖЖЗџЗЗЗџЗЗИџИИЙџЙЙКџКККџККЛџЛЛМџММНџЩЩЪџуууџъъъџъъъџыыыџьььџэээџюююџяяяџ№№№џђђђџ№№№џЮTTTYІІІщШШШџЫЫЫџЫЫЫџЫЫЫџЫЫЫџЫЫЫџЫЫЫџЫЫЫџЬЬЬџЭЭЭџЯЯЯџбббџвввџгггџдддџеееџжжжџзззџиииџйййџкккџлллџмммџнннџоооџпппџрррџсссџтттџуууџфффџхххџцццџчччџцццџчччџшшшџщщщџъъъџыыыџьььџэээџюююџыыыџПППщYYYYNNND}}}žŒŒŒДŒŒŒДŒŒŒДŒŒŒДŒŒŒДŒŒŒДŒŒŒДДДДŽŽŽДŽŽŽДДДДДДД‘‘‘Д‘‘‘Д‘‘‘Д’’’Д’’’Д’’’Д“““Д“““Д“““Д”””Д”””Д•••Д•••Д•••Д–––Д–––Д–––Д———Д———Д˜˜˜Д˜˜˜Д˜˜˜Д™™™Д™™™Д‹‹‹žSSSDrrrzzz  џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ( @ УУMMMЎЎЎяяяёёёѓѓѓѕѕѕіііјјјњњњћћћ§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЬЬЬRRR???~~~_~~‘‘‘~’’’~’’’~“““~“““~”””~•••~•••~–––~———~———~˜˜˜~™™™~™™™~ššš~›››~›››~œœœ~œœœ~~~žžž~ŸŸŸ~ŸŸŸ~   ~   ~_AAAЂРРР§ЩЩЩџЪЪЪџЫЫЫџЭЭЭџЮЮЮџаааџвввџбббџбббџгггџдддџеежџзззџиииџййкџлллџмммџнооџпппџрррџуууџшшшџщщщџъъъџьььџэээџюююџ№№№џшшш§ЉЉЉЂЌЌЌђЮЮЮџЭЭЭџЮЮЮџаааџбббџгггџдддџЗЗИџ••’џ‘‘‹џ’‘Œџ’’Œџ“’џ“’Œџ““џ”“џ““џ”“џ””Žџ””Žџ•”џ˜˜“џМММџыыыџ№№№џёёёџѓѓѓџѕѕѕџіііџњњњџЯЯЯђЎЎЎіЭЭЭџЬЬЬџЭЭЭџЯЯЯџаааџгггџУУУџ…„wџ–‘WџŸ™Wџ ™WџŸ™WџŸ˜Wџ ™WџŸ™WџŸ™Wџ ™Wџ ™Vџ ™Vџ šWџ ™Vџ›•Vџ…‚kџХХЦџёёёџёёёџђђђџєєєџѕѕѕџјјјџбббіЎЎЎіЭЭЭџЮЮЮџаааџЯЯЯџаааџгггџВВГџˆ„cџВЊWџГЋYџЇ SџЌЅVџГЋYџІžRџЏЇWџБЉXџЅRџВЊXџАЈWџЅžRџВЊYџДЌYџ•XџЅЅЄџяяяџ№№№џђђђџѕѕѕџїїїџјјјџбббіЎЎЎіЮЮЮџІІІџƒƒƒџОООџаааџвввџЉЉЊџŒˆ_џВЊXџВЊYџid4џ‡CџАЈXџ^Y/џ˜‘LџЄœRџYU-џЈЁTџœ•Nџ[W.џЌЄVџГЋYџ–Vџš™•џыыьџ№№№џ№№№џЯЯЯџбббџїїїџаааіЎЎЎіХХХџ666џџsssџбббџбббџЁЁЁџ‘Œ[џГЋXџДЌZџЉЁTџ­ЅVџГЋYџЇŸSџЏЇWџБЉXџІžSџВЊYџАЈXџІŸSџВЊYџГЋYџЂœVџ‘‘ˆџццчџђђђџЩЩЩџ%%%џ)))џгггџвввіЎЎЎіЩЩЩџ[[[џџŽŽŽџаааџаааџ˜˜—џ—‘YџЎІVџ˜’LџЇ TџЇ TџЅRџ­ЅVџ­ЅVџЊЂUџБЉXџЁšQџЅRџ­ЅVџЇ TџВЊYџЈ VџŒŠ|џппрџђђђџЦЦЦџџ"""џаааџвввіЎЎЎіЮЮЮџХХХџЙЙЙџЪЪЪџЭЭЭџЭЭЭџ‘‘џ—XџŸ˜Oџql9џ—Kџ…Bџql9џœ•Nџž—Oџ•KџЋЃUџd`2џ|w>џ–Oџid5џ•Kџ­ІWџˆ†rџжжиџяяяџэээџХХХџШШШџєєєџЯЯЯіЎЎЎіЭЭЭџЭЭЭџЭЭЭџЬЬЬџЭЭЭџЪЪЫџŒ‹„џЁšVџАЈXџ ™PџЋЃUџЌЄVџЊЃUџЏЇWџЏЇWџ­ІVџБЉXџЁšPџЇŸSџЏЇWџž—OџЊЂUџАЈWџ‡…iџЭЮЯџяяяџяяяџѓѓѓџєєєџѕѕѕџЮЮЮіЎЎЎіЭЭЭџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЬЬЬџ••’џ‰[џЅžVџІŸWџЅžVџЅžVџЅžVџЅžVџЅžVџЅžVџЅžVџІŸWџЅžVџЅžVџІŸWџЅžVџ›”Uџˆ‡yџззиџюююџюююџяяяџёёёџєєєџЮЮЮіЌЌЌђЮЮЮџЬЬЬџЬЬЬџЬЬЬџЬЬЬџЮЮЮџПППџ““џ‰ˆ~џŠ‰џŠ‰џŠ‰џ‹Š€џ‹Š€џŒ‹џŒ‹џŒ‹џŒ‚џŒ‚џŒ‚џŽƒџŽƒџ’’ŒџПППџъъъџьььџэээџяяяџёёёџєєєџЫЫЫђ‘‘‘ЂРРР§ШШШџШШШџШШШџШШШџШШШџЪЪЪџЩЩЩџХХЦџЦЦЧџШШШџЩЩЪџЪЪЫџЬЬЬџЭЭЮџЯЯЯџаабџббвџгггџддеџжжжџззиџллмџуууџфффџхххџчччџшшшџъъъџттт§ЅЅЅЂ@@@~~~_~~~~~~‘‘‘~’’’~“““~“““~”””~”””~•••~–––~–––~———~˜˜˜~˜˜˜~™™™~™™™~ššš~ššš~ššš~›››~œœœ~œœœ~~~_AAANNNЎЎЎююююююююююююяяя№№№ђђђѓѓѓѕѕѕїїїјјјњњњќќќ§§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЧЧЧRRRџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ(  УУ•••ЌЌЌЏЏЏБББГГГЕЕЕЗЗЗЙЙЙЛЛЛНННПППСССУУУХХХЦЦЦЎЎЎŽŽŽ+ŸŸŸHЂЂЂIЄЄЄIЉЉЊIЌЌЎIЎЎАIААВHВВДHДДЖHЖЖИHЗЗИHДДДHЕЕЕHЖЖЖHЄЄЄ+ЗЗЗмШШШњЫЫЫљЬЬЬљЗЖГљЎ­ЅљАЏЇљВБЉљГВЊљДДЌљЖЕЌљТСНљфффљыыыљюююњммммПППќЮЮЮџбббџТТТџ›—lџ šWџ ™XџŸ˜WџŸ˜WџЁšXџ ™Wџž™fџааЭџєєєџјјјџчччќЕЕЕћjjjџЎЎЎџККЗџЂœ`џЃ›PџЁšPџ–Nџž—NџЃ›QџЁ™OџЇ ZџСРИџоопџŒŒŒџЯЯЯћИИИћ„„„џЖЖЗџГВЌџœ–Wџ™’Lџ™’LџЅRџІŸSџ–Jџœ”MџЁšSџИЗЉџллмџ†††џЭЭЭћПППќаааџЯЯЯџАЏЊџ›•\џŸ™Uџ ™VџЃWџЃWџ—Tџž˜Uџ—WџЕГІџяя№џєєєџфффќЗЗЗмЧЧЧњЧЧЧљССРљЉЈЁљЇІ›љЉЈљЊЉŸљЌЋ љЎЌЂљЏЎЃљВБЉљггвљхххљшшшњзззмŽŽŽ+žžžHŸŸŸIЁЁЁIЅІЇIЇЇЉIЉЉЋIЋЋ­IЌ­ЏIЎЏБIААГHГГЕHБВВHАААHВВВH   +•••ЋЋЋЌЌЌЌЌЌЎЎЎАААВВВДДДЖЖЖИИИКККНННПППСССТТТЊЊЊџџџџџџџџџџџџchirp-20240224/chirp/share/chirpw.10000644000175000017500000000545114553436565015646 0ustar hibbyhibby.\" Hey, EMACS: -*- nroff -*- .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) .TH CHIRP "1" "January 2024" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: .\" .nh disable hyphenation .\" .hy enable hyphenation .\" .ad l left justify .\" .ad b justify to both left and right margins .\" .nf disable filling .\" .fi enable filling .\" .br insert line break .\" .sp insert n+1 empty lines .\" for manpage-specific macros, see man(7) .SH NAME chirpw \- A tool for programming two-way radio equipment .SH SYNOPSIS .B chirpw [\-h] [\-\-module module] [\-\-version] [\-\-profile] [\-\-onlydriver ONLYDRIVER [ONLYDRIVER ...]] [\-\-inspect] [\-\-page PAGE] [\-\-action {upload,download,query_rr,query_mg,query_rb,query_dm,new}] [\-\-restore] [\-\-force\-language FORCE_LANGUAGE] [\-\-no\-linux\-gdk\-backend] [\-\-install\-desktop\-app] [\-q] [\-v] [\-\-log LOG_FILE] [\-\-log\-level LOG_LEVEL] [file ...] .SH DESCRIPTION This manual page documents briefly the .B chirpw command. .PP \fBchirpw\fP is a tool for programming two-way radio equipment It provides a generic user interface to the programming data and process that can drive many radio models under the hood. .SH OPTIONS This program follows the usual GNU command line syntax, with long options starting with two dashes (`--'). A summary of options is included below. .TP .B \-\-help Show summary of options. .SS "positional arguments:" .TP file File to open .SS "options:" .TP \fB\-h\fR, \fB\-\-help\fR Show summary of options .TP \fB\-\-module\fR module Load module on startup .TP \fB\-\-version\fR Print version and exit .TP \fB\-\-profile\fR Enable profiling .TP \fB\-\-onlydriver\fR ONLYDRIVER [ONLYDRIVER ...] Include this driver while loading .TP \fB\-\-inspect\fR Show wxPython inspector .TP \fB\-\-page\fR PAGE Select this page of the default editor at start .TP \fB\-\-action\fR {upload,download,query_rr,query_mg,query_rb,query_dm,new} Start UI action immediately .TP \fB\-\-restore\fR Restore previous tabs .TP \fB\-\-force\-language\fR FORCE_LANGUAGE Force locale to this ISO language code .TP \fB\-\-no\-linux\-gdk\-backend\fR Do not force GDK_BACKEND=x11 .TP \fB\-\-install\-desktop\-app\fR Prompt to install a desktop icon .TP \fB\-q\fR, \fB\-\-quiet\fR Decrease verbosity .TP \fB\-v\fR, \fB\-\-verbose\fR Increase verbosity .TP \fB\-\-log\fR LOG_FILE Log messages to a file .TP \fB\-\-log\-level\fR LOG_LEVEL Log file verbosity (critical, error, warn, info, debug). Defaults to 'debug'. .SH AUTHOR chirpw was written by Dan Smith. .PP This manual page was written using help2man for the Debian project (and may be used by others). chirp-20240224/chirp/share/plus-icon.png0000644000175000017500000002252014442552774016701 0ustar hibbyhibby‰PNG  IHDRєxдњмzTXtRaw profile type exifxкэ˜Yrф:EџЙŠ^g‚ЫсёvаЫяJ™UЖгUЎсЇ#^ІS’)1\\ШЌџўГЭј„PЃ‰ЉHЎ9[>БЦъbЏO;Ggу9>>ў}3nž7mїєн7ЯНё›UџФoўс9ЃЎћž3ъКO<їбo/М6Ек ЬёІЁев‡šўЈI_?›_№Џ П.h•=rZ^Є Ÿ–Е'_bЊ> ‘e НA „i@;jXfјо,™н ŒфƒH<КЂi—ЦЖQˆ [мjС—MyБn•й*yЖKЋетMЮ5Єо;•oљ”COдЉ!ъj7ї™žbйфно.”ML­kuЭЃnџAfТ,вƒиJажО—d?“ŽlˆBd вwЎu;ЛG*-Э!Е…™зZХu#.ЫZЄo№pЖйWЫКБѓp{H*><ЎЬT—дп–ŸлЎHO*nё+ކ‰v•„э/ЁђЫFПiaЈ“Т–Њl[Є)#З<ЇјUФЦMZЌФm€ng›ђDuзŸЭш#—ІZj LЫ9ЛЧжgmЯлм4Чœч.›@r~'pчМъы,ыїMvœ3qSЏ[€џЧЛПГ9ѓ‹>нЌљИлплЌљИлплЌљkh&'UŸЎ“Ъo5ЎI -„ДI’ЭщУвdЮŽˆW[ЌЩу(>Q )>Ž|АLЫЙЯйЂЌЩkШ(ЙG‚™5ЊvZу˜ЯяcЁVѓ9ћТЉ'ИмxщШЂ:'+џЎYЦT зќkі™Ћ5§ЬЖgў5ћЬEдcv‚ЏТyЯXNћd/U ”тФkЁь‹бŠлГЧ;?v‡л Ю>‚jо ЮŸfuЄчм3уwяА3ЬJŸ<:ьМцЕTюFƒHЅ‚2 ЊСц!ћRs™НЌYА4XУcЮYЧЂњЏšf}ижМ2.јгЛc…OЭќЮ цi‡ЗГ?1ѓcіЧХЭЗљq ’>Л–}Кƒ3т0ѕЖа„›5l‘ЖcDеЭ31o—ЩV…Ћ”кi0rтізм—ЁaНфЇoоg#/Oс)!7|Ўёеg”›˜л˜`+кЮЮ`хN!­žРх<Жœ=/йdп‹FЊœ Єнe^ћIС5_ЊШЋK™|NеєО‡ša?{”жЬ;КЇЭЂQTOОЉI-=JjxЁd>h…’ЏЋ‡чZцk48Ж+„‚ЌоШ”IэZФIЄzёWт Hjg„&ФОUџM-kSъZЎ-hmNVKР2БЎЈђIю~[Ыќ—!?Ќ”KI{4R=чЩчHС?šђЯЊfŠЊfео5ЉГ./хоа›”dhсŸњJЧXєЌnkСеДљХ2tЃЏгПp(№k~ЉџРГїФ=–л#ИТ}m“ЌмЂ?kєEМ™49kи:—’(‘ƒНd ь”Јљ ейžŒеєЮщТЮцŒ–bи‘VZ'рНg+Ош|Э№z&З„oѓRœBЪ™n~Вњ Вчн шлfA›Њі0ЮтІRTbU˜mь[{њОшjNЩмGЄО@˜ЦџA&}ЅЧэїЌ6єгƒˆІцђ Е•јэиљ‚ZТ!™z{Ј›јљœџЪдзdѓЪРЯЙŠО6Eч›}#5Ф 0EŒз<™@пЛ6Эшgž№K“IQЊpnŸkЗєѕ(–К0FЇЊ„>Pь;m^;ић&аЭŸБаoМЪ| VoxзGњя2Ÿ“Ћ'ѓњя2bПєљЅЭšЯXцЏnжќ•ўA~(ˆнl…{ еOЪТ›B ХЖдн€=Œ>Оž>ЪPUЁ›> nћx4QГхолiЂb=ЏMO%E{ЈшшЁ§эыti <ЙЖУнЦUЩq:к8ЁŽjИЛИНвеХ•ГњTˆZЗљ#“HНKяЛ/Ђ+€eО‘:сЩ§цJIZ­ЏЧ—єŽЅa?уnj ЯТІуедZзbo2ЎІЖlЊћijЛ6Е'IPы2йьрYОЦь\wН$Kэ_ЖRЙЈUeъ‹$LKрј~B€`Кu’ЪCfŽ4еСѕ9Шх­ JйЎtўїнШџЅ bBJеќњтzPX+…iCCPICC profilexœ}‘=HУ@†пЖjEЊvqШP]Д ZФQЋP„ ЁVhеСфв?hвЄИ8 ЎЋ.ЮК:И ‚рˆЋ‹“Ђ‹”ј]RhуЧ=МїН/wпўz™ЉfЧ j–‘JФ…LvUОЂ }4c“˜ЉЯ‰bžуы>ОпEy–wнŸЃWЩ™ № ФГL7,т тщMKчМOfEI!>'7ш‚Ф\—]~у\pиЯ3УF:5O& m,З1+*qŒ8ЂЈхћ3.+œЗ8Ћх*kо“П0”гV–ЙNk ,b "ШЈЂ„2,DiзH1‘ЂѓИ‡Шё‹ф’ЩU#Ч*P!9~№?јн[3?5щ&…т@ч‹mŒС] QГэяcлnœgрJkљ+u`ц“єZK‹§лРХuK“ї€Ы`№I— Щ‘Дќљ<№~Fп”nž5ЗoЭsœ>iъUђ88F ”НюёююіО§[гьпГеrСьzаь iTXtXML:com.adobe.xmp мEœ[bKGDџџџ НЇ“ pHYs‰ЌвИtIMEч52ШrН5 ИIDATxкэм?k]їЧё,‚›уC~В ХиŽˆI/‹ ]Лxp†jэа)э#ШH@;tT ^эКnЫ€Н]ќч’ќ>ЩыжfаB’­ЕЯКЎГЦђocгыьў‹РЬО—щЯ2мр)п§ŸKђ[K№Zkэo]з§гю№ј‹џ\vџе`(VњГ Рcќ2Ор–ЅўlC№ˆwџѓёy0Lяєg€‡x-Щ13tЌ?у<ь&€ gЋЇєЋb29žфИ%€;оŸuў‡Яўg`„L8ы^Ю:Р1рЌCŒЏЩœu@€ € @€ @ @€ @ ЩŽ g`|ю›pж!Цgг€ГрEрЌCŒР]Ю:РШTеэ$w, иўЌC№џ`Р‡№тpЦ!FрZќ 0L›§‡рi\ЕdЭР­ѕg€GИ’ф–€ЙеŸmsрA’UKВкŸmL‘yLŸЎыўбZћI’гжfмхЊњШ ю№є>LВa`†mєgюА‡Лi­]Mђf’‹3цЫ$TеwІь=ЖZkŸ$YьГ`=ЩћUѕ­)Ял­ЕЯГћqЭY‹SюR’?Wе–)Ілœ fЧd29“d%Щ)kSцzvџкџ Sž_,'ɘdЩРЛ™н/љY7…`џBрD’I’х$'-ь“й§œПЊъ+s6^Hr4ЩЫ§у%ЯяT8“фm3<““И|№v’|“фыўqЯ_і рЩav>Щя,ёLўXUО>ž_€ @€ @ @€ @€@€ @€ € @€ @ @€ @€ € @0;&АŸoL`;0>_›Рv РE л€Иgл€‘ЉЊя’мАФžншЗЬЌuи Œ№F€ lЦv%Ћњ*ЩMK<Е›§f€€™Зf[€ёнXOrнOtНп 0Ћ&АL‹yРўшКюnkm>ЩYk<дЅЊњ‹РЂЕјЗ‡YЯўС№]€Дж6’œKВ`‘$Щ—IоЏЊ-S€€!GРvkэг$KI^љI>ЈЊo§f€€1DРVkэГ$‡“œщ —“ќЩWўТј3ЌЩdђV’•$‹#љ‘o%Y­ЊЋž}0і8”ф|’‹юпlfї§ЎTеЯ:рћјЯП NњЧ+3ў#нЩюїњW’kUЕэY<9Ž'9жпXHrdŠ_З;Iюїяє7“м­ЊлžE€1ј7ФlвSѓ”IENDЎB`‚chirp-20240224/chirp/share/chirp.desktop0000644000175000017500000000046114531336265016754 0ustar hibbyhibby[Desktop Entry] Type=Application Version=1.0 Name=CHIRP GenericName=Radio Programming Tool Comment=Program amateur radios Icon=chirp Exec=chirp %F Terminal=false MimeType=x-scheme-handler/chirp Categories=Utility;HamRadio Keywords=Hamradio;Programming;Handheld;Radio;Amateur;Programmer StartupNotify=true chirp-20240224/chirp/share/chirp.png0000644000175000017500000100144614562640504016072 0ustar hibbyhibby‰PNG  IHDR\rЈf pHYsУУЧoЈdtEXtSoftwarewww.inkscape.org›ю< IDATx €пџџџ6}~ IDATўнs IDAT{(4 IDATzІЋ IDAT €п ѕ­ IDAT6’ф IDAT,\Ф{ IDAT>ЈЈё IDAT €п˜сЄ| IDAT<`0ўўўџџџџџџџџџџўўўј§§§уаŸџџџЦџџџ™Vјјј,,,џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџќќќ№№№фффџуууњњњї§§§Јjџџџјџџџ‰pXXXHHH!!!џџџџџџџџџџџџџџџППП–––ОООџџџћ§§§ŽџџџxџџџвџџџZZZ``` џџџџџџџџџџџџџџџdГ‡- IDATыыыmmmџИИИхўўў0џџџьџџџ7С“““џџџџџџџџџџџџџџџџџџТТТWWWџљљљљ§§§>џџџЫџџџ(д///ŠŠŠ џџџџџџџџџџџџџџџфффDDDџшшш§ўўў*џџџлџџџ ч   џџџџџџџџџџџџџџџџџџѓѓѓ---џёёёє§§§џџџєџџџа /ІІІџџџџџџџџџџџџџџџџџџеее???џћћћЮўўў4F§§§/„„„џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ,,,‚‚‚џџџ3Cџџџц000–––џџџџџџџџџџџџџџџџџџ&&&џъъъхќќќKњњњoooџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџŠŠŠ§§§HџџџЦ)))9ЃЃЃџџџџџџџџџџџџџџџ?Nv? IDATџџџџяяяЦџџџ<3FFFџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ>>>3222џџџџџџџџџііізззсссёёёєєєџџџџџџџџџ """---џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџNNNБББCџџџ!!!џџџџџџџџџџџџѕѕѕЖЖЖЕЕЕггг їїїїїїшшшііі(((RRRVVVџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ???C€ УУУџџџњњњЂЂЂЂЂЂ777---чччеееЪЪЪччч^^^uuuџџџџџџџџџўўў€pЛЛЛзззxxxїїїNNN444зззБББёёё–––AAAџџџџџџџћћћ‘џџџџџџЗЗЗ```###~~~666)))vvv>>>]]]žžžџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЕЕЕ€€€[[[:::џџџ№№№№№№јјјIII‚‚‚ччч|||џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџггг‚‚‚^^^777чччРРРЯввёююќљњ§ќћ .--<;;&&&///oooŽŽŽ&&&UUUџџџџџџџџџџџџџџџEЫо IDATџџџџџџџџџџџџ €пџџџыыыqqqBBB777їїїЊЌЌШЧЧ02*Z_-/ њєѓъзжхЫШ‘‘()*[YX!!![[[sss%%%000џџџџџџџџџџџџџџџџџџџџџџџџ“lЙЙЙrrrщщщmmmыыы“••§ 2ei#%єщшЯŸš№мкjhh###ЇЇЇьььНННџџџџџџџњњњ•џџџЮЮЮУУУYYYђђђŒŽŽ!#B‚ˆ#% =w}DG‘‘уууNNNпппВВВџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџžžž888ўўў—™™ 9ms.X] @D•——ііі DDD„„„ўўўџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџъъъЧЧЧAAAЩЩЩцщщ9pu1`d ЗИИBBBшшшХХХџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџОООўўўБДД)PU -Z_ПППђђђ...ГГГџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЪЪЪ(((пппђ№ё$EH02 ббб(((ТТТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџкккббб,-47авв рррјјјџџџџџџџџџџџџРкх IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўўўшшшхшш$&#$чшшўўўрррџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџііі§§§ ёёё  ђ№№ѓѓѓџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ§§§ў§§џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ ёёёїяюѕыыѓѓѓћћћџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяїюэіьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёёјюэіэыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№јюэїьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџеееѕююыижъегќјј 58нНЙђцц $DGтЧФэмл (LPхЬЪъзе +QUиДАљёё&(02ызецЮЬ @"BDярпП…ётсўћћњѕєћііѕыщџџєщш§њњшбЯіьы ћћћђђђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№ іюю њєѓшбЯнОЛнОЛ ўќќГmf%&ѕьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їяээлкёху"$ "0[_зДАшбЯ "#џўўхЭЫўќќ36 #DG#BE !@Cіэьююю џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№оюэюомЬ˜TЁЈ  /1сХТ024chщдвУ‹†ћїіљђё5dh5fkїыъюююџџџџџџџџџњњњЗЗЗВВВЬЬЬюююAAANNN<<<џџџџџџџџџѓѓѓ№№№ џџџџџџџџџ№№№јикџџмМЙыйз,.B~„СˆыижИxr=sy%&їьы(&юююџџџџџџ‡глA IDATџџџџџџГГГwwwыыыўўў§§§яяяпппššš333...џџџџџџЬЬЬАААТТТііі888LLLAAAџџџџџџџџџџџџџџџщщщїяю&(џџџЫš•')#$E„‹Р†€ѓчцМ€y4bg#CFѕьы8яяя%%%џџџџџџџџџџџџ”””ўўўњњњЮЮЮ@@@›››SSSџџџъъъ~~~ЮЮЮ§§§њњњФФФХХХ"""„„„###џџџџџџџџџџџџлллѕюэ!GˆŽыижќњњ 58!@C(* 69 23  'LPљѓђ " D‡оСОљєѓѕыъ *+/[_џџџѕюэ№№№џџџџџџƒƒƒ———ўўў§§§§§§ccc GGGџџџџџџџџџкккjjjѕѕѕўўўўўўннн^^^‹‹‹:::џџџџџџџџџџџџџџџ№№№ћљљћіі !#!# =@4646/2/2#BE*OS#%#%ј№я§ќќюююџџџџџџЛЛЛўўўўўў]]]вввџџџџџџыыыjjjђђђћћћўўўљљљtttкккџџџџџџџџџџџџџџџџџџяяяіюэѕьыџџџэээџџџџџџџџџџџџ§§§wwwџџџўўўƒƒƒџџџџџџ~~~ѕѕѕўўў§§§uuu§§§џџџџџџџџџџџџџџџєєєћћћ їяюіьыѓѓѓњњњџџџџџџФФФсссўўўљљљІІІєєєџџџџџџџџџџџџЬЬЬЭЭЭћћћ§§§щщщВВВџџџџџџџџџџџџџџџџџџџџџёёёїюэіьыюююџџџџџџџџџџџџЖЖЖМММџџџАААќќќЋЋЋџџџџџџџџџџџџџџџ№№№іюэѕььюююџџџџџџџџџааањњњжжжџџџџџџџџџџџџУУУ§§§лллюююџџџџџџџџџџџџџџџ№№№јююјьъюююџџџџџџџџџЇF‹ш IDATшшшћћћцццџџџџџџ €пђђђѕѕѕцццџџџџџџџџџџџџџџџ№№№јюьіыъяяяџџџџџџџџџџџџџџџ  џџџџџџ№№№юююџџџџџџџџџџџџџџџ№№№їюэєьь№№№џџџџџџџџџџџџџџџџџџџџџџџџ ќќќџџџџџџџџџџџџџџџџџџёёёіюю§љљјєѓяяяџџџџџџџџџџџџџџџBBBљљљ>>>џџџџџџџџџџџџџџџџџџџџџџџџёёёіё№џўўѕьъэээџџџџџџџџџџџџLLLњњњ///џџџџџџџџџџџџ777џџџџџџџџџџџџ№№№џўўјё№ѕьы ќќќёёёџџџџџџџџџџџџџџџYYY‚‚‚џџџџџџџџџLLLOOOџџџџџџџџџџџџџџџџџџяяяіюэіьыюююџџџџџџџџџџџџџџџџџџ€€€777WWWџџџџџџBBB  XXXџџџџџџџџџџџџџџџџџџњњњѕѕѕ їюэіььююю џџџџџџџџџџџџЌЌЌЉЉЉџџџџџџџџџџџџ………ƒƒƒ џџџџџџџџџџџџџџџџџџ№№№їююіьыюююџџџџџџџџџџџџџџџ† IDAT111РРР;;;ФФФџџџџџџ$$$‹‹‹ttt§§§ўўўwww;;;џџџџџџџџџџџџ №№№їюэызеаІЂ№рп 57.Y^ џ§§иДАнНЛіюь )NR =@шбЯвЉЅёус9=-VZђцхЯЁœьки,/2_c їьы'%юююџџџџџџџџџџџџџџџ)))ЭЭЭšššюююўўўјјј%%%~~~OOOџџџџџџџџџ;;;ŸŸŸuuuыыыќќќ„„„:::џџџџџџџџџџџџ№№№уяютЧФЦ‹џџџќљјмНКцаЮJ‹’Т‹…шваўќќ№срШ–‘ёфт/Y^нНКЫ›–џџџџџќыыйЗГчаЮGˆŽяпнК{uџџў§§фЪЧчЯЭJ“ іьы97яяя###џџџџџџџџџџџџџџџџџџnnnmmmЯЯЯвввччч:::!!!џџџџџџџџџ(((ЏЏЏБББЋЋЋмммќќќџџџOOOZZZ џџџџџџџџџџџџ№№№лнп§љљЪ˜”џџџўћћіэьеЏЋ.X\уЩЦшбЯў§§џ§§зБЎ =AљѓѓЭŸšџўўўћћђцхкЗГ(MQЧ•џўўџўўўќќЫœ—?x~џџєээ№№№џџџџџџџџџџџџџџџ222222џџџџџџSSSSSSюююфффюююџџџџџџџџџџџџюююїюэюроќљјўћћцЮЫ.X\шваџъевэмйџ§ўўќћцЮЬ(MQњѕѕётсўќќщегџџџї№№§ќћюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџрррѕяю§јјџћїїћїїџўўџћјјќјљ§њіі§љјџќќџўўіьыэээџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№њііќљј"#џџџ*+'(ўќ§$&$%§ќќ+- ѕьыѓѓѓљљљџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їюю *PT-UZ"BE -.+- %FI)OS3af3`eіьыюююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёё§§§ їюэ-UY,SX Eƒˆ C€†)+<>w|)+іэыюююџџџџџџџџџџџџj3їU IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџђђђіюэ+SV)ORёус  B}ƒњєѓѓщш/Z^,UXёут  !?B =@ђхф їьы"юююџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяїяю!#  "$іыы$"яяяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ№№№їюэѕэы№№№џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџёёёщюэ§њњїѓѓяяяџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџяяяљё№єщчэээџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџїїї јёёькйѕѕѕ№№№&&&џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ їїїї№№эки" ппп###џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыљїіђцх§њњфЩЧ/.-ооо111џџџџџџџџџЮ@9п IDATџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ&&&фффњњњцЭЫтЧФ///ййй<<<џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ,,,ллл855мИДўќќќљјеЉЅCAAуууоооVVVџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџBBBЫЫЫ???ќћлЙЕгЉІ DDDУУУCCCџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџSSSЬЬЬёёёXVVбЅЂьйиоПМмЙЕ_]]юююЩЩЩeeeџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ555(((ЖЖЖ222EEDУŠƒызенНКЬ›–a``###ЉЉЉ:::DDDџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџxxx^^^666###POOИƒ~,UX'KOјё№бЃŸфЩЧbaa444ЭЭЭйййЦЦЦџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ///___šššyyyNMMЉЌЌнЙЖ>A46 џџџюнлуЧФмКЗzyxуууЄЄЄџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ“lЙЙЙџџџ§§§jjjчччoooќќќЩЩЩЫЭЭкйй§ќќ  ўњљїяяєыщњїї$&&EBB...ььь‹‹‹UUUˆˆˆџџџЖˆ IDATџџџ џћћћ• €п“lЙЙЙџџџѓѓѓ]]]ћћћhhhћћћяяяёёёќќќњњњќќќџџџїїїњњњќќќџџџііі$$$ррр›››;;;œœœџџџ џћћћ•“lЙЙЙџџџєєєtttвввddd%%%РРРЌЌЌdddџџџџџџ џћћћ•џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ •••888JJJиииДДДцццšššNNNџџџџџџџџџџџџџџџџџџџџџџџџџџџpЛЛЛџџџџџџеееŒŒŒЬЬЬ---222)))їїївввЧЧЧннн^^^rrrџџџџџџ џќќќ‘€ УУУџџџџџџдддЎЎЎОООщщщџџџџџџііі№№№щщщтттRRRhhhџџџџџџ€\ЃТТТ џџџџџџфффмммчччѕѕѕџџџљљљљљљџџџёёёџџџљљљїїїџџџђђђўўў&&&555***џџџџџџччч ZЛппп+++џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЛЛЛНџџџщњЭЭЭџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЦјU IDATџџџџџџџџџџџџџџџџџџџџџџџџБББјџџџъјјјЬЙЙЙџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџРРРџўўўЬ…йййиииџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџЏЏЏєєє…џџџх...˜˜˜џџџџџџџџџџџџџџџџџџџџџџџџ$$$џхххь§§§њњњ`ЮЮЮШШШџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ‘‘‘уууўўўmџџџЯ 0ЇЇЇџџџџџџџџџџџџџџџџџџџџџббб:::џ§§§Юўўў4џџџ ч   џџџџџџџџџџџџџџџџџџџџџёёё###џѕѕѕєўўўџџџєџџџіњњњ5ссс§oooђђђџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџррр***џєєє§ўўў3џџџєџџџ5Т“““ џџџџџџџџџџџџџџџџџџMз"Y IDATџџџИИИUUUџќќќјўўў?џџџЫџџџбўўўYYYaaaџџџџџџџџџџџџџџџџџџъъъbbbџМММтўўў1џџџюџџџ‡sWWWIII"""џџџџџџџџџџџџџџџџџџџџџџџџДДД’’’ФФФџџџ§џџџ”џџџpџџџ–Xљљљ +++ џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџњњњяяяфффўщщщќќќѕўўў­kџџџєџџџ5d1 ўўўџџџџџџџџџџџџџџџџџџџџџџіўўўфЮџџџЫџџџ~ х IDATR:Ѕi IDAT €п…Ф_ IDAT#–p! IDAT0#Ж IDATXЙR­ IDAT €пдbЇ IDATЏПZY IDATbзеž IDATАmс‘3IDATџџЭЏnТDIENDЎB`‚chirp-20240224/chirp/share/welcome_screen.png0000644000175000017500000007263014563632215017762 0ustar hibbyhibby‰PNG  IHDR Xšv‚pƒiCCPICC profile(‘}‘=HУ@Х_SE‘ЊƒD2T'ЛЈЧZ…"TЕBЋ&—~A“†$ХХQp-8јБXupqжеСU?@œœ]ЄФџ%…1їунНЧн;@hT˜fuХMЗЭt2!fsЋbЯ+ FLf–1'I)јŽЏ{јzхYўчў§jоb@@$Ž3УД‰7ˆc›ЖСyŸ8ЬJВJ|NЦž] YwœяcЧižСgрJoћЋ `і“єz[‹ƒлРХu[Sі€Ы`фЩMй•‚4…Bx?ЃoЪCЗ@пšз[kЇ@†КJн‡РD‘Вз}онлйлПgZ§§€ЈrЌЇЯНbbKGDџџџ НЇ“ pHYs з зB(›xtIMEш іTР IDATx^ьнyœUНїёowЯšЩ$3й—I23Y&Yиw˜" ˆ zн.Šˆ^Eёq}|ЎŠїЂWѕКм‹\DTTТО)ЪО†Щ$™ь3™ЕЛŸ?*5єrNеЉюžЩdцѓ~Нњ}–ЊъšгщпЏъT•ьо#)mxН?Ј(\<Ќ” 0tІЪ|ДН_вј€~Q\(ѓ:ЖJŠє‹тЫ2ЏуУA$`(m’єДЁW­Є$+яsoАє K@ШЛу™mнoШЛ+кIђ‚Щ*IѕђРШЛ.(шŒ[} -1Н6ЫЛ^цdyg‘ЪфmcГМyџAгo–§:›—$}Uо ъхПyg`.–єbРrПЅш†лј.•FйЗЇ˜WP2Ч4#Т 2џ8Юъ”Сtхќœ6‹ mЖШ§Чїѓ2oу‘A,ўЏЬЫъ—є5yG],’w'/гВvЩ§шuЉџ–y9iy‰ЩёіЎYт’Ю–є€В—”€$фн!ЪЖ_П%/шГD^0oћГw5rI@vHњЌТЇђХ%}SсЫѓ_ых%.aЗšЏ‘tЋЬЫиЈшз Зё=XN•yл.ъСpгŒWЫќУјOA2ќRљ}›rкФф%Йэ\ЏЙ]љ}wЪ ЂX"я‚ZгВ–єГ+{pёПњe*Eђ6™—‘–є'>oџxНyЧŸ фу2ЏЛ_вћњ™TЩќїNЫK&лЛц K@~ЎhЫ‹Щ›ПДЬ^IџЊhћМVљг§зŠ€~Й†уј,ƒ€ з1 РˆpŽЬ?Œ? ъ”сUeї[oiw“ђзqЉЅm&лѕПъdё'х/ЇWоД›BЭ–љ.Co(ќшЗT|—§HѕНђІзЃ\оЕ~hЉЏ”їYMыПмв'L•ьˆG™–dK@кхћBœ)ѓ2гђІ[nяш+2/ѓ+Ar Чё=X3Юc€ЁNцyЪ/uкЋIљ§lЉšŽ(оli›щH™Дџ%Ј“Сb™—SŠчˆ\)ѓВuкЋиф4™ћwJšаЏTўIцѕ?Ёшг‡2 ѓuлфˆ.l Ш;‚:…Ј’w омevШ;cPЈCeожпuЪ0\Чї`Ьd8i%В/ №ІFБnЕ”›пЁдa)rсЙ‰iЙ. ШHпћТhгРЈCь{Шќу”€Ьб›O;ї­6ДЫdš~аj(ѓ*ѓУКЂNП:ЬRўЄЅМэ†В †ВR:дRўˆЅМд–ZЪŸА”GЕCц›4ЉИГ ХВ% Х\ ™—ыrmРHпћТhгРЈCь{=ђ’\s”K]Ÿ)9Б]џс3% 'Ш~HЋЅ|•ЅмЦ6ЭkЋЬ›ђ2]и<икBKљ_-хЅ6пR^ЪРзјХd_їPА% Х*tЙ#u|я ЃuLЃ 0г:rЯІHЅЛўCВ_\!oюѕ`НІipйЎI[ЪїG#щГ –‘:ОG*Ц40 €У‡mzгВœї­†6Ћ e&k$Н–S6YљвЖ*п3’к хalˆ›h)п_t[Ъ‡ъn:Ж§ZЪѕлnCkћьЃбHпћc%H@€сУѕBєжœїmђVц*ь:„ЬOY.фь‡dŸђАПhЖЉV.ЯŽ(…э–rг­“ e ќlыFъјогР(A /ЫЛЫTЎЬЄ˜ы?|aгА–љGК а%ћlXЪїЖЛщ4YЪKЭЖўRо•Щє€=ЩОюбhЄŽя}1 Œ$ Р№b ђЇщЭgNДъK€Дъ“ŠОŸэЉр'YЪїЖлэкPXjЖЛž-Б”ТЖЌ—-хЃбHп…А]хŠ1 Œ$ Р№6 ЋеPЗкPdЄЕ9eSєцѓ@Z•яqyO.Фу–ђх–ђ§Хп-хGZЪKЭіtшC,хQM’љY'k5twњкŒдё]ˆbŸFߘF `xY)ѓ]ZZsўыл,щ9EgЛ$.ѓѕ…NП’Є‡eОИєйяЖЕ?xXонЫr'я)іƒЭЖ_—Ћ4зЁМгR^ш™А‘jЄŽя }–ђJKЙ+Ц40J€УЫIOЪ[хЭƒЮНО аN[rАЬ?єХ$ ВїџЊЅ|АU^Р”+&щ|CyЉuЩ|іЋJвЛ хQ}РRў'Kљh5RЧwСКc%H@€сЧ4 kŠЄЪK™€œ(ѓлIЪЃј™ЅМUв?[ъіПВ”_&ћХЎЅtЅќKВ?(бХЉ’Ž5”яєCљh7RЧЗ-™o)‚1 Р>pšМiXЙЏCYюѓ;ЂxIљЫ{СPfJVЂ*“wБЎщsuЋДзML’tГЬSЩrНGцmzPЇ Еђг2n—wKуbФ%}Rв,ѕU’6ЪМўoYњ„+ћпъЪ€~Й.–ygur№C™—лаЧХjх/Г#ЈC†с:ОKЕЄ~хжзUќ˜Юc€ЋFоYгeцk‹ŠЛыЬОŽДЄ/лбЛe_Ч.IчиЛ:Љ•єП$m“ЗL—­иD’О ћчњЕ П0ї8IШ[ЮOк}Rіѕ›ЮšЉ‘tЏьЃ)іЎyFS" Яё=˜ž”љГžдЩбpгŒhїШўьПnЖіvѓ^…Џ#-щл pГ‚зѕ EŸЦБTвї•&Т%@+ER%я)ёЖЯє Ђнšї8IЗ*{A H™М;r™ж’wіФenўaВ/'-щR{WЃб–€HУo|ІЩќ7Ћјgс з1 РˆіПШЄ%}ТклЭ4…ЏcЗ ?‚oR'я"ћ u&%§Yвg%%ятћ1’*ф=]њ`Iџ$щ*I/,Ч%@+E"yAЂiŠ\цgК]в%’Ы;ъZ&я фнч?dџcЪИЄ`ŒiР0 kQФуёђT*е$щLIЧH:ЊММ|ryyy"ЫsвщtX“Шc™6#u]ваЏЯd8lƒ4јл‘NЇгЉT*™JЅЖHzhяыwёxќеT*евœ Ы`Рў'‘H”'“Щ3$]:vьиcš››+—.][КtЉjjj”H$ЧУ3,ХbбўЉ jязљСdиВ‹ЉХbYAЋыВвщt^лRnwиВ нn[]аВќњАuјm]иклпЏ лоАѕеЇR)эмЙSќуѕвK/ЅŸzъЉžООО$§ ‘Hќ)™L’ˆ(šлП†`QWWлБcЧRIпž2eЪ ЇœrJйВeЫД`С•——+‘H„-bи0fЖ€/J ыZfЋ+ІПkЛА2з}`уК.[]1ћ;ЪzleЖ:л{—§e+Ге ж>0е'“Iuuuщ‰'žаѕз_Џ;юИЃЫ–-їHКМЎЎю;vьмг1FДр‘ @eeeМЇЇчЃёxќ;ЇŸ~zѕћпџ~555Ј3Х˜QD[™­.J—ОAuЖВ}Й\лйЪЂєМліK[[™­Юѕon*ѓп‡§“ЩЄž|ђI]qХњЫ_ўв%щг?щээM Аџš0ЌьM>ўЃЖЖі_?їЙЯUœўљšјЖююю •••w$“IЮ„ˆŒ@dуЦ‹эйГч{уЦћфЗОѕ­јI'ЄВВВАnУZXРдж/+4Р,v]ЙuAя§2зDСu=~™k{л{лrMe.ыrmg+ѓћGй_ЎыЫm;œіЉYY™;ь0Э›7/vЧwбнн=ОЎЎюŽюююМe@‘ѕєє|4‘H|э;пљNьШ#Д7ћ‹ЈІ‰K —[і>JпBкч– Ч}`*ЗЕ-f]AuЙЫѕпЛьЏЬі&a§ЃьПЬe]Aэrлњя§зТ… 5wюми­Зоzdwww›ЄП™—f$ ЂZ$щж/љЫ‰хЫ—‡Ен/˜‚1зг5рЫ,sm_ЬК2Ц(эsЫ†у>0•лкF]WЁm§ї.ћ+ГНIXџСкЎmcБ˜8р7.ЖrхЪS$§Vвfc'0и?ЏА/§ш­o}kљщЇŸжnПg ц2oщ*™ŸЭФ™икГЎ ЖQЗ-ї}1лeуњ9\|ПmЎ }л>J[гEц~_гv˜DYз`ьƒt:i\xс…:іиcЫ%§(Џ€ˆтtIЧ^tбEћ§5Rє Y*. "J0jтвзoWШЖхrйЎBжуК.зeG Ш]лšкл’S[›(ы2M“(Ÿ+ЈmUU•ЎИт I:NоП р„@_:яМѓдммжnП0XЙ-)1Е‹В.з`дЦЕo)Ж+Ъ>ˆТuDљ QіA”рндоп™m§џђwtY—пжEач J.>ј`}ій’єE€#Ў%}ъЉЇ:JУ]Xp•йЮ5ѓЙˆЅXW”`дФЕoдэ’ŠKЬЂ0m[:mŸNфЂа€<З­Ыў JJ\ ц>0mWцr/Кш"I:Fв,€Ўо)Ip@XЛ§Škœ+J 'Й' ХЎ+Jрk3Xћ@rKxŠMJlћРћэMlћ 7 wн_™эs•zHЅIJ\’ЅУ?мџпw ьџ“И •уЯ=ї\•——;ВУ)Ш“ьIIfЙщ}*•R:жіэлеггЃd2Љ\AAЄkџџЎлŸY5АЭьувǘm cк6Aлщђ9rыb1яš‡њњzUTT(+ђА}Ыж&lЬIoў}\­'З>hЛsЗЃІІF+VЌаwоy‚ЄяZ;Р^$ \yф‘G:;У™KP˜ЫјѕѕѕiЭš5ZЗnюЙчЕЕЕЉЛЛ[ЉTЪВЄьeь2ъЬїУ…џЗьэJ$ЊЈЈP}}НN8с-ZДH‹-в˜1cП9Ё`И&%QЏ(II:жћої>нyчG@Ў&;6ЌЭ~!JpeгееЅЧ\7мpƒ^§u566ъ ƒвЂE‹4vьXUTTЈММЄжжVM™2e Н-Qип“[л‰'Jв›;€p• Зо•Ь–k –NЇѕьГЯъкkЏU[[›N>љdН§эoWmmmжQpŒl ,ађхЫЕnн:§ъWПвќc]vйeZО|ЙЊЊЊŒ}\“’t:=$I‰MаwСЖмНcŸ‡p22Ђ C!–HŒмјТќ‚‚ЖОО>§х/беW_­“N:IяzзЛЌС&FЖx<ЎŠŠ ЭŸ?_sчЮеK/НЄЏ§ыzшЁ‡tйe—iТ„ mƒџА1' ^RтВ,ŸcВфО@Ѓ €QЧШйПX,Іžž§ъWПвmЗнІѓЯ?_ГgЯ єLг]Аџ3хŠЧуjiiбХ_ЌлnЛM\pЎЙцM:U’ћxѓEIJ\™жхї/6)€ЈH@ŒQŽDћbБ˜њћћuнuзщЎЛюв…^ЈI“&хЕK&“jkkгŽ;ДqуFэиБC}}}yэАŠЧу;vЌfЮœЉqуЦЉЁЁAхххYcfќјё:яМѓєЛп§Nў№‡ѕпџ§пўЕЮСњP%%AыЩ­wйnˆ‚РЈQhpѕч?џYЗоzЋ>іБх%§§§zљх—uїъеz}ћUM›Ё‰ѓ[TГЈYБјШВ6экЕSOПДF;_}EугIДl™:ш UWWД)++гйgŸ­_џњзКќђЫuеUWЉККк8ціeRbkkRшїlH@Œ…LCyх•WtХWшSŸњT^ђБ{їn§саы^гТ3Яб1 Pu§Хb{чЪЄ(щtZ:)Ѕўžm}eўјЇ?hенwыМsЯUccу@ЛD"ЁwМуКњъЋuгM7щј€1QII‰Ы6€[ЖеrAщЭk8z{{ѕo|CЇvZV€)IлЗoз~јCН^]Ћ?џ5{Мj&MV<‘P,'љbБ˜bё„ЪЋЧhк‹tќЇ.зЄЗžЎЋђ=ѕдSYmЋЋЋѕЎwНKŸћмчДaУ†Мeх&A‰p”iUAIvц{з„СДn—u@Ѓ†kфrO?§Д6nмЈжжжЌњЮЮN]}ѕеsШ:ьƒж˜ I8FЁDyЙš[—ы§‹ўѓ—џЅW^y%Ћ~Юœ9ZО|ЙОїНя ”љcЫ%ˆ;SтТu]Жv&Іэ€(H@ŒxQ‚>_2™д•W^ЉeЫ–ЉВВr <•JщЗП§­тѓZДјняU|„<…‰Хbšvаb-љч ѕуkЏUgggV§ 'œ _ўђ—кИqЃ$ћзё””И2­Ы?ыжЮЦЕH$ F рЪєmоМYЯ?џМ?ќ№ЌКз_]ГЧУР IDAT<§Œ–Оч§ŠрчЂ ‚XLЧЈqKеЪ•+ГЊІL™Ђ#Ž8BїмsЯРxГMПЪ5)Щ5!А%%.эlmР†РˆfK4‚’’x<ЎGyDЧsŒЦŒ“ечц›oжЇŸЅъКzОX,ІN?KќуЕ{їюЌК=ЋОНН]“ZЂЊК:Ы0кЭXВTwпН*+ ЏЏЏWeeЅ:;;)?)1ЕЕЪЄЂ"0bљСUд@ЮПxцЬ™eБ˜wWЌI Zlн›6CO?§Œ’ЩdVycccод,lFIЂŽхLQзх"J[№‘€б\ЙмЖ§§§’”u§‡$mиАA•cЧцѕ|5“ЇH’zzzВЪЧЇЭ›7g•MsŠ’(˜’WЎыВЕ€BpџH#RPА”{д6hЪI^лСfŒRiУ…ц>џ"єЬњм1f;Ѓр:FmSЊ\Я’HцuE™Њa8`DŠrt9ЮО#VEE…$яЂѓL3gЮTяžьч<™:6o’ЄЌgЧHвцЭ›еии8№оvG”dСѕьEБЩƒыzР €'ѓшr&зЄФŸzеооžеЗЁЁAэ[ђ–јКwnWCCƒтёьŸзз^{m БѕйЦчpKJ‚О7P#Nамx—ЄЄЊЊJБXLлЗoЯ*Ÿ>}К:6mЪkјzЛКд8gNVY__ŸRЉд@b;'эпI И"0"й‚+—Є$‹щ ƒИ–ЏЂЂBmиtЖoбœЦЦЌ1Еe‹wжЌІІF’ћ™8ŸkRbjke]œщPj\„`D –rƒ)[p•NЇЕ`С‚М;ХуqѕюШ>+RˆО={дЙu‹’9ЫЯ”ЈЈTэєщJ”gOл1IЇRкЖіIi•WбИoо>8WяюнкНЙM’4ЁiЎbёТŽCэоИAН{:‹ХUпдЄXЌАхЄгim{хe)$pŽХЊЎŸ ъК:)B@МуЕuћйWVYЅБгІ+Q^ж4аю5ћрХYeўTОБcЧf% acБиБьŸ%qM"\кHюэР†РˆRl чџKK‹~јсЌЖх{ƒгю];U5nМ БgkЛюОђ›ъкО]Љ^{`ЏЈдФцfxйч ŠS§}КяџЁо];5їФ“tш‡.АЖнОn­юљS<з9зќМрфХлџЈ5ї­VѕФI:§›пVЌМАхЄ“IнѓoЉПЋ+А],žPХјq:ќƒhЦвCлfziеZЛzUX3Х++5uс[tьЧ?КПƒьzу5ЭЙUѓЎ]ЛдввЂD"z&.,ЉШlŸЫЅПŸ”ИВ%ш$!ŠA`ФАё’”јmчЯŸЏлnЛ-ЋЮŸУпбЖБрd§Уhз+/+Q=F Я8[2lFO^ј§-jћлVm[ЛF“,Ьo”#йлЃdЧюлРкЄгi%;v+KEмS8•J)йБ[ЩqуŠXŠ'йеЅdg‡šWœЊЩ-oQюvЅ’§zњж[ДчѕзєФMџ)IЇвJvv(1ІF‡}јЃ2}цO=ЁѕїЌв? оѓ/RејŸtŸNЋЛ}‹‰DVqwwЗ9фЭmЖO—ЄФ&l<лоKб’—m€0$ FŒ(гPТ’’I“& ЬнїUTTЈ,WgћЇЄРdЯж­’ЄЊ tа9я6t=ЛwщХлnѕк;ђъGЊЉ Tуq'ф•Ї%эzу Н№ћ[дзлыMзŠ—ЋцуO4жЭ<јP­ПgеР8)Tзощyх9gPЖnнЊSN9ERєDaИ%%aпpA`D‰\ЕM$кИqc^П™ Гдѓ|H‚К˜bёИ1x+ЋЌвq—Qх•U7Г!Џ>Шžэлдўв‹жњoМf­Щв’5ЙHѕѕЫЃкЕСЛAAю3@6mкЄХ‹Gо‡[RbЅ-H$ FˆBЙLЙI‰ЛПП_eeoўSйаа ]ннLeUUj8ф№АfF}HmOўУZŸюыГжэk›žFЉtZЪ‚епЏѕ="I*ЏЈˆ|іC’њwьаSЗм˜WžNЇЕљЙg$ioBXиЕ,’ДgыеTWчikkгЄI“֘ЫXДqMJL ЖK_”Ж`C`D(U чЋЊЊ’фнСhкДimєЗм +P:­T*х–/Џœ8I“ц-АжwэиЎ­{юсfэъ•Zїр§R:­dЦчcЧ)–ˆЋzFƒПѓМ€%иЅњzѕђ=w[ыЧ66ЉљИVUжжZл„щюи­ЦццРЗuыж$жхьEЉЧВ4xIIцgW$ і{ЖрЊ˜@Юњж­[Щ;rяНћ—JOG‡юћоПkBѓ<5пЊКйsТК h8єpњЁ u1ImO?ЉепјЊБ~_;№яжŒЅ‡(NыХ;oзК{МЛW-XОBГ>NUuuS?!d)fхѕєжЏ|ЭZ_Y[ЋВЪЊШ _ІžнjЪyсЎНгѕЊЊЊœЯ^dжхЖЭeЯўїЁЏЏOkзЎеЖmл”JЅ”H$4aТ577ЋММм9бЬы2}C`ПхˆЏkRRVVІЩ“'kчЮYх&LPЧц"ž†>АЎДвЩЄq:Q*йЏіgŸж–ЇžP§Ќй‘X,ЎxЮ]˜Въ‹А[эДšИїьM}cГ*kkѕвЏ—VнЉњцЙо~(0а—•kь”ЉaЭŠВ{гF5.>0ыlРцЭ›%e?$S1II 6hеЊUњѕЏ­uыжiыж­ъээUEE…&NœЈ9sцш}я{Ÿ–/_ЎЉSЇ,зџоИrнШD`ŸыяязњѕыЕmл6ѕїї+NЋЌЌLуЦSSSSф#ЕRi’’8@]9ЯЇˆЧукSФ…м5“ЇH’К6oвƒ?ќЎ1 NіѕzЩ‰Є1&це‰ђrќOTѕј:=yУuzшћпбіГпЅƒЮzЇЪіNnvoм io]žUЖmл6UUUЉКК:Ћuvvj§њѕКяОћtръЋ_§ЊN9хХуёРяMАzШD`Ÿщщщбc=Іпќц7zщЅ—ДeЫ%їоёx\&LPSS“Ю9ч}єбyx“ ф2%% ,аІMйg;‰„’§§Jѕї+^§ŸайGЋWИW]лЗЋ-рZŒЪЉг4ЉiЎ&/|‹ЕMІВЊjЅЧз+–>У‹ХT^WПїГFKъ2Х •зе{г–Т‡(Џ­UЌЂBБxі’т‰2pњYЊ_ЇПпp^^uЇvЌ{U‡Ÿб@"&–ˆЋМ~‚Ъr€СаБnmж $ЉГГSGuT^яџП)Љ0qIJвщДЎЙц}эk_ЫKœmžyц}шCв7Оё ]pСЦ$ФхЬKX=dŠўы %ажжІќрZЙrЅњћѓoƒšJЅдооЎііv§ѕЏеGЁOњгš7o^V;з)U>—рЪП`С=ћьГYuўŽ:л7Ћvк EU]_ЏџћыъккЎdРЉЪЊ*5fтфРщTОxYЙNќ—ЯzgŽBЮд7Эеђ/ў)Іаd%HЫлоЎцжхŠХcАˆљb‰„Z/џЂ”–ЊыъѕMЧЗjтмљYLЦ‹ЭТЗОMѓ[O.&зr’ьыS2чŽi’—€,]К4Ћ,ѓьEІbЧђ 7м /|с жі6]]]КьВЫT__ЏwПћнaЭt(TсПP з^{M—]v™жЎ]жT’h=ђШ#КєвKѕяџўяZМxБЄрi(ХrўћЙsчЊНН=Ћ­џŒ‡ŽM› J@$ЉЌЂBЕг ыk‹ЧU7Ї1Ќ™$ЉЂІF5MaЭB•ъzŠX,ІКYСзИФтqo˜иЦІvкєА&%ббц=ЄЂЂ"Ћ|Ы–-zч;п™wі#їьEБcљЅ—^вЧ?ўёМђ(Ю?џ|vиajjЪ.‰SАDQјс/(Ріэлѕ™Я|Ц9љШдооЎЯ~іГZП~НЄрi,ІЃЫЙќ а`ЅгiUWWчMС*++SнјqкГmk^Œ^Ллк$НyћfпІM›дввbъ’Х6–cБќы/rпЧb1§чўЇR{Яу‡?ќЁSТсвlH@ ЉыЏП^ЏМђJX3ЋmлЖщЊЋЎВq ;Кœл6WfR’H$ђю‚%I3fЉЗѓЭчT]лЗiЦŒŠчмeьЕз^Ы:+bKx%ћј KJкккtЭ5зЈЎНіZНёЦ’Ђ%Qк €!Гnн:§ќч?kjхЪ•zєбGƒžB“?pьшшШjгаа оЎ=|=]]jllЬ*ыяяWV’NЇg0‚ЮФ™оgЖ}ьБЧTJыж­“džўЅ@`HФb1=єаCaЭœ­\Й2/8Šzt9,)ёošyH:э= Н3чкŒn{ЖЖkЮœ9YуlЫ–-’о|ЈЅ-б(6)Щ&XЌgžy&0ё )P,CІg?|ЗмrЫР-{}aSЊr…%%~ВmлЖЌv3fЬPч–в}иПэnл 99OAїккZIбЦЇkлX,І7цЕ-ЦКuы“y( €!бййЉ­[K{сvfрхLQЏѓШ•й>‹ЉЅЅEЛwяЮjS]]­ŽMmЙ]1Šэо№Ц@ЂслЕk—цЯŸŸwkоLAугe,Koо™­Tr/ЄЯDR H@ зЃE‘yИэ‚нЬКмЖ™lIIKK‹zzzВЪтёИКЗlрыкМI‰œgЖtuuщC1Nї bЫЖЄdіьй*Ѕ%K–Ї…йИ~.№‘€ўќJ)шH­фvGf[“––экЕ+ЋЬ?ЂЭА Iн;ЖKЪулЗoзС,)ј:лј4%%ГfіŒyІя ” €!1nмИА&‘Эœ9SRp —+jRВ`С‚МЉcwЧj+эм{ьŸvmєB˜;jѓцЭZВd‰$ѓ JJLуй–”yф‘%; R[[Ћ… зхњ€0$ †D,гyчжЬйбG=p$hJ•‹ Єdњєщћ***TЉГiX:Зlж˜ъъМ3 7nдфЩ“#Mљ+$))++гО№…МКB\uеUЊЊЊrJ€$ЮŒ( €!‘NЇѕЖЗН-Ќ™ГгO?=kZŠЫ”Њ ЄФvФЗЌЌ,я.Cёx\SЇЯPзŽКwяVcSSоиjooЗN=Œš”„Е=чœstкiЇхЕ‹bХŠжeDIш €!гввЂУ?<ЌYЈйГgы„NШ*Ы={5) :КмппŸwЫп™3gЊЗЛєжcџггй‘w ^џЮi•••Ю{ај ЫUUUКтŠ+дввЂBЬŸ?_?јСT]]mмзЯЙH@ ™ВВ2]~љхE_ўЙЯ}N555жzлЛ™uЙm3e&%ўМўЬgЄгоУ{r.NtщДвЉTXЋ‚™Іџ”JzЗ}АїMŽMmy!єXSScRхТ6–MIISS“ЎПўzxт‰Šтјуз-ЗмЂ†††МmГ}o і›“Р hnnж7ПљM}х+_QwwwXѓ,‰DBŸўєЇuдQGIŠvжŸR•Щтrы2пћOБnooзфЩ“к444шсGџІЁNЅД}нЋкёњzuяиЎКYs4БyЎ*Чыъ$йлЋ-/О ЏЏW,‘P]У,MšпЂxРѓ+\ЅS)m[ЛF;^[ЏоЮеЭš­IѓЈ|Œ=Œ$жюMЕ}нЋкНЉMЕгghТœ&ŠБ{уЭXqRVйЖmлTUU50~2%Ш&Жёiъ?oо<§ьg?гЏ§k§ќч?зЫ/ПlMВ,X ‹.КHчž{Ў&L˜ЕlŸщ{Х*ўз"jmmеЗОѕ-]yх•zу7ТšK’&NœЈK/НTgœqFжQYSRсЪ%)ЉЈЈP]]]ж3G$iЪ”)Cђ4єt2Љ—WнЉмxНњwюНц$SнќyСХšадМ€Нz№ъяЋэяUКП_’ЏЈдьcз\ЌФо;~"•Lъй?ќVЯ§ўЗъя№І$Хтqе/XЈЃ/ў„ЦݘВ„poќуq=њГЋ{г›зщTMŸЁ#>tЁfrX@ЯвйН~]оУ;;;uФGфЉАЯR&%“'Oж%—\Ђ3Я2Нrпj-yЯћ•(рšT2Љчяј“uлwМќЂvЌ[Ї‰ѓцы]МxЧэyЩ‡/ЙЇSЯпі;њЯыKeїо3/9Iр–-[tійgч§0%йQЦg”ЖОмфШжпuК•KB`ŸЪwŒ хXілšжgъoJJLm3ыРEaП,0DЂW.l\f]fлкккМЄЌЌL555кГЕ]ƒ%^VІN=нZ_V3VЧe?%Šђъj›;ЯZ?eёХ…('šuˆ§™/хѕ4mQў5Q4}œdљ›ЧтqНхЌwыJЉЗkц46f•%“Iѕііцнnк4F§Г aэlіuR… 0ьхN’“w”ПTЦЭlа’sџ)+Ш-јЬGŽђ1c4wйЩj>б{P_,&ХтЅліx"Ё™Њщ‹—f• •н7ЈЎ.ћ:œ;wjоМy*++8›a›ЙЂŒЯсž”€Mi~a ФЂNCБЩ ЎLŸmZ‰пзšuю4Ќ††unйœзwPФbŠ'Š'%M>|БxќЭх—(љ№Х2ЗН„ЩG&љC™|HвžЖywjыъъвСœUfsЎc9l|КЖuioKjl “Яѕ H$ †)SР%3‰\eОЧуjjjвЎ]ЛВкŒ;VAЗšХˆжГkЇ$х]lОcЧŽЌФ5јŠБœлжeЛLыrЉћЈС•‹ i,™ЫniiQwЮѕёx\]џiшžvmx]RўC7oоЌЅK—žА%ићKR’йЂ"0,й‚Зм€'jpхТŸ“й~С‚ъьЬ~ъv"‘PZВ>э#люЖ67./ikkгДiгœЧ›ЏI‰Ый‹(IIf{(УJдЃАва$%SЇNЭK@ќЙџНІ.с:кЗhбтХYc(™LjѓцЭ*//Hd3ЙŽ7Щў]JJ\О7Q’›(Ÿr‘€VЂW6ЅNJІM›–w HEE…b’vo`жhдіЬS:ц˜cВЦбыЏ{гВЦ'ЩќЛ&%QІIE§о FRЎH@ +QƒЋ(\‚+[А5sцLНёЦYeš5{ЖЖЎ]cьƒ‘ЋcS›Ж>ѓ”ІLЩ~VЪкЕkuФGЈЖЖ6R№?XI‰k[S{’ƒ…РА5Иr%ИJЇгЊЊЊR{{Л::ВЇ[­XБB›ž{F]жЌ^ЅC=tрaƒО^xA_|БЅ—}ŒК$%6Aп—ЛиЄЂ"0ЌИY\ЙА%%’TWWЇ‰'ъйgŸЭъГpсBmxш~эк}v#зž­эzёOПг™gž™UОsчN=ўју:ђШ#gэl\ƒџRŒхЈп—э€ЈH@ …<ЙmЃW.ќ#бхххКф’KђqуЦщф+єЬяnсnXЃ@:•в7^ЏуŽWЊрЪІTIЩфЩ“uійgkѕъеYэЦŽЋ /МHOќтЇкјд?˜Ђ2ЅS)­Нїn­§нЭКјт‹USS“UПrхJsЬ1jii‰ќЛ&%QЮHD§о“”@!H@ьsAGVЃWQ’”Фb1]zщЅZНzЕж­[—U7oо<]јЁъ‰kЈ—юњ‹њ{z„‘ЁЇcЗžМљ­ЛхF]ќ‘hЦŒYѕЏОњЊV­ZЅЏ§ы*++3.#J№ПП$%ў{’Q‘€иЇќ€Ц5ˆ‰\EсrФwкДiњв—ОЄ›nКI]]]Yut.љШGДћо•Кчлпд†<Ўю];•J&•NЅЖ3N{SЕЂО0dвЉ”zvявы{TЋџэыѓъЫњф'.UcccVЛ]Лvщ†nа•W^ЉІІ&ЏЏуп*J№я:–ƒ’’(m]лKLСљP ‘ рЪ5№ВKЎG’MќўЙI‰$Н§эoзƒ>Јпќц7zЯ{о“uд{іьйКєузsЯ=ЇUЗм gzћT5uКъf7ЊrœwЫжxYЙт‰„ЂˆХуJTT†5Ы“Ъ*ЋТZхqпK"ьлLQў&О‚њФнŽЗЅR)ѕwwkу“џаіžг”ЪrНя­'ЋЅЅEхххYmЛККtгM7iХŠ:чœsЌcЮO:]ЖлѕЛрВ,_аXЮ]nБпpСП*\Ѕё‹_ш ƒ kW(С•K€ф~amƒжe[ЎфнrѕвK/U}}НоёŽwфЇ’дппЏ7jїюнjooWggЇ’Щd^ЛLНННѕ&НННЮGн}Щd2t[rЅ%ѕmŸi_ІгъыяЗŸСБьџўО~ykt—L&эћСВžT:­доЛ—Хb1U”•kтФ jiiбфЩ“5sцLупЖЃЃC7п|ГІM›Ія~їЛtsЖ„ФЕЬTчкЮVfKJ‚књVЏ^­SN9E"Ўр€3 і[Рdšo\ЙsІРЯ%и2?~МОїНящѓŸџМЎПўzyц™ЊЏЏЯjSVVІYГfIвРQ№§нHј abБрiHmmmњЭo~ЃЅK—ъk_ћZжУm}\ЦœыОЌяM1gJ\О3р#АЯD ўЃW6ЅLJ&NœЈя|ч;њщOЊ§шG:ыЌГДpсB% гЋl-ій€ IDATНННzђЩ'ѕЇ?§I—\r‰>јСjܘ1}‚ЦГۘ3%%Ўугo›[_ŠЄФOЈ3pE`Ÿ01’ћй Пmn]!A~1IЩјёуѕ‰O|B‡v˜ЎКъ*н{яНZЖl™fЯž­ЊЊ*ХЏ=Р№”JЅдллЋ5kжшЎЛюв„ єЃ§HGuд@Ђ™„ЛŒП‘’”@ЁH@ИJ'“Щ’EAС•k€3TI‰-РєпWTTш„Nа’%Kє№УыўчДmл6577ы€PeeЅЊЊЊT^^n<;$‘HDоўx<9ё‰Хb‘З-‹Yo;Л?ыяязіэлЕsчN­YГFЯ<ѓŒІNЊ/~ё‹:ўјуUSScЙcІиБ,ЙџЅJJ\лJж$„г œŒМ_ƒ%йпп_в3ЂWХrQƒЋ\Ж3ЗЎЎЎNЇœrŠ–-[ІчŸ^ыж­г§їпЏЖЖ6ѕііZ/њNЇпМ:Wюz3й–Wъ>Жm“dMtќП™IцК2Fз>Й‚і-Љ2­+‹ ,ЋВВR&LPkkЋ>њбjбЂEЊЎЎ6nƒПэC1–ЅтЦsP_зЯ`ВwПѕ+ GIƒ #к–ŽŽŽщa\K.AK]І(ЂЋ ЄЄВВRK—.е’%KtЦg(NЋЇЇG{іь1Ў7•Jо‘ЪШіѕѕYыmњћГcФАЯ‹ХдппoнзЖu›юHe t3eю—ѕI^—Я‘)3iЩЌ+++SUU•ІNЊ‰'*žђћšжя:цlI—‰m=Йuaћ#SаXv§ [Жl‘Є-$ \=ђШ#œнкк)`2‰ќчЖвжg ќ\‚+WІэєƒзВВ2;6Ћ}”uEikЊЗэ—ЯeЛleЖ:—ПKPл Qк‡ЕѕпЛŒ™ЬіЙ\њћћР•i]Q“лvхіOЇѓЯрФb1§тПЄGЂM0šнwу7u/Tf —ЩpљPnрфA.m§і&._аvЙrнЎ(ыŠВПlэЅсЙLлdRŠ}ркжа›і—M”uЙюл>(і{cKJ:::Дjе*IКOр€€Ћ›%щЙчž kШФјuЙms•*ИВ1~QЖЫU” /—kпЬЖQЗ-ї}1лeуњ9ЂфQїA”ЯБП$%QіAдяiй>њЈџП7чU€ Wы%=јч?џ9Riтzdежж$jp…K€i њЂp њ‚іAЎ(vS№ыВ]…ЌЧхs˜r›(ЙI”€|Є$%Ўm%щЊЋЎ’Є$Н–W сџђР›N—tл7оЈцццАЖyТ‚НА`*3ˆ kk+3•m—ыr§m [Ж­Љ­­ЬVЅПKп КсИ\лйЪЂєjkЊЗэ—ЖЖ2[ыпмTцПw§;>іиc:іиc%яп†? p@”tџO~ђ“МЛ)ЙˆzdехL‰­­MfрчŒГ™\&[`e]ЅиЙcјя]їAІmKЇ‹;уДЂŒ—§kЫЖ1cуКЎBіAюv™іAWW—>ѓ™ЯHвН"љ €Ј>vчwіоvлmaэВфІЖQƒ+—Ж>з 9Wд@ЮuЛŠ]W!ћ з`ьŸЫv eRтЗ5Бэ—€HЇгКёЦuёХЇћњњОWWWwEwwЗq9`C ВžžUUUнййй9ўо{я=ЂОО>жммl}btPАузчОЯ ‚‚кцŠ\…ЕЫ,3­п%РŒ њeЎлцКLSy”ѕјeЎэїѕКLхЖЖЖuEiд>їНۘЩloжПдћ ЃЃCз\s>ѓ™ЯЄКККў_eeхg;;;нцј@щяяOWVVойеееvџ§їŸДqуЦђYГfЉЎЎЎш€'ЈНЉ>,ѓЫ\жхк.ГЬД~—3J€ш—Йn›ы2MхQжу—э/ћРV^Ь>№лFmoЊwљ QзхвЮTцЏЇПП_§ы_uщЅ—ъкkЏнгппieeхПѕєєЄђЬџ2€Ѓњњњиіэл—HњіфЩ“O<х”SЪ–-[І––•——g ŽlС’­>ЈНK[зр,Ъz‚ЪЂф&Ўы2еЙ~V[ЙыzТЪ\їЉЉ­­ЬTчкЮVцПw§ AТкћћРЅ­­ЬTчв.N+™LЊГГSO<ё„~ўѓŸыŽ;юшпКuын’.Ÿ0aТ“лЖmуЬ€‚џ މDy2™‘Vkg_ М№Qfg`!№˜К@I’ЄaјDZ5Ќ|xqђоэРЇ €k;‰яќzРу€€чћvп“4=м}Iв*СˆДjјL-|œМ x 'n9АИ И‚ЈvЕ№jрэH’$IR-€eфPOЌи†РБРХР­Dƒі[‰',‡OazmJО]uЏ] –obр_€_їmYю.яОП0?‰tлц/>œќXBююЎ&ЊСН”jE=­Мƒ(.&іс О­ЉAŽ_‘-П& ИзЇЯaєН`=јёTяр.р"р`тиєZ ИБЛŽ‡€?+ˆщЕљчžQлЏaв/ђэљ@ђў чEQКn GД[LtZq%p4А&§f›|ŠмCОМO‹$IБ“Ш/М?ЅџŒdЏюІ:ƒѓ`“žхЭ 51—hПђѕŸё­dЙAЗm>тГз9”gоz3\/"Я(ЇЏ;|[3ƒП^‡™ўЊѕЌшўmЛrQ\Aёчv€oЋЌчIЬћ цї:“<ўй5Б§6§GY9x'Qˆ.[і2`Њ ЛMОE,€H’4FП%П№ю_;ˆƒщ/sŸe0вЊƒfš8њugЏ “хнЖ&QЎHšсњхыa УПдa},ŸОк.€,ЇќГвзЇ жѓXтюy‡ШдVU?о”ИsпЁќn{mЄџ( iЦНъѕqЪЕБMОE,€H’4&!Пш.ЃџЊ§кxќ3ОIм™мШDlМg$‹yKСzF5NСFф™Хћ€Ѓ€'=‚Э ьNŒ{rvС:šnлРMРч‰.w$юЯ6&ЊяЄOdVлб+ЭpeЏѓ‰NŠтЁљЖЖuќЖaъ“Ы—н9ЏNd№ї ЊЅнлiЛв!ювŸьIьУрЉР“˜G€ЇЌыЌ$ц•ѓ3яKтЏˆыG[щ_VЩ4=/ŠЮНџ^Aœ{ ˆѓњ+ЩќХџОДЕƒ|R@$I“]Ш/КWеФтKфы?Ў"n3Ђз­б6 Wг RПвŒйЧjbЫŒjлN!_яОѓг з]DцЏNгmmыјJОžѓ˜к–Із%нИЖ ? ЖГLZmъЄ‚љ/NцЏ`>D†9Ћіs/ѕеŽъД•ўЃ,€,"ж_d5b{Вин bккЧAО’f(Ч‘fЖG%гЗ—F fMрUнщ+ЈЎ;3‘I…xбOCп6<˜L?Е4j2.LІыЦW9јЯš˜Ік:~ѓ€ƒКгKC˜Ь`•п!ЖГЬ“щ= цŸ\з~>qчОз~ФгˆŽю/ˆщW[щ?jџ |Зdо рлЩџ[єЬе>Žтћ iБ"­:ЊъЕCдядМЖJтŸIо їЫнљU~–LяTеЎЋЩ3‰/ ЊйьIѕњ6mМ8žШ0]JdrяdjяIE ЃSui;ˆЖŽп.РКнщя]8OGПnщNяШЪзЗSлуќ-+ћЛdњ”‚љMД•ў“–њzŸjыж#i†Г"ЭliƒЬ~ъI7ёИd:эiЋьѕ$>}23Jї2ЕЪЩ~Рї‰і —™Шзвў@‹лч™Г/я":иh/БЃщЌ‰ЖŽ_Кž+™оuџЮ'/4Ѕ>GД•x=бV(Г№МюєˆЭ0кJџIЛ;™юэцxUйGIcfDšйвЛ“лы—`ƒК€ E™ПQ9x3№ЇфН5ˆЛГGџAŒE№aъŸѕcЂЛу}˜|!ЃJ[ЧoУdњžоРifi2Н `ўф™рѕ‰ЇW™6Ÿ~@{щ?iUЬ[UіQв˜Y‘fЖ[€пwЇW#2ХeоLмСь}§А$~˜њяEТвЉФy{mОM^Ђ@r,ёДbѓ‰FЗkuџ_ | 8’x№щРжDІ=Ћ?)mПeљ$kєN3щ“ЎВТRкMoV k]ЂG3ˆB}QoiMЕ•ўгйlиGI#аЦн@I“ѕ`Лює{ˆЎ3лh$œfрЇ|<‹ІFuуc9бЛQкУбу‰.@&~я>DŒ3PЄnл^lоОЎћVэЇзŠ’їлRЗ­mПДšпжЅQ“7xbwњЪям_Lџ‰Ž žе§›н‘џ эєреVњ7Uw^ДiRћ(i†ч•ЄбXHžйнžшеІ ?&ЦTxIU`Щ'‡юкД‰пя%2•™]zbšlлЖЩє')/|ŒJ“mmыјЅƒё•uз:ьMўdъЂЊ@V~ ’= YN{™шЖвПMЮ‹6s%­B,€H3п5Рg“џ%ъЙлШѓnђю9ї'кS ъОdzЗвЈбЙ!™юН3>шЖUu#К€fыъW“mmыјн@ф `o,хYфOуЦiІŽ§ёЅВРЎ/ƒBt1МcwњlЊЛњmЂ­єяG“ѓЂMумGI’4ЭЌIєњ”і8ГјqgxѓnЬZD[‰ЇЏ…D&"[fЋžѕюFмЮцŸHdиВ‘Ž7 Fžў+"x 1"xj ђЫ;Р?јљРЮDžНO&њq0бѕэqDћ—э‰vЋw‚Ÿ@мнО“јмЌ<–A“mл-‰[FŒМОQрXx№n"›‹#YY:№к1ѓ‹4йVhяјН3YЧ2тЉвжФч>†Yќ<ђбп;ДS)MЃыˆv<ЛŽљФy§&рIм•єзОрtІЃХу‡ Ѓ­єЏˆАщyбфм{m{XСќЖіБЩ6q$tI’&`cЂ§CoІЊЩkЋо•oэcЙоWoцтюrе2Л,Sч0ъЗ%}}Ђx5ЖэG5Бй+Э”ЕUfл эПDЗДuЫЅћнvЄŸз}Ф w§и…ЉЫЮн†6вПЎЭЮ‹&ч^]кйЧ&лTФˆ4ƒXKZuмМxpSMlj)1ˆоK)nгp2бxћЎ‚yEю ИќлiДіЛ™ZџНL‡xtTЩќ&лvyЯceЮdtеQšl+Дsќ–uќЏ_9ќџмOєДvYEЬ0зЬП™x‚бяј?%FяЮДбѕn‘6вПMЯ‹6k%Iв46ŸЈ“§ "Cx#Qч})1^ЦЅDѕЋWбЃеЕ‰ цYРˆ чУDfтЧРЧ€чR=6Цc‰‚РuDІіnbtф“(~jвЭ‰1О\Kм_о§ћsтѓž^КtЎЩЖ­Gtїћ›nьƒDЕ’…фU]і#П#лцhЖ­™6ŽпкР?щz?Q(ИŠЈЗI7цbŸк~ђzр9DWЪ Юхћˆ§~/ƒ+qБюХД?XeЏaвПŸ' аџyбфмыч Hf˜}lВME|"I’ЄimOђ kк+–$I’$Е.m3БSMЌ$I’$ lkЂGД10Ё$I’$ЬIфO?Њ‰•$I’Є­Cо`љV`ѕъpIRль†W’4›МXП;}:1€Ÿ$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’4{Эо|ИxИИ†М{юыеЁЕ7№БwOЉ™™’^jцXђуz А~uИ$IуЕ‘ёИј#АИј№uрPМxeоJ~QџzMЌšY 8‡<}{_џдЋ;3!CН ёыїO+‰л€ђєЈz§>YЧLLЏо§^l[ЙDnpS—mхЋЎ“ЇС95Б’zЬ­ 4­€oWяž l, лЏNўx~5:G/Џ ZЬўМPџ:рЪђp…гwеulQ4KМ‡МрёrрŠXI=Ь№Hэл Иx‘!ЊГ!p4+€ Г_m~чпLОЎ+т ОYьKjb^EџЧY’ЄV§;љEш+еЁ+y4№љђY=іTz1ў АШИvJ^PŸ{5Qh)[G‡ЈІБIЩђщ6KT+[RАŽьuхэ\ъ2km~Vц`"SЖŽG€Лгm@ж :­гз9є_ˆ*SїFSіМjjђѕžP›™NqІWoрЂюџЗmƒz}‰<цаdи§jѓ;?ЪШ<рF">э%MR‰~яJЊЗg2НА4ЊиэLmџёќВРЎwеLЊюю|ЊbўСФgnPА №-т"[хh"ѓW”Щ<јPХќ~ЕёYo>GД(3‡њBмЈМјD]а4діyеW$гM џ“6‰єъu|їяЦФггд–DAт;зЁ?mяWпљQYNосСЖРS+b%aDjЫc‰ 5Ф“ŒЫ*bЫ|/™оН4*Ь#ъŸJV6"ю–яТдё!ЊѕкžЈb”Uѕњ№bb=ѓ‰§y#бч?Фz Zжѕщwˆ.†7!2яOОšФЦ№wі‡§Ќm€IўПиШ€­йџ2р4тxЖщfЂšеы‰э]—HѓGЯ% Y&яаюћƒš<>љџГф=_eЏ*XnPЃ8Џњёœюп??Ћ œf&•^НОEўшэФggоF>ўЧєgћ5ьw~дЮKІŸƒ$Ic№чфьZ[f'ђuќВ`~Zс‡TїЧџ$іуѓГ*Ђ>u™ЭˆЇ3рзѓгmZDјOрRр:"Г—VuЉz:3LъМк<™ОЎ4jњ™Tz•YN І№Dт)С[Кџ/ЄџЊˆ“кЏqўО”ЩЮПI€ЄЅЎб—Єўм•LWѕЅ_%]юЮвЈў-"КЌœOTИЗћўу’˜“Ш3§Ј{2S%}ТSдЭp›Њ>kЫ|’+Пэ‰ЦДI{]ЋN“:ЏжMІяe0П"кŒгЄвЋЪщФггˆ‘фз"zjвЉЦЄіkœП/eВѓoR iЦ№ ˆдŽ?%гл3XЦ2ЭЅыдвdzA2]з+M•4Гзд8Ћ9U}VZаДКм і кэУ`чШt6Љѓ*=З—”FM?“JЏ*KШ{ЮЫz›њ SoАд™д~ѓїЅLvўMЊчЕ|Cђ:є3ЩЄЮЋeЩtU—ЪгЭЄвЋNZнъaš=С€щЛ_ЉQ}NvўЅ7$А –дžїs$Э ќџ§ВР>­N<‰ЈоМ%ŸфpЂGЈй$Н››VЕЗWИЎћџЂ’и%яOg“:Џ'гы•FM?“JЏ:wууI˜Ћ:Л(2]ї+m‹R5–Ш0В'8УТЄYС' R{>L@Œ#бЏO“_Џ.ЎˆэЧЋШЋІќАgо‰ю"Ёџ.&W%iЧН=„Rк3Ю')/|ЬT“:ЏnLІЗ.š~&•^§x ё” ыŽЗ‰щК_iѕМДX›ЖщўmZh“f R{~D<Иx…•Ч шЕ€юЏ’ї>\лЏ-ˆ~њ3_ъ™7yw–ћS?иЊцzђЬџФ fevb4™кЊюF0XОI›дyЕˆќ‰б0Н(лЄвkдІы~Ѕ…‚§)ЯџьќMЩМ*k‘пdИО*P’Љmo ЏтГ6pб?§Dѕ›е‰ЧєO&FО–‡"ѓхюЋЮЁФђ;ЃwЯ' GџCžС§)1 qЏї“gкNЮ'Кнм‘hƒ0hCђЂptp ёYЋ‚Я&г_ вrKђЩїЮ$вoГ•–L:@хQнзVDc]рiРЛ‰БŽю]x†˜Фyѕ№‹юєГЊЇЁIЄз8LЧ§њ yл–ЇпћэШПѓЏ$КхО€СКбнЏ.&oзs3o†qЇзИLЗ§ZB|жЛˆпЧКя]MќoGtбд~фU5{лмI’4ЃэMTъЧдФЊs‰'Tр›5БšЌЃШПY5iдцm>:ФЭ„MЋУ%IšY,€Œп›ШгќиšXMж:Фр6šзс—qљoФТšXI’f э:ƒ‰ќpbђ ˆ†пыmx>I4яUЅЊКЮеє?W+ kcђBя=ŒЖ/I’&ТHЛЮ#OЯКзLэwЖ™Kєˆ•Зt|ЉMs‰ž ГsэаъpI’f& эъЇВ‚hˆ>Їdš~Ж%юFwˆЦЛV‡K9ќwтмšXI’f, эк•(\|—шїЂЊеэDob'lЌ™eoЂWЙблвSЊУЅFоMў[|-Ж7’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$л^ф#э~ :tЦЙ„иЏхuš•V•ѓ#§VэбиW•cІfŽ%ПN]ƒ#ТЋЙuR6 џJ_Ы€ЛˆЇo™щЇЎE o%?‡О^Ћйg&œл_цK€П,ˆ+ћэьїПЮж,XЧL0Yoк/Ж­\"7ИЉЫПЖr‰Uг?w_OОP+MaDЃ4Xијqz)№~рЇРЯ‰;„’Д*™ќљнрзW–‡—šЌ lь|ИиЃj! l5р]uA][дЭяЮщNП8Є"Vњ?@4);џœˆчЁЄUЧЁф…„ЯgUФ6ѕgРљјyTо@ЄqwдЬ"тœПЅћџIРЃЪУ%Љ=щЃьЋ“їчU6žAT!8XСдGз_CНlЂйj&Ÿk"Жџ6`Нъ№впNˆ3ыЛ'еYГи ™^fт1Kгў'фэuNЌZxљr—'гГБ Vъ ђДјdMЌ$ЕЂъ"Zd[рbІBўЖr‰йЧˆfЋ™|~Мќ{{dM,4ћэм7‰эW‡еL3‘aЈZOVЏ,#_ЗяmІsц`т^ЖŽG€Љою&кNї~єfb^мШЪŸwGВLлл9Žѓ#3ьwЃЉ=Шз{BMlІщoчoЩуw.‰ё˜ѕЇї РEнџo' чНОд5ёћпяWw'БEЏŸе•‹Дљ›7ЊDЧ йoЪяkb%ihM/ЂЉШ—§cIЬёILнылЌ\0и,™џMŠШдѕМЌ f тЎU‡тv+щEтІЎЏьѕё‚ѕ@ьaгšeV:РiыШVБ\бkаЬJ›щ №Ц’ešnwmІ{Пвtћ+ЗХЪ^ƒ@ъЖs\чДѓнhъdђuюR›iђлЙy;”З/ё˜ѕЇЈђВфНш‰п’xBи^п}ЏŸШСфэKъ^?!2ёНкќЭe`!љ2O­‰•ЄЁ4ЙˆіZ“Љwžз3џЙL§ёўёДb]тBћTтТŸfІz/е:Ԙ$EЎk™њу]T}bїdўпЬO/йыПW&юкэ|%™П˜т;uьЖвe ЂZЧч‰юBw$юœЭ#ъ˜яA\PВЯZAьKЏm˜z—єrЂKЦG]1?ЖЛЎе@: žYi3ЗaъФџ!ък?ŠH›­ПNMтк*€Д‘юMЅлљФў–­Л­эчљбжwЃЉŸыК™ў3ЧM~;OMbП_ч1ыOQd1^K‡чc~џёюћ‹Ш uэЩŸœvˆ`/"ЊcЭ#nŽНXgѓ–‚ѕДљ›7ъШ‹Щ—)ЋЪ&I­hr-ђ ђхїъ™w~2яc”{]wqL}:™ПCЯМКяЏ>зО•ыфІ L{зS/‹Xy_2Ћѕ›Гин bъ.иmЅKПN!_ЯОѓгЬбyLНpїКЄ7hfЅЭt>-™ещSЗнЃP—юMЄщv‘yiKнvŽѓќїwbВЊCMzѕЋњэ\lNЄgКOЫ)>—›šэЧЌЈS?урю{њy;Ј/€dUЖ:D{2›еО:ФoVЏ6ѓF]Y—М0љљšXЭb6Bзtps2НA2Н!љэ­Dнз2џA~Wp3тюYъЩtяђ~нП—eˆЛJНыxfїяm_$Rџ |Зdо Ђ AІщ€VmІKП.LІ{{7™GtСбћЩ!DU…q&гэ^FlїCL/&гmі*s"№ŸuA \˜LOђќ˜Фw`+ђ?ЏˆЋВ#yfЏCЄеГ‰‘д!вэ@рЧE+hшТdz6Г2_&ž~@4шžK4Ј^‡f Ќ МЊ;}1o™›‰Р“Ј‹d˜пМqX ќowКп‘х5 ЭCšОžI^•с<ъ3‡_žпў ІVSИ0™оЉ‘ьюпYDмˆњОћ?LтВHњо вBW]щ^mІKj"ЃГ№xт"И Q(\?‰ыНыИ qз р;DmКЈJч]’ї&ЙнƒІћ0:uнЮqžЃњnдй<™ОЎ4j8#u_^˜№˜5Зœшхdр‰D/ЋЕЈ–жg’Їы—ЉџЮ§,™о‰OfУ\[кrQ…o Э@4lšLп•L?6™ў ѕв˜tYˆ;kП&ЊN=+y3рЯЛгйсГˆњХћoэОїт.'Д3инЩtПѕХ3mІ D=хˆЖU]A–y\2}eiдdTЅѓ–Щє$Ж{иt—aЗsœчGлп~­›Oroiдр „џЎ.АЫc6œгїЃйЏEД[XЕP4 OЂК—Ч^УŒ$>ЬЕЅ-йw`R ЭVСвЄ-`ъcкєт’^дяЇ^“.›ЩЊa=|Џ}‰щŸ“?6Ю "[’їf“=§€ЉеЙUw—ЏJ›щВбxvЫЈРдAЛю)šŒЊtNЗ;НhCщ>mlч8Я6ПMЄнТ.)Њі+тЗ({Э%юіCd€џ‹ЉUTЫxЬ†З„ѓ ђюx?Удduњ9Ve†йЏaЎ-mЩОkTFiVГЂI{)љ]’п2ѕБѓтdКŸ;)iLКl&-8ќEїoV§*­ y•ƒ§ЛГШ­єw—n”кJ—љD#ЩьЛ”h@{$q\žNєЕ!y]ц"Ы’щ™tСIыДЗYНЉN[щ>jmmч8ЯЖОMЅћИviT3Ђ‹шl`Ш'_ЅКPс1kOZнъaš=С€ў SeЦѕфbTŸ“}–VFiVГ –&i>бЫFцŒžљi]жоQЧ‹Є=SЅЫf.$.ъsˆjX?іьЮ;+‰{„ ыMDOAяЅніУj+]^@^w§Кюџ‹(ЖЂф}˜:nФжЅQгOz73­.1jmЅћЈЕЕудп‰{u2}iСќ;‰>о!ЂП”Иѓ§ћф§LіDфIнWжNфB&Џ­tIЋО}’ђŒJ_ф“ЅнCNGщ1п“ёi+нG­­эчљбжwЃЉ“щЖ3ьџKlgжХэ‘DWЊEзЫL fqчщт’ИЌжЎР_uЇгЇ™я‘з}~љ]Э6к kщRеэу`ЗŠљ77Žн–Ј6RцYРvѓЧщzђ кР++bwЂ§Œ% —юу4ЬvŽѓќХwЃ‹ШŸ(ьT8 яoOў_H}Ёйc6Yw“w—Л?б•яt іЇ<И№7%ѓЊЌE^ОО*P’†U5˜жФEхiРы‰ю—%ёрп)їќžиs€чѕ€Гr2u„мЃ зіMтВeЪ.Ф_ьЮЯUЊыqoђuSћк$іА‚љuwЕ‘.Л%ѓ–uчoEdNж%ŽйЛ‰jщgЩЪойГЎїіљDbЏ$КиLG;tаВ6гљ“љKˆLо–Фv?šјЌ3‰:рuлнЏ6гН‰&щэnч8Я6ОƒјБЎl ‰~4Ф5(ЕCмАщЭј{ЬњW6a%_Чk цяF>@e‡pё@ЂЊй†D5ј €Ї7ФNЎ!я$%гфЛ[ї›З6ё[—юћvфПyЏ$К^юєМњ}Š“ЫВЊ‚’дŠє‡Мщk!ѕOт>F§zВзљTЏoІ^ФnЂМ!о+˜Кю3Kт2m^$ъ.иаNКќЈe;LНˆeVѓыж“ЎkаЬJ›щМQWОn›гWВЕ•юM4IЗL[л9Юѓкљn4u2љ:wЎ‰Э4-€,.#_ц7LЯ?кјn4•Vх<Ј4j8Ыˆ#йгиэЏ0Еg,йєr2qLњэТїкЙЩQхXЊДМŸ ЋЊ:\‘yфНЋ]Ядk­4…кrЂљuD=п=JэBмХъG‡h‡ёTр_ˆюzя'КјћqїъФќƒХЋ˜тЩtQћЬD!$saIмЄД‘.7ЧтИюђu—П–шW"3u{ЩђЉED§їїX—лѓsрCDНрSK—žœпO&юЬў’8ючьiDѕˆї“7ŽmcЬ6г}”кмЮqžm|7šК˜МMб!д7ІдЭDн§ЌЋм3Е‹XйєѓUЂjчФMЏEDZ.'Њв]JУчѓŽb0ЫдтГоE 4љ@їНЋ‰kєvФS’Іі#ї…ш9L’$ a.p‘IњfMЌfЏЃШЋŸXџ]ГЩЂЛшQhмД:\’$еyyЦђиšXЭ^ыН3uˆСL{лgHЋЊƒШ#жФJ’4ыAŒ}81RєDњѕ€gUВŽ ЂК{S)-Ќ~Ў&VZlL^№О‡•бK’ЄчQпLі:КdRf.pљ9“7$­ŠцуzeчћЁес’$ њ+€Ќ Ђ—uй,ЅЖ%яТt б№[Z@ў;ynMЌ$Iък•(\|—шОєЂЊеэDW•'ь+ѕkoђAњю$zS“V%я&/|\‹mž$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$I’$IЋ”џСЮˆК‚ВЊIENDЎB`‚chirp-20240224/chirp/stock_configs/0000755000175000017500000000000014566340177016011 5ustar hibbyhibbychirp-20240224/chirp/stock_configs/US FRS and GMRS Channels.csv0000644000175000017500000000672714411666130022461 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,FRS 1,462.562500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 2,FRS 2,462.587500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 3,FRS 3,462.612500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 4,FRS 4,462.637500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 5,FRS 5,462.662500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 6,FRS 6,462.687500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 7,FRS 7,462.712500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 8,FRS 8,467.562500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 9,FRS 9,467.587500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 10,FRS 10,467.612500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 11,FRS 11,467.637500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 12,FRS 12,467.662500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 13,FRS 13,467.687500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 14,FRS 14,467.712500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 15,FRS 15,462.550000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 16,FRS 16,462.575000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 17,FRS 17,462.600000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 18,FRS 18,462.625000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 19,FRS 19,462.650000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 20,FRS 20,462.675000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 21,FRS 21,462.700000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 22,FRS 22,462.725000,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 23,GMRS 1,462.562500,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 24,GMRS 2,462.587500,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 25,GMRS 3,462.612500,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 26,GMRS 4,462.637500,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 27,GMRS 5,462.662500,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 28,GMRS 6,462.687500,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 29,GMRS 7,462.712500,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 30,GMRS 8,467.562500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 31,GMRS 9,467.587500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 32,GMRS 10,467.612500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 33,GMRS 11,467.637500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 34,GMRS 12,467.662500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 35,GMRS 13,467.687500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 36,GMRS 14,467.712500,,5.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 37,GMRS 15,462.550000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 38,GMRS 16,462.575000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 39,GMRS 17,462.600000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 40,GMRS 18,462.625000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 41,GMRS 19,462.650000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 42,GMRS 20,462.675000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 43,GMRS 21,462.700000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 44,GMRS 22,462.725000,,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 45,GMRS 550/15R,462.550000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 46,GMRS 575/16R,462.575000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 47,GMRS 600/17R,462.600000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 48,GMRS 625/18R,462.625000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 49,GMRS 650/19R,462.650000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 50,GMRS 675/20R,462.675000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 51,GMRS 700/21R,462.700000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, 52,GMRS 725/22R,462.725000,+,5.000000,,88.5,88.5,023,NN,FM,12.50,,,,, chirp-20240224/chirp/stock_configs/PL Calling Frequencies and Simplex.csv0000644000175000017500000001263314454210572024746 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,RxDtcsCode,CrossMode,Mode,TStep,Skip,Power,Comment,URCALL,RPT1CALL,RPT2CALL,DVCODE 0,VHF SSTV,144.500000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] CzФ™stotliwoХ›Ф‡ SSTV,,,, 1,VHF APRS,144.800000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] CzФ™stotliwoХ›Ф‡ APRS 2m,,,, 2,VHF WX,144.950000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] CzФ™stotliwoХ›Ф‡ pracy stacji pogodowych SR0WX ,,,, 3,VHF CQ,145.375000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza,,,, 4,VHF CQ M,145.500000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza dla stacji mobilnych oraz EMCOM,,,, 5,VHF SOTA,145.550000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,"[2m] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza programУГw SOTA,POTA oraz podobnych",,,, 7,UHF APRS,432.500000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] CzФ™stotliwoХ›Ф‡ APRS 70cm,,,, 8,UHF CQ,433.450000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza,,,, 9,UHF CQ M,433.500000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza dla stacji mobilnych oraz EMCOM,,,, 11,,145.212500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 12,,145.225000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 13,,145.250000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 14,,145.262500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 15,,145.275000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 16,,145.300000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 17,,145.312500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 18,,145.325000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 19,,145.350000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 20,,145.362500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 21,VHF CQ,145.375000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza,,,, 22,,145.387500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 23,,145.400000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 24,,145.412500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 25,,145.425000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 26,,145.437500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 27,,145.450000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 28,,145.462500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 29,,145.475000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 30,,145.487500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 31,VHF CQ M,145.500000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza dla stacji mobilnych oraz EMCOM,,,, 32,,145.512500,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 33,,145.525000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 34,,145.537500,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 35,VHF SOTA,145.550000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,"[2m] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza programУГw SOTA,POTA oraz podobnych",,,, 36,,145.562500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[2m] KanaХ‚ FM/DV,,,, 38,,433.400000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 39,,433.412500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 40,,433.425000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 41,,433.437500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 42,UHF CQ,433.450000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza,,,, 43,,433.462500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 44,,433.475000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 45,,433.487500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 46,UHF CQ M,433.500000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] CzФ™stotliwoХ›Ф‡ wywoХ‚awcza dla stacji mobilnych oraz EMCOM,,,, 47,,433.512500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 48,,433.525000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 49,,433.537500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 50,,433.550000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 51,,433.562500,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, 52,,433.575000,,0.600000,,88.5,88.5,023,NN,023,Tone->Tone,NFM,12.50,,5.0W,[70cm] KanaХ‚ FM/DV,,,, chirp-20240224/chirp/stock_configs/US 60 meter channels (Dial).csv0000644000175000017500000000067514411666130023104 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,60m CH1,5.330500,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 2,60m CH2,5.346500,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 3,60m CH3,5.357000,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 4,60m CH4,5.371500,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 5,60m CH5,5.403500,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, chirp-20240224/chirp/stock_configs/UK Business Radio Simple Light Frequencies.csv0000644000175000017500000000207714411666130026327 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,BRSL1,77.687500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 2,BRSL2,86.337500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 3,BRSL3,86.350000,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 4,BRSL4,86.362500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 5,BRSL5,86.375000,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 6,BRSL6,164.050000,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 7,BRSL7,164.062500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 8,BRSL8,169.087500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 9,BRSL9,169.312500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 10,BRSL10,173.050000,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 11,BRSL11,173.062500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 12,BRSL12,173.087500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 13,BRSL13,449.312500,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 14,BRSL14,449.400000,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, 15,BRSL15,449.475000,,0.000000,,88.5,88.5,023,NN,NFM,12.50,,,,, chirp-20240224/chirp/stock_configs/US NOAA Weather Alert.csv0000644000175000017500000000134114454210572022152 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,WX1PA7,162.550000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 2,WX2PA1,162.400000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 3,WX3PA4,162.475000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 4,WX4PA2,162.425000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 5,WX5PA3,162.450000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 6,WX6PA5,162.500000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 7,WX7PA6,162.525000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 8,WX8,161.650000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 9,WX9,161.775000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 10,WX10,163.275000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, chirp-20240224/chirp/stock_configs/DE Freenet Frequencies.csv0000644000175000017500000000100114411666130022576 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,FRNET1,149.025000,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 2,FRNET2,149.037500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 3,FRNET3,149.050000,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 4,FRNET4,149.087500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 5,FRNET5,149.100000,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 6,FRNET6,149.112500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, chirp-20240224/chirp/stock_configs/US Marine VHF Channels.csv0000644000175000017500000001372014561124165022364 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,RxDtcsCode,CrossMode,Mode,TStep,Skip,Power,Comment,URCALL,RPT1CALL,RPT2CALL,DVCODE 1,SEA 01,156.050000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations and Commercial,,,, 2,SEA 05,156.250000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations. VTS in Seattle,,,, 3,SEA 06,156.300000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Intership Safety,,,, 4,SEA 07,156.350000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial,,,, 5,SEA 08,156.400000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial (Intership only),,,, 6,SEA 09,156.450000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Boater Calling. Commercial and Non-Commercial.,,,, 7,SEA 10,156.500000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial,,,, 8,SEA 11,156.550000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial. VTS in selected areas.,,,, 9,SEA 12,156.600000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations. VTS in selected areas.,,,, 10,SEA 13,156.650000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Intership Navigation Safety (Bridge-to-bridge). Ships >20m length maintain a listening watch on this channel in US waters.,,,, 11,SEA 14,156.700000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations. VTS in selected areas.,,,, 12,SEA 15,156.750000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Environmental (Receive only). Used by Class C EPIRBs.,,,, 13,SEA 16,156.800000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,"International Distress, Safety and Calling. Ships required to carry radio, USCG, and most coast stations maintain a listening watch on this channel.",,,, 14,SEA 17,156.850000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,State Control,,,, 15,SEA 18,156.900000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial,,,, 16,SEA 19,156.950000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial,,,, 17,SEA 20,157.000000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations (duplex),,,, 18,SEA 21,157.050000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations,,,, 19,SEA 22,157.100000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Coast Guard Liaison and Maritime Safety Information Broadcasts. Broadcasts announced on channel 16.,,,, 20,SEA 23,157.150000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,U.S. Government only,,,, 21,SEA 24,157.200000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 22,SEA 25,157.250000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 23,SEA 26,157.300000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 24,SEA 27,157.350000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 25,SEA 28,157.400000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 26,SEA 63,156.175000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations and Commercial. VTS in selected areas.,,,, 27,SEA 65,156.275000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations,,,, 28,SEA 66,156.325000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations,,,, 29,SEA 67,156.375000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial. Used for Bridge-to-bridge communications in lower Mississippi River. Intership only.,,,, 30,SEA 68,156.425000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Non-Commercial-Working Channel,,,, 31,SEA 69,156.475000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Non-Commercial,,,, 32,DSC 70,156.525000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Digital Selective Calling (voice communications not allowed),,,, 33,SEA 71,156.575000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Non-Commercial,,,, 34,SEA 72,156.625000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Non-Commercial (Intership only),,,, 35,SEA 73,156.675000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations,,,, 36,SEA 74,156.725000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations,,,, 37,SEA 77,156.875000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Port Operations,,,, 38,SEA 78,156.925000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Non-Commercial,,,, 39,SEA 79,156.975000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial,,,, 40,SEA 80,157.025000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Commercial,,,, 41,SEA 81,157.075000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,U.S. Government only - Environmental Protection Operations,,,, 42,SEA 82,157.125000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,U.S. Government only,,,, 43,SEA 83,157.175000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,U.S. Government only,,,, 44,SEA 84,157.225000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 45,SEA 85,157.275000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 46,SEA 86,157.325000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 47,SEA 87,157.375000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence (Marine Operator),,,, 48,SEA 88,157.425000,-,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,Public Correspondence in selected areas only.,,,, 49,AIS 1,161.975000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,,,,, 50,AIS 2,162.025000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,,,,, chirp-20240224/chirp/stock_configs/AU NZ UHF Citizens Band.csv0000644000175000017500000001317714411666130022342 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,CB 01RP,476.425,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 01 duplex,,, 2,CB 02RP,476.45,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 02 duplex,,, 3,CB 03RP,476.475,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 03 duplex,,, 4,CB 04RP,476.5,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 04 duplex,,, 5,CB 05,476.525,,,,88.5,88.5,23,NN,NFM,12.5,,Channel 05 emergency simplex,,, 6,CB 05RP,476.525,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 05 emergency duplex,,, 7,CB 06RP,476.55,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 06 duplex,,, 8,CB 07RP,476.575,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 07 duplex,,, 9,CB 08RP,476.6,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 08 duplex,,, 10,CB 09,476.625,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 11,CB 10,476.65,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 12,CB 11,476.675,,,,88.5,88.5,23,NN,NFM,12.5,,AU CB Call channel,,, 13,CB 12,476.7,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 14,CB 13,476.725,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 15,CB 14,476.75,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 16,CB 15,476.775,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 17,CB 16,476.8,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 18,CB 17,476.825,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 19,CB 18,476.85,,,,88.5,88.5,23,NN,NFM,12.5,,"Caravan, RV & Convoy channel",,, 20,CB 19,476.875,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 21,CB 20,476.9,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 22,CB 21,476.925,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 23,CB 22T,476.95,,,,88.5,88.5,23,NN,NFM,12.5,,Telemetery & Telecommand (no voice allowed),,, 24,CB 23T,476.975,,,,88.5,88.5,23,NN,NFM,12.5,,Telemetery & Telecommand (no voice allowed),,, 25,CB 24,477,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 26,CB 25,477.025,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 27,CB 26,477.05,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 28,CB 27,477.075,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 29,CB 28,477.1,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 30,CB 29,477.125,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 31,CB 30,477.15,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 32,CB 31,477.175,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 1 repeater input (use chan 1 duplex for repeater),,, 33,CB 32,477.2,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 2 repeater input (use chan 2 duplex for repeater),,, 34,CB 33,477.225,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 3 repeater input (use chan 3 duplex for repeater),,, 35,CB 34,477.25,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 4 repeater input (use chan 4 duplex for repeater),,, 36,CB 35,477.275,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 5 EMERGENCY repeater input (use chan 5 duplex for repeater),,, 37,CB 36,477.3,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 6 repeater input (use chan 6 duplex for repeater),,, 38,CB 37,477.325,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 7 repeater input (use chan 7 duplex for repeater),,, 39,CB 38,477.35,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 8 repeater input (use chan 8 duplex for repeater),,, 40,CB 39,477.375,,,,88.5,88.5,23,NN,NFM,12.5,,Road safety channel secondary,,, 41,CB 40,477.4,,,,88.5,88.5,23,NN,NFM,12.5,,Road safety channel primary,,, 42,CB 41R,476.4375,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 41 duplex,,, 43,CB 42R,476.4625,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 42 duplex,,, 44,CB 43R,476.4875,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 43 duplex,,, 45,CB 44R,476.5125,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 44 duplex,,, 46,CB 45R,476.5375,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 45 duplex,,, 47,CB 46R,476.5625,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 46 duplex,,, 48,CB 47R,476.5875,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 47 duplex,,, 49,CB 48R,476.6125,+,0.75,,88.5,88.5,23,NN,NFM,12.5,,Channel 48 duplex,,, 50,CB 49,476.6375,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 51,CB 50,476.6625,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 52,CB 51,476.6875,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 53,CB 52,476.7125,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 54,CB 53,476.7375,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 55,CB 54,476.7625,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 56,CB 55,476.7875,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 57,CB 56,476.8125,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 58,CB 57,476.8375,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 59,CB 58,476.8625,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 60,CB 59,476.8875,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 61,CB 60,476.9125,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 62,CB 61*,476.9375,,,,88.5,88.5,23,NN,NFM,12.5,,Reserved for future use,,, 63,CB 62*,476.9625,,,,88.5,88.5,23,NN,NFM,12.5,,Reserved for future use,,, 64,CB 63*,476.9875,,,,88.5,88.5,23,NN,NFM,12.5,,Reserved for future use,,, 65,CB 64,477.0125,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 66,CB 65,477.0375,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 67,CB 66,477.0625,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 68,CB 67,477.0875,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 69,CB 68,477.1125,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 70,CB 69,477.1375,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 71,CB 70,477.1625,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 72,CB 71R,477.1875,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 41 repeater input (use chan 41 duplex for repeater),,, 73,CB 72R,477.2125,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 42 repeater input (use chan 42 duplex for repeater),,, 74,CB 73R,477.2375,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 43 repeater input (use chan 43 duplex for repeater),,, 75,CB 74R,477.2625,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 44 repeater input (use chan 44 duplex for repeater),,, 76,CB 75R,477.2875,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 45 repeater input (use chan 45 duplex for repeater),,, 77,CB 76R,477.3125,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 46 repeater input (use chan 46 duplex for repeater),,, 78,CB 77R,477.3375,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 47 repeater input (use chan 47 duplex for repeater),,, 79,CB 78R,477.3625,,,,88.5,88.5,23,NN,NFM,12.5,,Chan 48 repeater input (use chan 48 duplex for repeater),,, 80,CB 79,477.3875,,,,88.5,88.5,23,NN,NFM,12.5,,,,, 81,CB 80,477.4125,,,,88.5,88.5,23,NN,NFM,12.5,,,,, chirp-20240224/chirp/stock_configs/US Calling Frequencies.csv0000644000175000017500000000060514411666130022627 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,6m Call,52.525000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 2,2m Call,146.520000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 3,220 Call,223.500000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 4,70cm Call,446.000000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, chirp-20240224/chirp/stock_configs/US CA Railroad Channels.csv0000644000175000017500000002736514411666130022555 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,Tstep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,AAR002,159.810000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 2,AAR003,159.930000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 3,AAR004,160.050000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 4,AAR005,160.185000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 5,AAR006,160.200000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 6,AAR007,160.215000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 7,AAR008,160.230000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 8,AAR009,160.245000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 9,AAR010,160.260000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 10,AAR011,160.275000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 11,AAR012,160.290000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 12,AAR013,160.305000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 13,AAR014,160.320000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 14,AAR015,160.335000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 15,AAR016,160.350000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 16,AAR017,160.365000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 17,AAR018,160.380000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 18,AAR019,160.395000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 19,AAR020,160.410000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 20,AAR021,160.425000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 21,AAR022,160.440000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 22,AAR023,160.455000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 23,AAR024,160.470000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 24,AAR025,160.485000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 25,AAR026,160.500000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 26,AAR027,160.515000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 27,AAR028,160.530000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 28,AAR029,160.545000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 29,AAR030,160.560000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 30,AAR031,160.575000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 31,AAR032,160.590000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 32,AAR033,160.605000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 33,AAR034,160.620000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 34,AAR035,160.635000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 35,AAR036,160.650000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 36,AAR037,160.665000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 37,AAR038,160.680000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 38,AAR039,160.695000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 39,AAR040,160.710000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 40,AAR041,160.725000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 41,AAR042,160.740000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 42,AAR043,160.755000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 43,AAR044,160.770000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 44,AAR045,160.785000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 45,AAR046,160.800000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 46,AAR047,160.815000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 47,AAR048,160.830000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 48,AAR049,160.845000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 49,AAR050,160.860000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 50,AAR051,160.875000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 51,AAR052,160.890000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 52,AAR053,160.905000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 53,AAR054,160.920000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 54,AAR055,160.935000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 55,AAR056,160.950000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 56,AAR057,160.965000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 57,AAR058,160.980000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 58,AAR059,160.995000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 59,AAR060,161.010000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 60,AAR061,161.025000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 61,AAR062,161.040000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 62,AAR063,161.055000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 63,AAR064,161.070000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 64,AAR065,161.085000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 65,AAR066,161.100000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 66,AAR067,161.115000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 67,AAR068,161.130000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 68,AAR069,161.145000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 69,AAR070,161.160000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 70,AAR071,161.175000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 71,AAR072,161.190000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 72,AAR073,161.205000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 73,AAR074,161.220000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 74,AAR075,161.235000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 75,AAR076,161.250000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 76,AAR077,161.265000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 77,AAR078,161.280000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 78,AAR079,161.295000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 79,AAR080,161.310000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 80,AAR081,161.325000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 81,AAR082,161.340000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 82,AAR083,161.355000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 83,AAR084,161.370000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 84,AAR085,161.385000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 85,AAR086,161.400000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 86,AAR087,161.415000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 87,AAR088,161.430000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 88,AAR089,161.445000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 89,AAR090,161.460000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 90,AAR091,161.475000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 91,AAR092,161.490000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 92,AAR093,161.505000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 93,AAR094,161.520000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 94,AAR095,161.535000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 95,AAR096,161.550000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 96,AAR097,161.565000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 97,AAR107,160.222500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 98,AAR108,160.237500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 99,AAR109,160.252500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 100,AAR110,160.267500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 101,AAR111,160.282500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 102,AAR112,160.297500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 103,AAR113,160.312500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 104,AAR114,160.327500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 105,AAR115,160.342500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 106,AAR116,160.357500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 107,AAR117,160.372500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 108,AAR118,160.387500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 109,AAR119,160.402500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 110,AAR120,160.417500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 111,AAR121,160.432500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 112,AAR122,160.447500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 113,AAR123,160.462500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 114,AAR124,160.477500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 115,AAR125,160.492500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 116,AAR126,160.507500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 117,AAR127,160.522500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 118,AAR128,160.537500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 119,AAR129,160.552500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 120,AAR130,160.567500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 121,AAR131,160.582500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 122,AAR132,160.597500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 123,AAR133,160.612500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 124,AAR134,160.627500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 125,AAR135,160.642500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 126,AAR136,160.657500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 127,AAR137,160.672500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 128,AAR138,160.687500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 129,AAR139,160.702500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 130,AAR140,160.717500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 131,AAR141,160.732500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 132,AAR142,160.747500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 133,AAR143,160.762500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 134,AAR144,160.777500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 135,AAR145,160.792500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 136,AAR146,160.807500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 137,AAR147,160.822500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 138,AAR148,160.837500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 139,AAR149,160.852500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 140,AAR150,160.867500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 141,AAR151,160.882500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 142,AAR152,160.897500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 143,AAR153,160.912500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 144,AAR154,160.927500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 145,AAR155,160.942500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 146,AAR156,160.957500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 147,AAR157,160.972500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 148,AAR158,160.987500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 149,AAR159,161.002500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 150,AAR160,161.017500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 151,AAR161,161.032500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 152,AAR162,161.047500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 153,AAR163,161.062500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 154,AAR164,161.077500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 155,AAR165,161.092500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 156,AAR166,161.107500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 157,AAR167,161.122500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 158,AAR168,161.137500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 159,AAR169,161.152500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 160,AAR170,161.167500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 161,AAR171,161.182500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 162,AAR172,161.197500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 163,AAR173,161.212500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 164,AAR174,161.227500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 165,AAR175,161.242500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 166,AAR176,161.257500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 167,AAR177,161.272500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 168,AAR178,161.287500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 169,AAR179,161.302500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 170,AAR180,161.317500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 171,AAR181,161.332500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 172,AAR182,161.347500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 173,AAR183,161.362500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 174,AAR184,161.377500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 175,AAR185,161.392500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 176,AAR186,161.407500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 177,AAR187,161.422500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 178,AAR188,161.437500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 179,AAR189,161.452500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 180,AAR190,161.467500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 181,AAR191,161.482500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 182,AAR192,161.497500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 183,AAR193,161.512500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 184,AAR194,161.527500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 185,AAR195,161.542500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 186,AAR196,161.557500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, chirp-20240224/chirp/stock_configs/SE NO KDR444.csv0000644000175000017500000000115614454210572020161 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,KDR444 1,444.600,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 2,KDR444 2,444.650,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 3,KDR444 3,444.800,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 4,KDR444 4,444.825,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 5,KDR444 5,444.850,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 6,KDR444 6,444.875,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 7,KDR444 7,444.925,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 8,KDR444 8,444.975,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, chirp-20240224/chirp/stock_configs/EU LPD and PMR Channels.csv0000644000175000017500000001257114411666130022310 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,LPD 01,433.075000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 2,LPD 02,433.100000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 3,LPD 03,433.125000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 4,LPD 04,433.150000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 5,LPD 05,433.175000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 6,LPD 06,433.200000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 7,LPD 07,433.225000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 8,LPD 08,433.250000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 9,LPD 09,433.275000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 10,LPD 10,433.300000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 11,LPD 11,433.325000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 12,LPD 12,433.350000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 13,LPD 13,433.375000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 14,LPD 14,433.400000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 15,LPD 15,433.425000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 16,LPD 16,433.450000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 17,LPD 17,433.475000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 18,LPD 18,433.500000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 19,LPD 19,433.525000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 20,LPD 20,433.550000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 21,LPD 21,433.575000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 22,LPD 22,433.600000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 23,LPD 23,433.625000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 24,LPD 24,433.650000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 25,LPD 25,433.675000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 26,LPD 26,433.700000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 27,LPD 27,433.725000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 28,LPD 28,433.750000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 29,LPD 29,433.775000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 30,LPD 30,433.800000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 31,LPD 31,433.825000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 32,LPD 32,433.850000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 33,LPD 33,433.875000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 34,LPD 34,433.900000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 35,LPD 35,433.925000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 36,LPD 36,433.950000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 37,LPD 37,433.975000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 38,LPD 38,434.000000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 39,LPD 39,434.025000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 40,LPD 40,434.050000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 41,LPD 41,434.075000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 42,LPD 42,434.100000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 43,LPD 43,434.125000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 44,LPD 44,434.150000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 45,LPD 45,434.175000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 46,LPD 46,434.200000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 47,LPD 47,434.225000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 48,LPD 48,434.250000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 49,LPD 49,434.275000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 50,LPD 50,434.300000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 51,LPD 51,434.325000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 52,LPD 52,434.350000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 53,LPD 53,434.375000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 54,LPD 54,434.400000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 55,LPD 55,434.425000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 56,LPD 56,434.450000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 57,LPD 57,434.475000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 58,LPD 58,434.500000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 59,LPD 59,434.525000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 60,LPD 60,434.550000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 61,LPD 61,434.575000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 62,LPD 62,434.600000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 63,LPD 63,434.625000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 64,LPD 64,434.650000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 65,LPD 65,434.675000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 66,LPD 66,434.700000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 67,LPD 67,434.725000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 68,LPD 68,434.750000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 69,LPD 69,434.775000,,0.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 71,PMR 01,446.006250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 72,PMR 02,446.018750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 73,PMR 03,446.031250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 74,PMR 04,446.043750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 75,PMR 05,446.056250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 76,PMR 06,446.068750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 77,PMR 07,446.081250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 78,PMR 08,446.093750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 81,PMR 09,446.106250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 82,PMR 10,446.118750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 83,PMR 11,446.131250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 84,PMR 12,446.143750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 85,PMR 13,446.156250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 86,PMR 14,446.168750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 87,PMR 15,446.181250,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, 88,PMR 16,446.193750,,0.600000,,88.5,88.5,023,NN,NFM,6.25,,,,, chirp-20240224/chirp/stock_configs/GR Marine VHF Channels.csv0000644000175000017500000001151114565075506022351 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,RxDtcsCode,CrossMode,Mode,TStep,Skip,Power,Comment,URCALL,RPT1CALL,RPT2CALL,DVCODE 1,MRN 01,160.650000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 2,MRN 02,160.700000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 3,MRN 03,160.750000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 4,MRN 04,160.800000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 5,MRN 05,160.850000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 6,MRN 06,156.300000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 7,MRN 07,160.950000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 8,MRN 08,156.400000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 9,MRN 09,156.450000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 10,MRN 10,156.500000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 11,MRN 11,156.550000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 12,MRN 12,156.600000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 13,MRN 13,156.650000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 14,MRN 14,156.700000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 15,MRN 15,156.750000,off,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 16,MRN 16,156.800000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 17,MRN 17,156.850000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 18,MRN 18,161.500000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 19,MRN 19,161.550000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 20,MRN 20,161.600000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 21,MRN 21,161.650000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 22,MRN 22,161.700000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 23,MRN 23,161.750000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 24,MRN 24,161.800000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 25,MRN 25,161.850000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 26,MRN 26,161.900000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 27,MRN 27,161.950000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 28,MRN 28,162.000000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 29,MRN 60,160.625000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 30,MRN 61,160.675000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 31,MRN 62,160.725000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 32,MRN 63,160.775000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 33,MRN 64,160.825000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 34,MRN 65,160.875000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 35,MRN 66,160.925000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 36,MRN 67,156.375000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 37,MRN 68,156.425000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 38,MRN 69,156.475000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 39,MRN 70,156.525000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 40,MRN 71,156.575000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 41,MRN 72,156.625000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 42,MRN 73,156.675000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 43,MRN 74,156.725000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 44,MRN 75,156.775000,off,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 45,MRN 76,156.825000,off,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 46,MRN 77,156.875000,,0.000000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 47,MRN 78,161.525000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 48,MRN 79,161.575000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 49,MRN 80,161.625000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 50,MRN 81,161.675000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 51,MRN 82,161.725000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 52,MRN 83,161.775000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 53,MRN 84,161.825000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 54,MRN 85,161.875000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 55,MRN 86,161.925000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,5.00,,50W,,,,, 56,MRN 87,161.975000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,,,,, 57,MRN 88,162.025000,-,4.600000,,88.5,88.5,023,NN,023,Tone->Tone,FM,25.00,,50W,,,,, chirp-20240224/chirp/stock_configs/US 60 meter channels (Center).csv0000644000175000017500000000067514411666130023453 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,60m CH1,5.332000,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 2,60m CH2,5.348000,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 3,60m CH3,5.358500,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 4,60m CH4,5.373000,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, 5,60m CH5,5.405000,,0.600000,,88.5,88.5,023,NN,USB,5.00,,,,, chirp-20240224/chirp/stock_configs/FR Marine VHF Channels.csv0000644000175000017500000000724614411666130022347 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,SEA 01,160.650000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 2,SEA 02,160.700000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 3,SEA 03,160.750000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 4,SEA 04,160.800000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 5,SEA 05,160.850000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 6,SEA 06,156.300000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 7,SEA 07,160.950000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 8,SEA 08,156.400000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 9,SEA 09,156.450000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 10,SEA 10,156.500000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 11,SEA 11,156.550000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 12,SEA 12,156.600000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 13,SEA 13,156.650000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 14,SEA 14,156.700000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 15,SEA 15,156.750000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 16,SEA 16,156.800000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 17,SEA 17,156.850000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 18,SEA 18,161.500000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 19,SEA 19,161.550000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 20,SEA 20,161.600000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 21,SEA 21,161.650000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 22,SEA 22,161.700000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 23,SEA 23,161.750000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 24,SEA 24,161.800000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 25,SEA 25,161.850000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 26,SEA 26,161.900000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 27,SEA 27,161.950000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 28,SEA 28,162.000000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 29,SEA 60,160.625000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 30,SEA 61,160.675000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 31,SEA 62,160.725000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 32,SEA 63,160.775000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 33,SEA 64,160.825000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 34,SEA 65,160.875000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 35,SEA 66,160.925000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 36,SEA 67,156.375000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 37,SEA 68,156.425000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 38,SEA 69,156.475000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 39,SEA 70,156.525000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 40,SEA 71,156.575000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 41,SEA 72,156.625000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 42,SEA 73,156.675000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 43,SEA 74,156.725000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 44,SEA 75,156.775000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 45,SEA 76,156.825000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 46,SEA 77,156.875000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 47,SEA 78,161.525000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 48,SEA 79,161.575000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 49,SEA 80,161.625000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 50,SEA 81,161.675000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 51,SEA 82,161.725000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 52,SEA 83,161.775000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 53,SEA 84,161.825000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 54,SEA 85,161.875000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 55,SEA 86,161.925000,-,4.600000,,88.5,88.5,023,NN,FM,5.00,,,,, 56,SEA 87,157.375000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 57,SEA 88,157.425000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, chirp-20240224/chirp/stock_configs/US MURS Channels.csv0000644000175000017500000000070514411666130021327 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,MURS 1,151.820000,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 2,MURS 2,151.880000,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 3,MURS 3,151.940000,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 4,Blue Dot,154.570000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, 5,Green Dot,154.600000,,0.000000,,88.5,88.5,023,NN,FM,5.00,,,,, chirp-20240224/chirp/stock_configs/SE Jaktradio 155MHz.csv0000644000175000017500000000104314411666130021623 0ustar hibbyhibbyLocation,Name,Frequency,Duplex,Offset,Tone,rToneFreq,cToneFreq,DtcsCode,DtcsPolarity,Mode,TStep,Skip,Comment,URCALL,RPT1CALL,RPT2CALL 1,JAKT 1,155.425,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 2,JAKT 2,155.475,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 3,JAKT 3,155.500,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 4,JAKT 4,155.525,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 5,JAKT 5,156.000,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 6,JAKT 6,156.400,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, 7,JAKT 7,156.450,,0.000000,,88.5,88.5,023,NN,NFM,5.00,,,,, chirp-20240224/chirp/platform.py0000644000175000017500000001737614430171343015355 0ustar hibbyhibby# Copyright 2008 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os from pathlib import Path import sys import re import logging from subprocess import Popen import six LOG = logging.getLogger(__name__) def _find_me(): return sys.modules["chirp.platform"].__file__ def natural_sorted(lst): def convert(text): return int(text) if text.isdigit() else text.lower() def natural_key(key): return [convert(c) for c in re.split('([0-9]+)', key)] return sorted(lst, key=natural_key) class Platform: """Base class for platform-specific functions""" def __init__(self, basepath): self._base = basepath self._last_dir = self.default_dir() def get_last_dir(self): """Return the last directory used""" return self._last_dir def set_last_dir(self, last_dir): """Set the last directory used""" self._last_dir = last_dir def config_dir(self): """Return the preferred configuration file directory""" return self._base def log_dir(self): """Return the preferred log file directory""" logdir = os.path.join(self.config_dir(), "logs") try: os.mkdir(logdir) except FileExistsError: pass return logdir def filter_filename(self, filename): """Filter @filename for platform-forbidden characters""" return filename def log_file(self, filename): """Return the full path to a log file with @filename""" filename = self.filter_filename(filename + ".txt").replace(" ", "_") return os.path.join(self.log_dir(), filename) def config_file(self, filename): """Return the full path to a config file with @filename""" return os.path.join(self.config_dir(), self.filter_filename(filename)) def open_text_file(self, path): """Spawn the necessary program to open a text file at @path""" raise NotImplementedError("The base class can't do that") def open_html_file(self, path): """Spawn the necessary program to open an HTML file at @path""" raise NotImplementedError("The base class can't do that") def default_dir(self): """Return the default directory for this platform""" return "." def os_version_string(self): """Return a string that describes the OS/platform version""" return "Unknown Operating System" def executable_path(self): """Return a full path to the program executable""" def we_are_frozen(): return hasattr(sys, "frozen") if we_are_frozen(): # Win32, find the directory of the executable return os.path.dirname(six.text_type(sys.executable, sys.getfilesystemencoding())) else: # UNIX: Find the parent directory of this module return os.path.dirname(os.path.abspath(os.path.join(_find_me(), ".."))) def find_resource(self, filename): """Searches for files installed to a share/ prefix.""" execpath = self.executable_path() share_candidates = [ os.path.join(execpath, "share"), os.path.join(sys.prefix, "share"), "/usr/local/share", "/usr/share", ] pkgshare_candidates = [os.path.join(i, "chirp") for i in share_candidates] search_paths = [execpath] + pkgshare_candidates + share_candidates for path in search_paths: candidate = os.path.join(path, filename) if os.path.exists(candidate): return candidate return "" def _unix_editor(): macos_textedit = "/Applications/TextEdit.app/Contents/MacOS/TextEdit" if os.path.exists(macos_textedit): return macos_textedit else: return "gedit" class UnixPlatform(Platform): """A platform module suitable for UNIX systems""" def __init__(self, basepath): if not basepath: basepath = os.path.join(self.default_dir(), ".chirp") Path(basepath).mkdir(exist_ok=True) super().__init__(str(basepath)) def default_dir(self): return str(Path.home()) def filter_filename(self, filename): return filename.replace("/", "") def open_text_file(self, path): pid1 = os.fork() if pid1 == 0: pid2 = os.fork() if pid2 == 0: editor = _unix_editor() LOG.debug("calling `%s %s'" % (editor, path)) os.execlp(editor, editor, path) else: sys.exit(0) else: os.waitpid(pid1, 0) LOG.debug("Exec child exited") def open_html_file(self, path): os.system("firefox '%s'" % path) def os_version_string(self): try: issue = open("/etc/issue.net", "r") ver = issue.read().strip().replace("\r", "").replace("\n", "")[:64] issue.close() ver = "%s - %s" % (os.uname()[0], ver) except Exception: ver = " ".join(os.uname()) return ver class Win32Platform(Platform): """A platform module suitable for Windows systems""" def __init__(self, basepath=None): if not basepath: appdata = os.getenv("APPDATA") if not appdata: appdata = "C:\\" basepath = os.path.abspath(os.path.join(appdata, "CHIRP")) if not os.path.isdir(basepath): try: os.mkdir(basepath) except FileExistsError: pass Platform.__init__(self, basepath) def default_dir(self): return os.path.abspath(os.path.join(os.getenv("USERPROFILE"), "Desktop")) def filter_filename(self, filename): for char in "/\\:*?\"<>|": filename = filename.replace(char, "") return filename def open_text_file(self, path): Popen(["notepad", path]) return def open_html_file(self, path): os.system("explorer %s" % path) def os_version_string(self): import win32api vers = {4: "Win2k", 5: "WinXP", 6: "WinVista/7", } (pform, sub, build, _, _) = win32api.GetVersionEx() return vers.get(pform, "Win32 (Unknown %i.%i:%i)" % (pform, sub, build)) def _get_platform(basepath): if os.name == "nt": return Win32Platform(basepath) else: return UnixPlatform(basepath) PLATFORM = None def get_platform(basepath=None): """Return the platform singleton""" global PLATFORM if not PLATFORM: PLATFORM = _get_platform(basepath) return PLATFORM def _do_test(): __pform = get_platform() print("Config dir: %s" % __pform.config_dir()) print("Default dir: %s" % __pform.default_dir()) print("Log file (foo): %s" % __pform.log_file("foo")) print("OS Version: %s" % __pform.os_version_string()) # __pform.open_text_file("d-rats.py") if __name__ == "__main__": _do_test() chirp-20240224/chirp/bandplan_iaru_r2.py0000644000175000017500000001501714563632215016730 0ustar hibbyhibby# Copyright 2013 Sean Burford # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from chirp import bandplan SHORTNAME = "iaru_r2" DESC = { "name": "IARU Region 2 (The Americas)", "updated": "October 8, 2010", "url": "http://www.iaru.org/uploads/1/3/0/7/13073366/r2_band_plan.pdf" } # Bands are broken up like this so that other plans can import bits. BANDS_160M = ( bandplan.Band((1800000, 2000000), "160 Meter Band"), bandplan.Band((1800000, 1810000), "Digimodes"), bandplan.Band((1810000, 1830000), "CW", mode="CW"), bandplan.Band((1830000, 1840000), "CW, priority for DX", mode="CW"), bandplan.Band((1840000, 1850000), "SSB, priority for DX", mode="LSB"), bandplan.Band((1850000, 1999000), "All modes", mode="LSB"), bandplan.Band((1999000, 2000000), "Beacons", mode="CW"), ) BANDS_80M = ( bandplan.Band((3500000, 4000000), "80 Meter Band"), bandplan.Band((3500000, 3510000), "CW, priority for DX", mode="CW"), bandplan.Band((3510000, 3560000), "CW, contest preferred", mode="CW"), bandplan.Band((3560000, 3580000), "CW", mode="CW"), bandplan.Band((3580000, 3590000), "All narrow band modes, digimodes"), bandplan.Band((3590000, 3600000), "All modes"), bandplan.Band((3600000, 3650000), "All modes, SSB contest preferred", mode="LSB"), bandplan.Band((3650000, 3700000), "All modes", mode="LSB"), bandplan.Band((3700000, 3775000), "All modes, SSB contest preferred", mode="LSB"), bandplan.Band((3775000, 3800000), "All modes, SSB DX preferred", mode="LSB"), bandplan.Band((3800000, 4000000), "All modes"), ) BANDS_40M = ( bandplan.Band((7000000, 7300000), "40 Meter Band"), bandplan.Band((7000000, 7025000), "CW, priority for DX", mode="CW"), bandplan.Band((7025000, 7035000), "CW", mode="CW"), bandplan.Band((7035000, 7038000), "All narrow band modes, digimodes"), bandplan.Band((7038000, 7040000), "All narrow band modes, digimodes"), bandplan.Band((7040000, 7043000), "All modes, digimodes"), bandplan.Band((7043000, 7300000), "All modes"), ) BANDS_30M = ( bandplan.Band((10100000, 10150000), "30 Meter Band"), bandplan.Band((10100000, 10130000), "CW", mode="CW"), bandplan.Band((10130000, 10140000), "All narrow band digimodes"), bandplan.Band((10140000, 10150000), "All modes, digimodes, no phone"), ) BANDS_20M = ( bandplan.Band((14000000, 14350000), "20 Meter Band"), bandplan.Band((14000000, 14025000), "CW, priority for DX", mode="CW"), bandplan.Band((14025000, 14060000), "CW, contest preferred", mode="CW"), bandplan.Band((14060000, 14070000), "CW", mode="CW"), bandplan.Band((14070000, 14089000), "All narrow band modes, digimodes"), bandplan.Band((14089000, 14099000), "All modes, digimodes"), bandplan.Band((14099000, 14101000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((14101000, 14112000), "All modes, digimodes"), bandplan.Band((14112000, 14285000), "All modes, SSB contest preferred", mode="USB"), bandplan.Band((14285000, 14300000), "All modes", mode="AM"), bandplan.Band((14300000, 14350000), "All modes"), ) BANDS_17M = ( bandplan.Band((18068000, 18168000), "17 Meter Band"), bandplan.Band((18068000, 18095000), "CW", mode="CW"), bandplan.Band((18095000, 18105000), "All narrow band modes, digimodes"), bandplan.Band((18105000, 18109000), "All narrow band modes, digimodes"), bandplan.Band((18109000, 18111000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((18111000, 18120000), "All modes, digimodes"), bandplan.Band((18120000, 18168000), "All modes"), ) BANDS_15M = ( bandplan.Band((21000000, 21450000), "15 Meter Band"), bandplan.Band((21000000, 21070000), "CW", mode="CW"), bandplan.Band((21070000, 21090000), "All narrow band modes, digimodes"), bandplan.Band((21090000, 21110000), "All narrow band modes, digimodes"), bandplan.Band((21110000, 21120000), "All modes (exc SSB), digimodes"), bandplan.Band((21120000, 21149000), "All narrow band modes"), bandplan.Band((21149000, 21151000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((21151000, 21450000), "All modes", mode="USB"), ) BANDS_12M = ( bandplan.Band((24890000, 24990000), "12 Meter Band"), bandplan.Band((24890000, 24915000), "CW", mode="CW"), bandplan.Band((24915000, 24925000), "All narrow band modes, digimodes"), bandplan.Band((24925000, 24929000), "All narrow band modes, digimodes"), bandplan.Band((24929000, 24931000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((24931000, 24940000), "All modes, digimodes"), bandplan.Band((24940000, 24990000), "All modes", mode="USB"), ) BANDS_10M = ( bandplan.Band((28000000, 29520000), "10 Meter Band"), bandplan.Band((28000000, 28070000), "CW", mode="CW"), bandplan.Band((28070000, 28120000), "All narrow band modes, digimodes"), bandplan.Band((28120000, 28150000), "All narrow band modes, digimodes"), bandplan.Band((28150000, 28190000), "All narrow band modes, digimodes"), bandplan.Band((28190000, 28199000), "Regional time shared beacons", mode="CW"), bandplan.Band((28199000, 28201000), "IBP, exclusively for beacons", mode="CW"), bandplan.Band((28201000, 28225000), "Continuous duty beacons", mode="CW"), bandplan.Band((28225000, 28300000), "All modes, beacons"), bandplan.Band((28300000, 28320000), "All modes, digimodes"), bandplan.Band((28320000, 29000000), "All modes"), bandplan.Band((29000000, 29200000), "All modes, AM preferred", mode="AM"), bandplan.Band((29200000, 29300000), "All modes including FM, digimodes"), bandplan.Band((29300000, 29510000), "Satellite downlink"), bandplan.Band((29510000, 29520000), "Guard band, no transmission allowed"), bandplan.Band((29520000, 29700000), "FM", step_khz=10, mode="NFM"), bandplan.Band((29620000, 29690000), "FM Repeaters", input_offset=-100000), ) BANDS = BANDS_160M + BANDS_80M + BANDS_40M + BANDS_30M + BANDS_20M + \ BANDS_17M + BANDS_15M + BANDS_12M + BANDS_10M chirp-20240224/chirp/logger.py0000644000175000017500000001617414563632215015012 0ustar hibbyhibby# Copyright 2015 Zachary T Welch # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . r""" The chirp.logger module provides the core logging facilities for CHIRP. It sets up the console and (optionally) a log file. For early debugging, it checks the CHIRP_DEBUG, CHIRP_LOG, and CHIRP_LOG_LEVEL environment variables. """ import contextlib import os import sys import logging import argparse from . import platform from chirp import CHIRP_VERSION def version_string(): args = (CHIRP_VERSION, platform.get_platform().os_version_string(), sys.version.split()[0]) return "CHIRP %s on %s (Python %s)" % args class VersionAction(argparse.Action): def __call__(self, parser, namespace, value, option_string=None): print(version_string()) sys.exit(1) def add_version_argument(parser): parser.add_argument("--version", action=VersionAction, nargs=0, help="Print version and exit") #: Map human-readable logging levels to their internal values. log_level_names = {"critical": logging.CRITICAL, "error": logging.ERROR, "warn": logging.WARNING, "info": logging.INFO, "debug": logging.DEBUG, } class Logger(object): log_format = '[%(asctime)s] %(name)s - %(levelname)s: %(message)s' def __init__(self): # create root logger self.logger = logging.getLogger() self.logger.setLevel(logging.DEBUG) self.LOG = logging.getLogger(__name__) # Set CHIRP_DEBUG in environment for early console debugging. # It can be a number or a name; otherwise, level is set to 'debug' # in order to maintain backward compatibility. CHIRP_DEBUG = os.getenv("CHIRP_DEBUG") self.early_level = logging.WARNING if CHIRP_DEBUG: try: self.early_level = int(CHIRP_DEBUG) except ValueError: try: self.early_level = log_level_names[CHIRP_DEBUG] except KeyError: self.early_level = logging.DEBUG # If we're on Win32 or MacOS, we don't use the console; instead, # we create 'debug.log', redirect all output there, and set the # console logging handler level to DEBUG. To test this on Linux, # set CHIRP_DEBUG_LOG in the environment. console_stream = None console_format = '%(levelname)s: %(message)s' if 'CHIRP_TESTENV' not in os.environ and ( hasattr(sys, "frozen") or not os.isatty(0) or os.getenv("CHIRP_DEBUG_LOG")): p = platform.get_platform() log = open(p.config_file("debug.log"), "w") sys.stdout = log sys.stderr = log console_stream = log console_format = self.log_format self.early_level = logging.DEBUG self.has_debug_log_file = True else: self.has_debug_log_file = False self.console = logging.StreamHandler(console_stream) self.console_level = self.early_level self.console.setLevel(self.early_level) self.console.setFormatter(logging.Formatter(console_format)) self.logger.addHandler(self.console) # Set CHIRP_LOG in environment to the name of log file. logname = os.getenv("CHIRP_LOG") self.logfile = None if logname is not None: self.create_log_file(logname) level = os.getenv("CHIRP_LOG_LEVEL") if level is not None: self.set_log_verbosity(level) else: self.set_log_level(logging.DEBUG) if self.early_level <= logging.DEBUG: self.LOG.debug(version_string()) def create_log_file(self, name): if self.logfile is None: self.logname = name # always truncate the log file with open(name, "w"): pass self.logfile = logging.FileHandler(name) format_str = self.log_format self.logfile.setFormatter(logging.Formatter(format_str)) self.logger.addHandler(self.logfile) else: self.logger.error("already logging to " + self.logname) def set_verbosity(self, level): self.LOG.debug("verbosity=%d", level) if level > logging.CRITICAL: level = logging.CRITICAL self.console_level = level self.console.setLevel(level) def set_log_level(self, level): self.LOG.debug("log level=%d", level) if level > logging.CRITICAL: level = logging.CRITICAL self.logfile.setLevel(level) def set_log_level_by_name(self, level): self.set_log_level(log_level_names[level]) instance: object Logger.instance = Logger() def is_visible(level): """Returns True if a message at level will be shown on the console""" return level >= Logger.instance.console_level def add_arguments(parser): parser.add_argument("-q", "--quiet", action="count", default=0, help="Decrease verbosity") parser.add_argument("-v", "--verbose", action="count", default=0, help="Increase verbosity") parser.add_argument("--log", dest="log_file", action="store", default=0, help="Log messages to a file") parser.add_argument("--log-level", action="store", default="debug", help="Log file verbosity (critical, error, warn, " + "info, debug). Defaults to 'debug'.") def handle_options(options): logger = Logger.instance if options.verbose or options.quiet: logger.set_verbosity(30 + 10 * (options.quiet - options.verbose)) if options.log_file: logger.create_log_file(options.log_file) try: level = int(options.log_level) logger.set_log_level(level) except ValueError: logger.set_log_level_by_name(options.log_level) if logger.early_level > logging.DEBUG: logger.LOG.debug(version_string()) class LookbackHandler(logging.Handler): def __init__(self): super().__init__() self._history = [] def emit(self, record): self._history.append(record) def get_history(self): return self._history @contextlib.contextmanager def log_history(level, root=None): root = logging.getLogger(root) handler = LookbackHandler() handler.setLevel(level) try: root.addHandler(handler) yield handler finally: root.removeHandler(handler) chirp-20240224/chirp/bandplan.py0000644000175000017500000001634714466370044015315 0ustar hibbyhibby# Copyright 2013 Sean Burford # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import chirp_common LOG = logging.getLogger(__name__) class Band(object): def __init__(self, limits, name, mode=None, step_khz=None, input_offset=None, output_offset=None, tones=None): # Apply semantic and chirp limitations to settings. # memedit applies radio limitations when settings are applied. try: assert limits[0] <= limits[1], "Lower freq > upper freq" if mode is not None: assert mode in chirp_common.MODES, "Mode %s not one of %s" % ( mode, chirp_common.MODES) if step_khz is not None: assert step_khz in chirp_common.TUNING_STEPS, ( "step_khz %s not one of %s" % (step_khz, chirp_common.TUNING_STEPS)) if tones: for tone in tones: assert tone in chirp_common.TONES, ( "tone %s not one of %s" % (tone, chirp_common.TONES)) except AssertionError as e: raise ValueError("%s %s: %s" % (name, limits, e)) self.name = name self.mode = mode self.step_khz = step_khz self.tones = tones self.limits = limits self.offset = None self.duplex = "simplex" if input_offset is not None: self.offset = input_offset self.duplex = "rpt TX" elif output_offset is not None: self.offset = output_offset self.duplex = "rpt RX" def __eq__(self, other): return (other.limits[0] == self.limits[0] and other.limits[1] == self.limits[1]) def contains(self, other): return (other.limits[0] >= self.limits[0] and other.limits[1] <= self.limits[1]) def width(self): return self.limits[1] - self.limits[0] def inverse(self): """Create an RX/TX shadow of this band using the offset.""" if not self.offset: return self limits = (self.limits[0] + self.offset, self.limits[1] + self.offset) offset = -1 * self.offset if self.duplex == "rpt RX": return Band(limits, self.name, self.mode, self.step_khz, input_offset=offset, tones=self.tones) return Band(limits, self.name, self.mode, self.step_khz, output_offset=offset, tones=self.tones) def __repr__(self): desc = '%s%s%s%s' % ( self.mode and 'mode: %s ' % (self.mode,) or '', self.step_khz and 'step_khz: %s ' % (self.step_khz,) or '', self.offset and 'offset: %s ' % (self.offset,) or '', self.tones and 'tones: %s ' % (self.tones,) or '') return "%s-%s %s %s %s" % ( self.limits[0], self.limits[1], self.name, self.duplex, desc) class BandPlans(object): def __init__(self, config): self._config = config self.plans = {} # Migrate old "automatic repeater offset" setting to # "North American Amateur Band Plan" ro = self._config.get("autorpt", "memedit") if ro is not None: self._config.set_bool("north_america", ro, "bandplan") self._config.remove_option("autorpt", "memedit") # And default new users to North America. if not self._config.is_defined("north_america", "bandplan"): self._config.set_bool("north_america", True, "bandplan") from chirp import bandplan_na, bandplan_au from chirp import bandplan_iaru_r1, bandplan_iaru_r2, bandplan_iaru_r3 for plan in (bandplan_na, bandplan_au, bandplan_iaru_r1, bandplan_iaru_r2, bandplan_iaru_r3): name = plan.DESC.get("name", plan.SHORTNAME) self.plans[plan.SHORTNAME] = (name, plan) rpt_inputs = [] for band in plan.BANDS: # Add repeater inputs. rpt_input = band.inverse() if rpt_input not in plan.BANDS: rpt_inputs.append(band.inverse()) plan.bands = list(plan.BANDS) plan.bands.extend(rpt_inputs) def get_defaults_for_frequency(self, freq): freq = int(freq) result = Band((freq, freq), repr(freq)) for shortname, details in self.plans.items(): if self._config.get_bool(shortname, "bandplan"): matches = [x for x in details[1].bands if x.contains(result)] # Add matches to defaults, favoring more specific matches. matches = sorted(matches, key=lambda x: x.width(), reverse=True) for match in matches: result.mode = match.mode or result.mode result.step_khz = match.step_khz or result.step_khz result.offset = match.offset or result.offset result.duplex = match.duplex or result.duplex result.tones = match.tones or result.tones if match.name: result.name = '/'.join((result.name or '', match.name)) # Limit ourselves to one band plan match for simplicity. # Note that if the user selects multiple band plans by editing # the config file it will work as expected (except where plans # conflict). if matches: break return result def get_enabled_plan(self): for shortname, details in self.plans.items(): if self._config.get_bool(shortname, "bandplan"): return details[1] def get_repeater_bands(self): bands_with_repeaters = [] current_plan = self.get_enabled_plan() # For now, assume anything above 28 MHz could have a repeater. # Alternately, we could scan for bands with repeater sub-bands and only # include those. min_freq = chirp_common.to_MHz(28) def add_nodupes(b): for existing in bands_with_repeaters: if b.name == existing.name: if sum(b.limits) < sum(existing.limits): # Don't add, this is smaller return else: bands_with_repeaters.remove(existing) break bands_with_repeaters.append(b) for band in current_plan.bands: if (band.limits[0] >= min_freq and band.name.lower().endswith('meter band')): add_nodupes(band) return sorted(bands_with_repeaters, key=lambda b: b.limits[0]) chirp-20240224/chirp/settings.py0000644000175000017500000004507014561124165015366 0ustar hibbyhibby# Copyright 2012 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import logging from chirp import chirp_common LOG = logging.getLogger(__name__) BANNED_NAME_CHARACTERS = r'%' class InvalidValueError(Exception): """An invalid value was specified for a given setting""" pass class InternalError(Exception): """A driver provided an invalid settings object structure""" pass class InvalidNameError(Exception): """A driver provided a setting with an invalid name""" pass class RadioSettingValue: """Base class for a single radio setting""" def __init__(self): self._current = None self._preinit_current = None self._has_changed = False self._validate_callback = self.null_callback self._mutable = True def initialize(self): """Initialize this value to the stashed value""" assert self._current is None and self._preinit_current is not None self.set_value(self._preinit_current) self._preinit_current = None def queue_current(self, current): """Set this value's current on initialization""" self._preinit_current = current def null_callback(self, x): return x def set_mutable(self, mutable): self._mutable = mutable def get_mutable(self): return self._mutable def changed(self): """Returns True if the setting has been changed since init""" return self._has_changed def set_validate_callback(self, callback): self._validate_callback = callback def set_value(self, value): """Sets the current value, triggers changed""" if not self.get_mutable() and self.initialized: raise InvalidValueError("This value is not mutable") if self._current is not None and value != self._current: self._has_changed = True self._current = self._validate_callback(value) def get_value(self): """Gets the current value""" if not self.initialized: LOG.error('Accessing setting value before init!') return self._current def __trunc__(self): return int(self.get_value()) def __int__(self): return int(self.get_value()) def __float__(self): return float(self.get_value()) def __str__(self): return str(self.get_value()) def __floordiv__(self, value): return int(self.get_value()) // value def __div__(self, value): return float(self.get_value()) / value def __mul__(self, value): return self.get_value() * value def __gt__(self, value): return self.get_value() > value def __lt__(self, value): return self.get_value() < value def __eq__(self, value): return self.get_value() == value @property def initialized(self): return self._current is not None class RadioSettingValueInteger(RadioSettingValue): """An integer setting""" def __init__(self, minval, maxval, current, step=1): RadioSettingValue.__init__(self) self._min = minval self._max = maxval self._step = step self.queue_current(current) def set_value(self, value): try: value = int(value) except Exception: raise InvalidValueError("An integer is required") if value > self._max or value < self._min: raise InvalidValueError("Value %i not in range %i-%i" % (value, self._min, self._max)) RadioSettingValue.set_value(self, value) def get_min(self): """Returns the minimum allowed value""" return self._min def get_max(self): """Returns the maximum allowed value""" return self._max def get_step(self): """Returns the step increment""" return self._step class RadioSettingValueFloat(RadioSettingValue): """A floating-point setting""" def __init__(self, minval, maxval, current, resolution=0.001, precision=4): RadioSettingValue.__init__(self) self._min = minval self._max = maxval self._res = resolution self._pre = precision self.queue_current(current) def format(self, value=None): """Formats the value into a string""" if value is None: value = self._current fmt_string = "%%.%if" % self._pre return fmt_string % value def set_value(self, value): try: value = float(value) except Exception: raise InvalidValueError("A floating point value is required") if value > self._max or value < self._min: raise InvalidValueError("Value %s not in range %s-%s" % ( self.format(value), self.format(self._min), self.format(self._max))) # FIXME: honor resolution RadioSettingValue.set_value(self, value) def get_min(self): """Returns the minimum allowed value""" return self._min def get_max(self): """Returns the maximum allowed value""" class RadioSettingValueBoolean(RadioSettingValue): """A boolean setting""" def __init__(self, current): RadioSettingValue.__init__(self) self.queue_current(current) def set_value(self, value): RadioSettingValue.set_value(self, bool(value)) def __bool__(self): return bool(self.get_value()) __nonzero__ = __bool__ def __str__(self): return str(bool(self.get_value())) class RadioSettingValueList(RadioSettingValue): """A list-of-strings setting""" def __init__(self, options, current=None, current_index=0): RadioSettingValue.__init__(self) self._options = list(options) self.queue_current(current or self._options[int(current_index)]) def set_value(self, value): if value not in self._options: raise InvalidValueError("%s is not valid for this setting" % value) RadioSettingValue.set_value(self, value) def set_index(self, index): # Will raise IndexError as expected self.set_value(self._options[int(index)]) def get_options(self): """Returns the list of valid option values""" return self._options def __trunc__(self): return self._options.index(self._current) def __int__(self): return self._options.index(self._current) class RadioSettingValueString(RadioSettingValue): """A string setting""" def __init__(self, minlength, maxlength, current, autopad=True, charset=chirp_common.CHARSET_ASCII): RadioSettingValue.__init__(self) self._minlength = minlength self._maxlength = maxlength self._charset = charset self._autopad = autopad self.queue_current(current) def set_charset(self, charset): """Sets the set of allowed characters""" self._charset = charset def set_value(self, value): if len(value) < self._minlength or len(value) > self._maxlength: raise InvalidValueError("Value must be between %i and %i chars" % (self._minlength, self._maxlength)) for char in value: if char not in self._charset: raise InvalidValueError("Value contains invalid " + "character `%s'" % char) if self._autopad: value = value.ljust(self._maxlength) RadioSettingValue.set_value(self, value) def __str__(self): return self._current def __len__(self): return len(self._current) def __getitem__(self, i): return self._current[i] class RadioSettingValueMap(RadioSettingValueList): """Map User Options to Radio Memory Values Provides User Option list for GUI, maintains state, verifies new values, and allows {setting,getting} by User Option OR Memory Value. External conversions not needed. """ def __init__(self, map_entries, mem_val=None, user_option=None): """Create new map Pass in list of 2 member tuples, typically of type (str, int), for each Radio Setting. First member of each tuple is the User Option Name, second is the Memory Value that corresponds. An example is APO: ("Off", 0), ("0.5", 5), ("1.0", 10). """ # Catch bugs early by testing tuple geometry for map_entry in map_entries: if not len(map_entry) == 2: raise InvalidValueError("map_entries must be 2 el tuples " "instead of: %s" % str(map_entry)) user_options = [e[0] for e in map_entries] self._mem_vals = [e[1] for e in map_entries] RadioSettingValueList.__init__(self, user_options, user_options[0]) if mem_val is not None: self.set_mem_val(mem_val) elif user_option is not None: self.set_value(user_option) self._has_changed = False def set_mem_val(self, mem_val): """Change setting to User Option that corresponds to 'mem_val'""" if mem_val in self._mem_vals: index = self._mem_vals.index(mem_val) self.set_value(self._options[index]) else: raise InvalidValueError( "%s is not valid for this setting" % mem_val) def get_mem_val(self): """Get the mem val corresponding to the currently selected user option""" return self._mem_vals[self._options.index(self.get_value())] def __trunc__(self): """Return memory value that matches current user option""" index = self._options.index(self._current) value = self._mem_vals[index] return value def __int__(self): """Return memory value that matches current user option""" index = self._options.index(self._current) value = self._mem_vals[index] return value def zero_indexed_seq_map(user_options): """RadioSettingValueMap factory method Radio Setting Maps commonly use a list of strings that map to a sequence that starts with 0. Pass in a list of User Options and this function returns a list of tuples of form (str, int). """ mem_vals = list(range(0, len(user_options))) return list(zip(user_options, mem_vals)) class RadioSettings(list): def __init__(self, *groups): list.__init__(self, groups) def __str__(self): items = [str(self[i]) for i in range(0, len(self))] return "\n".join(items) class RadioSettingGroup(object): """A group of settings""" def _validate(self, element): # RadioSettingGroup can only contain RadioSettingGroup objects if not isinstance(element, RadioSettingGroup): raise InternalError("Incorrect type %s" % type(element)) def __init__(self, name, shortname, *elements): for c in BANNED_NAME_CHARACTERS: if c in name: raise InvalidNameError( 'Name must not contain %r character' % c) self._name = name # Setting identifier self._shortname = shortname # Short human-readable name/description self.__doc__ = name # Longer explanation/documentation self._elements = {} self._element_order = [] self._frozen = False for i, element in enumerate(elements): self._validate(element) if (isinstance(element, RadioSettingValue) and not element.initialized): # Late-initialize this value try: element.initialize() except InvalidValueError as e: LOG.error('Failed to load %s value %i: %s', self._name, i, e) self.append(element) def set_frozen(self): self._frozen = True for i in self: if isinstance(i, RadioSettingGroup): i.set_frozen() def get_name(self): """Returns the group name""" return self._name def get_shortname(self): """Returns the short group identifier""" return self._shortname def set_doc(self, doc): """Sets the docstring for the group""" self.__doc__ = doc def __str__(self): string = "group '%s': {\n" % self._name for element in sorted(self._elements.values()): for line in str(element).split("\n"): string += "\t" + line + "\n" string += "}" return string # Kinda list interface def append(self, element): """Adds an element to the group""" if self._frozen: raise ValueError('Setting is frozen') self[element.get_name()] = element def __iter__(self): class RSGIterator: """Iterator for a RadioSettingGroup""" def __init__(self, rsg): self.__rsg = rsg self.__i = 0 def __iter__(self): return self def next(self): return self.__next__() def __next__(self): """Next Iterator Interface""" if self.__i >= len(self.__rsg.keys()): raise StopIteration() e = self.__rsg[self.__rsg.keys()[self.__i]] self.__i += 1 return e return RSGIterator(self) # Dictionary interface def __len__(self): return len(self._elements) def __getitem__(self, name): return self._elements[name] def __setitem__(self, name, value): if name in self._element_order: raise KeyError("Duplicate item %s" % name) self._elements[name] = value self._element_order.append(name) def __delitem__(self, item): del self._elements[item.get_name()] self._element_order.remove(item.get_name()) def __contains__(self, name): return name in self._elements def items(self): """Returns a key=>value set of elements, like a dict""" return [(name, self._elements[name]) for name in self._element_order] def keys(self): """Returns a list of string element names""" return self._element_order def values(self): """Returns the list of elements""" return [self._elements[name] for name in self._element_order] def __lt__(self, other): return self._name < other._name class RadioSettingSubGroup(RadioSettingGroup): """A subgroup of related settings. These are to be displayed with less weight than a regular group. Used for repeated sections of related settings, or small groups that don't merit their own panel of display in the UI. """ class RadioSetting(RadioSettingGroup): """A single setting, which could be an array of items like a group""" def __init__(self, *args): super(RadioSetting, self).__init__(*args) self._apply_callback = None self._warning_text = None self._safe_value = None self._volatile = False @property def volatile(self): return self._volatile def set_volatile(self, value): self._volatile = value def set_apply_callback(self, callback, *args): self._apply_callback = lambda: callback(self, *args) def has_apply_callback(self): return self._apply_callback is not None def run_apply_callback(self): return self._apply_callback() def set_warning(self, warning_text, safe_value=None): """Set a warning message to be shown to the user when changed. This should not be over-used as it will be annoying (on purpose). This message will be shown to the user with an option to continue to abort. It should be used to warn the user of potential invalid operation or compatibility issues. If safe_value is set, this will only warn the user if the value is changed *to* something other than the safe_value. """ self._warning_text = warning_text self._safe_value = safe_value def get_warning(self, value): if value != self._safe_value: return self._warning_text def _validate(self, value): # RadioSetting can only contain RadioSettingValue objects if not isinstance(value, RadioSettingValue): raise InternalError("Incorrect type") def changed(self): """Returns True if any of the elements in the group have been changed""" for element in self._elements.values(): if element.changed(): return True return False def __str__(self): return "%s:%s" % (self._name, self.value) def __repr__(self): return "[RadioSetting %s:%s]" % (self._name, self.value) # Magic foo.value attribute def __getattr__(self, name): if name == "value": if len(self) == 1: return self._elements[self._element_order[0]] else: return list(self._elements.values()) elif name in ('__getstate__', '__setstate__', '__deepcopy__'): super().__getattr__(name) else: return self.__dict__[name] def __setattr__(self, name, value): if name == "value": if self._frozen: raise ValueError('Value is frozen') if len(self) == 1: self._elements[self._element_order[0]].set_value(value) else: raise InternalError("Setting %s is not a scalar" % self._name) else: self.__dict__[name] = value # List interface def append(self, value): index = len(self._element_order) self._elements[index] = value self._element_order.append(index) def __getitem__(self, name): if not isinstance(name, int): raise IndexError("Index `%s' is not an integer" % name) return self._elements[name] def __setitem__(self, name, value): if not isinstance(name, int): raise IndexError("Index `%s' is not an integer" % name) if name in self._elements: self._elements[name].set_value(value) else: self._elements[name] = value chirp-20240224/chirp/__init__.py0000644000175000017500000000004014566340175015257 0ustar hibbyhibbyCHIRP_VERSION = "next-20240224" chirp-20240224/chirp/bitwise_grammar.py0000644000175000017500000000544514566340166016712 0ustar hibbyhibby# Copyright 2010 Dan Smith # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import re from chirp.pyPEG import keyword, parse as pypeg_parse TYPES = ["bit", "u8", "u16", "ul16", "u24", "ul24", "u32", "ul32", "i8", "i16", "il16", "i24", "il24", "i32", "il32", "char", "lbcd", "bbcd"] DIRECTIVES = ["seekto", "seek", "printoffset"] def string(): return re.compile(r"\"[^\"]*\"") def symbol(): return re.compile(r"\w+") def count(): return re.compile(r"([1-9][0-9]*|0x[0-9a-fA-F]+)") def bitdef(): return symbol, ":", count def _bitdeflist(): return bitdef, -1, (",", bitdef) def bitfield(): return _bitdeflist def array(): return symbol, '[', count, ']' def _typedef(): return re.compile(r"(%s)" % "|".join(TYPES)) def definition(): return _typedef, [array, bitfield, symbol], ";" def seekto(): return keyword("seekto"), count def seek(): return keyword("seek"), count def printoffset(): return keyword("printoffset"), string def directive(): return "#", [seekto, seek, printoffset], ";" def _block_inner(): return -2, [definition, struct, directive] def _block(): return "{", _block_inner, "}" def struct_defn(): return symbol, _block def struct_decl(): return [symbol, _block], [array, symbol] def struct(): return keyword("struct"), [struct_defn, struct_decl], ";" def _language(): return _block_inner def parse(data): lines = data.split("\n") for index, line in enumerate(lines): if '//' in line: lines[index] = line[:line.index('//')] class FakeFileInput(object): """Simulate line-by-line file reading from @data""" line = -1 def isfirstline(self): return self.line == 0 def filename(self): return "input" def lineno(self): return self.line def __iter__(self): return self def __next__(self): self.line += 1 try: # Note, FileInput objects keep the newlines return lines[self.line] + "\n" except IndexError: raise StopIteration return pypeg_parse(_language, FakeFileInput()) chirp-20240224/tools/0000755000175000017500000000000014566340177013211 5ustar hibbyhibbychirp-20240224/tools/cpep8.manifest0000644000175000017500000000361514456716614015766 0ustar hibbyhibby# # # NOTE: Do not add files to this manifest anymore. New files will be run # under flake8 automatically if they are in the tree. Files in this manifest # will continue to run under cpep8's less-strict rules until they can be # fixed. # # ./chirp/drivers/alinco.py ./chirp/drivers/anytone778uv.py ./chirp/drivers/anytone_ht.py ./chirp/drivers/anytone_iii.py ./chirp/drivers/baofeng_common.py ./chirp/drivers/baofeng_uv3r.py ./chirp/drivers/bf_t8.py ./chirp/drivers/btech.py ./chirp/drivers/ft1d.py ./chirp/drivers/ft2900.py ./chirp/drivers/ft60.py ./chirp/drivers/ft7800.py ./chirp/drivers/ft90.py ./chirp/drivers/ga510.py ./chirp/drivers/generic_csv.py ./chirp/drivers/gmrsv2.py ./chirp/drivers/h777.py ./chirp/drivers/ic2730.py ./chirp/drivers/icf.py ./chirp/drivers/icomciv.py ./chirp/drivers/iradio_uv_5118.py ./chirp/drivers/kenwood_live.py ./chirp/drivers/kg935g.py ./chirp/drivers/kguv920pa.py ./chirp/drivers/kguv9dplus.py ./chirp/drivers/kyd.py ./chirp/drivers/leixen.py ./chirp/drivers/lt725uv.py ./chirp/drivers/radioddity_r2.py ./chirp/drivers/radtel_t18.py ./chirp/drivers/retevis_rb15.py ./chirp/drivers/retevis_rb17p.py ./chirp/drivers/retevis_rt1.py ./chirp/drivers/retevis_rt21.py ./chirp/drivers/retevis_rt22.py ./chirp/drivers/retevis_rt23.py ./chirp/drivers/retevis_rt26.py ./chirp/drivers/retevis_rt76p.py ./chirp/drivers/retevis_rt87.py ./chirp/drivers/retevis_rt98.py ./chirp/drivers/tdxone_tdq8a.py ./chirp/drivers/th9000.py ./chirp/drivers/th9800.py ./chirp/drivers/th_uv3r.py ./chirp/drivers/th_uv3r25.py ./chirp/drivers/th_uv8000.py ./chirp/drivers/th_uv88.py ./chirp/drivers/thd72.py ./chirp/drivers/tk760.py ./chirp/drivers/tk760g.py ./chirp/drivers/tk8180.py ./chirp/drivers/tmd710.py ./chirp/drivers/ts480.py ./chirp/drivers/ts590.py ./chirp/drivers/uv5r.py ./chirp/drivers/uv5x3.py ./chirp/drivers/vgc.py ./chirp/drivers/vx6.py ./chirp/drivers/vx7.py ./chirp/drivers/vx8.py ./chirp/drivers/wouxun.py chirp-20240224/tools/check_commit.sh0000755000175000017500000000562114566340166016177 0ustar hibbyhibby#!/bin/bash BASE=${1:-origin/master} RETCODE=0 RED='\033[1;31m' GREEN='\033[1;32m' NC='\033[0m' function fail() { echo -e "${RED}$*${NC}" RETCODE=1 } echo -e "${GREEN}Checking from $(git rev-parse --short ${BASE}):${NC}" git log --pretty=oneline --no-merges --abbrev-commit ${BASE}.. echo git diff ${BASE}.. '*.py' | grep '^+' > added_lines if grep -E '(from|import).*six' added_lines; then fail No new uses of future fi if grep -E '\wsix\w' added_lines; then fail No new uses of six fi if grep -E '(from|import).*builtins' added_lines; then fail No new uses of future fi if grep -E '\wfuture\w' added_lines; then fail No new uses of future fi if grep -E '(from|import).*past(?!e)' added_lines; then fail Use of past library not allowed fi if grep -E 'MemoryMap\(' added_lines; then fail New uses of MemoryMap should be MemoryMapBytes fi if grep -E "[^_]_\([^\"']" added_lines; then fail 'Translated strings must be literals!' fi if grep -E "eval\(" added_lines; then fail 'Use of eval() is dangerous and not permitted!' fi if git diff ${BASE}.. 'tools/cpep8.manifest' | tail -n +5 | grep -q '^+'; then fail 'Do not add new files to cpep8.manifest; no longer needed' fi if git diff ${BASE}.. 'tools/cpep8.blacklist' | tail -n +5 | grep -q '^+'; then fail 'Do not add new files to cpep8.blacklist; fix the code' fi grep -i 'license' added_lines > license_lines if grep -ivE '(GNU General Public License|Free Software Foundation|gnu.org.licenses)' license_lines; then fail 'Files must be GPLv3 licensed (or not contain any license language)' fi for file in $(git diff --name-only ${BASE}..); do if file $file | grep -q CRLF; then fail "$file : Files should be LF (Unix) format, not CR (Mac) or CRLF (Windows)" fi done #if grep 'def match_model' added_lines; then # fail 'New drivers should not have match_model() implemented as it is not needed' #fi if git log ${BASE}.. --merges | grep .; then fail Please do not include merge commits in your PR fi make -C chirp/locale clean all >/dev/null 2>&1 if git diff chirp/locale | grep '^+[^#+]' | grep -v POT-Creation; then fail Locale files need updating fi added_files=$(git diff --name-only --diff-filter=A ${BASE}..) added_py=$(git diff --name-only --diff-filter=A ${BASE}.. | grep '\.py$') if echo $added_py | grep -q chirp.drivers && ! echo $added_files | grep -q tests.images; then fail All new drivers should include a test image fi existing_drivers=$(git ls-tree --name-only $BASE chirp/drivers/) limit=51 for nf in $added_py; do for of in $existing_drivers; do common=$(wdiff -s $of $nf | grep -I $nf | sed -r 's/.* ([0-9]+)% common.*/\1/') if [ ! "$common" ]; then continue fi if [ "$common" -gt "$limit" ]; then fail "New file $nf shares at least ${common}% with $of!" fi done done rm -f added_lines license_lines exit $RETCODE chirp-20240224/tools/cpep8.exceptions0000644000175000017500000000064214411666130016322 0ustar hibbyhibby# This file contains a list of per-file exceptions to the pep8 style rules # Each line must contain the file name, a tab, and a comma-separated list # of style rules to ignore in that file. This mechanism should be used # sparingly and as a measure of last resort. ./share/make_supported.py E402 ./tests/run_tests E402 ./tests/unit/test_memedit_edits.py E402 ./chirpw E402 ./chirp/memmap.py E731 ./chirp/util.py E731 chirp-20240224/tools/serialsniff.c0000644000175000017500000002247114506756044015666 0ustar hibbyhibby/* * * Copyright 2008 Dan Smith * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * * Modifications made by: * Stuart Blake Tener, N3GWG * Email: * Mobile phone: +1 (310) 358-0202 * * 02 MAR 2009 - Version 1.01 * * Logic was changed to use "ptsname" instead of "ptsname_r" * in pursuance of provisioning greater compatibility with other * Unix variants and Open Standards Unix flavors which have not * otherwise implemented the "ptsname_r" system call. * Changes developed and tested under MacOS 10.5.6 (Leopard) * * Added "--quiescent" switch, which when used on the command * line prevents the printing of "Timeout" and count notices * on the console. * Changes developed and tested under MacOS 10.5.6 (Leopard) * * Added program title and version tagline, printed when the * software is first started. * * 03 MAR 2009 - Version 1.02 * * Added "--digits" switch, which when used on the command * line allows for setting the number of hex digits print per * line. * * Added code to allow "-q" shorthand for "quiescent mode". * * Changes were made to add "#ifdef" statements so that only code * appropriate to MacOS would be compiled if a "#define MACOS" is * defined early within the source code. * * Cleaned up comments in the source for my new source code. * * Changes developed and tested under MacOS 10.5.6 (Leopard) * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define STREQ(a,b) (strcmp(a,b) == 0) char *version = "1.02 (03 MAR 2009)"; int quiescent = 0; int total_hex = 20; struct path { int fd; char path[1024]; char name[1024]; int rawlog_fd; }; void hexdump(char *buf, int len, FILE *dest) { /* * In precedence to the modification of this procedure to support the * variable size hexadecimal output, the total bytes output was fixed * to be a length of 8. * * The amendment of this procedure to support the "total_hex" variable * allows for the user to pass a command line argument instantiating a * desired number of hexadecimal bytes (and their ASCII equivalent) to * be displayed. * */ int i; int j; for (i = 0; i < len; i += total_hex) { for (j = i; j < i + total_hex; j++) { if ((j % 4) == 0) fprintf(dest, " "); if (j < len) fprintf(dest, "%02x", buf[j] & 0xFF); else fprintf(dest, "--"); } fprintf(dest, " "); for (j = i; j < i + total_hex; j++) { if ((j % 4) == 0) fprintf(dest, " "); if (j > len) fprintf(dest, "."); else if ((buf[j] > ' ') && (buf[j] < '~')) fprintf(dest, "%c", buf[j]); else fprintf(dest, "."); } fprintf(dest, "\n"); } } int saferead(int fd, char *buf, int len) { struct itimerval val; int ret; int count = 0; memset(&val, 0, sizeof(val)); val.it_value.tv_usec = 50000; setitimer(ITIMER_REAL, &val, NULL); while (count < len) { getitimer(ITIMER_REAL, &val); if ((val.it_value.tv_sec == 0) && (val.it_value.tv_usec == 0)) { if (!quiescent) printf("Timeout\n"); break; } ret = read(fd, &(buf[count]), len - count); if (ret > 0) count += ret; } return count; } void proxy(struct path *pathA, struct path *pathB) { fd_set rfds; int ret; struct timeval tv; while (1) { int count = 0; int ret; char buf[4096]; FD_ZERO(&rfds); FD_SET(pathA->fd, &rfds); FD_SET(pathB->fd, &rfds); ret = select(30, &rfds, NULL, NULL, NULL); if (ret == -1) { perror("select"); break; } if (FD_ISSET(pathA->fd, &rfds)) { count = saferead(pathA->fd, buf, sizeof(buf)); if (count < 0) break; ret = write(pathB->fd, buf, count); if (ret != count) printf("Failed to write %i (%i)\n", count, ret); if (!quiescent) printf("%s %i:\n", pathA->name, count); hexdump(buf, count, stdout); if (pathA->rawlog_fd >= 0) { ret = write(pathA->rawlog_fd, buf, count); if (ret != count) printf("Failed to write %i to %s log", count, pathA->name); } } if (FD_ISSET(pathB->fd, &rfds)) { count = saferead(pathB->fd, buf, sizeof(buf)); if (count < 0) break; ret = write(pathA->fd, buf, count); if (ret != count) printf("Failed to write %i (%i)\n", count, ret); if (!quiescent) printf("%s %i:\n", pathB->name, count); hexdump(buf, count, stdout); if (pathB->rawlog_fd >= 0) { ret = write(pathB->rawlog_fd, buf, count); if (ret != count) printf("Failed to write %i to %s log", count, pathB->name); } } } } static bool open_pty(struct path *path) { #ifdef MACOS char *ptsname_path; #endif path->fd = posix_openpt(O_RDWR); if (path->fd < 0) { perror("posix_openpt"); return false; } grantpt(path->fd); unlockpt(path->fd); #ifdef MACOS ptsname_path = ptsname(path->fd); strncpy(path->path,ptsname_path,sizeof(path->path) - 1); #else ptsname_r(path->fd, path->path, sizeof(path->path)); #endif fprintf(stderr, "%s\n", path->path); return true; } static bool open_serial(const char *serpath, struct path *path) { path->fd = open(serpath, O_RDWR); if (path->fd < 0) perror(serpath); strncpy(path->path, serpath, sizeof(path->path)); return path->fd >= 0; } static bool open_socket(const char *foo, struct path *path) { int lfd; struct sockaddr_in srv; struct sockaddr_in cli; unsigned int cli_len = sizeof(cli); int optval = 1; lfd = socket(AF_INET, SOCK_STREAM, 0); if (lfd < 0) { perror("socket"); return false; } srv.sin_family = AF_INET; srv.sin_port = htons(2000); srv.sin_addr.s_addr = INADDR_ANY; setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); if (bind(lfd, (struct sockaddr *)&srv, sizeof(srv)) < 0) { perror("bind"); return false; } if (listen(lfd, 1) < 0) { perror("listen"); return false; } printf("Waiting...\n"); path->fd = accept(lfd, (struct sockaddr *)&cli, &cli_len); if (path->fd < 0) { perror("accept"); return false; } printf("Accepted socket client\n"); strcpy(path->path, "SOCKET"); return true; } static bool open_path(const char *opt, struct path *path) { if (STREQ(opt, "pty")) return open_pty(path); else if (STREQ(opt, "listen")) return open_socket(opt, path); else return open_serial(opt, path); } static bool open_log(const char *filename, struct path *path) { path->rawlog_fd = open(filename, O_WRONLY | O_CREAT, 0644); if (path->rawlog_fd < 0) perror(filename); return path->rawlog_fd >= 0; } static void usage() { printf("Usage:\n" "serialsniff [OPTIONS]\n" "Where OPTIONS are:\n" "\n" " -A,--pathA=DEV Path to device A (or 'pty')\n" " -B,--pathB=DEV Path to device B (or 'pty')\n" " --logA=FILE Log pathA (raw) to FILE\n" " --logB=FILE Log pathB (raw) to FILE\n" " --nameA=NAME Set pathA name to NAME\n" " --nameB=NAME Set pathB name to NAME\n" " --q,-q,--quiescent Run in quiescent mode\n" " --d,-d,--digits Number of hex digits to print in one line\n\n" " --d=nn or -d nn or --digits nn\n" "\n" ); } int main(int argc, char **argv) { struct sigaction sa; struct path pathA; struct path pathB; int c; strcpy(pathA.name, "A"); strcpy(pathB.name, "B"); pathA.fd = pathA.rawlog_fd = -1; pathB.fd = pathB.rawlog_fd = -1; printf("\nserialsniff - Version %s\n\n",version); while (1) { int optind; static struct option lopts[] = { {"pathA", 1, 0, 'A'}, {"pathB", 1, 0, 'B'}, {"logA", 1, 0, 1 }, {"logB", 1, 0, 2 }, {"nameA", 1, 0, 3 }, {"nameB", 1, 0, 4 }, {"quiescent", 0, 0, 'q' }, {"digits", 1, 0, 'd'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "A:B:d:l:q", lopts, &optind); if (c == -1) break; switch (c) { case 'A': if (!open_path(optarg, &pathA)) return 1; break; case 'B': if (!open_path(optarg, &pathB)) return 2; break; case 1: if (!open_log(optarg, &pathA)) return 3; break; case 2: if (!open_log(optarg, &pathB)) return 4; break; case 3: strncpy(pathA.name, optarg, sizeof(pathA.name)); break; case 4: strncpy(pathB.name, optarg, sizeof(pathB.name)); break; case 'q': quiescent = 1; break; case 'd': total_hex=atoi(optarg); break; case '?': return 3; } } memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_IGN; sigaction(SIGALRM, &sa, NULL); if ((pathA.fd < 0) || (pathB.fd < 0)) { usage(); return -1; } proxy(&pathA, &pathB); return 0; } chirp-20240224/tools/checkpatch.sh0000755000175000017500000000271714411666130015641 0ustar hibbyhibby#!/usr/bin/env bash # # CHIRP coding standards compliance script # # To add a test to this file, create a new check_foo() function # and then add it to the list of TESTS= below # TESTS="check_long_lines check_bug_number check_commit_message_line_length" function check_long_lines() { local rev="$1" local files="$2" # For now, ignore this check on chirp/ files=$(echo $files | sed -r 's#\bchirp[^ ]*\b##') if [ -z "$files" ]; then return fi pep8 --select=E501 $files || \ error "Please use <80 columns in source files" } function check_bug_number() { local rev="$1" hg log -vr $rev | grep -qE '#[0-9]+' || \ error "A bug number is required like #123" } function _less_than_80() { while true; do read line if [ -z "$line" ]; then break elif [ $(echo -n "$line" | wc -c) -ge 80 ]; then return 1 fi done } function check_commit_message_line_length() { local rev="$1" hg log -vr $rev | (_less_than_80) || \ error "Please keep commit message lines to <80 columns" } # --- END OF TEST FUNCTIONS --- function error() { echo FAIL: $* ERROR=1 } function get_touched_files() { local rev="$1" hg status -n --change $rev | grep '\.py$' } rev=${1:-tip} files=$(get_touched_files $rev) for testname in $TESTS; do eval "$testname $rev \"$files\"" done if [ -z "$ERROR" ]; then echo "Patch '${rev}' is OK" else exit 1 fi chirp-20240224/tools/icomsio.sh0000755000175000017500000000436514506756044015220 0ustar hibbyhibby#!/usr/bin/env bash # # ICOM ID-RP* serial helper script # # Copyright 2009 Dan Smith # # This script will scan the USB bus on this system and determine # the product ID of any attached ICOM repeater modules. It will # unload and then reload the FTDI serial driver with the proper # options to detect the device. After that, it will determine the # device name and link /dev/icom to that device for easy access. LINK="icom" VENDOR="0x0c26" DEVICE=$(lsusb -d ${VENDOR}: | cut -d ' ' -f 6 | cut -d : -f 2 | sed -r 's/\n/ /g') product_to_name() { local prod=$1 if [ "$prod" = "0012" ]; then echo "ID-RP2000V TX" elif [ "$prod" = "0013" ]; then echo "ID-RP2000V RX" elif [ "$prod" = "0010" ]; then echo "ID-RP4000V TX" elif [ "$prod" = "0011" ]; then echo "ID-RP4000V RX" elif [ "$prod" = "000b" ]; then echo "ID-RP2D" elif [ "$prod" = "000c" ]; then echo "ID-RP2V TX" elif [ "$prod" = "000d" ]; then echo "ID-RP2V RX" else echo "Unknown module (id=${prod})" fi } if [ $(id -u) != 0 ]; then echo "This script must be run as root" exit 1 fi if [ -z "$DEVICE" ]; then echo "No devices found" exit 1 fi if echo $DEVICE | grep -q ' '; then echo "Multiple devices found. Choose one:" i=0 for dev in $DEVICE; do name=$(product_to_name $dev) echo " ${i}: ${name}" i=$(($i + 1)) done echo -n "> " read num array=($DEVICE) DEVICE=${array[$num]} if [ -z "$DEVICE" ]; then exit fi fi modprobe -r ftdi_sio || { echo "Unable to unload ftdi_sio" exit 1 } modprobe ftdi_sio vendor=${VENDOR} product=0x${DEVICE} || { echo "Failed to load ftdi_sio" exit 1 } sleep 0.5 info=$(lsusb -d ${VENDOR}:0x${DEVICE}) bus=$(echo $info | cut -d ' ' -f 2 | sed 's/^0*//') dev=$(echo $info | cut -d ' ' -f 4 | sed 's/^0*//') for usbserial in /sys/class/tty/ttyUSB*; do driver=$(basename $(readlink -f ${usbserial}/device/driver)) device=$(basename $usbserial) if [ "$driver" = "ftdi_sio" ]; then name=$(product_to_name $DEVICE) ln -sf /dev/${device} /dev/${LINK} echo "Device $name is /dev/${device} -> /dev/${LINK}" break fi done chirp-20240224/tools/fast-driver.py0000755000175000017500000000663314506756044016022 0ustar hibbyhibby#!/usr/bin/env Python3 import glob import os import subprocess import sys def parse_import_line(line): pieces = line.split() if line.startswith('from'): base = pieces[1] if 'drivers.' in base: imports = [base.split('.')[-1]] return imports else: imports = pieces[3:] if pieces[-1].endswith(','): raise Exception('Failed to parse multi-line import') return [x.strip().strip(',') for x in imports] elif 'drivers' in line: raise Exception('Unhandled bare import driver line: %s' % line) else: return [] def find_imports(of_modules): driver_imports = [] for fn in glob.glob('chirp/drivers/*.py'): with open(fn) as f: lines = [ln for ln in f.readlines() if 'import ' in ln and 'drivers' in ln] imports = [] for line in lines: imports.extend(parse_import_line(line)) if set(imports) & of_modules: driver_imports.append(os.path.splitext(os.path.basename(fn))[0]) return driver_imports files = subprocess.check_output( ['git', 'diff', 'origin/master', '--name-only', '.']).decode().split() # A list of modules and their parent [(chirp/drivers, tk8180)] files_by_module = [x.rsplit('/', 1) for x in files if '/' in x and '.py' in x] # Grab just the drivers driver_modules = set([os.path.splitext(os.path.basename(mod))[0] for parent, mod in files_by_module if parent == 'chirp/drivers']) # Determine which are live drivers that we don't test with these tests live_drivers = set() for driver in driver_modules: try: with open(os.path.join('chirp', 'drivers', '%s.py' % driver)) as f: content = f.read() except FileNotFoundError: # File must have been removed continue if 'LiveRadio' in content: live_drivers.add(driver) print('Touched drivers: %s' % ','.join(driver_modules)) # Find deps before we remove live modules in case there are any changed # modules that depend on the bases that have live drivers in them (i.e. icf or # kenwood_live) deps = find_imports(driver_modules) print('Found deps of touched modules: %s' % ','.join(deps)) # Remove live drivers from driver_modules before we add in the deps of changed # modules, as they may imply some shared code (like icf) driver_modules -= live_drivers driver_modules.update(set(deps)) # Determine if any base modules have been changed that would necessitate # running all the driver tests exclude_mods = ('chirp/wxui', 'chirp/cli', 'chirp/sources', 'chirp/drivers', 'chirp/locale', 'chirp/share', 'chirp/stock_configs', 'tools') base_modules = [mod for parent, mod in files_by_module if parent not in exclude_mods] if base_modules: print('Base modules touched; running all drivers: %s' % base_modules) driver_exp = [] elif driver_modules: driver_exp = ' or '.join(f for f in driver_modules) else: print('No driver tests necessary for changes in %s' % ','.join( files)) sys.exit(0) args = ['pytest'] if driver_exp: args += ['-k', driver_exp] args += sys.argv[1:] print(args) rc = subprocess.call(args) if rc == 5: # This means no tests were found likely because we generated a bad # tag, so just run the full set print('Running full driver set') rc = subprocess.call(['pytest'] + sys.argv[1:]) sys.exit(rc) chirp-20240224/tools/py3_driver_progress.py0000644000175000017500000001746214506756044017605 0ustar hibbyhibby#!/usr/bin/python3 import argparse import csv import os import sys import textwrap from chirp import directory directory.import_drivers() def tester_link(text): if text.startswith('@'): return '[%s](https://github.com/%s)' % (text, text[1:]) elif text.startswith('+'): assert text[1:] in directory.DRV_TO_RADIO, \ '%s is not in the driver directory' % text[1:] return '[Implied by %s](#user-content-%s)' % (text[1:], text[1:]) elif text.startswith('*'): assert os.path.exists(os.path.join('chirp', 'drivers', text[1:] + '.py')) return ('[Probably works](' 'https://github.com/kk7ds/chirp' '/blob/py3/chirp/drivers/%s.py)' % ( text[1:])) elif text.startswith('#') and text[1:].isdigit(): return ('[Reported working]' '(https://chirp.danplanet.com/issues/%i)' % int(text[1:])) else: return text def read_stats(statsfile): with open(statsfile) as f: lines = f.readlines() models = {} total = 0 skip = ['Repeaterbook', 'Radio Reference', 'CHIRP', 'CSV'] for line in lines[1:]: model, count = line.strip().split('\t') model = model.replace(' ', '_').\ replace('(', '').\ replace(')', '').\ replace('/', '_') if any(s in model for s in skip): continue count = int(count) models[model] = count total += count return total, models def read_testers(testersfile): headers = ['Driver', 'Tester', 'Tested'] line = 0 testers = {} for fields in csv.reader(open(testersfile)): line += 1 if fields[0][0] == '#': continue if len(fields) != len(headers): print('Error on line %i: invalid number of fields in: %s' % ( line, ','.join(fields)), file=sys.stderr) return 1 if fields[0] in testers: print('Error: duplicate driver %r in testers file' % fields[0], file=sys.stderr) return 2 testers[fields[0]] = fields[1:] return testers def get_share_for_radio(stats, stats_total, parent_cls): count = 0 for cls in [parent_cls] + parent_cls.ALIASES: driver = directory.radio_class_id(cls) simple_driver = '%s_%s' % (cls.VENDOR, cls.MODEL) if driver in stats: count += stats.pop(driver, 0) elif simple_driver in stats: count += stats.pop(simple_driver, 0) if count == 0: share = '' else: pct = (count * 100 / stats_total) share = '%.2f%%' % pct if pct > 1: share = '**%s**' % share return count, share def main(): p = argparse.ArgumentParser() p.add_argument('testers') p.add_argument('stats') p.add_argument('-o', '--output', default='-') args = p.parse_args() testers = read_testers(args.testers) stats_total, stats = read_stats(args.stats) if args.output == '-': output = sys.stdout else: output = open(args.output, 'w') print('## Status', file=output) print('| Driver | Tester | Tested | Byte Clean | "Market Share" |', file=output) print('| ------ | ------ | ------ | ---------- | -------------- |', file=output) drivers = sorted([ident for ident in directory.DRV_TO_RADIO]) drvstested = 0 byteclean = 0 tested_stats = 0 for driver in drivers: cls = directory.get_radio(driver) tester, tested = testers.pop(driver, ('', '')) if tester: drvstested += 1 count, share = get_share_for_radio(stats, stats_total, cls) if tester: tested_stats += count if not cls.NEEDS_COMPAT_SERIAL: byteclean += 1 print('| %s | %s | %s | %s | %s |' % ( driver, driver, tester_link(tester), tested, '' if cls.NEEDS_COMPAT_SERIAL else 'Yes', share), file=output) print('## Stats', file=output) print('\n**Drivers:** %i' % (len(drivers)), file=output) print('\n**Tested:** %i%% (%i/%i) (%i%% of usage stats)' % ( drvstested / len(drivers) * 100, drvstested, len(drivers) - drvstested, tested_stats * 100 / stats_total), file=output) print('\n**Byte clean:** %i%% (%i/%i)' % ( byteclean / len(drivers) * 100, byteclean, len(drivers) - byteclean), file=output) print(textwrap.dedent(""" ## Meaning of this testing The goal here is not necessarily to test the drivers themselves in terms of actual functionality, but rather to validate the Python 3 conversion work required of nearly all drivers. Thus, we are not trying to comprehensively test these models so much as make sure they work at least as well as they do on the Python 2 branch. Uncovering and reporting new bugs is definitely welcome, but for the purpoes of this effort, "no worse than the legacy branch" is good enough. There are multiple levels of confirmation in the matrix above: * Tested with real hardware (i.e. a person listed in the "Tester" column) using roughly the procedure below. * An "implied by (model)" link means that another model was tested, and it is so similar, that the model on that line can be considered tested as well. * A "probably works" link means that the driver has not been tested with real hardware, nor is it substantially similar to another model, but shares a common base that entirely provides the cloning routines with other drivers that have been tested with real hardware, such that confidence is high that it will work. Only drivers with test images in the tree (or live drivers) should be marked with this class. * A "unit tested" link means that the driver has not been tested with real hardware, nor does it share common cloning routines with another radio. However, synthetic simulation tests have been added to exercise the parts of the cloning routines that are likely to fail under python3. This is the lowest-confidence status and a real confirmation is needed. If you have a model listed in this matrix with either "implied" or "probably works" status, an actual confirmation with real hardware is welcome and can replace the weaker reference. ## Minimal test procedure For the purposes of the Python 3 effort, a "tested" radio means at least the following procedure was followed: 1. Download from the radio 1. Make some change to a memory 1. If the radio has settings support, make sure settings load and tweak one setting 1. Upload to the radio 1. Confirm that the changes stick and look correct, or at least are not a regression from the master py2 branch. The drivers are all passing the automated tests, but tests with real hardware and serial ports is important, especially around bytes-vs-string safety. To update this document, add/edit entries in `tests/py3_driver_testers.txt` and then run `tox -e makesupported`. Commit the result (including the changes to this `.md` file) and submit a PR. The "Byte Clean" flag refers to whether or not the radio has set the `NEEDS_COMPAT_SERIAL = False` flag on the radio class, and thus uses `MemoryMapBytes` exclusively internally. Whenever possible, all radios that are fixed for py3 should do so with this flag set to False and with the byte-native memory map."""), file=output) for driver, (tester, tested) in testers.items(): print('Error in testers file; driver %s by %s on %s unknown' % ( driver, tester, tested), file=sys.stderr) if testers: return 3 if __name__ == '__main__': sys.exit(main()) chirp-20240224/tools/cpep8.blacklist0000644000175000017500000000117214553436565016126 0ustar hibbyhibby# cpep8.blacklist: The list of files that do not meet PEP8 standards. # DO NOT ADD NEW FILES!! Instead, fix the code to be compliant. # Over time, this list should shrink and (eventually) be eliminated. ./chirp/drivers/kyd_IP620.py ./chirp/drivers/ft450d.py ./chirp/drivers/ft70.py ./chirp/drivers/hg_uv98.py ./chirp/drivers/hobbypcb.py ./chirp/drivers/retevis_rb28.py ./chirp/drivers/th7800.py ./chirp/drivers/icx90.py ./chirp/drivers/kguv8e.py ./chirp/drivers/rh5r_v2.py ./chirp/drivers/puxing_px888k.py ./chirp/drivers/ftlx011.py ./chirp/drivers/icv86.py ./chirp/drivers/fd268.py ./chirp/drivers/tk270.py ./chirp/drivers/bf_t1.py chirp-20240224/tools/cpep8.py0000755000175000017500000001133114551723752014602 0ustar hibbyhibby#!/usr/bin/env python # # cpep8.py - Check Python source files for PEP8 compliance. # # Copyright 2015 Zachary T Welch # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import warnings import os import sys import argparse import subprocess # pep8 has a FutureWarning about nested sets. This isn't our problem, so # squelch it here during import. with warnings.catch_warnings(): warnings.simplefilter('ignore') import pep8 parser = argparse.ArgumentParser() parser.add_argument("-a", "--all", action="store_true", help="Check all files, ignoring blacklist") parser.add_argument("-d", "--dir", action="append", default=['chirp', 'tests'], help="Root directory of source tree") parser.add_argument("-s", "--stats", action="store_true", help="Only show statistics") parser.add_argument("--strict", action="store_true", help="Ignore listed exceptions") parser.add_argument("-S", "--scan", action="store_true", help="Scan for additional files") parser.add_argument("-u", "--update", action="store_true", help="Update manifest/blacklist files") parser.add_argument("-v", "--verbose", action="store_true", help="Display list of checked files") parser.add_argument("files", metavar="file", nargs='*', help="List of files to check (if none, check all)") args = parser.parse_args() def file_to_lines(name): fh = open(name, "r") lines = fh.read().split("\n") lines.pop() fh.close() return [x for x in lines if not x.startswith('#')] scriptdir = os.path.dirname(sys.argv[0]) manifest_filename = os.path.join(scriptdir, "cpep8.manifest") blacklist_filename = os.path.join(scriptdir, "cpep8.blacklist") exceptions_filename = os.path.join(scriptdir, "cpep8.exceptions") cpep8_manifest = set(file_to_lines(manifest_filename)) flake8_manifest = set() for src_dir in [os.path.join('.', d) for d in args.dir]: for root, dirs, files in os.walk(src_dir): for f in files: filename = os.path.join(root, f) if filename.replace('\\', '/') in cpep8_manifest: continue if f.endswith('.py'): flake8_manifest.add(filename) continue with open(filename, "rb") as fh: shebang = fh.readline() if shebang.startswith(b"#!/usr/bin/env python"): flake8_manifest.add(filename) # unless we are being --strict, load per-file style exceptions exceptions = {} if not args.strict: exception_lines = file_to_lines(exceptions_filename) exception_lists = [x.split('\t') for x in exception_lines if not x.startswith('#')] for filename, codes in exception_lists: exceptions[filename] = codes def get_exceptions(f): try: ignore = exceptions[f] except KeyError: ignore = None return ignore if args.files: old_files = cpep8_manifest cpep8_manifest = [] flake8_manifest = [] for fn in args.files: if not fn.startswith('./'): fn = './' + fn if fn in old_files: cpep8_manifest.append(fn) else: flake8_manifest.append(fn) # read the blacklisted source files blacklist = file_to_lines(blacklist_filename) check_list = [] for f in cpep8_manifest: if args.all or f.replace('\\', '/') not in blacklist: check_list.append(f) check_list = sorted(check_list) total_errors = 0 for f in check_list: if args.verbose: print("Checking %s" % f) checker = pep8.Checker(f, quiet=args.stats, ignore=get_exceptions(f)) results = checker.check_all() if args.stats: checker.report.print_statistics() total_errors += results flake8_manifest = [f for f in flake8_manifest if f.replace('\\', '/') not in blacklist] for i in range(0, len(flake8_manifest), 10): files = flake8_manifest[i:i + 10] if args.verbose: print('Checking %s' % files) r = subprocess.call(['flake8', '--builtins=_,ngettext'] + files) if r != 0: total_errors += r sys.exit(total_errors and 1 or 0) chirp-20240224/tools/check_for_bug.sh0000755000175000017500000000033214411666130016313 0ustar hibbyhibby#!/usr/bin/env sh # This checks a given revision to make sure that it has a bug number # in it, of the form "#123". It should be used in your pretxncommit # hook hg log -r $1 --template {desc} | egrep -q "\#[0-9]+" chirp-20240224/tools/Makefile0000644000175000017500000000151214506756044014646 0ustar hibbyhibby# # # Makefile for serialsniff # # Author: IT2 Stuart Blake Tener, USNR (N3GWG) # # Version 1.00 # # This makefile checks to see if we are running under the OS "Darwin" # and passes the proper macro flag ("MACOS") if we are. # # Incidentally, it is noteworthy that MacOS (Darwin) is not the only # operating system which is deficient some of the library routines # MacOS is currently defficient. Thus, it is instructive that other # operating systems names might need to be added for compilation to # become occurring in their environments. # # ifndef SYSNAME SYSNAME := $(shell uname -s) ifeq ($(SYSNAME),Darwin) MYFLAGS := "-DMACOS" REMOVE := srm -vrfz else REMOVE := rm -rf endif endif serialsniff: serialsniff.c $(CC) $? -o $@ $(LDFLAGS) $(CFLAGS) $(MYFLAGS) clean: $(REMOVE) serialsniff *~ *.o *.bak core tags shar a.out chirp-20240224/requirements.txt0000644000175000017500000000040214563632215015323 0ustar hibbyhibbysix wxPython>=4.0,<4.2.0 ; platform_system=="Linux" # See https://github.com/wxWidgets/Phoenix/issues/2225 wxPython==4.2.0 ; platform_system!="Linux" pyserial requests pywin32; platform_system=="Windows" suds importlib-resources;python_version<"3.10" yattag chirp-20240224/setup.py0000644000175000017500000000133514566340176013564 0ustar hibbyhibbyfrom distutils.core import setup from setuptools import find_packages setup(name='chirp', description='A cross-platform cross-radio programming tool', packages=find_packages(include=["chirp*"]), include_package_data=True, version='20240224', url='https://chirp.danplanet.com', python_requires=">=3.7,<4", install_requires=[ 'pyserial', 'requests', 'six', 'importlib-resources;python_version<"3.10"', 'yattag', ], extras_require={ 'wx': ['wxPython'], }, entry_points={ 'console_scripts': ["chirp=chirp.wxui:chirpmain", "chirpc=chirp.cli.main:main"], }, )